bdy 1.7.60-dev → 1.8.3-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 (95) hide show
  1. package/package.json +42 -11
  2. package/.eslintrc.yml +0 -23
  3. package/bin/cli.js +0 -5
  4. package/dockerfile +0 -15
  5. package/link.sh +0 -3
  6. package/src/agent/linux.js +0 -127
  7. package/src/agent/manager.js +0 -404
  8. package/src/agent/osx.js +0 -150
  9. package/src/agent/socket/tunnel.js +0 -232
  10. package/src/agent/socket.js +0 -260
  11. package/src/agent/system.js +0 -205
  12. package/src/agent/wait.js +0 -20
  13. package/src/agent/windows.js +0 -168
  14. package/src/agent.js +0 -256
  15. package/src/api/agent.js +0 -95
  16. package/src/api/buddy.js +0 -131
  17. package/src/api/socket.js +0 -148
  18. package/src/cfg.js +0 -239
  19. package/src/command/agent/install.js +0 -116
  20. package/src/command/agent/restart.js +0 -27
  21. package/src/command/agent/run.js +0 -16
  22. package/src/command/agent/start.js +0 -27
  23. package/src/command/agent/status.js +0 -44
  24. package/src/command/agent/stop.js +0 -27
  25. package/src/command/agent/tunnel/http.js +0 -45
  26. package/src/command/agent/tunnel/list.js +0 -26
  27. package/src/command/agent/tunnel/remove.js +0 -29
  28. package/src/command/agent/tunnel/start.js +0 -37
  29. package/src/command/agent/tunnel/status.js +0 -31
  30. package/src/command/agent/tunnel/tcp.js +0 -45
  31. package/src/command/agent/tunnel/tls.js +0 -45
  32. package/src/command/agent/tunnel.js +0 -20
  33. package/src/command/agent/uninstall.js +0 -36
  34. package/src/command/agent/update.js +0 -42
  35. package/src/command/agent/version.js +0 -22
  36. package/src/command/agent.js +0 -26
  37. package/src/command/config/add/http.js +0 -31
  38. package/src/command/config/add/tcp.js +0 -31
  39. package/src/command/config/add/tls.js +0 -31
  40. package/src/command/config/add.js +0 -12
  41. package/src/command/config/get/region.js +0 -12
  42. package/src/command/config/get/timeout.js +0 -12
  43. package/src/command/config/get/token.js +0 -12
  44. package/src/command/config/get/tunnel.js +0 -20
  45. package/src/command/config/get/tunnels.js +0 -12
  46. package/src/command/config/get/whitelist.js +0 -12
  47. package/src/command/config/get.js +0 -18
  48. package/src/command/config/remove/tunnel.js +0 -21
  49. package/src/command/config/remove.js +0 -8
  50. package/src/command/config/set/region.js +0 -18
  51. package/src/command/config/set/timeout.js +0 -21
  52. package/src/command/config/set/token.js +0 -18
  53. package/src/command/config/set/whitelist.js +0 -18
  54. package/src/command/config/set.js +0 -14
  55. package/src/command/config.js +0 -14
  56. package/src/command/http.js +0 -33
  57. package/src/command/pre.js +0 -45
  58. package/src/command/start.js +0 -30
  59. package/src/command/tcp.js +0 -31
  60. package/src/command/tls.js +0 -31
  61. package/src/command/version.js +0 -10
  62. package/src/format.js +0 -171
  63. package/src/index.js +0 -38
  64. package/src/input.js +0 -283
  65. package/src/logger.js +0 -92
  66. package/src/output/interactive/tunnel.js +0 -871
  67. package/src/output/noninteractive/agent/tunnels.js +0 -32
  68. package/src/output/noninteractive/config/tunnel.js +0 -51
  69. package/src/output/noninteractive/config/tunnels.js +0 -19
  70. package/src/output/noninteractive/tunnel.js +0 -79
  71. package/src/output.js +0 -131
  72. package/src/server/cert.js +0 -51
  73. package/src/server/http1.js +0 -79
  74. package/src/server/http2.js +0 -79
  75. package/src/server/sftp.js +0 -474
  76. package/src/server/ssh.js +0 -107
  77. package/src/server/tls.js +0 -41
  78. package/src/ssh/client.js +0 -204
  79. package/src/texts.js +0 -445
  80. package/src/tunnel/agent.js +0 -100
  81. package/src/tunnel/compression.js +0 -32
  82. package/src/tunnel/dns.js +0 -55
  83. package/src/tunnel/html/404.html +0 -129
  84. package/src/tunnel/html/503.html +0 -136
  85. package/src/tunnel/html.js +0 -32
  86. package/src/tunnel/http/log.js +0 -204
  87. package/src/tunnel/http/serve.js +0 -127
  88. package/src/tunnel/http/stream.js +0 -47
  89. package/src/tunnel/http.js +0 -406
  90. package/src/tunnel/identification.js +0 -95
  91. package/src/tunnel/latency.js +0 -69
  92. package/src/tunnel/tcp.js +0 -85
  93. package/src/tunnel.js +0 -713
  94. package/src/utils.js +0 -577
  95. package/unlink.sh +0 -3
package/src/api/agent.js DELETED
@@ -1,95 +0,0 @@
1
- const logger = require('../logger.js');
2
- const {
3
- ERR_FAILED_TO_CONNECT_TO_AGENT,
4
- ERR_NOT_FOUND,
5
- ERR_SWW,
6
- LOG_ERROR
7
- } = require('../texts.js');
8
- const { WebSocket } = require('ws');
9
-
10
- const TIMEOUT = 120000;
11
-
12
- const openSocket = (port, path) => {
13
- return new Promise((resolve, reject) => {
14
- const ws = new WebSocket(`ws://localhost:${port}${path}`);
15
- ws.on('error', () => {
16
- reject(new Error(ERR_FAILED_TO_CONNECT_TO_AGENT));
17
- });
18
- ws.on('open', () => {
19
- resolve(ws);
20
- });
21
- });
22
- };
23
-
24
- const makeRequest = async (port, path, body) => {
25
- const c = new AbortController();
26
- setTimeout(() => {
27
- c.abort();
28
- }, TIMEOUT);
29
- const response = await fetch(`http://localhost:${port}${path}`, {
30
- body: body ? JSON.stringify(body) : null,
31
- headers: { 'Content-Type': 'application/json' },
32
- method: 'POST',
33
- signal: c.signal,
34
- });
35
- if (response.status === 404) {
36
- throw new Error(ERR_NOT_FOUND);
37
- }
38
- if (response.status === 400) {
39
- const data = await response.json();
40
- throw new Error(data.message);
41
- }
42
- if (response.status !== 200) {
43
- throw new Error(ERR_SWW);
44
- }
45
- let data;
46
- try {
47
- data = await response.json();
48
- } catch (err) {
49
- logger.error(LOG_ERROR);
50
- logger.error(err);
51
- throw new Error(ERR_FAILED_TO_CONNECT_TO_AGENT);
52
- }
53
- return data;
54
- };
55
-
56
- class ApiAgent {
57
- constructor(port) {
58
- this.port = port;
59
- }
60
- async fetchStatus() {
61
- return makeRequest(this.port,'/status');
62
- }
63
-
64
- async addTunnel(data) {
65
- return makeRequest(this.port,'/tunnel/add', data);
66
- }
67
-
68
- async fetchTunnels() {
69
- return makeRequest(this.port,'/tunnels');
70
- }
71
-
72
- async stopTunnel(id) {
73
- return makeRequest(this.port, '/tunnel/stop', {
74
- id
75
- });
76
- }
77
-
78
- async startAgent() {
79
- return makeRequest(this.port,'/agent/start');
80
- }
81
-
82
- async restartAgent() {
83
- return makeRequest(this.port,'/agent/restart');
84
- }
85
-
86
- async stopAgent() {
87
- return makeRequest(this.port,'/agent/stop');
88
- }
89
-
90
- async socketTunnel(id) {
91
- return openSocket(this.port, `/tunnel?id=${encodeURIComponent(id)}`);
92
- }
93
- }
94
-
95
- module.exports = ApiAgent;
package/src/api/buddy.js DELETED
@@ -1,131 +0,0 @@
1
- const { Agent: HttpsAgent } = require('https');
2
- const Tunnel = require('../tunnel.js');
3
- const logger = require('../logger.js');
4
- const Agent = require('../agent.js');
5
- const {
6
- apiErrorCodeToClass,
7
- getHostname,
8
- getPlatform,
9
- getVersion,
10
- ApiErrorFailedToConnect,
11
- } = require('../utils');
12
- const {
13
- LOG_AGENT_REGISTERED,
14
- LOG_GETTING_AGENT,
15
- LOG_REGION_DETECTED,
16
- LOG_REGISTERING_AGENT,
17
- LOG_REGISTERING_TUNNEL,
18
- LOG_REMOVING_TUNNEL,
19
- LOG_TUNNEL_REGISTERED,
20
- LOG_UNREGISTERING_AGENT
21
- } = require('../texts.js');
22
-
23
- const TIMEOUT = 120000;
24
-
25
- const nodeFetch = (url, opts) => {
26
- return new Promise((resolve, reject) => {
27
- import('node-fetch').then(({ default: fetch }) => {
28
- fetch(url, opts).then(resolve).catch(reject);
29
- }).catch(reject);
30
- });
31
- };
32
-
33
- const makeRequest = async (host, path, body, method = 'POST', respAsJson = true, timeout = TIMEOUT) => {
34
- let data;
35
- try {
36
- const c = new AbortController();
37
- setTimeout(() => {
38
- c.abort();
39
- }, timeout);
40
- const response = await nodeFetch(`${host}${path}`, {
41
- body: body ? JSON.stringify(body) : null,
42
- headers: body ? { 'Content-Type': 'application/json' } : null,
43
- method,
44
- signal: c.signal,
45
- agent: new HttpsAgent({
46
- rejectUnauthorized: false,
47
- }),
48
- });
49
- if (respAsJson) data = await response.json();
50
- else data = await response.text();
51
- } catch (err) {
52
- throw new ApiErrorFailedToConnect(host);
53
- }
54
- if (respAsJson) {
55
- if (data.code !== 200) {
56
- throw apiErrorCodeToClass(data.result.code, host);
57
- }
58
- return data.result;
59
- } else {
60
- return data;
61
- }
62
- };
63
-
64
- class ApiBuddyClass {
65
- async register(service, host, token, onDefaultRegion) {
66
- const version = getVersion();
67
- const hostname = getHostname();
68
- const platform = getPlatform();
69
- logger.info(LOG_REGISTERING_AGENT);
70
- const r = await makeRequest(host, '/tunnel/agent/add', {
71
- token,
72
- version,
73
- hostname,
74
- platform,
75
- service
76
- });
77
- logger.info(LOG_AGENT_REGISTERED(r.id));
78
- logger.info(LOG_REGION_DETECTED(r.region));
79
- if (onDefaultRegion) onDefaultRegion(r.region);
80
- return new Agent(r.id, host, r.token, service, this);
81
- }
82
-
83
- async unregister(id, host, token) {
84
- logger.info(LOG_UNREGISTERING_AGENT);
85
- await makeRequest(host, '/tunnel/agent/remove', {
86
- token,
87
- id
88
- });
89
- return true;
90
- }
91
-
92
- async fetchAgent(id, host, token) {
93
- logger.info(LOG_GETTING_AGENT);
94
- const r = await makeRequest(host, '/tunnel/agent/fetch', {
95
- token,
96
- id
97
- });
98
- return new Agent(r.id, host, token, r.service, this);
99
- }
100
-
101
- async addTunnel(agentId, host, token, prepared, sshHostKey) {
102
- logger.info(LOG_REGISTERING_TUNNEL);
103
- const config = await makeRequest(host, '/tunnel/add', {
104
- ...prepared,
105
- token,
106
- agentId
107
- });
108
- logger.info(LOG_TUNNEL_REGISTERED(config.id));
109
- return new Tunnel({
110
- ...config,
111
- sshHostKey
112
- });
113
- }
114
-
115
- async removeTunnel(agentId, tunnelId, host, token) {
116
- logger.info(LOG_REMOVING_TUNNEL);
117
- await makeRequest(host, '/tunnel/remove', {
118
- agentId,
119
- tunnelId,
120
- token
121
- });
122
- }
123
-
124
- async fetchMyIp() {
125
- return makeRequest('https://es.buddy.works', '/ip', null, 'GET', false);
126
- }
127
- }
128
-
129
- const ApiBuddy = new ApiBuddyClass();
130
-
131
- module.exports = ApiBuddy;
package/src/api/socket.js DELETED
@@ -1,148 +0,0 @@
1
- const { io } = require('socket.io-client');
2
- const { Agent: HttpsAgent } = require('https');
3
- const EventEmitter = require('events');
4
- const logger = require('../logger.js');
5
- const {
6
- LOG_SOCKET_CONNECTED,
7
- LOG_SOCKET_DISCONNECTED
8
- } = require('../texts');
9
- const {
10
- apiErrorCodeToClass,
11
- getHostname,
12
- getPlatform,
13
- getVersion,
14
- SOCKET_IO_EVENT_FETCH_FAILED,
15
- SOCKET_IO_EVENT_FETCH_SUCCESS,
16
- SOCKET_IO_EVENT_CONNECTED,
17
- SOCKET_IO_EVENT_DISCONNECTED,
18
- SOCKET_IO_EVENT_AGENT,
19
- SOCKET_IO_EVENT_TUNNEL,
20
- EVENT_TUNNEL_HTTP_NEW_RESPONSE_END
21
- } = require('../utils');
22
-
23
- const MAX_REQUESTS_SYNC_WINDOW = 30000;
24
- const MAX_REQUESTS_SYNC_IN_WINDOW = 100;
25
-
26
- class ApiSocketClass extends EventEmitter {
27
- fetch(activate = true, action = null, resetFirstHeard = false, tunnels) {
28
- this.socket.emit('fetchTunnelAgent', {
29
- id: this.id,
30
- token: this.token,
31
- hostname: this.hostname,
32
- platform: this.platform,
33
- version: this.version,
34
- activate,
35
- action,
36
- resetFirstHeard,
37
- tunnels
38
- });
39
- }
40
-
41
- update(activate, tunnels, force = false) {
42
- const now = Date.now();
43
- // nie robimy update jak byl mniej niz 5s temu
44
- if (!force && this.lastUpdate && now - this.lastUpdate < 5000) return;
45
- this.lastUpdate = now;
46
- this.socket.emit('updateTunnelAgent', {
47
- id: this.id,
48
- token: this.token,
49
- hostname: this.hostname,
50
- platform: this.platform,
51
- version: this.version,
52
- activate,
53
- tunnels
54
- });
55
- }
56
-
57
- emitRequest(tunnelId, logRequest) {
58
- this.socket.emit('tunnelRequest', {
59
- id: this.id,
60
- token: this.token,
61
- tunnelId,
62
- request: logRequest.toSocket()
63
- });
64
- }
65
-
66
- request(tunnelId, logRequest) {
67
- if (this.tunnelRequests > MAX_REQUESTS_SYNC_IN_WINDOW) return;
68
- this.tunnelRequests += 1;
69
- logRequest.once(EVENT_TUNNEL_HTTP_NEW_RESPONSE_END, () => {
70
- this.emitRequest(tunnelId, logRequest);
71
- });
72
- this.emitRequest(tunnelId, logRequest);
73
- }
74
-
75
- onSyncAgent(data, action) {
76
- this.emit(SOCKET_IO_EVENT_AGENT, data, action);
77
- }
78
-
79
- onSyncTunnel(data, action) {
80
- this.emit(SOCKET_IO_EVENT_TUNNEL, data, action);
81
- }
82
-
83
- onSync(data) {
84
- try {
85
- const json = JSON.parse(data);
86
- if (json.payloadType === 'TunnelAgentFront') this.onSyncAgent(json.payload, json.action);
87
- else if (json.payloadType === 'TunnelFront') this.onSyncTunnel(json.payload, json.action);
88
- } catch {
89
- // do nothing
90
- }
91
- }
92
-
93
- constructor(host, id, token) {
94
- super();
95
- this.id = id;
96
- this.token = token;
97
- this.connected = false;
98
- this.hostname = getHostname();
99
- this.platform = getPlatform();
100
- this.version = getVersion();
101
- this.lastUpdate = null;
102
- this.tunnelRequests = 0;
103
- setInterval(() => {
104
- this.tunnelRequests = 0;
105
- }, MAX_REQUESTS_SYNC_WINDOW);
106
- this.socket = io(host, {
107
- forceNew: true,
108
- autoConnect: true,
109
- autoUnref: true,
110
- forceBase64: true,
111
- transports: ['websocket'],
112
- reconnection: true,
113
- rejectUnauthorized: false,
114
- agent: new HttpsAgent({
115
- rejectUnauthorized: false,
116
- }),
117
- maxHttpBufferSize: 3e6,
118
- extraHeaders: {
119
- cookie: 'a=b'
120
- }
121
- });
122
- this.socket.on('connect', () => {
123
- this.connected = true;
124
- logger.info(LOG_SOCKET_CONNECTED);
125
- this.emit(SOCKET_IO_EVENT_CONNECTED);
126
- this.socket.emit('joinTunnelAgent', {
127
- id: this.id,
128
- token: this.token,
129
- });
130
- });
131
- this.socket.on('disconnect', () => {
132
- this.connected = false;
133
- logger.info(LOG_SOCKET_DISCONNECTED);
134
- this.emit(SOCKET_IO_EVENT_DISCONNECTED);
135
- });
136
- this.socket.on('fetchTunnelAgentSuccess', (data) => {
137
- logger.debug('Socket fetch success');
138
- this.emit(SOCKET_IO_EVENT_FETCH_SUCCESS, data);
139
- });
140
- this.socket.on('fetchTunnelAgentFailed', (code) => {
141
- logger.debug('Socket fetch failed');
142
- this.emit(SOCKET_IO_EVENT_FETCH_FAILED, apiErrorCodeToClass(code, host));
143
- });
144
- this.socket.on('sync', (data) => this.onSync(data));
145
- }
146
- }
147
-
148
- module.exports = ApiSocketClass;
package/src/cfg.js DELETED
@@ -1,239 +0,0 @@
1
- const { resolve } = require('path');
2
- const {
3
- mkdirSync,
4
- readFileSync,
5
- chmodSync,
6
- statSync,
7
- writeFileSync
8
- } = require('fs');
9
- const { decode } = require('jsonwebtoken');
10
- const {
11
- DEFAULT_TIMEOUT,
12
- getHomeDirectory,
13
- TUNNEL_HTTP,
14
- TUNNEL_TLS
15
- } = require('./utils.js');
16
- const Input = require('./input.js');
17
- const {
18
- ERR_CANT_CREATE_DIR_IN_HOME,
19
- ERR_CONFIG_CORRUPTED,
20
- ERR_TOKEN_NOT_PROVIDED,
21
- ERR_WRONG_TOKEN
22
- } = require('./texts.js');
23
-
24
- class Cfg {
25
- constructor() {
26
- this.dir = getHomeDirectory();
27
- this.file = resolve(this.dir, 'cfg.json');
28
- this.json = {};
29
- this.load();
30
- }
31
-
32
- createDir() {
33
- try {
34
- mkdirSync(this.dir, {
35
- recursive: true,
36
- });
37
- } catch (err) {
38
- throw new Error(ERR_CANT_CREATE_DIR_IN_HOME('.bdy'));
39
- }
40
- try {
41
- chmodSync(this.dir, 0o777);
42
- } catch {
43
- // do nothing
44
- }
45
- }
46
-
47
- createEmptyFile() {
48
- try {
49
- writeFileSync(this.file, '{}', 'utf-8');
50
- } catch (err) {
51
- throw new Error(ERR_CANT_CREATE_DIR_IN_HOME('.bdy/cfg.json'));
52
- }
53
- try {
54
- chmodSync(this.file, 0o666);
55
- } catch {
56
- // do nothing
57
- }
58
- }
59
-
60
- ensureDir() {
61
- try {
62
- statSync(this.dir);
63
- } catch(err) {
64
- this.createDir();
65
- }
66
- }
67
-
68
- ensureFile() {
69
- this.ensureDir();
70
- try {
71
- statSync(this.file);
72
- } catch (err) {
73
- this.createEmptyFile();
74
- }
75
- }
76
-
77
- ensureTunnels() {
78
- if (!this.json.tunnels) this.json.tunnels = {};
79
- }
80
-
81
- async prepareTunnel(tunnelType, target, options, useDefaults) {
82
- const type = Input.type(tunnelType);
83
- const tunnel = {
84
- type,
85
- target: Input.target(target, type)
86
- };
87
- if (options.region !== undefined) tunnel.region = Input.region(options.region);
88
- else if (useDefaults) tunnel.region = this.getRegion();
89
- if (options.whitelist !== undefined) tunnel.whitelist = Input.whitelist(options.whitelist);
90
- else if (useDefaults) tunnel.whitelist = this.getWhitelist();
91
- if (options.timeout !== undefined) tunnel.timeout = Input.timeout(options.timeout);
92
- else if (useDefaults) tunnel.timeout = this.getTimeout();
93
- if (options.domain !== undefined) tunnel.domain = Input.domain(options.domain);
94
- if (options.subdomain !== undefined) tunnel.subdomain = Input.subdomain(options.subdomain);
95
- if (type === TUNNEL_HTTP) {
96
- if (options.host !== undefined) tunnel.host = options.host;
97
- if (options.auth !== undefined) {
98
- const { password, login } = Input.auth(options.auth);
99
- tunnel.login = login;
100
- tunnel.password = password;
101
- }
102
- if (options.ca !== undefined) tunnel.ca = Input.ca(options.ca);
103
- if (options.serve !== undefined) tunnel.serve = Input.serve(options.serve);
104
- if (options.useragent !== undefined) tunnel.useragents = Input.useragents(options.useragent);
105
- if (options.header !== undefined) tunnel.headers = Input.headers(options.header);
106
- if (options.responseHeader !== undefined) tunnel.responseHeaders = Input.headers(options.responseHeader);
107
- if (options.circuitBreaker !== undefined) tunnel.circuitBreaker = Input.circuitBreaker(options.circuitBreaker);
108
- tunnel.log = !!options.log;
109
- tunnel.verify = !!options.verify;
110
- tunnel.http2 = !!options.http2;
111
- tunnel.compression = !!options.compression;
112
- } else if (type === TUNNEL_TLS) {
113
- tunnel.terminate = Input.terminate(options.terminate);
114
- if (options.key !== undefined || options.cert !== undefined){
115
- const { key, cert } = Input.keyCert(options.key, options.cert);
116
- tunnel.key = key;
117
- tunnel.cert = cert;
118
- }
119
- if (options.ca !== undefined) tunnel.ca = Input.ca(options.ca);
120
- }
121
- if (options.name !== undefined) tunnel.name = Input.name(options.name);
122
- return tunnel;
123
- }
124
-
125
- async addTunnel(name, type, target, options) {
126
- this.ensureTunnels();
127
- this.json.tunnels[name] = await this.prepareTunnel(type, target, {
128
- name,
129
- ...options
130
- }, false);
131
- this.save();
132
- }
133
-
134
- removeTunnel(name) {
135
- this.ensureTunnels();
136
- delete this.json.tunnels[name];
137
- this.save();
138
- }
139
-
140
- getTunnels() {
141
- this.ensureTunnels();
142
- return this.json.tunnels;
143
- }
144
-
145
- hasTunnel(name) {
146
- this.ensureTunnels();
147
- return !!this.json.tunnels[name];
148
- }
149
-
150
- getTunnel(name) {
151
- this.ensureTunnels();
152
- return this.json.tunnels[name];
153
- }
154
-
155
- setToken(token) {
156
- if (!token) delete this.json.token;
157
- else this.json.token = token;
158
- this.save();
159
- }
160
-
161
- setWhitelist(whitelist) {
162
- if (!whitelist || !whitelist.length) delete this.json.whitelist;
163
- else this.json.whitelist = whitelist;
164
- this.save();
165
- }
166
-
167
- setTimeout(timeout) {
168
- if (!timeout) delete this.json.timeout;
169
- else this.json.timeout = timeout;
170
- this.save();
171
- }
172
-
173
- getToken() {
174
- return this.json.token || '';
175
- }
176
-
177
- getTokenHost() {
178
- const token = this.getToken();
179
- if (!token) {
180
- throw new Error(ERR_TOKEN_NOT_PROVIDED);
181
- }
182
- const d = decode(token);
183
- if (d === null) {
184
- throw new Error(ERR_WRONG_TOKEN);
185
- }
186
- if (!d.host) {
187
- throw new Error(ERR_WRONG_TOKEN);
188
- }
189
- return d.host;
190
- }
191
-
192
- getRegion() {
193
- return (this.json.region || '').toUpperCase();
194
- }
195
-
196
- getTimeout() {
197
- return this.json.timeout || DEFAULT_TIMEOUT;
198
- }
199
-
200
- getWhitelist() {
201
- return this.json.whitelist || [];
202
- }
203
-
204
- setRegion(region) {
205
- this.json.region = region;
206
- this.save();
207
- }
208
-
209
- setRegionIfNotSet(region) {
210
- if (!this.json.region && region) this.json.region = region.toUpperCase();
211
- this.save();
212
- }
213
-
214
- load() {
215
- this.ensureFile();
216
- try {
217
- const txt = readFileSync(this.file, 'utf-8');
218
- this.json = JSON.parse(txt);
219
- } catch (err) {
220
- throw new Error(ERR_CONFIG_CORRUPTED);
221
- }
222
- }
223
-
224
- save() {
225
- this.ensureDir();
226
- try {
227
- writeFileSync(this.file, JSON.stringify(this.json, null, 4), 'utf-8');
228
- } catch (err) {
229
- throw new Error(ERR_CANT_CREATE_DIR_IN_HOME('.bdy/cfg.json'));
230
- }
231
- try {
232
- chmodSync(this.file, 0o666);
233
- } catch {
234
- // do nothing
235
- }
236
- }
237
- }
238
-
239
- module.exports = new Cfg();