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,5 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ console.log = () => { }; // fix for termkit
5
+ require("../src/index.js");
@@ -0,0 +1,119 @@
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 system_1 = __importDefault(require("./system"));
7
+ const path_1 = __importDefault(require("path"));
8
+ const child_process_1 = require("child_process");
9
+ const logger_1 = __importDefault(require("../logger"));
10
+ const texts_1 = require("../texts");
11
+ class AgentLinux extends system_1.default {
12
+ hasAdminRights() {
13
+ return new Promise((resolve) => {
14
+ resolve(process.getuid() === 0);
15
+ });
16
+ }
17
+ isSupported() {
18
+ return new Promise((resolve) => {
19
+ this.systemctl('--version')
20
+ .then(() => {
21
+ resolve(['arm64', 'x64'].includes(process.arch));
22
+ })
23
+ .catch(() => {
24
+ resolve(false);
25
+ });
26
+ });
27
+ }
28
+ isEnabled() {
29
+ return new Promise((resolve) => {
30
+ this.systemctl('is-enabled bdy')
31
+ .then(() => {
32
+ resolve(true);
33
+ })
34
+ .catch(() => {
35
+ resolve(false);
36
+ });
37
+ });
38
+ }
39
+ getBinaryArchive() {
40
+ return `linux-${process.arch}.tar.gz`;
41
+ }
42
+ getSystemConfigDir() {
43
+ return '/etc/bdy';
44
+ }
45
+ getSystemConfigPath() {
46
+ return path_1.default.join(this.getSystemConfigDir(), 'agent.json');
47
+ }
48
+ getServicePath() {
49
+ return '/etc/systemd/system/bdy.service';
50
+ }
51
+ getServiceConfig(id, host, token, port, start, user, debug) {
52
+ const cli = this.getSystemBinaryPath();
53
+ return `[Unit]
54
+ Description=Buddy Tunnel Agent
55
+ After=network.target
56
+
57
+ [Service]
58
+ Environment="DEBUG=${debug ? 1 : 0}"
59
+ User=${user || 'root'}
60
+ WorkingDirectory=/
61
+ ExecStart=${cli} agent run --id="${id}" --host="${host}" --token="${token}" --port=${port} --start=${!!start}
62
+ Restart=always
63
+ RestartSec=3
64
+
65
+ [Install]
66
+ WantedBy=multi-user.target`;
67
+ }
68
+ async enable(id, host, token, port, start, user, pass, debug) {
69
+ try {
70
+ logger_1.default.info(texts_1.LOG_AGENT_SYSTEM_DIR);
71
+ await this.ensureSystemConfigDir();
72
+ logger_1.default.info(texts_1.LOG_AGENT_DOWNLOADING_ARCHIVE);
73
+ await this.downloadBinaryArchive();
74
+ logger_1.default.info(texts_1.LOG_AGENT_EXTRACTING_ARCHIVE);
75
+ await this.extractBinaryArchive();
76
+ logger_1.default.info(texts_1.LOG_AGENT_SYSTEM_SERVICE_CONFIG);
77
+ await this.saveFile(this.getServicePath(), this.getServiceConfig(id, host, token, port, start, user, debug));
78
+ logger_1.default.info(texts_1.LOG_AGENT_ENABLING_SYSTEM);
79
+ await this.systemctl('enable --now bdy');
80
+ logger_1.default.info(texts_1.LOG_AGENT_ENABLED);
81
+ }
82
+ catch (err) {
83
+ logger_1.default.error(err);
84
+ throw err;
85
+ }
86
+ }
87
+ async update() {
88
+ try {
89
+ logger_1.default.info(texts_1.LOG_AGENT_STOPPING_SYSTEM);
90
+ await this.systemctl('stop bdy');
91
+ logger_1.default.info(texts_1.LOG_AGENT_SYSTEM_DIR);
92
+ await this.ensureSystemConfigDir();
93
+ logger_1.default.info(texts_1.LOG_AGENT_DOWNLOADING_ARCHIVE);
94
+ await this.downloadBinaryArchive();
95
+ logger_1.default.info(texts_1.LOG_AGENT_EXTRACTING_ARCHIVE);
96
+ await this.extractBinaryArchive();
97
+ logger_1.default.info(texts_1.LOG_AGENT_STARTING_SYSTEM);
98
+ await this.systemctl('start bdy');
99
+ }
100
+ catch (err) {
101
+ logger_1.default.error(err);
102
+ throw err;
103
+ }
104
+ }
105
+ async disable() {
106
+ return this.systemctl('disable --now bdy');
107
+ }
108
+ systemctl(cmd) {
109
+ return new Promise((resolve, reject) => {
110
+ (0, child_process_1.exec)(`systemctl ${cmd}`, (err, stdout, stderr) => {
111
+ if (!err)
112
+ resolve(stdout, stderr);
113
+ else
114
+ reject(err, stderr);
115
+ });
116
+ });
117
+ }
118
+ }
119
+ exports.default = AgentLinux;
@@ -0,0 +1,395 @@
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 ws_1 = require("ws");
8
+ const logger_js_1 = __importDefault(require("../logger.js"));
9
+ const http_1 = __importDefault(require("http"));
10
+ const output_js_1 = __importDefault(require("../output.js"));
11
+ const texts_js_1 = require("../texts.js");
12
+ const windows_1 = __importDefault(require("./windows"));
13
+ const linux_1 = __importDefault(require("./linux"));
14
+ const system_1 = __importDefault(require("./system"));
15
+ const osx_1 = __importDefault(require("./osx"));
16
+ const buddy_js_1 = __importDefault(require("../api/buddy.js"));
17
+ const socket_js_1 = __importDefault(require("./socket.js"));
18
+ class AgentManagerClass {
19
+ constructor() {
20
+ this.status = utils_js_1.AGENT_STATUS_DISABLED;
21
+ this.id = null;
22
+ this.host = null;
23
+ this.token = null;
24
+ this.port = null;
25
+ this.shouldStart = null;
26
+ this.sshHostKey = null;
27
+ this.agent = null;
28
+ this.server = null;
29
+ this.ws = null;
30
+ if ((0, utils_js_1.isOsx)()) {
31
+ this.system = new osx_1.default();
32
+ }
33
+ else if ((0, utils_js_1.isLinux)()) {
34
+ this.system = new linux_1.default();
35
+ }
36
+ else if ((0, utils_js_1.isWindows)()) {
37
+ this.system = new windows_1.default();
38
+ }
39
+ else {
40
+ this.system = new system_1.default();
41
+ }
42
+ }
43
+ start(id, host, token, port, start) {
44
+ this.load(id, host, token, parseInt(port, 10), !!start).then();
45
+ }
46
+ async tryFetch() {
47
+ try {
48
+ this.agent = await buddy_js_1.default.fetchAgent(this.id, this.host, this.token);
49
+ this.agent.manager = this;
50
+ this.agent.startRefreshingConfiguration((success) => {
51
+ if (success)
52
+ this.status = utils_js_1.AGENT_STATUS_ENABLED;
53
+ else
54
+ this.status = utils_js_1.AGENT_STATUS_FETCH_FAILED;
55
+ });
56
+ if (this.shouldStart)
57
+ await this.agent.start();
58
+ this.status = utils_js_1.AGENT_STATUS_ENABLED;
59
+ }
60
+ catch (err) {
61
+ if (err instanceof utils_js_1.ApiErrorAgentNotFound) {
62
+ await this.disableAgentAndExit(texts_js_1.ERR_AGENT_NOT_FOUND);
63
+ }
64
+ else {
65
+ output_js_1.default.normal(texts_js_1.AGENT_FETCH_RETRY);
66
+ this.status = utils_js_1.AGENT_STATUS_FETCH_FAILED;
67
+ await (0, utils_js_1.sleep)(3000);
68
+ return this.tryFetch();
69
+ }
70
+ }
71
+ }
72
+ serverOutput(res, data) {
73
+ res.statusCode = 200;
74
+ res.setHeader('content-type', 'application/json');
75
+ res.end(JSON.stringify(data));
76
+ }
77
+ server404(res) {
78
+ res.statusCode = 404;
79
+ res.end('Not found');
80
+ }
81
+ serverError(res, message) {
82
+ res.statusCode = 400;
83
+ res.end(JSON.stringify({
84
+ message,
85
+ }));
86
+ }
87
+ async processTunnels(res) {
88
+ const tunnels = [];
89
+ if (this.agent) {
90
+ this.agent.tunnels.forEach((tunnel) => {
91
+ if (tunnel.type === utils_js_1.TUNNEL_SSH)
92
+ return;
93
+ tunnels.push({
94
+ id: tunnel.id,
95
+ type: tunnel.type,
96
+ target: tunnel.target,
97
+ domain: tunnel.domain,
98
+ subdomain: tunnel.subdomain,
99
+ serve: tunnel.serve,
100
+ status: tunnel.status,
101
+ region: tunnel.region,
102
+ sshId: tunnel.sshId,
103
+ sshForwardPort: tunnel.sshForwardPort,
104
+ regionLatency: tunnel.regionLatency
105
+ ? tunnel.regionLatency.latency
106
+ : -1,
107
+ targetLatency: tunnel.targetLatency
108
+ ? tunnel.targetLatency.latency
109
+ : -1,
110
+ });
111
+ });
112
+ }
113
+ this.serverOutput(res, {
114
+ tunnels,
115
+ });
116
+ }
117
+ async processStatus(res) {
118
+ this.serverOutput(res, {
119
+ id: this.id,
120
+ status: this.status,
121
+ version: (0, utils_js_1.getVersion)(),
122
+ started: this.shouldStart,
123
+ enabled: this.status === utils_js_1.AGENT_STATUS_ENABLED,
124
+ });
125
+ }
126
+ processBody(req) {
127
+ return new Promise((resolve, reject) => {
128
+ let data = '';
129
+ req.setEncoding('utf-8');
130
+ req.on('data', (d) => {
131
+ data += d;
132
+ });
133
+ req.on('end', () => {
134
+ try {
135
+ resolve(JSON.parse(data));
136
+ }
137
+ catch (err) {
138
+ reject(err);
139
+ }
140
+ });
141
+ });
142
+ }
143
+ async processTunnelStop(req, res) {
144
+ if (!this.agent) {
145
+ this.serverError(res, 'Agent not enabled');
146
+ return;
147
+ }
148
+ let data;
149
+ try {
150
+ data = await this.processBody(req);
151
+ }
152
+ catch {
153
+ this.serverError(res, 'Wrong input data');
154
+ return;
155
+ }
156
+ const tunnel = this.agent.destroyTunnel(data.id);
157
+ if (!tunnel) {
158
+ this.serverError(res, 'Tunnel not found');
159
+ return;
160
+ }
161
+ try {
162
+ await buddy_js_1.default.removeTunnel(this.id, tunnel.id, this.host, this.token);
163
+ }
164
+ catch (err) {
165
+ this.serverError(res, err.message);
166
+ return;
167
+ }
168
+ this.serverOutput(res, {
169
+ success: true,
170
+ });
171
+ }
172
+ async agentRestart() {
173
+ let saved = await this.agentStop();
174
+ if (!saved)
175
+ return false;
176
+ return await this.agentStart();
177
+ }
178
+ async disableAgentAndExit(txt) {
179
+ logger_js_1.default.error(txt);
180
+ try {
181
+ await this.system.disable();
182
+ }
183
+ catch {
184
+ // do nothing
185
+ }
186
+ try {
187
+ await buddy_js_1.default.unregister(this.id, this.host, this.token);
188
+ }
189
+ catch {
190
+ // do nothing
191
+ }
192
+ try {
193
+ this.system.clearSystemFiles();
194
+ }
195
+ catch {
196
+ // do nothing
197
+ }
198
+ try {
199
+ this.system.clearAgentFiles();
200
+ }
201
+ catch {
202
+ // do nothing
203
+ }
204
+ output_js_1.default.exitError(txt);
205
+ }
206
+ async agentStop() {
207
+ const saved = this.resaveAgentConfig(false, true);
208
+ if (!saved)
209
+ return false;
210
+ await this.agent.stop();
211
+ return true;
212
+ }
213
+ async processAgentRestart(req, res) {
214
+ if (!this.agent) {
215
+ this.serverError(res, 'Agent not enabled');
216
+ return;
217
+ }
218
+ const saved = await this.agentRestart();
219
+ if (!saved) {
220
+ this.serverError(res, 'Something went wrong');
221
+ return;
222
+ }
223
+ this.serverOutput(res, {
224
+ success: true,
225
+ });
226
+ }
227
+ async processAgentStop(req, res) {
228
+ if (!this.agent) {
229
+ this.serverError(res, 'Agent not enabled');
230
+ return;
231
+ }
232
+ const saved = await this.agentStop();
233
+ if (!saved) {
234
+ this.serverError(res, 'Something went wrong');
235
+ return;
236
+ }
237
+ this.serverOutput(res, {
238
+ success: true,
239
+ });
240
+ }
241
+ async agentStart() {
242
+ const saved = this.resaveAgentConfig(true, true);
243
+ if (!saved) {
244
+ return false;
245
+ }
246
+ await this.agent.start();
247
+ return true;
248
+ }
249
+ async processAgentStart(req, res) {
250
+ if (!this.agent) {
251
+ this.serverError(res, 'Agent not enabled');
252
+ return;
253
+ }
254
+ const saved = await this.agentStart();
255
+ if (!saved) {
256
+ this.serverError(res, 'Something went wrong');
257
+ return;
258
+ }
259
+ this.serverOutput(res, {
260
+ success: true,
261
+ });
262
+ }
263
+ async processTunnelAdd(req, res) {
264
+ if (!this.agent) {
265
+ this.serverError(res, 'Agent not enabled');
266
+ return;
267
+ }
268
+ let data;
269
+ try {
270
+ data = await this.processBody(req);
271
+ }
272
+ catch {
273
+ this.serverError(res, 'Wrong input data');
274
+ return;
275
+ }
276
+ let tunnel;
277
+ try {
278
+ tunnel = await buddy_js_1.default.addTunnel(this.id, this.host, this.token, data, this.sshHostKey);
279
+ }
280
+ catch (err) {
281
+ this.serverError(res, err.message);
282
+ return;
283
+ }
284
+ this.agent.addTunnel(tunnel);
285
+ this.serverOutput(res, {
286
+ id: tunnel.id,
287
+ type: tunnel.type,
288
+ });
289
+ }
290
+ async processRequest(req, res) {
291
+ logger_js_1.default.info((0, texts_js_1.LOG_REQUEST)(req.url));
292
+ if (req.url === '/status')
293
+ return this.processStatus(res);
294
+ if (req.url === '/tunnels')
295
+ return this.processTunnels(res);
296
+ if (req.url === '/tunnel/add')
297
+ return this.processTunnelAdd(req, res);
298
+ if (req.url === '/tunnel/stop')
299
+ return this.processTunnelStop(req, res);
300
+ if (req.url === '/agent/start')
301
+ return this.processAgentStart(req, res);
302
+ if (req.url === '/agent/stop')
303
+ return this.processAgentStop(req, res);
304
+ if (req.url === '/agent/restart')
305
+ return this.processAgentRestart(req, res);
306
+ this.server404(res);
307
+ }
308
+ processUpgrade(req, socket, head) {
309
+ logger_js_1.default.info((0, texts_js_1.LOG_REQUEST)(req.url));
310
+ const url = new URL(req.url, 'http://localhost');
311
+ const id = url.searchParams.get('id');
312
+ if (url.pathname === '/tunnel' && id) {
313
+ this.ws.handleUpgrade(req, socket, head, (con) => {
314
+ this.ws.emit('connection', con, id);
315
+ });
316
+ return;
317
+ }
318
+ socket.destroy();
319
+ }
320
+ processWebsocketConnection(con, id) {
321
+ if (!this.agent) {
322
+ con.close();
323
+ return;
324
+ }
325
+ const tunnel = this.agent.tunnels.find((t) => t.id === id);
326
+ if (!tunnel || tunnel.type === utils_js_1.TUNNEL_SSH) {
327
+ con.close();
328
+ return;
329
+ }
330
+ new socket_js_1.default(con, tunnel);
331
+ }
332
+ createServer() {
333
+ this.server = http_1.default.createServer((req, res) => this.processRequest(req, res));
334
+ this.ws = new ws_1.WebSocketServer({ noServer: true });
335
+ this.ws.on('connection', (con, id) => this.processWebsocketConnection(con, id));
336
+ this.server.on('upgrade', (req, socket, head) => this.processUpgrade(req, socket, head));
337
+ this.server.listen(this.port, async (err) => {
338
+ if (err) {
339
+ await this.disableAgentAndExit(texts_js_1.LOG_ERROR_STARTING_AGENT_SERVER);
340
+ }
341
+ else {
342
+ logger_js_1.default.info(texts_js_1.LOG_AGENT_SERVER_STARTED);
343
+ }
344
+ });
345
+ }
346
+ resaveAgentConfig(shouldStart, forceParam = false) {
347
+ if (!forceParam) {
348
+ try {
349
+ // load from config
350
+ const json = this.system.loadAgentConfig();
351
+ this.shouldStart = !!json.shouldStart;
352
+ this.sshHostKey = json.sshHostKey;
353
+ }
354
+ catch {
355
+ // save from param
356
+ this.shouldStart = shouldStart;
357
+ }
358
+ if (!this.sshHostKey)
359
+ this.sshHostKey = (0, utils_js_1.createSshHostKey)();
360
+ }
361
+ else {
362
+ // save from param
363
+ this.shouldStart = shouldStart;
364
+ }
365
+ try {
366
+ // resave config
367
+ this.system.saveAgentConfig(this.shouldStart, this.sshHostKey);
368
+ return true;
369
+ }
370
+ catch {
371
+ return false;
372
+ }
373
+ }
374
+ async load(id, host, token, port, start) {
375
+ this.status = utils_js_1.AGENT_STATUS_INITIALIZING;
376
+ this.id = id;
377
+ this.host = host;
378
+ this.token = token;
379
+ this.port = parseInt(port, 10);
380
+ if (!this.id || !this.token || !this.host || !this.port) {
381
+ await this.disableAgentAndExit(texts_js_1.ERR_AGENT_NOT_REGISTERED);
382
+ return;
383
+ }
384
+ const ok = this.resaveAgentConfig(start);
385
+ if (!ok) {
386
+ await this.disableAgentAndExit(texts_js_1.ERR_SAVING_AGENT_CONFIG);
387
+ return;
388
+ }
389
+ this.createServer();
390
+ await this.tryFetch();
391
+ logger_js_1.default.info(texts_js_1.LOG_AGENT_STARTED);
392
+ }
393
+ }
394
+ const AgentManager = new AgentManagerClass();
395
+ exports.default = AgentManager;
@@ -0,0 +1,139 @@
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 texts_1 = require("../texts");
7
+ const logger_1 = __importDefault(require("../logger"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const child_process_1 = require("child_process");
10
+ const system_1 = __importDefault(require("./system"));
11
+ class AgentOsx extends system_1.default {
12
+ hasAdminRights() {
13
+ return new Promise((resolve) => {
14
+ resolve(process.getuid() === 0);
15
+ });
16
+ }
17
+ isSupported() {
18
+ // cant check for process.arch because of rosetta (process.arch returns x64 for m1)
19
+ return Promise.resolve(true);
20
+ }
21
+ isEnabled() {
22
+ return new Promise((resolve) => {
23
+ this.launchCtl('print system/bdy | grep domain')
24
+ .then((str) => {
25
+ resolve(!!str && !!str.match(/domain\s=\ssystem/i));
26
+ })
27
+ .catch(() => {
28
+ resolve(false);
29
+ });
30
+ });
31
+ }
32
+ getBinaryArchive() {
33
+ return 'darwin-arm64.tar.gz';
34
+ }
35
+ getSystemConfigDir() {
36
+ return '/Library/Application Support/bdy';
37
+ }
38
+ getSystemConfigPath() {
39
+ return path_1.default.join(this.getSystemConfigDir(), 'agent.json');
40
+ }
41
+ getServicePath() {
42
+ return '/Library/LaunchDaemons/bdy.plist';
43
+ }
44
+ getServiceConfig(id, host, token, port, start, user, debug) {
45
+ const cli = this.getSystemBinaryPath();
46
+ let cfg = `<?xml version='1.0' encoding='UTF-8'?>
47
+ <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
48
+ <plist version='1.0'>
49
+ <dict>
50
+ <key>Label</key>
51
+ <string>bdy</string>
52
+ <key>ProgramArguments</key>
53
+ <array>
54
+ <string>${cli}</string>
55
+ <string>agent</string>
56
+ <string>run</string>
57
+ <string>--id</string>
58
+ <string>${id}</string>
59
+ <string>--host</string>
60
+ <string>${host}</string>
61
+ <string>--token</string>
62
+ <string>${token}</string>
63
+ <string>--port</string>
64
+ <string>${port}</string>
65
+ <string>--start</string>
66
+ <string>${!!start}</string>
67
+ </array>
68
+ <key>EnvironmentVariables</key>
69
+ <dict>
70
+ <key>DEBUG</key>
71
+ <string>${debug ? 1 : 0}</string>
72
+ </dict>
73
+ <key>KeepAlive</key>
74
+ <true/>
75
+ <key>RunAtLoad</key>
76
+ <true/>`;
77
+ if (user) {
78
+ cfg += `
79
+ <key>UserName</key>
80
+ <string>${user}</string>`;
81
+ }
82
+ cfg += `
83
+ </dict>
84
+ </plist>`;
85
+ return cfg;
86
+ }
87
+ async enable(id, host, token, port, start, user, pass, debug) {
88
+ try {
89
+ logger_1.default.info(texts_1.LOG_AGENT_SYSTEM_DIR);
90
+ await this.ensureSystemConfigDir();
91
+ logger_1.default.info(texts_1.LOG_AGENT_DOWNLOADING_ARCHIVE);
92
+ await this.downloadBinaryArchive();
93
+ logger_1.default.info(texts_1.LOG_AGENT_EXTRACTING_ARCHIVE);
94
+ await this.extractBinaryArchive();
95
+ logger_1.default.info(texts_1.LOG_AGENT_SYSTEM_SERVICE_CONFIG);
96
+ await this.saveFile(this.getServicePath(), this.getServiceConfig(id, host, token, port, start, user, debug));
97
+ logger_1.default.info(texts_1.LOG_AGENT_ENABLING_SYSTEM);
98
+ await this.launchCtl(`bootstrap system ${this.getServicePath()}`);
99
+ logger_1.default.info(texts_1.LOG_AGENT_ENABLED);
100
+ }
101
+ catch (err) {
102
+ logger_1.default.info(err);
103
+ throw err;
104
+ }
105
+ }
106
+ async update() {
107
+ try {
108
+ logger_1.default.info(texts_1.LOG_AGENT_STOPPING_SYSTEM);
109
+ await this.launchCtl('bootout system/bdy');
110
+ logger_1.default.info(texts_1.LOG_AGENT_SYSTEM_DIR);
111
+ await this.ensureSystemConfigDir();
112
+ logger_1.default.info(texts_1.LOG_AGENT_DOWNLOADING_ARCHIVE);
113
+ await this.downloadBinaryArchive();
114
+ logger_1.default.info(texts_1.LOG_AGENT_EXTRACTING_ARCHIVE);
115
+ await this.extractBinaryArchive();
116
+ logger_1.default.info(texts_1.LOG_AGENT_STARTING_SYSTEM);
117
+ await this.launchCtl(`bootstrap system ${this.getServicePath()}`);
118
+ logger_1.default.info(texts_1.LOG_AGENT_ENABLED);
119
+ }
120
+ catch (err) {
121
+ logger_1.default.error(err);
122
+ throw err;
123
+ }
124
+ }
125
+ disable() {
126
+ return this.launchCtl('bootout system/bdy');
127
+ }
128
+ launchCtl(cmd) {
129
+ return new Promise((resolve, reject) => {
130
+ (0, child_process_1.exec)(`launchctl ${cmd}`, (err, stdout, stderr) => {
131
+ if (!err)
132
+ resolve(stdout, stderr);
133
+ else
134
+ reject(err, stderr);
135
+ });
136
+ });
137
+ }
138
+ }
139
+ exports.default = AgentOsx;