@zerooneit/expressive-tea 1.3.0-beta.4 → 1.3.0-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/.eslintrc.js +44 -0
  2. package/.gitattributes +4 -0
  3. package/classes/Boot.d.ts +7 -4
  4. package/classes/Boot.js +53 -46
  5. package/classes/Engine.d.ts +15 -0
  6. package/classes/Engine.js +30 -0
  7. package/classes/LoadBalancer.js +1 -1
  8. package/classes/ProxyRoute.d.ts +3 -3
  9. package/decorators/annotations.d.ts +1 -1
  10. package/decorators/module.d.ts +4 -3
  11. package/decorators/module.js +2 -1
  12. package/decorators/proxy.d.ts +2 -2
  13. package/decorators/proxy.js +5 -1
  14. package/decorators/router.d.ts +4 -4
  15. package/decorators/router.js +6 -4
  16. package/decorators/server.d.ts +4 -4
  17. package/engines/constants/constants.d.ts +2 -0
  18. package/engines/constants/constants.js +5 -0
  19. package/engines/http/index.d.ts +5 -6
  20. package/engines/http/index.js +20 -22
  21. package/engines/socketio/index.d.ts +9 -0
  22. package/engines/socketio/index.js +23 -0
  23. package/engines/teacup/index.d.ts +5 -7
  24. package/engines/teacup/index.js +35 -52
  25. package/engines/teapot/index.d.ts +9 -10
  26. package/engines/teapot/index.js +51 -81
  27. package/engines/websocket/index.d.ts +5 -5
  28. package/engines/websocket/index.js +10 -13
  29. package/exceptions/RequestExceptions.d.ts +1 -1
  30. package/helpers/boot-helper.d.ts +2 -2
  31. package/helpers/boot-helper.js +3 -2
  32. package/helpers/promise-helper.d.ts +1 -0
  33. package/helpers/promise-helper.js +7 -0
  34. package/helpers/server.d.ts +5 -5
  35. package/helpers/server.js +12 -10
  36. package/helpers/teapot-helper.d.ts +6 -4
  37. package/helpers/teapot-helper.js +19 -4
  38. package/helpers/websocket-helper.d.ts +2 -2
  39. package/interfaces/index.d.ts +4 -0
  40. package/interfaces/index.js +2 -0
  41. package/inversify.config.d.ts +4 -4
  42. package/package.json +42 -33
  43. package/services/DependencyInjection.d.ts +4 -2
  44. package/services/DependencyInjection.js +2 -2
  45. package/services/WebsocketService.d.ts +2 -2
  46. package/tsconfig.linter.json +24 -0
  47. package/tslint-to-eslint-config.log +12 -0
  48. package/.circleci/config.yml +0 -58
@@ -2,15 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const chalk = require("chalk");
5
- const url = require("url");
6
- // tslint:disable-next-line:no-duplicate-imports
5
+ const url_1 = require("url");
7
6
  const socket_io_client_1 = require("socket.io-client");
8
7
  const inversify_1 = require("inversify");
9
8
  const Metadata_1 = require("@expressive-tea/commons/classes/Metadata");
10
9
  const constants_1 = require("@expressive-tea/commons/constants");
11
10
  const teapot_helper_1 = require("../../helpers/teapot-helper");
12
11
  const object_helper_1 = require("@expressive-tea/commons/helpers/object-helper");
13
- let TeacupEngine = class TeacupEngine {
12
+ const Engine_1 = require("../../classes/Engine");
13
+ let TeacupEngine = class TeacupEngine extends Engine_1.default {
14
14
  header() {
15
15
  console.log(chalk.white.bold('Teacup Engine is initializing...'));
16
16
  console.log(chalk `
@@ -25,83 +25,66 @@ let TeacupEngine = class TeacupEngine {
25
25
  All Communication are encrypted to ensure intruder can not connected, however, please does not share any sensitive data like keys or passwords to avoid security issues.
26
26
  `);
27
27
  }
28
- constructor(ctx, settings, server, serverSecure) {
29
- this.server = server;
30
- this.serverSecure = serverSecure;
31
- this.settings = settings;
32
- this.context = ctx;
33
- this.teacupSettings = Metadata_1.default.get(constants_1.ASSIGN_TEACUP_KEY, (0, object_helper_1.getClass)(this.context));
34
- this.isActive = Metadata_1.default.get(constants_1.ASSIGN_TEACUP_KEY, (0, object_helper_1.getClass)(this.context), 'isTeacupActive');
35
- if (!this.isActive) {
36
- return;
37
- }
38
- const scheme = url.parse(this.teacupSettings.serverUrl);
39
- const { publicKey, privateKey } = teapot_helper_1.default.generateKeys(this.teacupSettings.clientKey);
40
- this.publicKey = publicKey;
41
- this.privateKey = privateKey;
42
- this.clientSignature = teapot_helper_1.default.sign(this.teacupSettings.clientKey, this.privateKey, this.teacupSettings.clientKey);
43
- this.client = (0, socket_io_client_1.io)(`http://${scheme.host}`, {
44
- path: '/teapot',
45
- reconnection: true,
46
- autoConnect: false
47
- });
48
- }
49
- handshaked(data) {
28
+ handshaked(key, signature, isSecure, cb) {
50
29
  try {
51
- console.log(chalk `{cyan.bold [TEACUP]} - [{magenta.bold ${this.client.id}}]: {yellow.bold Started Verification}`);
52
- const serverPublicKey = Buffer.from(data.key, 'base64').toString('ascii');
53
- const serverSignature = Buffer.from(data.signature, 'base64');
54
- if (teapot_helper_1.default.verify(this.teacupSettings.clientKey, serverPublicKey, serverSignature)) {
55
- console.log(chalk `{cyan.bold [TEACUP]} - [{magenta.bold ${this.client.id}}]: {green.bold Verified}`);
56
- this.publicServerKey = serverPublicKey;
57
- this.serverSignature = serverSignature;
58
- this.client.emit('handshake', {
59
- key: Buffer.from(this.publicKey).toString('base64'),
60
- signature: this.clientSignature.toString('base64')
61
- });
62
- return;
30
+ console.log(chalk `{cyan.bold [TEACUP]} - [{magenta.bold ${this.client.id}}]: {yellow.bold Server Verification Started}`);
31
+ if (!teapot_helper_1.default.verify(this.teacupSettings.clientKey, key.toString('ascii'), signature)) {
32
+ throw new Error('Fail to Verify Client on Teapod.');
63
33
  }
64
- throw new Error('Fail to Verify Client on Teapod.');
34
+ console.log(chalk `{cyan.bold [TEACUP]} - [{magenta.bold ${this.client.id}}]: {green.bold Server Has Been Verified}`);
35
+ this.publicServerKey = key;
36
+ this.serverSignature = signature;
37
+ cb(Buffer.from(this.publicKey), this.clientSignature);
65
38
  }
66
39
  catch (e) {
67
40
  console.error(chalk `{cyan.bold [TEACUP]} - {red.bold TEAPOD} {magenta.bold ${this.client.id}}: Failed with next message: ${e.message}`);
68
41
  this.client.disconnect();
69
42
  }
70
43
  }
71
- accepted() {
44
+ accepted(cb) {
72
45
  var _a;
73
46
  console.log(chalk `{cyan.bold [TEACUP]} - [{magenta.bold ${this.client.id}}]: {green.bold Registered} - {blue.bold <${this.teacupSettings.serverUrl}>} <-> {white.bold ${this.teacupSettings.mountTo}}`);
74
- this.client.emit('register', teapot_helper_1.default.encrypt({
47
+ const encryptedMessage = teapot_helper_1.default.encrypt({
75
48
  mountTo: this.teacupSettings.mountTo,
76
49
  address: this.teacupSettings.address
77
- }, this.serverSignature.slice(0, 32)));
50
+ }, this.serverSignature.slice(0, 32));
51
+ cb(encryptedMessage);
78
52
  const onClose = () => {
79
53
  try {
80
54
  this.client.close();
81
55
  }
82
- catch (_) { }
56
+ catch (_) {
57
+ }
83
58
  };
84
59
  this.server.on('close', onClose);
85
60
  (_a = this.serverSecure) === null || _a === void 0 ? void 0 : _a.on('close', onClose);
86
61
  }
87
62
  async start() {
88
- if (!this.isActive) {
89
- return;
90
- }
63
+ this.teacupSettings = Metadata_1.default.get(constants_1.ASSIGN_TEACUP_KEY, (0, object_helper_1.getClass)(this.context));
64
+ const scheme = new url_1.URL(this.teacupSettings.serverUrl);
65
+ const { publicKey, privateKey } = teapot_helper_1.default.generateKeys(this.teacupSettings.clientKey);
66
+ const protocol = teapot_helper_1.default.httpSchema(scheme.protocol);
67
+ this.publicKey = publicKey;
68
+ this.privateKey = privateKey;
69
+ this.clientSignature = teapot_helper_1.default.sign(this.teacupSettings.clientKey, this.privateKey, this.teacupSettings.clientKey);
70
+ this.client = (0, socket_io_client_1.io)(`${protocol}//${scheme.host}/teapot`, {
71
+ path: '/exp-tea/',
72
+ reconnection: true,
73
+ autoConnect: false
74
+ });
91
75
  this.header();
76
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
92
77
  this.client.on('handshake', this.handshaked.bind(this));
78
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
93
79
  this.client.on('accepted', this.accepted.bind(this));
94
80
  this.client.on('error', console.log);
95
81
  this.client.connect();
96
82
  }
83
+ static canRegister(ctx, settings) {
84
+ return Metadata_1.default.get(constants_1.ASSIGN_TEACUP_KEY, (0, object_helper_1.getClass)(ctx), 'isTeacupActive');
85
+ }
97
86
  };
98
87
  TeacupEngine = tslib_1.__decorate([
99
- (0, inversify_1.injectable)(),
100
- tslib_1.__param(0, (0, inversify_1.inject)('context')),
101
- tslib_1.__param(1, (0, inversify_1.inject)('settings')),
102
- tslib_1.__param(2, (0, inversify_1.inject)('server')),
103
- tslib_1.__param(3, (0, inversify_1.inject)('secureServer')),
104
- tslib_1.__param(3, (0, inversify_1.optional)()),
105
- tslib_1.__metadata("design:paramtypes", [Object, Object, Object, Object])
88
+ (0, inversify_1.injectable)()
106
89
  ], TeacupEngine);
107
90
  exports.default = TeacupEngine;
@@ -1,23 +1,22 @@
1
- export default class TeapotEngine {
2
- private readonly settings;
3
- private readonly context;
4
- private readonly server;
5
- private readonly serverSecure?;
6
- private clients;
7
- private registeredRoute;
1
+ import ExpressiveTeaEngine from '../../classes/Engine';
2
+ import Boot from '../../classes/Boot';
3
+ import Settings from '../../classes/Settings';
4
+ export default class TeapotEngine extends ExpressiveTeaEngine {
5
+ private readonly clients;
6
+ private readonly registeredRoute;
8
7
  private teapotSettings;
9
8
  private publicKey;
10
9
  private privateKey;
11
- private isActive;
12
10
  private serverSignature;
13
11
  private socketServer;
14
12
  private static header;
15
13
  private registerTeacup;
16
- private acceptedHandshake;
14
+ private clientVerification;
17
15
  private registered;
18
16
  private removeFromRoutes;
19
17
  private findClientInRoutes;
20
18
  private disconnected;
21
- constructor(ctx: any, server: any, serverSecure: any, settings: any);
19
+ init(): Promise<void>;
22
20
  start(): Promise<void>;
21
+ static canRegister(ctx?: Boot, settings?: Settings): boolean;
23
22
  }
@@ -4,11 +4,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const tslib_1 = require("tslib");
5
5
  const chalk = require("chalk");
6
6
  const inversify_1 = require("inversify");
7
- const ProxyRoute_1 = require("../../classes/ProxyRoute");
8
7
  const Metadata_1 = require("@expressive-tea/commons/classes/Metadata");
9
8
  const constants_1 = require("@expressive-tea/commons/constants");
9
+ const ProxyRoute_1 = require("../../classes/ProxyRoute");
10
+ const Engine_1 = require("../../classes/Engine");
10
11
  const teapot_helper_1 = require("../../helpers/teapot-helper");
11
- let TeapotEngine = TeapotEngine_1 = class TeapotEngine {
12
+ const constants_2 = require("../constants/constants");
13
+ const object_helper_1 = require("@expressive-tea/commons/helpers/object-helper");
14
+ let TeapotEngine = TeapotEngine_1 = class TeapotEngine extends Engine_1.default {
15
+ constructor() {
16
+ super(...arguments);
17
+ this.clients = new Map();
18
+ this.registeredRoute = new Map();
19
+ }
12
20
  static header(teapotSettings) {
13
21
  console.log(chalk.white.bold('Teapot Engine is initializing...'));
14
22
  console.log(chalk `
@@ -28,64 +36,46 @@ All Communication are encrypted to ensure intruder can not connected, however, p
28
36
  }
29
37
  registerTeacup(teacup) {
30
38
  console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${teacup.id}}]: {grey.bold Connected}`);
31
- teacup.emit('handshake', {
32
- key: Buffer.from(this.publicKey).toString('base64'),
33
- signature: this.serverSignature.toString('base64')
34
- });
35
- teacup.on('handshake', this.acceptedHandshake.bind(teacup, this));
36
- teacup.on('register', this.registered.bind(teacup, this));
37
- teacup.on('disconnect', this.disconnected.bind(teacup, this));
39
+ teacup.emit('handshake', Buffer.from(this.publicKey), this.serverSignature, Boolean(this.serverSecure), this.clientVerification.bind(this, teacup));
40
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
41
+ teacup.on('disconnect', this.disconnected.bind(this, teacup));
38
42
  }
39
- acceptedHandshake(ctx, data) {
40
- const self = this;
43
+ clientVerification(teacup, userPublicKey, userSignature) {
44
+ console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${teacup.id}}]: {yellow.bold Client Verification Started}`);
45
+ console.log('userKey', userPublicKey.toString('base64'));
46
+ console.log('userSignature', userSignature.toString('base64'));
41
47
  try {
42
- console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${self.id}}]: {yellow.bold Start Verification}`);
43
- const clientPublicKey = Buffer.from(data.key, 'base64').toString('ascii');
44
- const clientSignature = Buffer.from(data.signature, 'base64');
45
- if (teapot_helper_1.default.verify(ctx.teapotSettings.clientKey, clientPublicKey, clientSignature)) {
46
- console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${self.id}}]: {green.bold Verified correctly}`);
47
- ctx.clients.set(self.id, {
48
- publicKey: clientPublicKey,
49
- signature: clientSignature
50
- });
51
- self.emit('accepted', teapot_helper_1.default.encrypt({
52
- signature: ctx.serverSignature.toString('base64')
53
- }, clientSignature.slice(0, 32)));
54
- return;
48
+ if (!teapot_helper_1.default.verify(this.teapotSettings.clientKey, userPublicKey.toString('ascii'), userSignature)) {
49
+ console.log(chalk `{cyan.bold [TEAPOT]} - {red.bold TEACUP} [{magenta.bold ${teacup.id}}]: Failed to verify and will be disconnected...`);
50
+ return teacup.disconnect();
55
51
  }
56
- console.log(chalk `{cyan.bold [TEAPOT]} - {red.bold TEACUP} [{magenta.bold ${self.id}}]: Failed to verify and will be disconnected...`);
57
- self.disconnect();
52
+ this.clients.set(teacup.id, {
53
+ publicKey: userPublicKey,
54
+ signature: userSignature
55
+ });
56
+ teacup.emit('accepted', this.registered.bind(this, teacup));
57
+ console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${teacup.id}}]: {green.bold Client Verified}`);
58
58
  }
59
59
  catch (e) {
60
- console.log(chalk `{cyan.bold [TEAPOT]} - {red.bold TEACUP} [{magenta.bold ${self.id}}]: Failed wiht next message: ${e.message}`);
61
- self.disconnect();
60
+ console.log(chalk `{cyan.bold [TEAPOT]} - {red.bold TEACUP} [{magenta.bold ${teacup.id}}]: Failed wiht next message: ${e.message}`);
61
+ teacup.disconnect();
62
62
  }
63
63
  }
64
- registered(ctx, data) {
65
- const self = this;
64
+ registered(teacup, encryptedMessage) {
66
65
  try {
67
- const message = teapot_helper_1.default.decrypt(data, ctx.serverSignature.slice(0, 32));
68
- let proxyRoute;
69
- if (ctx.registeredRoute.has(message.mountTo)) {
70
- proxyRoute = ctx.registeredRoute.get(message.mountTo);
71
- proxyRoute.registerServer(message.address, self.id);
72
- }
73
- else {
74
- proxyRoute = new ProxyRoute_1.default(message.mountTo);
75
- proxyRoute.registerServer(message.address, self.id);
76
- ctx.registeredRoute.set(message.mountTo, proxyRoute);
77
- ctx.context.getApplication().use(message.mountTo, (req, res, next) => {
78
- const router = proxyRoute.registerRoute();
79
- if (!proxyRoute.hasClients()) {
80
- return next();
81
- }
82
- return router(req, res, next);
83
- });
66
+ const message = teapot_helper_1.default.decrypt(encryptedMessage, this.serverSignature.slice(0, 32));
67
+ const isRegistered = this.registeredRoute.has(message.mountTo);
68
+ const proxyRoute = isRegistered ? this.registeredRoute.get(message.mountTo) : new ProxyRoute_1.default(message.mountTo);
69
+ proxyRoute.registerServer(message.address, teacup.id);
70
+ if (!isRegistered) {
71
+ this.registeredRoute.set(message.mountTo, proxyRoute);
72
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
73
+ this.context.getApplication().use(message.mountTo, teapot_helper_1.default.proxyResponse.bind(this, proxyRoute));
84
74
  }
85
- console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${self.id}}] {blue.bold <${message.address}>} <--> {white.bold ${message.mountTo}}`);
75
+ console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${teacup.id}}] {blue.bold <${message.address}>} <--> {white.bold ${message.mountTo}}`);
86
76
  }
87
77
  catch (e) {
88
- console.log(chalk `{cyan.bold [TEAPOT]} - {red.bold TEACUP} {magenta.bold ${self.id}}: Failed wiht next message: ${e.message}`);
78
+ console.log(chalk `{cyan.bold [TEAPOT]} - {red.bold TEACUP} {magenta.bold ${teacup.id}}: Failed wiht next message: ${e.message}`);
89
79
  }
90
80
  }
91
81
  removeFromRoutes(routes = [], id) {
@@ -103,54 +93,34 @@ All Communication are encrypted to ensure intruder can not connected, however, p
103
93
  });
104
94
  return routes;
105
95
  }
106
- disconnected(ctx, reason) {
107
- const self = this;
96
+ disconnected(teacup, reason) {
108
97
  try {
109
- const routes = ctx.findClientInRoutes(self.id);
110
- ctx.removeFromRoutes(routes, self.id);
111
- console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${self.id}}]: Got disconnected by ${reason}`);
98
+ const routes = this.findClientInRoutes(teacup.id);
99
+ this.removeFromRoutes(routes, teacup.id);
100
+ console.log(chalk `{cyan.bold [TEAPOT]} - {blue TEACUP} [{magenta.bold ${teacup.id}}]: Got disconnected by ${reason}`);
112
101
  }
113
102
  catch (e) {
114
- console.log(chalk `{cyan.bold [TEAPOT]} - {red.bold TEACUP} {magenta.bold ${self.id}}: Failed wiht next message: ${e.message}`);
103
+ console.log(chalk `{cyan.bold [TEAPOT]} - {red.bold TEACUP} {magenta.bold ${teacup.id}}: Failed wiht next message: ${e.message}`);
115
104
  }
116
105
  }
117
- constructor(ctx, server, serverSecure, settings) {
118
- this.clients = new Map();
119
- this.registeredRoute = new Map();
120
- this.settings = settings;
121
- this.context = ctx;
122
- this.server = server;
123
- this.serverSecure = serverSecure;
124
- this.isActive = Metadata_1.default.get(constants_1.ASSIGN_TEAPOT_KEY, this.context, 'isTeapotActive');
106
+ async init() {
125
107
  this.teapotSettings = Metadata_1.default.get(constants_1.ASSIGN_TEAPOT_KEY, this.context);
126
- if (!this.isActive) {
127
- return;
128
- }
129
108
  const { publicKey, privateKey } = teapot_helper_1.default.generateKeys(this.teapotSettings.serverKey);
130
109
  this.publicKey = publicKey;
131
110
  this.privateKey = privateKey;
132
111
  this.serverSignature = teapot_helper_1.default.sign(this.teapotSettings.clientKey, privateKey, this.teapotSettings.serverKey);
133
- this.socketServer = require('socket.io')({
134
- path: '/teapot',
135
- cookie: false
136
- });
137
112
  }
138
113
  async start() {
139
- if (!this.isActive) {
140
- return;
141
- }
114
+ this.socketServer = Metadata_1.default.get(constants_2.SOCKET_IO_INSTANCE_KEY, this.context).of('/teapot');
142
115
  TeapotEngine_1.header(this.teapotSettings);
116
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
143
117
  this.socketServer.on('connection', this.registerTeacup.bind(this));
144
- this.socketServer.listen(this.server);
118
+ }
119
+ static canRegister(ctx, settings) {
120
+ return Metadata_1.default.get(constants_1.ASSIGN_TEAPOT_KEY, (0, object_helper_1.getClass)(ctx), 'isTeapotActive');
145
121
  }
146
122
  };
147
123
  TeapotEngine = TeapotEngine_1 = tslib_1.__decorate([
148
- (0, inversify_1.injectable)(),
149
- tslib_1.__param(0, (0, inversify_1.inject)('context')),
150
- tslib_1.__param(1, (0, inversify_1.inject)('server')),
151
- tslib_1.__param(2, (0, inversify_1.inject)('secureServer')),
152
- tslib_1.__param(2, (0, inversify_1.optional)()),
153
- tslib_1.__param(3, (0, inversify_1.inject)('settings')),
154
- tslib_1.__metadata("design:paramtypes", [Object, Object, Object, Object])
124
+ (0, inversify_1.injectable)()
155
125
  ], TeapotEngine);
156
126
  exports.default = TeapotEngine;
@@ -1,9 +1,9 @@
1
- export default class WebsocketEngine {
2
- private readonly settings;
3
- private readonly server;
4
- private readonly serverSecure?;
1
+ import ExpressiveTeaEngine from '../../classes/Engine';
2
+ import Boot from '../../classes/Boot';
3
+ import Settings from '../../classes/Settings';
4
+ export default class WebsocketEngine extends ExpressiveTeaEngine {
5
5
  canStart: boolean;
6
6
  isDetached: boolean;
7
- constructor(server: any, serverSecure: any, settings: any);
8
7
  init(): Promise<void>;
8
+ static canRegister(ctx?: Boot, settings?: Settings): boolean;
9
9
  }
@@ -4,17 +4,16 @@ const tslib_1 = require("tslib");
4
4
  const WebsocketService_1 = require("../../services/WebsocketService");
5
5
  const WebSocket = require("ws");
6
6
  const inversify_1 = require("inversify");
7
- let WebsocketEngine = class WebsocketEngine {
8
- constructor(server, serverSecure, settings) {
7
+ const Engine_1 = require("../../classes/Engine");
8
+ let WebsocketEngine = class WebsocketEngine extends Engine_1.default {
9
+ constructor() {
10
+ super(...arguments);
9
11
  this.canStart = false;
10
12
  this.isDetached = false;
11
- this.settings = settings;
12
- this.server = server;
13
- this.serverSecure = serverSecure;
14
- this.canStart = this.settings.get('startWebsocket');
15
- this.isDetached = this.settings.get('detachWebsocket');
16
13
  }
17
14
  async init() {
15
+ this.canStart = this.settings.get('startWebsocket');
16
+ this.isDetached = this.settings.get('detachWebsocket');
18
17
  if (this.canStart) {
19
18
  WebsocketService_1.default.init();
20
19
  WebsocketService_1.default.getInstance().setWebSocket(new WebSocket.Server(this.isDetached ? { noServer: true } : { server: this.server }));
@@ -25,13 +24,11 @@ let WebsocketEngine = class WebsocketEngine {
25
24
  WebsocketService_1.default.getInstance().setHttpServer(this.serverSecure);
26
25
  }
27
26
  }
27
+ static canRegister(ctx, settings) {
28
+ return settings.get('startWebsocket');
29
+ }
28
30
  };
29
31
  WebsocketEngine = tslib_1.__decorate([
30
- (0, inversify_1.injectable)(),
31
- tslib_1.__param(0, (0, inversify_1.inject)('server')),
32
- tslib_1.__param(1, (0, inversify_1.inject)('secureServer')),
33
- tslib_1.__param(1, (0, inversify_1.optional)()),
34
- tslib_1.__param(2, (0, inversify_1.inject)('settings')),
35
- tslib_1.__metadata("design:paramtypes", [Object, Object, Object])
32
+ (0, inversify_1.injectable)()
36
33
  ], WebsocketEngine);
37
34
  exports.default = WebsocketEngine;
@@ -25,7 +25,7 @@
25
25
  export declare class GenericRequestException extends Error {
26
26
  statusCode: number;
27
27
  message: string;
28
- constructor(message: any, statusCode?: number);
28
+ constructor(message: string | never, statusCode?: number);
29
29
  }
30
30
  /**
31
31
  * Shortcut Exception for 400 HTTP Errors (Bad Request).
@@ -1,6 +1,6 @@
1
1
  import { BOOT_STAGES } from '@expressive-tea/commons/constants';
2
- import { Express } from 'express';
3
- import Boot from '../classes/Boot';
2
+ import { type Express } from 'express';
3
+ import type Boot from '../classes/Boot';
4
4
  export declare function resolveStage(stage: BOOT_STAGES, ctx: Boot, server: Express, ...extraArgs: unknown[]): Promise<void>;
5
5
  export declare function resolveDirectives(instance: typeof Boot | Boot, server: Express): Promise<void>;
6
6
  export declare function resolveStatic(instance: typeof Boot | Boot, server: Express): Promise<void>;
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
- // tslint:disable:no-duplicate-imports
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
4
3
  exports.resolveProxy = exports.resolveStatic = exports.resolveDirectives = exports.resolveStage = void 0;
5
4
  const constants_1 = require("@expressive-tea/commons/constants");
@@ -24,7 +23,9 @@ exports.resolveStage = resolveStage;
24
23
  async function resolveDirectives(instance, server) {
25
24
  const registeredDirectives = Metadata_1.default.get(constants_1.REGISTERED_DIRECTIVES_KEY, (0, object_helper_1.getClass)(instance)) || [];
26
25
  registeredDirectives.forEach((options) => {
27
- server.set.call(server, options.name, ...options.settings);
26
+ // @ts-expect-error Settings can be any parameter
27
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
28
+ server.set(options.name, ...options.settings);
28
29
  });
29
30
  }
30
31
  exports.resolveDirectives = resolveDirectives;
@@ -0,0 +1 @@
1
+ export declare function delay(ms: number): Promise<unknown>;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.delay = void 0;
4
+ async function delay(ms) {
5
+ return new Promise(resolve => setTimeout(resolve, ms));
6
+ }
7
+ exports.delay = delay;
@@ -1,9 +1,9 @@
1
- import { NextFunction, Request, Response } from 'express';
2
- import { ExpressiveTeaAnnotations, ExpressiveTeaArgumentOptions } from '@expressive-tea/commons/interfaces';
1
+ import { type NextFunction, type Request, type Response } from 'express';
2
+ import { type ExpressiveTeaAnnotations, type ExpressiveTeaArgumentOptions } from '@expressive-tea/commons/interfaces';
3
3
  export declare function autoResponse(request: Request, response: Response, annotations: ExpressiveTeaAnnotations[], responseResult?: any): void;
4
4
  export declare function executeRequest(request: Request, response: Response, next: NextFunction): Promise<void>;
5
- export declare function mapArguments(decoratedArguments: ExpressiveTeaArgumentOptions[], request: Request, response: Response, next: NextFunction, introspectedArgs?: string[]): unknown[];
6
- export declare function extractParameters(target: unknown, args?: string | string[], propertyName?: string | symbol): any;
5
+ export declare function mapArguments(decoratedArguments: ExpressiveTeaArgumentOptions[], request: Request, response: Response, next: NextFunction, introspectedArgs?: string[]): any[];
6
+ export declare function extractParameters(target: unknown, args?: string | string[], propertyName?: string): any;
7
7
  export declare function generateRoute(route: string, verb: string, ...settings: any): (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => void;
8
- export declare function router(verb: string, route: string, target: any, handler: (...args: any[]) => void | any | Promise<any>, propertyKey: string | symbol, settings?: any): void;
8
+ export declare function router(verb: string, route: string, target: any, handler: (...args: any[]) => never | any | Promise<any>, propertyKey: string | symbol, settings?: any): void;
9
9
  export declare function fileSettings(): any;
package/helpers/server.js CHANGED
@@ -10,7 +10,8 @@ const fs = require("fs");
10
10
  function autoResponse(request, response, annotations, responseResult) {
11
11
  const view = (0, lodash_1.find)(annotations, { type: 'view' });
12
12
  if (view) {
13
- return response.render(view.arguments[0], responseResult);
13
+ response.render(view.arguments[0], responseResult);
14
+ return;
14
15
  }
15
16
  response.send((0, lodash_1.isNumber)(responseResult) ? responseResult.toString() : responseResult);
16
17
  }
@@ -22,14 +23,15 @@ async function executeRequest(request, response, next) {
22
23
  next(error);
23
24
  isNextUsed = true;
24
25
  };
25
- const result = await this.options.handler.apply(this.self, mapArguments(this.decoratedArguments, request, response, nextWrapper(), (0, object_helper_1.getOwnArgumentNames)(this.options.handler)));
26
+ const result = await this.options.handler.apply(this.self, mapArguments(this.decoratedArguments, request, response, nextWrapper(), this.options.introspectedArgs));
26
27
  if (!response.headersSent && !isNextUsed) {
27
28
  autoResponse(request, response, this.annotations, result);
28
29
  }
29
30
  }
30
31
  catch (e) {
31
32
  if (e instanceof RequestExceptions_1.GenericRequestException) {
32
- return next(e);
33
+ next(e);
34
+ return;
33
35
  }
34
36
  next(new RequestExceptions_1.GenericRequestException(e.message || 'System Error'));
35
37
  }
@@ -39,7 +41,6 @@ function mapArguments(decoratedArguments, request, response, next, introspectedA
39
41
  return (0, lodash_1.chain)(decoratedArguments)
40
42
  .sortBy('index')
41
43
  .map((argument) => {
42
- const argumentKey = (0, lodash_1.get)(introspectedArgs, argument.index);
43
44
  switch (argument.type) {
44
45
  case constants_1.ARGUMENT_TYPES.REQUEST:
45
46
  return request;
@@ -48,13 +49,13 @@ function mapArguments(decoratedArguments, request, response, next, introspectedA
48
49
  case constants_1.ARGUMENT_TYPES.NEXT:
49
50
  return next;
50
51
  case constants_1.ARGUMENT_TYPES.QUERY:
51
- return extractParameters(request.query, argument.arguments, argumentKey);
52
+ return extractParameters(request.query, argument.arguments, (0, lodash_1.get)(introspectedArgs, argument.index));
52
53
  case constants_1.ARGUMENT_TYPES.BODY:
53
- return extractParameters(request.body, argument.arguments, argumentKey);
54
+ return extractParameters(request.body, argument.arguments, (0, lodash_1.get)(introspectedArgs, argument.index));
54
55
  case constants_1.ARGUMENT_TYPES.GET_PARAM:
55
- return extractParameters(request.params, argument.arguments, argumentKey);
56
+ return extractParameters(request.params, argument.arguments, (0, lodash_1.get)(introspectedArgs, argument.index));
56
57
  default:
57
- return;
58
+ return undefined;
58
59
  }
59
60
  })
60
61
  .thru((args) => (0, lodash_1.size)(args) ? args : [request, response, next])
@@ -78,12 +79,13 @@ function extractParameters(target, args, propertyName) {
78
79
  }
79
80
  exports.extractParameters = extractParameters;
80
81
  function generateRoute(route, verb, ...settings) {
81
- return (target, propertyKey, descriptor) => router(verb, route, target, descriptor.value, propertyKey, settings);
82
+ return (target, propertyKey, descriptor) => { router(verb, route, target, descriptor.value, propertyKey, settings); };
82
83
  }
83
84
  exports.generateRoute = generateRoute;
84
85
  function router(verb, route, target, handler, propertyKey, settings) {
86
+ const introspectedArgs = (0, object_helper_1.getOwnArgumentNames)(handler);
85
87
  const existedRoutesHandlers = Metadata_1.default.get(constants_1.ROUTER_HANDLERS_KEY, target) || [];
86
- existedRoutesHandlers.unshift({ verb, route, handler, target, propertyKey, settings });
88
+ existedRoutesHandlers.unshift({ verb, route, handler, target, propertyKey, settings, introspectedArgs });
87
89
  Metadata_1.default.set(constants_1.ROUTER_HANDLERS_KEY, existedRoutesHandlers, target);
88
90
  }
89
91
  exports.router = router;
@@ -1,17 +1,19 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- import { KeyPairSyncResult } from 'crypto';
3
+ import { type KeyPairSyncResult } from 'crypto';
4
+ import { type NextFunction, type Request, type Response } from 'express';
5
+ import type ProxyRoute from '../classes/ProxyRoute';
4
6
  export interface EncryptedMessage {
5
7
  iv: string;
6
8
  message: string;
7
9
  }
8
- export interface TeaGatewayMessage {
9
- [property: string]: any;
10
- }
10
+ export type TeaGatewayMessage = Record<string, any>;
11
11
  export default class TeaGatewayHelper {
12
12
  static encrypt(data: TeaGatewayMessage, signature: Buffer): EncryptedMessage;
13
13
  static decrypt(data: EncryptedMessage, signature: Buffer): TeaGatewayMessage;
14
14
  static sign(data: string, privateKey: string, passphrase: string): Buffer;
15
15
  static verify(data: string, publicKey: string, signature: Buffer): boolean;
16
16
  static generateKeys(passphrase: string): KeyPairSyncResult<any, any>;
17
+ static proxyResponse(proxyRoute: ProxyRoute, req: Request, res: Response, next: NextFunction): void;
18
+ static httpSchema(schema: string): "http:" | "https:";
17
19
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const crypto = require("crypto");
4
+ const crypto_1 = require("crypto");
4
5
  class TeaGatewayHelper {
5
6
  static encrypt(data, signature) {
6
7
  const iv = crypto.randomBytes(16);
@@ -17,19 +18,18 @@ class TeaGatewayHelper {
17
18
  return JSON.parse(decrypted.toString());
18
19
  }
19
20
  static sign(data, privateKey, passphrase) {
20
- return crypto.sign('sha256', Buffer.from(data), {
21
+ return crypto.sign(null, Buffer.from(data), {
21
22
  key: privateKey,
22
23
  passphrase
23
24
  });
24
25
  }
25
26
  static verify(data, publicKey, signature) {
26
- return crypto.verify('sha256', Buffer.from(data), {
27
+ return crypto.verify(null, Buffer.from(data), {
27
28
  key: publicKey
28
29
  }, signature);
29
30
  }
30
31
  static generateKeys(passphrase) {
31
- const { generateKeyPairSync } = require('crypto');
32
- return generateKeyPairSync('rsa', {
32
+ return (0, crypto_1.generateKeyPairSync)('ed25519', {
33
33
  modulusLength: 2048,
34
34
  publicKeyEncoding: {
35
35
  type: 'spki',
@@ -43,5 +43,20 @@ class TeaGatewayHelper {
43
43
  }
44
44
  });
45
45
  }
46
+ static proxyResponse(proxyRoute, req, res, next) {
47
+ const router = proxyRoute.registerRoute();
48
+ if (!proxyRoute.hasClients()) {
49
+ next();
50
+ return;
51
+ }
52
+ router(req, res, next);
53
+ }
54
+ static httpSchema(schema) {
55
+ if (schema.includes('teapot'))
56
+ return 'http:';
57
+ if (schema.includes('teapots'))
58
+ return 'https:';
59
+ throw new Error(`Invalid Schema: ${schema}`);
60
+ }
46
61
  }
47
62
  exports.default = TeaGatewayHelper;
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- import * as http from 'http';
4
- import * as https from 'https';
3
+ import type * as http from 'http';
4
+ import type * as https from 'https';
5
5
  export declare function initWebsocket(server: http.Server, secureServer: https.Server): Promise<void>;
@@ -0,0 +1,4 @@
1
+ import { type ExpressiveTeaHandlerOptions } from '@expressive-tea/commons/interfaces';
2
+ export interface ExpressiveTeaHandlerOptionsWithInstrospectedArgs extends ExpressiveTeaHandlerOptions {
3
+ introspectedArgs: string[];
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });