bdy 1.12.13-dev-pipeline-run → 1.13.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 (40) hide show
  1. package/distTs/package.json +13 -12
  2. package/distTs/src/agent.js +302 -0
  3. package/distTs/src/api/agent.js +99 -0
  4. package/distTs/src/api/buddy.js +139 -0
  5. package/distTs/src/api/client.js +10 -6
  6. package/distTs/src/api/socket.js +159 -0
  7. package/distTs/src/cfg.js +234 -0
  8. package/distTs/src/command/config.js +17 -0
  9. package/distTs/src/command/http.js +30 -0
  10. package/distTs/src/command/pipeline/run.js +29 -26
  11. package/distTs/src/command/start.js +28 -0
  12. package/distTs/src/command/tcp.js +30 -0
  13. package/distTs/src/command/tls.js +30 -0
  14. package/distTs/src/command/ut/upload.js +17 -7
  15. package/distTs/src/command/vt/compare.js +2 -2
  16. package/distTs/src/command/vt/exec.js +4 -3
  17. package/distTs/src/command/vt/storybook.js +4 -3
  18. package/distTs/src/input.js +20 -10
  19. package/distTs/src/output/interactive/tunnel.js +860 -0
  20. package/distTs/src/output/noninteractive/agent/tunnels.js +43 -0
  21. package/distTs/src/output/noninteractive/config/tunnel.js +65 -0
  22. package/distTs/src/output/noninteractive/config/tunnels.js +18 -0
  23. package/distTs/src/output/noninteractive/tunnel.js +59 -0
  24. package/distTs/src/server/cert.js +52 -0
  25. package/distTs/src/server/http1.js +75 -0
  26. package/distTs/src/server/http2.js +78 -0
  27. package/distTs/src/server/sftp.js +497 -0
  28. package/distTs/src/server/ssh.js +446 -0
  29. package/distTs/src/server/tls.js +41 -0
  30. package/distTs/src/ssh/client.js +197 -0
  31. package/distTs/src/texts.js +7 -51
  32. package/distTs/src/tunnel/html/503.html +338 -0
  33. package/distTs/src/tunnel/tunnel.js +31 -13
  34. package/distTs/src/tunnel.js +656 -0
  35. package/distTs/src/unitTest/ci.js +12 -8
  36. package/distTs/src/utils.js +17 -7
  37. package/distTs/src/visualTest/context.js +4 -4
  38. package/distTs/src/visualTest/exec.js +0 -24
  39. package/distTs/src/visualTest/resources.js +18 -8
  40. package/package.json +13 -12
@@ -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_js_1 = require("../../../utils.js");
7
+ const texts_js_1 = require("../../../texts.js");
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_js_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_js_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_js_1 = require("../../../utils.js");
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_js_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_js_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_js_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_js_1 = __importDefault(require("../logger.js"));
8
+ const uuid_1 = require("uuid");
9
+ const http_1 = __importDefault(require("http"));
10
+ const texts_js_1 = require("../texts.js");
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_js_1.default.debug((0, texts_js_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_js_1.default.debug((0, texts_js_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_js_1 = require("../texts.js");
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_js_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_js_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_js_1.LOG_HTTP2_REQUEST)(req.method, req.url));
75
+ this.emit(utils_1.HTTP2_REQUEST, req, res);
76
+ }
77
+ }
78
+ exports.default = ServerHttp2;