bdy 1.10.14-stage → 1.11.0-beta

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 (100) hide show
  1. package/distTs/bin/cli.js +1 -1
  2. package/distTs/package.json +1 -1
  3. package/distTs/src/agent/agent.js +302 -0
  4. package/distTs/src/agent/manager.js +41 -41
  5. package/distTs/src/agent/socket/client.js +159 -0
  6. package/distTs/src/agent/socket/tunnel.js +3 -3
  7. package/distTs/src/agent/wait.js +2 -2
  8. package/distTs/src/command/agent/disable.js +1 -1
  9. package/distTs/src/command/agent/enable.js +1 -1
  10. package/distTs/src/command/agent/install.js +45 -45
  11. package/distTs/src/command/agent/restart.js +8 -8
  12. package/distTs/src/command/agent/start.js +8 -8
  13. package/distTs/src/command/agent/status.js +15 -15
  14. package/distTs/src/command/agent/stop.js +8 -8
  15. package/distTs/src/command/agent/target/disable.js +1 -1
  16. package/distTs/src/command/agent/target/enable.js +1 -1
  17. package/distTs/src/command/agent/target/status.js +1 -1
  18. package/distTs/src/command/agent/tunnel/http.js +18 -18
  19. package/distTs/src/command/agent/tunnel/list.js +7 -7
  20. package/distTs/src/command/agent/tunnel/remove.js +9 -9
  21. package/distTs/src/command/agent/tunnel/start.js +14 -14
  22. package/distTs/src/command/agent/tunnel/status.js +11 -11
  23. package/distTs/src/command/agent/tunnel/tcp.js +19 -19
  24. package/distTs/src/command/agent/tunnel/tls.js +17 -17
  25. package/distTs/src/command/agent/tunnel.js +16 -16
  26. package/distTs/src/command/agent/uninstall.js +13 -13
  27. package/distTs/src/command/agent/update.js +12 -12
  28. package/distTs/src/command/agent/version.js +6 -6
  29. package/distTs/src/command/agent.js +18 -18
  30. package/distTs/src/command/config/add/http.js +15 -15
  31. package/distTs/src/command/config/add/tcp.js +15 -15
  32. package/distTs/src/command/config/add/tls.js +15 -15
  33. package/distTs/src/command/config/add.js +8 -8
  34. package/distTs/src/command/config/get/region.js +5 -5
  35. package/distTs/src/command/config/get/timeout.js +5 -5
  36. package/distTs/src/command/config/get/token.js +5 -5
  37. package/distTs/src/command/config/get/tunnel.js +9 -9
  38. package/distTs/src/command/config/get/tunnels.js +6 -6
  39. package/distTs/src/command/config/get/whitelist.js +5 -5
  40. package/distTs/src/command/config/get.js +14 -14
  41. package/distTs/src/command/config/remove/tunnel.js +9 -9
  42. package/distTs/src/command/config/remove.js +4 -4
  43. package/distTs/src/command/config/set/region.js +8 -8
  44. package/distTs/src/command/config/set/timeout.js +9 -9
  45. package/distTs/src/command/config/set/token.js +7 -7
  46. package/distTs/src/command/config/set/whitelist.js +8 -8
  47. package/distTs/src/command/config/set.js +10 -10
  48. package/distTs/src/command/pre.js +14 -14
  49. package/distTs/src/command/tunnel/config.js +17 -0
  50. package/distTs/src/command/tunnel/http.js +30 -0
  51. package/distTs/src/command/tunnel/start.js +28 -0
  52. package/distTs/src/command/tunnel/tcp.js +30 -0
  53. package/distTs/src/command/tunnel/tls.js +30 -0
  54. package/distTs/src/command/tunnel.js +19 -0
  55. package/distTs/src/command/ut/upload.js +6 -6
  56. package/distTs/src/command/ut.js +3 -2
  57. package/distTs/src/command/version.js +4 -4
  58. package/distTs/src/command/vt/close.js +4 -4
  59. package/distTs/src/command/vt/compare.js +16 -16
  60. package/distTs/src/command/vt/exec.js +12 -12
  61. package/distTs/src/command/vt/installBrowser.js +2 -2
  62. package/distTs/src/command/vt/scrap.js +17 -17
  63. package/distTs/src/command/vt/storybook.js +8 -8
  64. package/distTs/src/command/vt.js +5 -4
  65. package/distTs/src/index.js +12 -20
  66. package/distTs/src/input.js +38 -38
  67. package/distTs/src/logger.js +2 -2
  68. package/distTs/src/output.js +14 -14
  69. package/distTs/src/texts.js +5 -4
  70. package/distTs/src/tunnel/agent.js +3 -3
  71. package/distTs/src/tunnel/api/agent.js +99 -0
  72. package/distTs/src/tunnel/api/buddy.js +139 -0
  73. package/distTs/src/tunnel/cfg.js +234 -0
  74. package/distTs/src/tunnel/http/log.js +3 -3
  75. package/distTs/src/tunnel/http.js +29 -29
  76. package/distTs/src/tunnel/identification.js +13 -13
  77. package/distTs/src/tunnel/latency.js +3 -3
  78. package/distTs/src/tunnel/output/interactive/tunnel.js +860 -0
  79. package/distTs/src/tunnel/output/noninteractive/agent/tunnels.js +43 -0
  80. package/distTs/src/tunnel/output/noninteractive/config/tunnel.js +65 -0
  81. package/distTs/src/tunnel/output/noninteractive/config/tunnels.js +18 -0
  82. package/distTs/src/tunnel/output/noninteractive/tunnel.js +59 -0
  83. package/distTs/src/tunnel/server/cert.js +52 -0
  84. package/distTs/src/tunnel/server/http1.js +75 -0
  85. package/distTs/src/tunnel/server/http2.js +78 -0
  86. package/distTs/src/tunnel/server/sftp.js +497 -0
  87. package/distTs/src/tunnel/server/ssh.js +446 -0
  88. package/distTs/src/tunnel/server/tls.js +41 -0
  89. package/distTs/src/tunnel/ssh/client.js +197 -0
  90. package/distTs/src/tunnel/tcp.js +3 -3
  91. package/distTs/src/tunnel/tunnel.js +656 -0
  92. package/distTs/src/utils.js +2 -2
  93. package/distTs/src/visualTest/ci.js +10 -10
  94. package/distTs/src/visualTest/context.js +4 -4
  95. package/distTs/src/visualTest/requests.js +71 -71
  96. package/distTs/src/visualTest/resources.js +5 -5
  97. package/distTs/src/visualTest/server.js +9 -9
  98. package/distTs/src/visualTest/snapshots.js +18 -18
  99. package/distTs/src/visualTest/validation.js +3 -3
  100. package/package.json +1 -1
@@ -0,0 +1,43 @@
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 utils_1 = require("../../../../utils");
7
+ const texts_1 = require("../../../../texts");
8
+ const format_1 = __importDefault(require("../../../../format"));
9
+ class OutputNoninteractiveAgentTunnels {
10
+ constructor(terminal, tunnels) {
11
+ this.terminal = terminal;
12
+ this.tunnels = tunnels;
13
+ }
14
+ start(output) {
15
+ if (!this.tunnels.length) {
16
+ output.exitNormal(texts_1.NO_TUNNELS_STARTED);
17
+ }
18
+ else {
19
+ const tunnels = [
20
+ ['Id', 'Type', 'Target / Latency', 'Entry / Latency', 'Status'],
21
+ ];
22
+ this.tunnels.forEach((tunnel) => {
23
+ let target;
24
+ let status;
25
+ if (tunnel.serve)
26
+ target = format_1.default.serve(tunnel.serve) + ' / 0ms';
27
+ else
28
+ target =
29
+ format_1.default.target(tunnel.type, tunnel.target) +
30
+ ` / ${format_1.default.latency(tunnel.targetLatency)}`;
31
+ const entry = format_1.default.entry(tunnel) + ` / ${format_1.default.latency(tunnel.regionLatency)}`;
32
+ if (tunnel.status === utils_1.TUNNEL_OPEN)
33
+ status = 'Open';
34
+ else
35
+ status = 'Closed';
36
+ tunnels.push([tunnel.id, tunnel.type, target, entry, status]);
37
+ });
38
+ output.table(tunnels);
39
+ output.exitNormal();
40
+ }
41
+ }
42
+ }
43
+ exports.default = OutputNoninteractiveAgentTunnels;
@@ -0,0 +1,65 @@
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 utils_1 = require("../../../../utils");
7
+ const format_1 = __importDefault(require("../../../../format"));
8
+ class OutputNoninteractiveConfigTunnel {
9
+ constructor(terminal, tunnel) {
10
+ this.terminal = terminal;
11
+ this.tunnel = tunnel;
12
+ }
13
+ start(output) {
14
+ const data = [
15
+ ['Name', this.tunnel.name],
16
+ ['Type', format_1.default.type(this.tunnel.type)],
17
+ ];
18
+ if (this.tunnel.type === utils_1.TUNNEL_HTTP && this.tunnel.serve) {
19
+ data.push(['Serve', format_1.default.serve(this.tunnel.serve)]);
20
+ }
21
+ else {
22
+ data.push([
23
+ 'Target',
24
+ format_1.default.target(this.tunnel.type, this.tunnel.target),
25
+ ]);
26
+ }
27
+ data.push(['Region', format_1.default.tunnelRegion(this.tunnel.region)]);
28
+ data.push(['Timeout', format_1.default.tunnelTimeout(this.tunnel.timeout)]);
29
+ data.push(['Whitelist', format_1.default.tunnelWhitelist(this.tunnel.whitelist)]);
30
+ if (this.tunnel.type === utils_1.TUNNEL_HTTP) {
31
+ data.push(['Host Header', format_1.default.hostHeader(this.tunnel.host)]);
32
+ data.push([
33
+ 'Basic Auth',
34
+ format_1.default.basicAuth(this.tunnel.login, this.tunnel.password),
35
+ ]);
36
+ data.push([
37
+ 'User Agents',
38
+ format_1.default.tunnelUserAgent(this.tunnel.useragents),
39
+ ]);
40
+ data.push(['Request Headers', format_1.default.tunnelHeaders(this.tunnel.headers)]);
41
+ data.push([
42
+ 'Response Headers',
43
+ format_1.default.tunnelHeaders(this.tunnel.responseHeaders),
44
+ ]);
45
+ data.push([
46
+ 'Circuit Breaker',
47
+ format_1.default.tunnelCircuitBreaker(this.tunnel.circuitBreaker),
48
+ ]);
49
+ data.push(['Log Requests', format_1.default.yesNo(this.tunnel.log)]);
50
+ data.push(['TLS Auth', format_1.default.yesNo(!!this.tunnel.ca)]);
51
+ data.push(['TLS Verify', format_1.default.yesNo(this.tunnel.verify)]);
52
+ data.push(['Force HTTP/2', format_1.default.yesNo(this.tunnel.http2)]);
53
+ data.push(['Compression', format_1.default.yesNo(this.tunnel.compression)]);
54
+ }
55
+ else if (this.tunnel.type === utils_1.TUNNEL_TLS) {
56
+ data.push(['Terminate TLS At', this.tunnel.terminate]);
57
+ data.push(['TLS Key', format_1.default.yesNo(!!this.tunnel.key)]);
58
+ data.push(['TLS Cert', format_1.default.yesNo(!!this.tunnel.cert)]);
59
+ data.push(['TLS Auth', format_1.default.yesNo(!!this.tunnel.ca)]);
60
+ }
61
+ output.table(data);
62
+ output.exitNormal();
63
+ }
64
+ }
65
+ exports.default = OutputNoninteractiveConfigTunnel;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class OutputNoninteractiveConfigTunnels {
4
+ constructor(terminal, tunnels) {
5
+ this.terminal = terminal;
6
+ this.tunnels = tunnels;
7
+ }
8
+ start(output) {
9
+ const data = [['Name', 'Type', 'Target']];
10
+ Object.keys(this.tunnels).forEach((name) => {
11
+ const t = this.tunnels[name];
12
+ data.push([name, t.type, String(t.target)]);
13
+ });
14
+ output.table(data);
15
+ output.exitNormal();
16
+ }
17
+ }
18
+ exports.default = OutputNoninteractiveConfigTunnels;
@@ -0,0 +1,59 @@
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 utils_1 = require("../../../utils");
7
+ const format_1 = __importDefault(require("../../../format"));
8
+ class OutputNoninteractiveTunnel {
9
+ constructor(terminal, tunnel) {
10
+ this.tunnel = tunnel;
11
+ this.terminal = terminal;
12
+ }
13
+ status(t, status) {
14
+ this.terminal(`${format_1.default.date()}: Tunnel ${t.type} to ${t.serve || t.target} ${status}\n`);
15
+ }
16
+ onOpen(t) {
17
+ this.status(t, `open. Entry: ${format_1.default.entry(t)}`);
18
+ }
19
+ onClosed(t) {
20
+ this.status(t, 'closed');
21
+ }
22
+ onTcpOpen(t) {
23
+ this.status(t, 'has incoming tcp connection');
24
+ }
25
+ onTcpClosed(t) {
26
+ this.status(t, 'closed tcp connection');
27
+ }
28
+ onTlsOpen(t) {
29
+ this.status(t, 'has incoming tls connection');
30
+ }
31
+ onTlsClosed(t) {
32
+ this.status(t, 'closed tls connection');
33
+ }
34
+ onHttpIdentified(t, type) {
35
+ this.status(t, `identified as ${type}`);
36
+ }
37
+ onHttpRequest(t, logRequest) {
38
+ this.status(t, `Request ${logRequest.method} ${logRequest.url}`);
39
+ }
40
+ onHttpResponse(t, logRequest) {
41
+ this.status(t, `Response ${logRequest.method} ${logRequest.url} ${logRequest.status} in ${logRequest.time}ms`);
42
+ }
43
+ onStopped() {
44
+ process.exit();
45
+ }
46
+ start() {
47
+ this.tunnel.on(utils_1.TUNNEL_EVENT_OPEN, (t) => this.onOpen(t));
48
+ this.tunnel.on(utils_1.TUNNEL_EVENT_CLOSED, (t) => this.onClosed(t));
49
+ this.tunnel.on(utils_1.TUNNEL_EVENT_TCP_OPEN, (t) => this.onTcpOpen(t));
50
+ this.tunnel.on(utils_1.TUNNEL_EVENT_TCP_CLOSED, (t) => this.onTcpClosed(t));
51
+ this.tunnel.on(utils_1.TUNNEL_EVENT_TLS_OPEN, (t) => this.onTlsOpen(t));
52
+ this.tunnel.on(utils_1.TUNNEL_EVENT_TLS_CLOSED, (t) => this.onTlsClosed(t));
53
+ this.tunnel.on(utils_1.TUNNEL_EVENT_HTTP_IDENTIFIED, (t, type) => this.onHttpIdentified(t, type));
54
+ this.tunnel.on(utils_1.TUNNEL_EVENT_HTTP_REQUEST, (t, logRequest) => this.onHttpRequest(t, logRequest));
55
+ this.tunnel.on(utils_1.TUNNEL_EVENT_HTTP_RESPONSE, (t, logRequest) => this.onHttpResponse(t, logRequest));
56
+ this.tunnel.on(utils_1.TUNNEL_EVENT_STOPPED, (t) => this.onStopped(t));
57
+ }
58
+ }
59
+ exports.default = OutputNoninteractiveTunnel;
@@ -0,0 +1,52 @@
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 node_forge_1 = __importDefault(require("node-forge"));
7
+ const toPositiveHex = (hexString) => {
8
+ let hexAsInt = parseInt(hexString[0], 16);
9
+ if (hexAsInt < 8) {
10
+ return hexString;
11
+ }
12
+ hexAsInt -= 8;
13
+ return hexAsInt.toString() + hexString.substring(1);
14
+ };
15
+ class ServerCert {
16
+ constructor() {
17
+ const keyPair = node_forge_1.default.pki.rsa.generateKeyPair(2048);
18
+ const cert = node_forge_1.default.pki.createCertificate();
19
+ cert.serialNumber = toPositiveHex(node_forge_1.default.util.bytesToHex(node_forge_1.default.random.getBytesSync(9)));
20
+ cert.validity.notBefore = new Date();
21
+ const notAfter = new Date();
22
+ notAfter.setTime(notAfter.getTime() + 622080000000);
23
+ cert.validity.notAfter = notAfter;
24
+ const attrs = [
25
+ {
26
+ name: 'commonName',
27
+ value: 'buddy.tunnel',
28
+ },
29
+ ];
30
+ cert.setSubject(attrs);
31
+ cert.setIssuer(attrs);
32
+ cert.publicKey = keyPair.publicKey;
33
+ cert.setExtensions([
34
+ {
35
+ name: 'basicConstraints',
36
+ cA: true,
37
+ },
38
+ {
39
+ name: 'keyUsage',
40
+ keyCertSign: true,
41
+ digitalSignature: true,
42
+ nonRepudiation: true,
43
+ keyEncipherment: true,
44
+ dataEncipherment: true,
45
+ },
46
+ ]);
47
+ cert.sign(keyPair.privateKey, node_forge_1.default.md.sha256.create());
48
+ this.key = node_forge_1.default.pki.privateKeyToPem(keyPair.privateKey);
49
+ this.cert = node_forge_1.default.pki.certificateToPem(cert);
50
+ }
51
+ }
52
+ exports.default = ServerCert;
@@ -0,0 +1,75 @@
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 events_1 = __importDefault(require("events"));
7
+ const logger_1 = __importDefault(require("../../logger"));
8
+ const uuid_1 = require("uuid");
9
+ const http_1 = __importDefault(require("http"));
10
+ const texts_1 = require("../../texts");
11
+ const utils_1 = require("../../utils");
12
+ class ServerHttp1 extends events_1.default {
13
+ constructor(host) {
14
+ super();
15
+ this.server = http_1.default.createServer((req, res) => this.processRequest(req, res, host));
16
+ this.server.on('connection', (socket) => {
17
+ socket.id = (0, uuid_1.v4)();
18
+ this.emit(utils_1.HTTP1_SOCKET_OPEN, socket);
19
+ socket.once('close', () => {
20
+ this.emit(utils_1.HTTP1_SOCKET_CLOSED, socket);
21
+ });
22
+ });
23
+ this.server.listen();
24
+ }
25
+ stop() {
26
+ this.server.close();
27
+ this.server.removeAllListeners();
28
+ this.server = null;
29
+ }
30
+ handleSshTunnel(stream, info, ip) {
31
+ logger_1.default.debug((0, texts_1.LOG_HTTP1_CONNECTION)(ip));
32
+ stream.remoteAddress = ip;
33
+ this.server.emit('connection', stream);
34
+ }
35
+ retryRequest(logRequest) {
36
+ const address = this.server.address();
37
+ if (!address || !address.port)
38
+ return;
39
+ let req = http_1.default.request({
40
+ host: 'localhost',
41
+ port: address.port,
42
+ method: logRequest.method,
43
+ setHost: false,
44
+ path: logRequest.url,
45
+ headers: logRequest.headers,
46
+ });
47
+ if (logRequest.requestBody.data.length > 0)
48
+ req.write(logRequest.requestBody.data);
49
+ req.on('response', (res) => {
50
+ res.resume();
51
+ });
52
+ req.on('close', () => {
53
+ req.removeAllListeners();
54
+ req = null;
55
+ });
56
+ req.end();
57
+ }
58
+ checkHostHeader(req, res, host) {
59
+ const headerHost = (req.headers.host || '').split(':')[0];
60
+ if (headerHost === host)
61
+ return true;
62
+ else {
63
+ res.statusCode = 421;
64
+ res.end('Misdirected Request');
65
+ return false;
66
+ }
67
+ }
68
+ async processRequest(req, res, host) {
69
+ if (!this.checkHostHeader(req, res, host))
70
+ return;
71
+ logger_1.default.debug((0, texts_1.LOG_HTTP1_REQUEST)(req.method, req.url));
72
+ this.emit(utils_1.HTTP1_REQUEST, req, res);
73
+ }
74
+ }
75
+ exports.default = ServerHttp1;
@@ -0,0 +1,78 @@
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 events_1 = __importDefault(require("events"));
7
+ const http2_1 = __importDefault(require("http2"));
8
+ const logger_js_1 = __importDefault(require("../../logger.js"));
9
+ const uuid_1 = require("uuid");
10
+ const texts_1 = require("../../texts");
11
+ const utils_1 = require("../../utils");
12
+ class ServerHttp2 extends events_1.default {
13
+ constructor(host) {
14
+ super();
15
+ this.server = http2_1.default.createServer((req, res) => this.processRequest(req, res, host));
16
+ this.server.on('session', (session) => {
17
+ session.id = (0, uuid_1.v4)();
18
+ this.emit(utils_1.HTTP2_SESSION_OPEN, session);
19
+ session.once('close', () => {
20
+ this.emit(utils_1.HTTP2_SESSION_CLOSED, session);
21
+ });
22
+ });
23
+ this.server.listen();
24
+ }
25
+ stop() {
26
+ this.server.close();
27
+ this.server.removeAllListeners();
28
+ this.server = null;
29
+ }
30
+ handleSshTunnel(stream, info, ip) {
31
+ logger_js_1.default.debug((0, texts_1.LOG_HTTP2_CONNECTION)(ip));
32
+ stream.remoteAddress = ip;
33
+ this.server.emit('connection', stream);
34
+ }
35
+ retryRequest(logRequest) {
36
+ const address = this.server.address();
37
+ if (!address || !address.port)
38
+ return;
39
+ let client = http2_1.default.connect(`http://localhost:${address.port}`, {
40
+ maxSessionMemory: 100,
41
+ noDelay: true
42
+ });
43
+ let req = client.request(logRequest.headers);
44
+ if (logRequest.requestBody.data.length > 0)
45
+ req.write(logRequest.requestBody.data);
46
+ req.on('response', () => {
47
+ req.resume();
48
+ });
49
+ req.on('error', (err) => {
50
+ logger_js_1.default.debug(texts_1.LOG_ERROR);
51
+ logger_js_1.default.debug(err);
52
+ });
53
+ req.on('close', () => {
54
+ req.removeAllListeners();
55
+ client.close();
56
+ req = null;
57
+ client = null;
58
+ });
59
+ req.end();
60
+ }
61
+ checkHostHeader(req, res, host) {
62
+ const headerHost = (req.headers[':authority'] || '').split(':')[0];
63
+ if (headerHost === host)
64
+ return true;
65
+ else {
66
+ res.statusCode = 421;
67
+ res.end('Misdirected Request');
68
+ return false;
69
+ }
70
+ }
71
+ async processRequest(req, res, host) {
72
+ if (!this.checkHostHeader(req, res, host))
73
+ return;
74
+ logger_js_1.default.debug((0, texts_1.LOG_HTTP2_REQUEST)(req.method, req.url));
75
+ this.emit(utils_1.HTTP2_REQUEST, req, res);
76
+ }
77
+ }
78
+ exports.default = ServerHttp2;