bdy 1.8.3-dev → 1.8.4-dev

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 (112) hide show
  1. package/distTs/bin/cli.js +5 -0
  2. package/distTs/src/agent/linux.js +119 -0
  3. package/distTs/src/agent/manager.js +395 -0
  4. package/distTs/src/agent/osx.js +139 -0
  5. package/distTs/src/agent/socket/tunnel.js +212 -0
  6. package/distTs/src/agent/socket.js +220 -0
  7. package/distTs/src/agent/system.js +177 -0
  8. package/distTs/src/agent/wait.js +23 -0
  9. package/distTs/src/agent/windows.js +159 -0
  10. package/distTs/src/agent.js +237 -0
  11. package/distTs/src/api/agent.js +84 -0
  12. package/distTs/src/api/buddy.js +117 -0
  13. package/distTs/src/api/socket.js +133 -0
  14. package/distTs/src/cfg.js +238 -0
  15. package/distTs/src/command/agent/install.js +106 -0
  16. package/distTs/src/command/agent/restart.js +27 -0
  17. package/distTs/src/command/agent/run.js +19 -0
  18. package/distTs/src/command/agent/start.js +28 -0
  19. package/distTs/src/command/agent/status.js +35 -0
  20. package/distTs/src/command/agent/stop.js +28 -0
  21. package/distTs/src/command/agent/tunnel/http.js +44 -0
  22. package/distTs/src/command/agent/tunnel/list.js +27 -0
  23. package/distTs/src/command/agent/tunnel/remove.js +28 -0
  24. package/distTs/src/command/agent/tunnel/start.js +34 -0
  25. package/distTs/src/command/agent/tunnel/status.js +31 -0
  26. package/distTs/src/command/agent/tunnel/tcp.js +43 -0
  27. package/distTs/src/command/agent/tunnel/tls.js +43 -0
  28. package/distTs/src/command/agent/tunnel.js +23 -0
  29. package/distTs/src/command/agent/uninstall.js +38 -0
  30. package/distTs/src/command/agent/update.js +38 -0
  31. package/distTs/src/command/agent/version.js +21 -0
  32. package/distTs/src/command/agent.js +29 -0
  33. package/distTs/src/command/config/add/http.js +25 -0
  34. package/distTs/src/command/config/add/tcp.js +25 -0
  35. package/distTs/src/command/config/add/tls.js +25 -0
  36. package/distTs/src/command/config/add.js +15 -0
  37. package/distTs/src/command/config/get/region.js +15 -0
  38. package/distTs/src/command/config/get/timeout.js +15 -0
  39. package/distTs/src/command/config/get/token.js +15 -0
  40. package/distTs/src/command/config/get/tunnel.js +19 -0
  41. package/distTs/src/command/config/get/tunnels.js +15 -0
  42. package/distTs/src/command/config/get/whitelist.js +15 -0
  43. package/distTs/src/command/config/get.js +21 -0
  44. package/distTs/src/command/config/remove/tunnel.js +19 -0
  45. package/distTs/src/command/config/remove.js +11 -0
  46. package/distTs/src/command/config/set/region.js +17 -0
  47. package/distTs/src/command/config/set/timeout.js +17 -0
  48. package/distTs/src/command/config/set/token.js +16 -0
  49. package/distTs/src/command/config/set/whitelist.js +17 -0
  50. package/distTs/src/command/config/set.js +17 -0
  51. package/distTs/src/command/config.js +17 -0
  52. package/distTs/src/command/http.js +30 -0
  53. package/distTs/src/command/pre.js +49 -0
  54. package/distTs/src/command/start.js +28 -0
  55. package/distTs/src/command/tcp.js +30 -0
  56. package/distTs/src/command/tls.js +30 -0
  57. package/distTs/src/command/version.js +13 -0
  58. package/distTs/src/command/vt/close.js +28 -0
  59. package/distTs/src/command/vt/exec.js +79 -0
  60. package/distTs/src/command/vt/storybook.js +90 -0
  61. package/distTs/src/command/vt.js +15 -0
  62. package/distTs/src/format.js +172 -0
  63. package/distTs/src/index.js +40 -0
  64. package/distTs/src/input.js +286 -0
  65. package/distTs/src/logger.js +93 -0
  66. package/distTs/src/output/interactive/tunnel.js +860 -0
  67. package/distTs/src/output/noninteractive/agent/tunnels.js +43 -0
  68. package/distTs/src/output/noninteractive/config/tunnel.js +67 -0
  69. package/distTs/src/output/noninteractive/config/tunnels.js +18 -0
  70. package/distTs/src/output/noninteractive/tunnel.js +59 -0
  71. package/distTs/src/output.js +138 -0
  72. package/distTs/src/server/cert.js +52 -0
  73. package/distTs/src/server/http1.js +74 -0
  74. package/distTs/src/server/http2.js +74 -0
  75. package/distTs/src/server/sftp.js +487 -0
  76. package/distTs/src/server/ssh.js +112 -0
  77. package/distTs/src/server/tls.js +41 -0
  78. package/distTs/src/ssh/client.js +191 -0
  79. package/distTs/src/texts.js +345 -0
  80. package/distTs/src/tunnel/agent.js +100 -0
  81. package/distTs/src/tunnel/compression.js +41 -0
  82. package/distTs/src/tunnel/dns.js +54 -0
  83. package/distTs/src/tunnel/html.js +30 -0
  84. package/distTs/src/tunnel/http/log.js +196 -0
  85. package/distTs/src/tunnel/http/serve.js +132 -0
  86. package/distTs/src/tunnel/http/stream.js +45 -0
  87. package/distTs/src/tunnel/http.js +405 -0
  88. package/distTs/src/tunnel/identification.js +96 -0
  89. package/distTs/src/tunnel/latency.js +71 -0
  90. package/distTs/src/tunnel/tcp.js +92 -0
  91. package/distTs/src/tunnel.js +647 -0
  92. package/distTs/src/types/ciInfo.js +10 -0
  93. package/distTs/src/types/options.js +2 -0
  94. package/distTs/src/types/plugin.js +2 -0
  95. package/distTs/src/types/queue.js +2 -0
  96. package/distTs/src/types/requests.js +2 -0
  97. package/distTs/src/types/resources.js +2 -0
  98. package/distTs/src/types/snapshots.js +2 -0
  99. package/distTs/src/types/storybook.js +2 -0
  100. package/distTs/src/utils.js +437 -0
  101. package/distTs/src/visualTest/browser.js +32 -0
  102. package/distTs/src/visualTest/ci.js +206 -0
  103. package/distTs/src/visualTest/context.js +44 -0
  104. package/distTs/src/visualTest/exec.js +51 -0
  105. package/distTs/src/visualTest/queue.js +43 -0
  106. package/distTs/src/visualTest/requests.js +197 -0
  107. package/distTs/src/visualTest/resources.js +195 -0
  108. package/distTs/src/visualTest/server.js +33 -0
  109. package/distTs/src/visualTest/snapshots.js +109 -0
  110. package/distTs/src/visualTest/utils/parseDom.js +238 -0
  111. package/distTs/src/visualTest/validation.js +18 -0
  112. package/package.json +1 -1
@@ -0,0 +1,647 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const basic_auth_1 = __importDefault(require("basic-auth"));
7
+ const utils_js_1 = require("./utils.js");
8
+ const latency_js_1 = __importDefault(require("./tunnel/latency.js"));
9
+ const client_js_1 = __importDefault(require("./ssh/client.js"));
10
+ const events_1 = __importDefault(require("events"));
11
+ const tcp_js_1 = __importDefault(require("./tunnel/tcp.js"));
12
+ const tls_js_1 = __importDefault(require("./server/tls.js"));
13
+ const ssh_js_1 = __importDefault(require("./server/ssh.js"));
14
+ const logger_js_1 = __importDefault(require("./logger.js"));
15
+ const identification_js_1 = __importDefault(require("./tunnel/identification.js"));
16
+ const http_js_1 = __importDefault(require("./tunnel/http.js"));
17
+ const http2_js_1 = __importDefault(require("./server/http2.js"));
18
+ const http1_js_1 = __importDefault(require("./server/http1.js"));
19
+ const log_js_1 = __importDefault(require("./tunnel/http/log.js"));
20
+ const format_1 = __importDefault(require("./format"));
21
+ const texts_js_1 = require("./texts.js");
22
+ const dns_js_1 = __importDefault(require("./tunnel/dns.js"));
23
+ class Tunnel extends events_1.default {
24
+ constructor({ id, type, target, region, timeout, domain, subdomain, whitelist, tlsSettings, httpSettings, sshSettings, sshHostKey, }) {
25
+ super();
26
+ if (!sshHostKey)
27
+ sshHostKey = (0, utils_js_1.createSshHostKey)();
28
+ this.id = id;
29
+ this.sshHostKey = sshHostKey;
30
+ this.create({
31
+ type,
32
+ target,
33
+ region,
34
+ timeout,
35
+ domain,
36
+ subdomain,
37
+ whitelist,
38
+ tlsSettings,
39
+ httpSettings,
40
+ sshSettings,
41
+ });
42
+ }
43
+ create({ type, target, region, timeout, domain, subdomain, whitelist, tlsSettings, httpSettings, sshSettings, }) {
44
+ this.type = type;
45
+ this.region = region;
46
+ this.target = target;
47
+ this.whitelist = whitelist || [];
48
+ this.domain = domain;
49
+ this.subdomain = subdomain;
50
+ this.timeout = timeout || utils_js_1.DEFAULT_TIMEOUT;
51
+ this.useragents = [];
52
+ this.headers = [];
53
+ this.responseHeaders = [];
54
+ if (tlsSettings) {
55
+ this.terminate = tlsSettings.terminate;
56
+ this.key = tlsSettings.key;
57
+ this.cert = tlsSettings.cert;
58
+ this.ca = tlsSettings.ca;
59
+ }
60
+ if (httpSettings) {
61
+ this.host = httpSettings.host;
62
+ this.login = httpSettings.login;
63
+ this.password = httpSettings.password;
64
+ this.ca = httpSettings.ca;
65
+ this.serve = httpSettings.serve;
66
+ this.useragents = httpSettings.userAgents || [];
67
+ this.headers = httpSettings.headers || [];
68
+ this.responseHeaders = httpSettings.responseHeaders || [];
69
+ this.circuitBreaker = httpSettings.circuitBreaker;
70
+ this.log = httpSettings.log;
71
+ this.verify = httpSettings.verify;
72
+ this.compression = httpSettings.compression;
73
+ this.http2 = httpSettings.http2;
74
+ }
75
+ if (sshSettings) {
76
+ this.sshIp = sshSettings.ip;
77
+ this.sshId = sshSettings.sshId;
78
+ this.sshPort = sshSettings.port;
79
+ this.sshUser = sshSettings.user;
80
+ this.sshPassword = sshSettings.password;
81
+ this.sshForwardPort = sshSettings.forwardPort;
82
+ this.sshClientUser = sshSettings.clientUser;
83
+ this.sshClientPassword = sshSettings.clientPassword;
84
+ }
85
+ this.targetProto = 'http';
86
+ this.targetHost = 'localhost';
87
+ this.targetPort = 80;
88
+ this.targetAuth = null;
89
+ if (this.type === utils_js_1.TUNNEL_HTTP) {
90
+ let m = this.target.match(utils_js_1.TARGET_ONLY_PORT_REGEX);
91
+ if (m) {
92
+ this.targetPort = parseInt(m[0], 10);
93
+ }
94
+ else {
95
+ m = this.target.match(utils_js_1.TARGET_HTTP_REGEX);
96
+ if (m) {
97
+ if (m[2])
98
+ this.targetProto = m[2];
99
+ if (m[6])
100
+ this.targetPort = parseInt(m[6], 10);
101
+ else if (this.targetProto === 'https')
102
+ this.targetPort = 443;
103
+ if (m[4])
104
+ this.targetHost = m[4];
105
+ if (m[3])
106
+ this.targetAuth = m[3].replace(/@$/, '');
107
+ }
108
+ }
109
+ }
110
+ else if (this.type === utils_js_1.TUNNEL_SSH) {
111
+ this.targetHost = 'localhost';
112
+ this.targetProto = 'ssh://';
113
+ this.targetPort = 22;
114
+ }
115
+ else {
116
+ const m = this.target.match(utils_js_1.TARGET_TCP_TLS_REGEX);
117
+ if (m) {
118
+ this.targetPort = parseInt(m[3], 10);
119
+ if (m[2])
120
+ this.targetHost = m[2];
121
+ }
122
+ }
123
+ this.connections = {};
124
+ this.totalConnections = 0;
125
+ this.status = utils_js_1.TUNNEL_CLOSED;
126
+ this.dns = null;
127
+ this.regionLatency = null;
128
+ this.targetLatency = null;
129
+ this.tls = null;
130
+ this.httpLog = null;
131
+ this.identify = null;
132
+ this.http2server = null;
133
+ this.http1server = null;
134
+ this.sshServer = null;
135
+ this.ssh = null;
136
+ this.started = false;
137
+ }
138
+ recreate({ type, target, region, timeout, domain, subdomain, whitelist, tlsSettings, httpSettings, sshSettings, }) {
139
+ const started = this.started;
140
+ this.stop(false);
141
+ this.create({
142
+ type,
143
+ target,
144
+ region,
145
+ timeout,
146
+ domain,
147
+ subdomain,
148
+ whitelist,
149
+ tlsSettings,
150
+ httpSettings,
151
+ sshSettings,
152
+ });
153
+ if (started)
154
+ this.start();
155
+ }
156
+ hasChanged(data) {
157
+ const tunnel = new Tunnel({
158
+ ...data,
159
+ sshHostKey: this.sshHostKey,
160
+ });
161
+ if (this.type !== tunnel.type)
162
+ return true;
163
+ if (this.target !== tunnel.target)
164
+ return true;
165
+ if (this.region !== tunnel.region)
166
+ return true;
167
+ if (this.timeout !== tunnel.timeout)
168
+ return true;
169
+ if (this.domain !== tunnel.domain)
170
+ return true;
171
+ if (this.subdomain !== tunnel.subdomain)
172
+ return true;
173
+ if (this.terminate !== tunnel.terminate)
174
+ return true;
175
+ if (this.key !== tunnel.key)
176
+ return true;
177
+ if (this.cert !== tunnel.cert)
178
+ return true;
179
+ if (this.ca !== tunnel.ca)
180
+ return true;
181
+ if (this.host !== tunnel.host)
182
+ return true;
183
+ if (this.login !== tunnel.login)
184
+ return true;
185
+ if (this.password !== tunnel.password)
186
+ return true;
187
+ if (this.serve !== tunnel.serve)
188
+ return true;
189
+ if (this.circuitBreaker !== tunnel.circuitBreaker)
190
+ return true;
191
+ if (this.log !== tunnel.log)
192
+ return true;
193
+ if (this.verify !== tunnel.verify)
194
+ return true;
195
+ if (this.http2 !== tunnel.http2)
196
+ return true;
197
+ if (this.compression !== tunnel.compression)
198
+ return true;
199
+ if (this.sshIp !== tunnel.sshIp)
200
+ return true;
201
+ if (this.sshId !== tunnel.sshId)
202
+ return true;
203
+ if (this.sshPort !== tunnel.sshPort)
204
+ return true;
205
+ if (this.sshUser !== tunnel.sshUser)
206
+ return true;
207
+ if (this.sshPassword !== tunnel.sshPassword)
208
+ return true;
209
+ if (this.sshForwardPort !== tunnel.sshForwardPort)
210
+ return true;
211
+ if (this.sshClientPassword !== tunnel.sshClientPassword)
212
+ return true;
213
+ if (this.sshClientUser !== tunnel.sshClientUser)
214
+ return true;
215
+ if (this.whitelist.length !== tunnel.whitelist.length)
216
+ return true;
217
+ this.whitelist.sort();
218
+ tunnel.whitelist.sort();
219
+ for (let i = 0; i < this.whitelist.length; i += 1) {
220
+ if (this.whitelist[i] !== tunnel.whitelist[i])
221
+ return true;
222
+ }
223
+ if (this.useragents.length !== tunnel.useragents.length)
224
+ return true;
225
+ this.useragents.sort();
226
+ tunnel.useragents.sort();
227
+ for (let i = 0; i < this.useragents.length; i += 1) {
228
+ if (this.useragents[i] !== tunnel.useragents[i])
229
+ return true;
230
+ }
231
+ const sortHeaders = (a, b) => a.name.localeCompare(b.name);
232
+ if (this.headers.length !== tunnel.headers.length)
233
+ return true;
234
+ this.headers.sort(sortHeaders);
235
+ tunnel.headers.sort(sortHeaders);
236
+ for (let i = 0; i < this.headers.length; i += 1) {
237
+ const thisH = this.headers[i];
238
+ const tunnelH = tunnel.headers[i];
239
+ if (thisH.name !== tunnelH.name)
240
+ return true;
241
+ if (thisH.value !== tunnelH.value)
242
+ return true;
243
+ }
244
+ if (this.responseHeaders.length !== tunnel.responseHeaders.length)
245
+ return true;
246
+ this.responseHeaders.sort(sortHeaders);
247
+ tunnel.responseHeaders.sort(sortHeaders);
248
+ for (let i = 0; i < this.responseHeaders.length; i += 1) {
249
+ const thisRH = this.responseHeaders[i];
250
+ const tunnelRH = tunnel.responseHeaders[i];
251
+ if (thisRH.name !== tunnelRH.name)
252
+ return true;
253
+ if (thisRH.value !== tunnelRH.value)
254
+ return true;
255
+ }
256
+ return false;
257
+ }
258
+ async sshConnected() {
259
+ try {
260
+ logger_js_1.default.debug((0, texts_js_1.LOG_TUNNEL_CONNECTED)(this.id, this.sshForwardPort));
261
+ await this.ssh.forwardIn(this.sshForwardPort);
262
+ this.status = utils_js_1.TUNNEL_OPEN;
263
+ }
264
+ catch (err) {
265
+ // reconnect
266
+ logger_js_1.default.debug((0, texts_js_1.LOG_TUNNEL_FAILED)(this.id));
267
+ logger_js_1.default.debug(err);
268
+ this.ssh.close();
269
+ return;
270
+ }
271
+ this.emit(utils_js_1.TUNNEL_EVENT_OPEN, this);
272
+ }
273
+ sshDisconnected() {
274
+ if (this.status !== utils_js_1.TUNNEL_CLOSED) {
275
+ logger_js_1.default.debug((0, texts_js_1.LOG_TUNNEL_DISCONNECTED)(this.id));
276
+ this.status = utils_js_1.TUNNEL_CLOSED;
277
+ this.emit(utils_js_1.TUNNEL_EVENT_CLOSED, this);
278
+ }
279
+ }
280
+ tunnelToTarget(stream, onClose) {
281
+ this.totalConnections += 1;
282
+ const tcp = new tcp_js_1.default(this.targetHost, this.targetPort, stream);
283
+ this.connections[tcp.id] = tcp;
284
+ tcp.on(utils_js_1.TCP_EVENT_CLOSED, () => {
285
+ this.connections[tcp.id].removeAllListeners();
286
+ delete this.connections[tcp.id];
287
+ onClose();
288
+ });
289
+ tcp.pipe();
290
+ }
291
+ httpIdentified(type) {
292
+ logger_js_1.default.info((0, texts_js_1.LOG_TUNNEL_IDENTIFIED)(this.id, type));
293
+ this.emit(utils_js_1.TUNNEL_EVENT_HTTP_IDENTIFIED, this, type);
294
+ }
295
+ httpConnectionOpen(s) {
296
+ this.totalConnections += 1;
297
+ this.connections[s.id] = s;
298
+ this.emit(utils_js_1.TUNNEL_EVENT_HTTP_OPEN, this);
299
+ }
300
+ httpConnectionClosed(s) {
301
+ delete this.connections[s.id];
302
+ this.emit(utils_js_1.TUNNEL_EVENT_HTTP_CLOSED, this);
303
+ }
304
+ httpBasicAuth(req, res) {
305
+ if (this.login || this.password) {
306
+ const user = (0, basic_auth_1.default)(req);
307
+ if (!user || user.name !== this.login || user.pass !== this.password) {
308
+ logger_js_1.default.debug(texts_js_1.LOG_TUNNEL_HTTP_WRON_AUTH);
309
+ this.httpEndFast(req, res, 401, 'Unauthorised', {
310
+ 'WWW-Authenticate': 'Basic real="Buddy"',
311
+ });
312
+ return false;
313
+ }
314
+ }
315
+ return true;
316
+ }
317
+ httpEndFast(req, res, statusCode, msg, headers = {}) {
318
+ const log = this.httpLog.newRequest(req.method, req.headers, req.url, req.httpVersion, req);
319
+ if (!log) {
320
+ this.httpLog.newResponse(req, statusCode, headers);
321
+ res.statusCode = statusCode;
322
+ Object.keys(headers).forEach((k) => {
323
+ res.setHeader(k, headers[k]);
324
+ });
325
+ res.end(msg);
326
+ }
327
+ else {
328
+ req.pipe(log.requestBody);
329
+ log.requestBody.pipeToNothing(() => {
330
+ this.httpLog.newResponse(req, statusCode, headers, log);
331
+ res.statusCode = statusCode;
332
+ Object.keys(headers).forEach((k) => {
333
+ res.setHeader(k, headers[k]);
334
+ });
335
+ res.end(msg);
336
+ });
337
+ }
338
+ }
339
+ httpRateLimit(req, res) {
340
+ const isRateLimited = this.httpLog.isRateLimited(req);
341
+ if (isRateLimited) {
342
+ logger_js_1.default.debug(texts_js_1.LOG_TUNNEL_HTTP_RATE_LIMIT);
343
+ this.httpEndFast(req, res, 429, 'Too Many Requests', {
344
+ 'Retry-After': '60',
345
+ });
346
+ return false;
347
+ }
348
+ return true;
349
+ }
350
+ httpCircuitBreaker(req, res) {
351
+ const isOpen = this.httpLog.isCircuitBreakerOpen();
352
+ if (isOpen) {
353
+ logger_js_1.default.debug(texts_js_1.LOG_TUNNEL_HTTP_CIRCUIT_BREAKER_OPEN);
354
+ this.httpEndFast(req, res, 503, 'Service Unavailable', {});
355
+ return false;
356
+ }
357
+ return true;
358
+ }
359
+ httpUserAgent(req, res) {
360
+ if (this.useragents && this.useragents.length > 0) {
361
+ const ua = req.headers['user-agent'] || '';
362
+ for (let i = 0; i < this.useragents.length; i += 1) {
363
+ const str = this.useragents[i];
364
+ if ((0, utils_js_1.isStringRegExp)(str)) {
365
+ try {
366
+ const r = new RegExp(str, 'i');
367
+ if (r.test(ua))
368
+ return true;
369
+ }
370
+ catch {
371
+ // do nothing
372
+ }
373
+ }
374
+ else if (ua.includes(str)) {
375
+ return true;
376
+ }
377
+ }
378
+ logger_js_1.default.debug(texts_js_1.LOG_TUNNEL_HTTP_WRONG_USER_AGENTS);
379
+ this.httpEndFast(req, res, 401, 'Unauthorised', {});
380
+ return false;
381
+ }
382
+ return true;
383
+ }
384
+ targetReconnected() {
385
+ if (this.identify)
386
+ this.identify.identify();
387
+ }
388
+ httpLogRequest(logRequest) {
389
+ this.emit(utils_js_1.TUNNEL_EVENT_HTTP_REQUEST, this, logRequest);
390
+ }
391
+ httpLogResponse(logRequest) {
392
+ this.emit(utils_js_1.TUNNEL_EVENT_HTTP_RESPONSE, this, logRequest);
393
+ }
394
+ retryHttpLogRequest(logRequest) {
395
+ if (logRequest.requestBody.tooLarge)
396
+ return;
397
+ if (logRequest.httpVersion === '2.0')
398
+ return this.http2server.retryRequest(logRequest);
399
+ return this.http1server.retryRequest(logRequest);
400
+ }
401
+ httpRequest(req, res) {
402
+ const isAuth = this.httpBasicAuth(req, res) &&
403
+ this.httpUserAgent(req, res) &&
404
+ this.httpRateLimit(req, res) &&
405
+ this.httpCircuitBreaker(req, res);
406
+ if (!isAuth)
407
+ return;
408
+ const http = new http_js_1.default({
409
+ req,
410
+ res,
411
+ auth: this.targetAuth,
412
+ proto: this.targetProto,
413
+ host: this.targetHost,
414
+ port: this.targetPort,
415
+ hostHeader: this.host,
416
+ timeout: this.timeout,
417
+ verify: this.verify,
418
+ compression: this.compression,
419
+ headers: this.headers,
420
+ serve: this.serve,
421
+ responseHeaders: this.responseHeaders,
422
+ httpIdentify: this.identify.type,
423
+ httpLog: this.httpLog,
424
+ });
425
+ http.pipe().then();
426
+ }
427
+ tlsSocket(tlsSocket) {
428
+ this.tunnelToTarget(tlsSocket, () => {
429
+ this.emit(utils_js_1.TUNNEL_EVENT_TLS_CLOSED, this);
430
+ });
431
+ this.emit(utils_js_1.TUNNEL_EVENT_TLS_OPEN, this);
432
+ }
433
+ canStreamTcp() {
434
+ if (this.type === utils_js_1.TUNNEL_TCP)
435
+ return true;
436
+ return (this.type === utils_js_1.TUNNEL_TLS &&
437
+ [utils_js_1.TLS_TERMINATE_AT_TARGET, utils_js_1.TLS_TERMINATE_AT_REGION].includes(this.terminate));
438
+ }
439
+ canStreamTls() {
440
+ return this.type === utils_js_1.TUNNEL_TLS;
441
+ }
442
+ canStreamSsh() {
443
+ return this.type === utils_js_1.TUNNEL_SSH;
444
+ }
445
+ canStreamHttp() {
446
+ return this.type === utils_js_1.TUNNEL_HTTP;
447
+ }
448
+ safeEndStream(stream) {
449
+ try {
450
+ stream.removeAllListeners();
451
+ stream.once('error', () => { });
452
+ stream.end();
453
+ }
454
+ catch {
455
+ // do nothing
456
+ }
457
+ setTimeout(() => {
458
+ try {
459
+ stream.destroy();
460
+ }
461
+ catch {
462
+ // do nothing
463
+ }
464
+ }, 1000);
465
+ }
466
+ sshStreamTcp(stream) {
467
+ if (!this.canStreamTcp()) {
468
+ this.safeEndStream(stream);
469
+ return;
470
+ }
471
+ logger_js_1.default.debug((0, texts_js_1.LOG_TUNNEL_TCP_STREAM)(this.id));
472
+ this.tunnelToTarget(stream, () => {
473
+ this.emit(utils_js_1.TUNNEL_EVENT_TCP_CLOSED, this);
474
+ });
475
+ this.emit(utils_js_1.TUNNEL_EVENT_TCP_OPEN, this);
476
+ }
477
+ sshStreamHttp1(stream, info, ip) {
478
+ if (!this.canStreamHttp()) {
479
+ this.safeEndStream(stream);
480
+ return;
481
+ }
482
+ logger_js_1.default.debug((0, texts_js_1.LOG_TUNNEL_HTTP1_STREAM)(this.id));
483
+ if (this.http1server) {
484
+ this.http1server.handleSshTunnel(stream, info, ip);
485
+ return;
486
+ }
487
+ this.safeEndStream(stream);
488
+ }
489
+ sshStreamHttp2(stream, info, ip) {
490
+ if (!this.canStreamHttp()) {
491
+ this.safeEndStream(stream);
492
+ return;
493
+ }
494
+ logger_js_1.default.debug((0, texts_js_1.LOG_TUNNEL_HTTP2_STREAM)(this.id));
495
+ if (this.http2server) {
496
+ this.http2server.handleSshTunnel(stream, info, ip);
497
+ return;
498
+ }
499
+ this.safeEndStream(stream);
500
+ }
501
+ sshStreamSsh(stream) {
502
+ if (!this.canStreamSsh()) {
503
+ this.safeEndStream(stream);
504
+ return;
505
+ }
506
+ logger_js_1.default.debug((0, texts_js_1.LOG_TUNNEL_SSH_STREAM)(this.id));
507
+ if (this.sshServer) {
508
+ this.sshServer.handleSshTunnel(stream);
509
+ return;
510
+ }
511
+ this.safeEndStream(stream);
512
+ }
513
+ sshStreamTls(stream) {
514
+ if (!this.canStreamTls()) {
515
+ this.safeEndStream(stream);
516
+ return;
517
+ }
518
+ if (this.terminate === utils_js_1.TLS_TERMINATE_AT_TARGET) {
519
+ logger_js_1.default.debug((0, texts_js_1.LOG_TUNNEL_TLS_TARGET_STREAM)(this.id));
520
+ this.sshStreamTcp(stream);
521
+ return;
522
+ }
523
+ if (this.terminate === utils_js_1.TLS_TERMINATE_AT_REGION) {
524
+ logger_js_1.default.debug((0, texts_js_1.LOG_TUNNEL_TLS_REGION_STREAM)(this.id));
525
+ this.sshStreamTcp(stream);
526
+ return;
527
+ }
528
+ if (this.tls) {
529
+ logger_js_1.default.debug((0, texts_js_1.LOG_TUNNEL_TLS_AGENT_STREAM)(this.id));
530
+ this.tls.handleSshTunnel(stream);
531
+ return;
532
+ }
533
+ this.safeEndStream(stream);
534
+ }
535
+ start() {
536
+ if (this.started)
537
+ return;
538
+ this.started = true;
539
+ logger_js_1.default.info((0, texts_js_1.LOG_STARTING_TUNNEL)(this.id));
540
+ // region latency
541
+ this.regionLatency = new latency_js_1.default(this.sshIp, this.sshPort);
542
+ this.regionLatency.startChecking();
543
+ // target latency
544
+ if (!this.serve && this.type !== utils_js_1.TUNNEL_SSH) {
545
+ this.targetLatency = new latency_js_1.default(this.targetHost, this.targetPort);
546
+ this.targetLatency.on(utils_js_1.TUNNEL_LATENCY_EVENT_RECONNECTED, () => this.targetReconnected());
547
+ this.targetLatency.startChecking();
548
+ }
549
+ // dns health
550
+ this.dns = new dns_js_1.default(this.sshIp, this.domain, this.subdomain, this.region, this.sshId);
551
+ this.dns.startChecking();
552
+ if (this.type === utils_js_1.TUNNEL_TLS && this.terminate === utils_js_1.TLS_TERMINATE_AT_AGENT) {
553
+ // tls
554
+ this.tls = new tls_js_1.default(this.key, this.cert, this.ca);
555
+ this.tls.on(utils_js_1.TLS_SOCKET, (socket) => this.tlsSocket(socket));
556
+ }
557
+ else if (this.type === utils_js_1.TUNNEL_HTTP) {
558
+ // http
559
+ this.httpLog = new log_js_1.default(this.log, this.circuitBreaker);
560
+ this.httpLog.on(utils_js_1.EVENT_TUNNEL_HTTP_NEW_REQUEST, (logRequest) => this.httpLogRequest(logRequest));
561
+ this.httpLog.on(utils_js_1.EVENT_TUNNEL_HTTP_NEW_RESPONSE, (logRequest) => this.httpLogResponse(logRequest));
562
+ this.identify = new identification_js_1.default(this.targetProto, this.targetHost, this.targetPort, this.http2 || !!this.serve);
563
+ this.identify.on(utils_js_1.EVENT_TUNNEL_IDENTIFIED, (type) => this.httpIdentified(type));
564
+ const host = format_1.default.entryHost(this);
565
+ this.http2server = new http2_js_1.default(host);
566
+ this.http2server.on(utils_js_1.HTTP2_SESSION_OPEN, (session) => this.httpConnectionOpen(session));
567
+ this.http2server.on(utils_js_1.HTTP2_SESSION_CLOSED, (session) => this.httpConnectionClosed(session));
568
+ this.http2server.on(utils_js_1.HTTP2_REQUEST, (req, res) => this.httpRequest(req, res));
569
+ this.http1server = new http1_js_1.default(host);
570
+ this.http1server.on(utils_js_1.HTTP1_SOCKET_OPEN, (socket) => this.httpConnectionOpen(socket));
571
+ this.http1server.on(utils_js_1.HTTP1_SOCKET_CLOSED, (socket) => this.httpConnectionClosed(socket));
572
+ this.http1server.on(utils_js_1.HTTP1_REQUEST, (req, res) => this.httpRequest(req, res));
573
+ }
574
+ else if (this.type === utils_js_1.TUNNEL_SSH) {
575
+ // ssh server
576
+ this.sshServer = new ssh_js_1.default(this.sshClientUser, this.sshClientPassword, this.sshHostKey);
577
+ }
578
+ // ssh
579
+ this.ssh = new client_js_1.default(this.sshIp, this.sshPort, this.sshUser, this.sshPassword);
580
+ this.ssh.on(utils_js_1.SSH_CLIENT_EVENT_CONNECTED, () => this.sshConnected());
581
+ this.ssh.on(utils_js_1.SSH_CLIENT_EVENT_DISCONNECTED, () => this.sshDisconnected());
582
+ this.ssh.on(utils_js_1.SSH_CLIENT_EVENT_STREAM_TCP, (stream) => this.sshStreamTcp(stream));
583
+ this.ssh.on(utils_js_1.SSH_CLIENT_EVENT_STREAM_TLS, (stream) => this.sshStreamTls(stream));
584
+ this.ssh.on(utils_js_1.SSH_CLIENT_EVENT_STREAM_HTTP1, (stream, info, ip) => this.sshStreamHttp1(stream, info, ip));
585
+ this.ssh.on(utils_js_1.SSH_CLIENT_EVENT_STREAM_HTTP2, (stream, info, ip) => this.sshStreamHttp2(stream, info, ip));
586
+ this.ssh.on(utils_js_1.SSH_CLIENT_EVENT_STREAM_SSH, (stream) => this.sshStreamSsh(stream));
587
+ this.ssh.openKeepAlive();
588
+ }
589
+ stop(emitEvent = true) {
590
+ if (!this.started)
591
+ return;
592
+ this.started = false;
593
+ logger_js_1.default.info((0, texts_js_1.LOG_STOPPING_TUNNEL)(this.id));
594
+ if (emitEvent)
595
+ this.emit(utils_js_1.TUNNEL_EVENT_STOPPED, this);
596
+ if (this.regionLatency) {
597
+ this.regionLatency.removeAllListeners();
598
+ this.regionLatency.stopChecking();
599
+ this.regionLatency = null;
600
+ }
601
+ if (this.dns) {
602
+ this.dns.stopChecking();
603
+ this.dns = null;
604
+ }
605
+ if (this.targetLatency) {
606
+ this.targetLatency.removeAllListeners();
607
+ this.targetLatency.stopChecking();
608
+ this.targetLatency = null;
609
+ }
610
+ if (this.tls) {
611
+ this.tls.removeAllListeners();
612
+ this.tls.stop();
613
+ this.tls = null;
614
+ }
615
+ if (this.httpLog) {
616
+ this.httpLog.removeAllListeners();
617
+ this.httpLog.stop();
618
+ this.httpLog = null;
619
+ }
620
+ if (this.sshServer) {
621
+ this.sshServer.removeAllListeners();
622
+ this.sshServer.stop();
623
+ this.sshServer = null;
624
+ }
625
+ if (this.identify) {
626
+ this.identify.removeAllListeners();
627
+ this.identify.stop();
628
+ this.identify = null;
629
+ }
630
+ if (this.http2server) {
631
+ this.http2server.removeAllListeners();
632
+ this.http2server.stop();
633
+ this.http2server = null;
634
+ }
635
+ if (this.http1server) {
636
+ this.http1server.removeAllListeners();
637
+ this.http1server.stop();
638
+ this.http1server = null;
639
+ }
640
+ if (this.ssh) {
641
+ this.ssh.removeAllListeners();
642
+ this.ssh.closeKeepAlive();
643
+ this.ssh = null;
644
+ }
645
+ }
646
+ }
647
+ exports.default = Tunnel;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CI = void 0;
4
+ var CI;
5
+ (function (CI) {
6
+ CI["BUDDY"] = "BUDDY";
7
+ CI["GITHUB_ACTION"] = "GITHUB_ACTION";
8
+ CI["CIRCLE_CI"] = "CIRCLE_CI";
9
+ CI["NONE"] = "NONE";
10
+ })(CI || (exports.CI = CI = {}));
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });