vpn-split 18.0.19 → 18.0.21

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.
@@ -1,31 +1,31 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VpnSplit = void 0;
4
- var tslib_1 = require("tslib");
5
4
  //#region imports
6
- var tnp_core_1 = require("tnp-core");
7
- var express = require("express");
8
- var httpProxy = require("http-proxy");
9
- var tnp_helpers_1 = require("tnp-helpers");
10
- var tnp_config_1 = require("tnp-config");
11
- var hostile_backend_1 = require("./hostile.backend");
12
- var models_1 = require("./models");
13
- var axios_1 = require("axios");
14
- var ng2_logger_1 = require("ng2-logger");
15
- var crypto = require("crypto");
16
- var dgram = require("dgram"); // <-- For UDP sockets
17
- var log = ng2_logger_1.Log.create('vpn-split', ng2_logger_1.Level.INFO);
5
+ const tnp_core_1 = require("tnp-core");
6
+ const http = require("http");
7
+ const express = require("express");
8
+ const httpProxy = require("http-proxy");
9
+ const tnp_helpers_1 = require("tnp-helpers");
10
+ const tnp_config_1 = require("tnp-config");
11
+ const hostile_backend_1 = require("./hostile.backend");
12
+ const models_1 = require("./models");
13
+ const axios_1 = require("axios");
14
+ const ng2_logger_1 = require("ng2-logger");
15
+ const crypto = require("crypto");
16
+ const dgram = require("dgram"); // <-- For UDP sockets
17
+ const log = ng2_logger_1.Log.create('vpn-split', ng2_logger_1.Level.INFO);
18
18
  //#endregion
19
19
  //#region consts
20
- var GENERATED = '#GENERATED_BY_CLI#';
21
- var EOL = process.platform === 'win32' ? '\r\n' : '\n';
22
- var SERVERS_PATH = '/$$$$servers$$$$';
23
- var HOST_FILE_PATHUSER = (0, tnp_core_1.crossPlatformPath)([
20
+ const GENERATED = '#GENERATED_BY_CLI#';
21
+ const EOL = process.platform === 'win32' ? '\r\n' : '\n';
22
+ const SERVERS_PATH = '/$$$$servers$$$$';
23
+ const HOST_FILE_PATHUSER = (0, tnp_core_1.crossPlatformPath)([
24
24
  tnp_core_1.os.userInfo().homedir,
25
25
  'hosts-file__vpn-split',
26
26
  ]);
27
- var from = models_1.HostForServer.From;
28
- var defaultHosts = {
27
+ const from = models_1.HostForServer.From;
28
+ const defaultHosts = {
29
29
  'localhost alias': from({
30
30
  ipOrDomain: '127.0.0.1',
31
31
  aliases: 'localhost',
@@ -43,369 +43,175 @@ var defaultHosts = {
43
43
  }),
44
44
  };
45
45
  //#endregion
46
- var VpnSplit = /** @class */ (function () {
47
- function VpnSplit(portsToPass, hosts, cwd) {
46
+ class VpnSplit {
47
+ portsToPass;
48
+ hosts;
49
+ cwd;
50
+ //#region getters
51
+ get hostsArr() {
52
+ const hosts = this.hosts;
53
+ return tnp_core_1._.keys(hosts).map(hostName => {
54
+ const v = hosts[hostName];
55
+ v.name = hostName;
56
+ return v;
57
+ });
58
+ }
59
+ get hostsArrWithoutDefault() {
60
+ return this.hostsArr.filter(f => !f.isDefault);
61
+ }
62
+ get serveKeyName() {
63
+ return 'tmp-' + tnp_config_1.config.file.server_key;
64
+ }
65
+ get serveKeyPath() {
66
+ return tnp_core_1.path.join(this.cwd, this.serveKeyName);
67
+ }
68
+ get serveCertName() {
69
+ return 'tmp-' + tnp_config_1.config.file.server_cert;
70
+ }
71
+ get serveCertPath() {
72
+ return tnp_core_1.path.join(this.cwd, this.serveCertName);
73
+ }
74
+ get serveCertChainName() {
75
+ return 'tmp-' + tnp_config_1.config.file.server_chain_cert;
76
+ }
77
+ get serveCertChainPath() {
78
+ return tnp_core_1.path.join(this.cwd, this.serveCertChainName);
79
+ }
80
+ //#endregion
81
+ //#region fields
82
+ __hostile;
83
+ //#endregion
84
+ //#region singleton
85
+ static _instances = {};
86
+ constructor(portsToPass, hosts, cwd) {
48
87
  this.portsToPass = portsToPass;
49
88
  this.hosts = hosts;
50
89
  this.cwd = cwd;
51
90
  this.__hostile = new hostile_backend_1.Hostile();
52
91
  }
53
- Object.defineProperty(VpnSplit.prototype, "hostsArr", {
54
- //#region getters
55
- get: function () {
56
- var hosts = this.hosts;
57
- return tnp_core_1._.keys(hosts).map(function (hostName) {
58
- var v = hosts[hostName];
59
- v.name = hostName;
60
- return v;
61
- });
62
- },
63
- enumerable: false,
64
- configurable: true
65
- });
66
- Object.defineProperty(VpnSplit.prototype, "hostsArrWithoutDefault", {
67
- get: function () {
68
- return this.hostsArr.filter(function (f) { return !f.isDefault; });
69
- },
70
- enumerable: false,
71
- configurable: true
72
- });
73
- Object.defineProperty(VpnSplit.prototype, "serveKeyName", {
74
- get: function () {
75
- return 'tmp-' + tnp_config_1.config.file.server_key;
76
- },
77
- enumerable: false,
78
- configurable: true
79
- });
80
- Object.defineProperty(VpnSplit.prototype, "serveKeyPath", {
81
- get: function () {
82
- return tnp_core_1.path.join(this.cwd, this.serveKeyName);
83
- },
84
- enumerable: false,
85
- configurable: true
86
- });
87
- Object.defineProperty(VpnSplit.prototype, "serveCertName", {
88
- get: function () {
89
- return 'tmp-' + tnp_config_1.config.file.server_cert;
90
- },
91
- enumerable: false,
92
- configurable: true
93
- });
94
- Object.defineProperty(VpnSplit.prototype, "serveCertPath", {
95
- get: function () {
96
- return tnp_core_1.path.join(this.cwd, this.serveCertName);
97
- },
98
- enumerable: false,
99
- configurable: true
100
- });
101
- Object.defineProperty(VpnSplit.prototype, "serveCertChainName", {
102
- get: function () {
103
- return 'tmp-' + tnp_config_1.config.file.server_chain_cert;
104
- },
105
- enumerable: false,
106
- configurable: true
107
- });
108
- Object.defineProperty(VpnSplit.prototype, "serveCertChainPath", {
109
- get: function () {
110
- return tnp_core_1.path.join(this.cwd, this.serveCertChainName);
111
- },
112
- enumerable: false,
113
- configurable: true
114
- });
115
- VpnSplit.Instance = function () {
116
- return tslib_1.__awaiter(this, arguments, void 0, function (_a) {
117
- var _b = _a === void 0 ? {} : _a, _c = _b.ports, ports = _c === void 0 ? [80, 443, 4443, 22, 2222, 8180, 8080, 4407, 7999, 9443] : _c, _d = _b.additionalDefaultHosts, additionalDefaultHosts = _d === void 0 ? {} : _d, _e = _b.cwd, cwd = _e === void 0 ? process.cwd() : _e, _f = _b.allowNotSudo, allowNotSudo = _f === void 0 ? false : _f;
118
- return tslib_1.__generator(this, function (_g) {
119
- switch (_g.label) {
120
- case 0: return [4 /*yield*/, (0, tnp_core_1.isElevated)()];
121
- case 1:
122
- if (!(_g.sent()) && !allowNotSudo) {
123
- tnp_helpers_1.Helpers.error("[vpn-split] Please run this program as sudo (or admin on windows)", false, true);
124
- }
125
- if (!VpnSplit._instances[cwd]) {
126
- VpnSplit._instances[cwd] = new VpnSplit(ports, tnp_core_1._.merge(defaultHosts, additionalDefaultHosts), cwd);
127
- }
128
- return [2 /*return*/, VpnSplit._instances[cwd]];
129
- }
130
- });
131
- });
132
- };
92
+ static async Instance({ ports = [80, 443, 4443, 22, 2222, 8180, 8080, 4407, 7999, 9443], additionalDefaultHosts = {}, cwd = process.cwd(), allowNotSudo = false, } = {}) {
93
+ if (!(await (0, tnp_core_1.isElevated)()) && !allowNotSudo) {
94
+ tnp_helpers_1.Helpers.error(`[vpn-split] Please run this program as sudo (or admin on windows)`, false, true);
95
+ }
96
+ if (!VpnSplit._instances[cwd]) {
97
+ VpnSplit._instances[cwd] = new VpnSplit(ports, tnp_core_1._.merge(defaultHosts, additionalDefaultHosts), cwd);
98
+ }
99
+ return VpnSplit._instances[cwd];
100
+ }
133
101
  //#endregion
134
102
  //#region start server
135
- VpnSplit.prototype.startServer = function () {
136
- return tslib_1.__awaiter(this, arguments, void 0, function (saveHostInUserFolder) {
137
- var _a, _b, portToPassthrough, e_1_1, _c, _d, portToPassthrough, e_2_1;
138
- var e_1, _e, e_2, _f;
139
- if (saveHostInUserFolder === void 0) { saveHostInUserFolder = false; }
140
- return tslib_1.__generator(this, function (_g) {
141
- switch (_g.label) {
142
- case 0:
143
- this.createCertificateIfNotExists();
144
- //#region modify /etc/host to direct traffic appropriately
145
- saveHosts(this.hosts, { saveHostInUserFolder: saveHostInUserFolder });
146
- _g.label = 1;
147
- case 1:
148
- _g.trys.push([1, 6, 7, 8]);
149
- _a = tslib_1.__values(this.portsToPass), _b = _a.next();
150
- _g.label = 2;
151
- case 2:
152
- if (!!_b.done) return [3 /*break*/, 5];
153
- portToPassthrough = _b.value;
154
- return [4 /*yield*/, this.serverPassthrough(portToPassthrough)];
155
- case 3:
156
- _g.sent();
157
- _g.label = 4;
158
- case 4:
159
- _b = _a.next();
160
- return [3 /*break*/, 2];
161
- case 5: return [3 /*break*/, 8];
162
- case 6:
163
- e_1_1 = _g.sent();
164
- e_1 = { error: e_1_1 };
165
- return [3 /*break*/, 8];
166
- case 7:
167
- try {
168
- if (_b && !_b.done && (_e = _a.return)) _e.call(_a);
169
- }
170
- finally { if (e_1) throw e_1.error; }
171
- return [7 /*endfinally*/];
172
- case 8:
173
- _g.trys.push([8, 13, 14, 15]);
174
- _c = tslib_1.__values(this.portsToPass), _d = _c.next();
175
- _g.label = 9;
176
- case 9:
177
- if (!!_d.done) return [3 /*break*/, 12];
178
- portToPassthrough = _d.value;
179
- return [4 /*yield*/, this.serverUdpPassthrough(portToPassthrough)];
180
- case 10:
181
- _g.sent();
182
- _g.label = 11;
183
- case 11:
184
- _d = _c.next();
185
- return [3 /*break*/, 9];
186
- case 12: return [3 /*break*/, 15];
187
- case 13:
188
- e_2_1 = _g.sent();
189
- e_2 = { error: e_2_1 };
190
- return [3 /*break*/, 15];
191
- case 14:
192
- try {
193
- if (_d && !_d.done && (_f = _c.return)) _f.call(_c);
194
- }
195
- finally { if (e_2) throw e_2.error; }
196
- return [7 /*endfinally*/];
197
- case 15:
198
- tnp_helpers_1.Helpers.info("Activated (server).");
199
- return [2 /*return*/];
200
- }
201
- });
202
- });
203
- };
103
+ async startServer(saveHostInUserFolder = false) {
104
+ this.createCertificateIfNotExists();
105
+ //#region modify /etc/host to direct traffic appropriately
106
+ saveHosts(this.hosts, { saveHostInUserFolder });
107
+ //#endregion
108
+ // Start TCP/HTTPS passthrough
109
+ for (const portToPassthrough of this.portsToPass) {
110
+ await this.serverPassthrough(portToPassthrough);
111
+ }
112
+ // Start UDP passthrough
113
+ for (const portToPassthrough of this.portsToPass) {
114
+ await this.serverUdpPassthrough(portToPassthrough);
115
+ }
116
+ tnp_helpers_1.Helpers.info(`Activated (server).`);
117
+ }
204
118
  //#endregion
205
119
  //#region apply hosts
206
- VpnSplit.prototype.applyHosts = function (hosts) {
120
+ applyHosts(hosts) {
207
121
  // console.log(hosts);
208
122
  saveHosts(hosts);
209
- };
210
- VpnSplit.prototype.applyHostsLocal = function (hosts) {
123
+ }
124
+ applyHostsLocal(hosts) {
211
125
  // console.log(hosts);
212
126
  saveHostsLocal(hosts);
213
- };
127
+ }
214
128
  //#endregion
215
129
  //#region start client
216
- VpnSplit.prototype.startClient = function (vpnServerTargets_1) {
217
- return tslib_1.__awaiter(this, arguments, void 0, function (vpnServerTargets, saveHostInUserFolder) {
218
- var vpnServerTargets_2, vpnServerTargets_2_1, vpnServerTarget, hosts, vpnServerTargets_3, vpnServerTargets_3_1, vpnServerTarget, newHosts, newHosts_1, newHosts_1_1, host, e_3_1, originalHosts, combinedHostsObj, _a, _b, portToPassthrough, e_4_1, _c, _d, portToPassthrough, e_5_1;
219
- var e_6, _e, e_3, _f, e_7, _g, e_4, _h, e_5, _j;
220
- if (saveHostInUserFolder === void 0) { saveHostInUserFolder = false; }
221
- return tslib_1.__generator(this, function (_k) {
222
- switch (_k.label) {
223
- case 0:
224
- if (!Array.isArray(vpnServerTargets)) {
225
- vpnServerTargets = [vpnServerTargets];
226
- }
227
- try {
228
- for (vpnServerTargets_2 = tslib_1.__values(vpnServerTargets), vpnServerTargets_2_1 = vpnServerTargets_2.next(); !vpnServerTargets_2_1.done; vpnServerTargets_2_1 = vpnServerTargets_2.next()) {
229
- vpnServerTarget = vpnServerTargets_2_1.value;
230
- this.preventBadTargetForClient(vpnServerTarget);
231
- }
232
- }
233
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
234
- finally {
235
- try {
236
- if (vpnServerTargets_2_1 && !vpnServerTargets_2_1.done && (_e = vpnServerTargets_2.return)) _e.call(vpnServerTargets_2);
237
- }
238
- finally { if (e_6) throw e_6.error; }
239
- }
240
- this.createCertificateIfNotExists();
241
- hosts = [];
242
- _k.label = 1;
243
- case 1:
244
- _k.trys.push([1, 6, 7, 8]);
245
- vpnServerTargets_3 = tslib_1.__values(vpnServerTargets), vpnServerTargets_3_1 = vpnServerTargets_3.next();
246
- _k.label = 2;
247
- case 2:
248
- if (!!vpnServerTargets_3_1.done) return [3 /*break*/, 5];
249
- vpnServerTarget = vpnServerTargets_3_1.value;
250
- return [4 /*yield*/, this.getRemoteHosts(vpnServerTarget)];
251
- case 3:
252
- newHosts = _k.sent();
253
- try {
254
- for (newHosts_1 = (e_7 = void 0, tslib_1.__values(newHosts)), newHosts_1_1 = newHosts_1.next(); !newHosts_1_1.done; newHosts_1_1 = newHosts_1.next()) {
255
- host = newHosts_1_1.value;
256
- // Mark the original VPN server domain
257
- host.originHostname = vpnServerTarget.hostname;
258
- hosts.push(host);
259
- }
260
- }
261
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
262
- finally {
263
- try {
264
- if (newHosts_1_1 && !newHosts_1_1.done && (_g = newHosts_1.return)) _g.call(newHosts_1);
265
- }
266
- finally { if (e_7) throw e_7.error; }
267
- }
268
- _k.label = 4;
269
- case 4:
270
- vpnServerTargets_3_1 = vpnServerTargets_3.next();
271
- return [3 /*break*/, 2];
272
- case 5: return [3 /*break*/, 8];
273
- case 6:
274
- e_3_1 = _k.sent();
275
- e_3 = { error: e_3_1 };
276
- return [3 /*break*/, 8];
277
- case 7:
278
- try {
279
- if (vpnServerTargets_3_1 && !vpnServerTargets_3_1.done && (_f = vpnServerTargets_3.return)) _f.call(vpnServerTargets_3);
280
- }
281
- finally { if (e_3) throw e_3.error; }
282
- return [7 /*endfinally*/];
283
- case 8:
284
- originalHosts = this.hostsArr;
285
- combinedHostsObj = tnp_core_1._.values(tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(originalHosts), false), tslib_1.__read(hosts.map(function (h) {
286
- return models_1.HostForServer.From({
287
- aliases: h.alias,
288
- ipOrDomain: h.ip,
289
- originHostname: h.originHostname,
290
- }, "external host ".concat(h.alias, " ").concat(h.ip));
291
- })), false).map(function (c) {
292
- var copy = c.clone();
293
- if (!copy.isDefault) {
294
- copy.ip = "127.0.0.1";
295
- }
296
- return copy;
297
- })
298
- .reduce(function (prev, curr) {
299
- var _a;
300
- return tnp_core_1._.merge(prev, (_a = {},
301
- _a[curr.aliases.join(' ')] = curr,
302
- _a));
303
- }, {}));
304
- saveHosts(combinedHostsObj, { saveHostInUserFolder: saveHostInUserFolder });
305
- _k.label = 9;
306
- case 9:
307
- _k.trys.push([9, 14, 15, 16]);
308
- _a = tslib_1.__values(this.portsToPass), _b = _a.next();
309
- _k.label = 10;
310
- case 10:
311
- if (!!_b.done) return [3 /*break*/, 13];
312
- portToPassthrough = _b.value;
313
- return [4 /*yield*/, this.clientPassthrough(portToPassthrough, vpnServerTargets, combinedHostsObj)];
314
- case 11:
315
- _k.sent();
316
- _k.label = 12;
317
- case 12:
318
- _b = _a.next();
319
- return [3 /*break*/, 10];
320
- case 13: return [3 /*break*/, 16];
321
- case 14:
322
- e_4_1 = _k.sent();
323
- e_4 = { error: e_4_1 };
324
- return [3 /*break*/, 16];
325
- case 15:
326
- try {
327
- if (_b && !_b.done && (_h = _a.return)) _h.call(_a);
328
- }
329
- finally { if (e_4) throw e_4.error; }
330
- return [7 /*endfinally*/];
331
- case 16:
332
- _k.trys.push([16, 21, 22, 23]);
333
- _c = tslib_1.__values(this.portsToPass), _d = _c.next();
334
- _k.label = 17;
335
- case 17:
336
- if (!!_d.done) return [3 /*break*/, 20];
337
- portToPassthrough = _d.value;
338
- return [4 /*yield*/, this.clientUdpPassthrough(portToPassthrough, vpnServerTargets, combinedHostsObj)];
339
- case 18:
340
- _k.sent();
341
- _k.label = 19;
342
- case 19:
343
- _d = _c.next();
344
- return [3 /*break*/, 17];
345
- case 20: return [3 /*break*/, 23];
346
- case 21:
347
- e_5_1 = _k.sent();
348
- e_5 = { error: e_5_1 };
349
- return [3 /*break*/, 23];
350
- case 22:
351
- try {
352
- if (_d && !_d.done && (_j = _c.return)) _j.call(_c);
353
- }
354
- finally { if (e_5) throw e_5.error; }
355
- return [7 /*endfinally*/];
356
- case 23:
357
- tnp_helpers_1.Helpers.info("Client activated");
358
- return [2 /*return*/];
359
- }
130
+ async startClient(vpnServerTargets, saveHostInUserFolder = false) {
131
+ if (!Array.isArray(vpnServerTargets)) {
132
+ vpnServerTargets = [vpnServerTargets];
133
+ }
134
+ for (const vpnServerTarget of vpnServerTargets) {
135
+ this.preventBadTargetForClient(vpnServerTarget);
136
+ }
137
+ this.createCertificateIfNotExists();
138
+ // Get remote host definitions from remote server
139
+ const hosts = [];
140
+ for (const vpnServerTarget of vpnServerTargets) {
141
+ const newHosts = await this.getRemoteHosts(vpnServerTarget);
142
+ for (const host of newHosts) {
143
+ // Mark the original VPN server domain
144
+ host.originHostname = vpnServerTarget.hostname;
145
+ hosts.push(host);
146
+ }
147
+ }
148
+ // Merge with original, redirecting all non-default entries to 127.0.0.1
149
+ const originalHosts = this.hostsArr;
150
+ const combinedHostsObj = tnp_core_1._.values([
151
+ ...originalHosts,
152
+ ...hosts.map(h => models_1.HostForServer.From({
153
+ aliases: h.alias,
154
+ ipOrDomain: h.ip,
155
+ originHostname: h.originHostname,
156
+ }, `external host ${h.alias} ${h.ip}`)),
157
+ ]
158
+ .map(c => {
159
+ let copy = c.clone();
160
+ if (!copy.isDefault) {
161
+ copy.ip = `127.0.0.1`;
162
+ }
163
+ return copy;
164
+ })
165
+ .reduce((prev, curr) => {
166
+ return tnp_core_1._.merge(prev, {
167
+ [curr.aliases.join(' ')]: curr,
360
168
  });
361
- });
362
- };
169
+ }, {}));
170
+ saveHosts(combinedHostsObj, { saveHostInUserFolder });
171
+ // Start TCP/HTTPS passthrough
172
+ for (const portToPassthrough of this.portsToPass) {
173
+ await this.clientPassthrough(portToPassthrough, vpnServerTargets, combinedHostsObj);
174
+ }
175
+ // Start UDP passthrough
176
+ for (const portToPassthrough of this.portsToPass) {
177
+ await this.clientUdpPassthrough(portToPassthrough, vpnServerTargets, combinedHostsObj);
178
+ }
179
+ tnp_helpers_1.Helpers.info(`Client activated`);
180
+ }
363
181
  //#endregion
364
182
  //#region private methods / get remote hosts
365
- VpnSplit.prototype.getRemoteHosts = function (vpnServerTarget) {
366
- return tslib_1.__awaiter(this, void 0, void 0, function () {
367
- var url, response, err_1;
368
- return tslib_1.__generator(this, function (_a) {
369
- switch (_a.label) {
370
- case 0:
371
- _a.trys.push([0, 2, , 3]);
372
- url = "http://".concat(vpnServerTarget.hostname).concat(SERVERS_PATH);
373
- return [4 /*yield*/, (0, axios_1.default)({ url: url, method: 'GET' })];
374
- case 1:
375
- response = _a.sent();
376
- return [2 /*return*/, response.data];
377
- case 2:
378
- err_1 = _a.sent();
379
- tnp_helpers_1.Helpers.error("Remote server: ".concat(vpnServerTarget.hostname, " may be inactive..."), true, true);
380
- return [2 /*return*/, []];
381
- case 3: return [2 /*return*/];
382
- }
383
- });
384
- });
385
- };
183
+ async getRemoteHosts(vpnServerTarget) {
184
+ try {
185
+ const url = `http://${vpnServerTarget.hostname}${SERVERS_PATH}`;
186
+ const response = await (0, axios_1.default)({ url, method: 'GET' });
187
+ return response.data;
188
+ }
189
+ catch (err) {
190
+ tnp_helpers_1.Helpers.error(`Remote server: ${vpnServerTarget.hostname} may be inactive...`, true, true);
191
+ return [];
192
+ }
193
+ }
386
194
  //#endregion
387
195
  //#region private methods / create certificate
388
- VpnSplit.prototype.createCertificateIfNotExists = function () {
196
+ createCertificateIfNotExists() {
389
197
  if (!tnp_helpers_1.Helpers.exists(this.serveKeyPath) ||
390
198
  !tnp_helpers_1.Helpers.exists(this.serveCertPath)) {
391
- tnp_helpers_1.Helpers.info("[vpn-split] Generating new self-signed certificate for localhost...");
392
- var commandGen = "openssl req -nodes -new -x509 -keyout ".concat(this.serveKeyName, " -out ").concat(this.serveCertName);
199
+ tnp_helpers_1.Helpers.info(`[vpn-split] Generating new self-signed certificate for localhost...`);
200
+ const commandGen = `openssl req -nodes -new -x509 -keyout ${this.serveKeyName} -out ${this.serveCertName}`;
393
201
  tnp_helpers_1.Helpers.run(commandGen, { cwd: this.cwd, output: true }).sync();
394
202
  }
395
- };
203
+ }
396
204
  //#endregion
397
205
  //#region private methods / TCP & HTTPS passthrough
398
- VpnSplit.prototype.getTarget = function (_a) {
399
- var req = _a.req, res = _a.res, port = _a.port, hostname = _a.hostname;
400
- return "".concat(req.protocol, "://").concat(hostname, ":").concat(port);
401
- };
402
- VpnSplit.prototype.getProxyConfig = function (_a) {
403
- var req = _a.req, res = _a.res, port = _a.port, hostname = _a.hostname, isHttps = _a.isHttps;
404
- var serverPassthrough = !!hostname;
405
- var target = this.getTarget({
406
- req: req,
407
- res: res,
408
- port: port,
206
+ getTarget({ req, res, port, hostname, }) {
207
+ return `${req.protocol}://${hostname}:${port}`;
208
+ }
209
+ getProxyConfig({ req, res, port, hostname, isHttps, }) {
210
+ const serverPassthrough = !!hostname;
211
+ const target = this.getTarget({
212
+ req,
213
+ res,
214
+ port,
409
215
  hostname: serverPassthrough ? hostname : req.hostname,
410
216
  });
411
217
  // console.log({
@@ -417,7 +223,7 @@ var VpnSplit = /** @class */ (function () {
417
223
  // });
418
224
  return isHttps
419
225
  ? {
420
- target: target,
226
+ target,
421
227
  ssl: {
422
228
  key: tnp_core_1.fse.readFileSync(this.serveKeyPath),
423
229
  cert: tnp_core_1.fse.readFileSync(this.serveCertPath),
@@ -427,195 +233,150 @@ var VpnSplit = /** @class */ (function () {
427
233
  }),
428
234
  secure: false,
429
235
  }
430
- : { target: target };
431
- };
432
- VpnSplit.prototype.getNotFoundMsg = function (req, res, port, type) {
433
- return "[vpn-split] You are requesting a URL that is not in proxy reach [".concat(type, "]\nProtocol: ").concat(req.protocol, "\nHostname: ").concat(req.hostname, "\nOriginalUrl: ").concat(req.originalUrl, "\nReq.method: ").concat(req.method, "\nPort: ").concat(port, "\nSERVERS_PATH: ").concat(SERVERS_PATH);
434
- };
435
- VpnSplit.prototype.getMaybeChangeOriginTrueMsg = function (req, res, port, type) {
436
- return "[vpn-split] Possibly need changeOrigin: true in your proxy config\nProtocol: ".concat(req.protocol, "\nHostname: ").concat(req.hostname, "\nOriginalUrl: ").concat(req.originalUrl, "\nReq.method: ").concat(req.method, "\nPort: ").concat(port);
437
- };
438
- VpnSplit.prototype.filterHeaders = function (req, res) {
236
+ : { target };
237
+ }
238
+ getNotFoundMsg(req, res, port, type) {
239
+ return `[vpn-split] You are requesting a URL that is not in proxy reach [${type}]
240
+ Protocol: ${req.protocol}
241
+ Hostname: ${req.hostname}
242
+ OriginalUrl: ${req.originalUrl}
243
+ Req.method: ${req.method}
244
+ Port: ${port}
245
+ SERVERS_PATH: ${SERVERS_PATH}`;
246
+ }
247
+ getMaybeChangeOriginTrueMsg(req, res, port, type) {
248
+ return `[vpn-split] Possibly need changeOrigin: true in your proxy config
249
+ Protocol: ${req.protocol}
250
+ Hostname: ${req.hostname}
251
+ OriginalUrl: ${req.originalUrl}
252
+ Req.method: ${req.method}
253
+ Port: ${port}`;
254
+ }
255
+ filterHeaders(req, res) {
439
256
  // If you have any headers to remove, do it here:
440
- var headersToRemove = [
257
+ const headersToRemove = [
441
258
  // 'Strict-Transport-Security',
442
259
  // 'Content-Security-Policy',
443
260
  // ...
444
261
  ];
445
- headersToRemove.forEach(function (headerName) {
262
+ headersToRemove.forEach(headerName => {
446
263
  delete req.headers[headerName];
447
264
  res.setHeader(headerName, '');
448
265
  });
449
- };
450
- VpnSplit.prototype.isHttpsPort = function (port) {
266
+ }
267
+ isHttpsPort(port) {
451
268
  // Decide your logic for “is HTTPS” here
452
269
  return [443, 4443, 9443].includes(port);
453
- };
270
+ }
454
271
  //#region server passthrough (TCP/HTTPS)
455
- VpnSplit.prototype.serverPassthrough = function (portToPassthrough) {
456
- return tslib_1.__awaiter(this, void 0, void 0, function () {
457
- var isHttps, app, proxy, currentLocalIps, server;
458
- var _this = this;
459
- return tslib_1.__generator(this, function (_a) {
460
- switch (_a.label) {
461
- case 0:
462
- isHttps = this.isHttpsPort(portToPassthrough);
463
- process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
464
- app = express();
465
- proxy = httpProxy.createProxyServer({});
466
- currentLocalIps = tslib_1.__spreadArray([
467
- 'localhost',
468
- '127.0.0.1'
469
- ], tslib_1.__read(tnp_helpers_1.Helpers.allLocalIpAddresses().map(function (a) { return a.hostname; })), false);
470
- app.use(function (req, res, next) {
471
- _this.filterHeaders(req, res);
472
- if (currentLocalIps.includes(req.hostname)) {
473
- if (req.method === 'GET' && req.originalUrl === SERVERS_PATH) {
474
- res.send(JSON.stringify(_this.hostsArrWithoutDefault.map(function (h) { return ({
475
- ip: h.ip,
476
- alias: tnp_helpers_1.Helpers.arrays.from(h.aliases).join(' '),
477
- }); })));
478
- }
479
- else {
480
- var msg = _this.getNotFoundMsg(req, res, portToPassthrough, 'server');
481
- log.d(msg);
482
- res.send(msg);
483
- }
484
- next();
485
- }
486
- else {
487
- proxy.web(req, res, _this.getProxyConfig({ req: req, res: res, port: portToPassthrough, isHttps: isHttps }), next);
488
- }
489
- });
490
- server = isHttps
491
- ? tnp_core_1.https.createServer({
492
- key: tnp_core_1.fse.readFileSync(this.serveKeyPath),
493
- cert: tnp_core_1.fse.readFileSync(this.serveCertPath),
494
- }, app)
495
- : tnp_core_1.http.createServer(app);
496
- return [4 /*yield*/, tnp_helpers_1.Helpers.killProcessByPort(portToPassthrough, { silent: true })];
497
- case 1:
498
- _a.sent();
499
- return [4 /*yield*/, new Promise(function (resolve, reject) {
500
- server.listen(portToPassthrough, function () {
501
- console.log("TCP/HTTPS server listening on port ".concat(portToPassthrough, " (secure=").concat(isHttps, ")"));
502
- resolve();
503
- });
504
- })];
505
- case 2:
506
- _a.sent();
507
- return [2 /*return*/];
272
+ async serverPassthrough(portToPassthrough) {
273
+ const isHttps = this.isHttpsPort(portToPassthrough);
274
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
275
+ const app = express();
276
+ const proxy = httpProxy.createProxyServer({});
277
+ const currentLocalIps = [
278
+ 'localhost',
279
+ '127.0.0.1',
280
+ ...tnp_helpers_1.Helpers.allLocalIpAddresses().map(a => a.hostname),
281
+ ];
282
+ app.use((req, res, next) => {
283
+ this.filterHeaders(req, res);
284
+ if (currentLocalIps.includes(req.hostname)) {
285
+ if (req.method === 'GET' && req.originalUrl === SERVERS_PATH) {
286
+ res.send(JSON.stringify(this.hostsArrWithoutDefault.map(h => ({
287
+ ip: h.ip,
288
+ alias: tnp_helpers_1.Helpers.arrays.from(h.aliases).join(' '),
289
+ }))));
508
290
  }
291
+ else {
292
+ const msg = this.getNotFoundMsg(req, res, portToPassthrough, 'server');
293
+ log.d(msg);
294
+ res.send(msg);
295
+ }
296
+ next();
297
+ }
298
+ else {
299
+ proxy.web(req, res, this.getProxyConfig({ req, res, port: portToPassthrough, isHttps }), next);
300
+ }
301
+ });
302
+ const server = isHttps
303
+ ? tnp_core_1.https.createServer({
304
+ key: tnp_core_1.fse.readFileSync(this.serveKeyPath),
305
+ cert: tnp_core_1.fse.readFileSync(this.serveCertPath),
306
+ }, app)
307
+ : http.createServer(app);
308
+ await tnp_helpers_1.Helpers.killProcessByPort(portToPassthrough, { silent: true });
309
+ await new Promise((resolve, reject) => {
310
+ server.listen(portToPassthrough, () => {
311
+ console.log(`TCP/HTTPS server listening on port ${portToPassthrough} (secure=${isHttps})`);
312
+ resolve();
509
313
  });
510
314
  });
511
- };
315
+ }
512
316
  //#endregion
513
317
  //#region client passthrough (TCP/HTTPS)
514
- VpnSplit.prototype.clientPassthrough = function (portToPassthrough, vpnServerTargets, hostsArr) {
515
- return tslib_1.__awaiter(this, void 0, void 0, function () {
516
- var aliasToOriginHostname, hostsArr_1, hostsArr_1_1, h, _a, _b, alias, originToUrlMap, vpnServerTargets_1, vpnServerTargets_1_1, url, isHttps, app, proxy, server;
517
- var e_8, _c, e_9, _d, e_10, _e;
518
- var _this = this;
519
- return tslib_1.__generator(this, function (_f) {
520
- switch (_f.label) {
521
- case 0:
522
- aliasToOriginHostname = {};
523
- try {
524
- for (hostsArr_1 = tslib_1.__values(hostsArr), hostsArr_1_1 = hostsArr_1.next(); !hostsArr_1_1.done; hostsArr_1_1 = hostsArr_1.next()) {
525
- h = hostsArr_1_1.value;
526
- try {
527
- for (_a = (e_9 = void 0, tslib_1.__values(h.aliases)), _b = _a.next(); !_b.done; _b = _a.next()) {
528
- alias = _b.value;
529
- aliasToOriginHostname[alias] = h.originHostname;
530
- }
531
- }
532
- catch (e_9_1) { e_9 = { error: e_9_1 }; }
533
- finally {
534
- try {
535
- if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
536
- }
537
- finally { if (e_9) throw e_9.error; }
538
- }
539
- }
540
- }
541
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
542
- finally {
543
- try {
544
- if (hostsArr_1_1 && !hostsArr_1_1.done && (_c = hostsArr_1.return)) _c.call(hostsArr_1);
545
- }
546
- finally { if (e_8) throw e_8.error; }
547
- }
548
- // Remove defaults from the map so we don't cause collisions
549
- delete aliasToOriginHostname['localhost'];
550
- delete aliasToOriginHostname['broadcasthost'];
551
- originToUrlMap = {};
552
- try {
553
- for (vpnServerTargets_1 = tslib_1.__values(vpnServerTargets), vpnServerTargets_1_1 = vpnServerTargets_1.next(); !vpnServerTargets_1_1.done; vpnServerTargets_1_1 = vpnServerTargets_1.next()) {
554
- url = vpnServerTargets_1_1.value;
555
- originToUrlMap[url.hostname] = url;
556
- }
557
- }
558
- catch (e_10_1) { e_10 = { error: e_10_1 }; }
559
- finally {
560
- try {
561
- if (vpnServerTargets_1_1 && !vpnServerTargets_1_1.done && (_e = vpnServerTargets_1.return)) _e.call(vpnServerTargets_1);
562
- }
563
- finally { if (e_10) throw e_10.error; }
564
- }
565
- isHttps = this.isHttpsPort(portToPassthrough);
566
- process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
567
- app = express();
568
- proxy = httpProxy.createProxyServer({});
569
- app.use(function (req, res, next) {
570
- _this.filterHeaders(req, res);
571
- // Identify the real origin server based on alias
572
- var originHostname = aliasToOriginHostname[req.hostname];
573
- if (!originHostname) {
574
- // Not one of our known aliases
575
- var msg = _this.getMaybeChangeOriginTrueMsg(req, res, portToPassthrough, 'client');
576
- res.send(msg);
577
- next();
578
- return;
579
- }
580
- // Proxy onward to the real server domain at the same port
581
- var targetUrlObj = originToUrlMap[originHostname];
582
- if (!targetUrlObj) {
583
- var notFoundMsg = _this.getNotFoundMsg(req, res, portToPassthrough, 'client');
584
- res.send(notFoundMsg);
585
- next();
586
- return;
587
- }
588
- // Forward
589
- proxy.web(req, res, _this.getProxyConfig({
590
- req: req,
591
- res: res,
592
- port: portToPassthrough,
593
- isHttps: isHttps,
594
- hostname: targetUrlObj.hostname,
595
- }), next);
596
- });
597
- server = isHttps
598
- ? tnp_core_1.https.createServer({
599
- key: tnp_core_1.fse.readFileSync(this.serveKeyPath),
600
- cert: tnp_core_1.fse.readFileSync(this.serveCertPath),
601
- }, app)
602
- : tnp_core_1.http.createServer(app);
603
- return [4 /*yield*/, tnp_helpers_1.Helpers.killProcessByPort(portToPassthrough, { silent: true })];
604
- case 1:
605
- _f.sent();
606
- return [4 /*yield*/, new Promise(function (resolve, reject) {
607
- server.listen(portToPassthrough, function () {
608
- log.i("TCP/HTTPS client listening on port ".concat(portToPassthrough, " (secure=").concat(isHttps, ")"));
609
- resolve();
610
- });
611
- })];
612
- case 2:
613
- _f.sent();
614
- return [2 /*return*/];
615
- }
318
+ async clientPassthrough(portToPassthrough, vpnServerTargets, hostsArr) {
319
+ // Map from an alias => the “real” origin hostname (the server domain)
320
+ const aliasToOriginHostname = {};
321
+ for (const h of hostsArr) {
322
+ for (const alias of h.aliases) {
323
+ aliasToOriginHostname[alias] = h.originHostname;
324
+ }
325
+ }
326
+ // Remove defaults from the map so we don't cause collisions
327
+ delete aliasToOriginHostname['localhost'];
328
+ delete aliasToOriginHostname['broadcasthost'];
329
+ // Build a dictionary from originHostname => URL (for quick lookup)
330
+ const originToUrlMap = {};
331
+ for (const url of vpnServerTargets) {
332
+ originToUrlMap[url.hostname] = url;
333
+ }
334
+ const isHttps = this.isHttpsPort(portToPassthrough);
335
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
336
+ const app = express();
337
+ const proxy = httpProxy.createProxyServer({});
338
+ app.use((req, res, next) => {
339
+ this.filterHeaders(req, res);
340
+ // Identify the real origin server based on alias
341
+ const originHostname = aliasToOriginHostname[req.hostname];
342
+ if (!originHostname) {
343
+ // Not one of our known aliases
344
+ const msg = this.getMaybeChangeOriginTrueMsg(req, res, portToPassthrough, 'client');
345
+ res.send(msg);
346
+ next();
347
+ return;
348
+ }
349
+ // Proxy onward to the real server domain at the same port
350
+ const targetUrlObj = originToUrlMap[originHostname];
351
+ if (!targetUrlObj) {
352
+ const notFoundMsg = this.getNotFoundMsg(req, res, portToPassthrough, 'client');
353
+ res.send(notFoundMsg);
354
+ next();
355
+ return;
356
+ }
357
+ // Forward
358
+ proxy.web(req, res, this.getProxyConfig({
359
+ req,
360
+ res,
361
+ port: portToPassthrough,
362
+ isHttps,
363
+ hostname: targetUrlObj.hostname,
364
+ }), next);
365
+ });
366
+ const server = isHttps
367
+ ? tnp_core_1.https.createServer({
368
+ key: tnp_core_1.fse.readFileSync(this.serveKeyPath),
369
+ cert: tnp_core_1.fse.readFileSync(this.serveCertPath),
370
+ }, app)
371
+ : http.createServer(app);
372
+ await tnp_helpers_1.Helpers.killProcessByPort(portToPassthrough, { silent: true });
373
+ await new Promise((resolve, reject) => {
374
+ server.listen(portToPassthrough, () => {
375
+ log.i(`TCP/HTTPS client listening on port ${portToPassthrough} (secure=${isHttps})`);
376
+ resolve();
616
377
  });
617
378
  });
618
- };
379
+ }
619
380
  //#endregion
620
381
  //#region UDP passthrough
621
382
  /**
@@ -623,34 +384,112 @@ var VpnSplit = /** @class */ (function () {
623
384
  * This example forwards inbound messages right back to the sender,
624
385
  * or you can forward them to an external IP:port if desired.
625
386
  */
626
- VpnSplit.prototype.serverUdpPassthrough = function (port) {
627
- return tslib_1.__awaiter(this, void 0, void 0, function () {
628
- var socket;
629
- return tslib_1.__generator(this, function (_a) {
630
- return [2 /*return*/];
387
+ async serverUdpPassthrough(port) {
388
+ return;
389
+ // Example of a simple “echo-style” server or forwarder
390
+ const socket = dgram.createSocket('udp4');
391
+ // (Optionally) kill existing processes on that port – though for UDP
392
+ // we might not have a direct “listener process.” Adjust as needed.
393
+ // await Helpers.killProcessByPort(port, { silent: true }).catch(() => {});
394
+ socket.on('message', (msg, rinfo) => {
395
+ // rinfo contains { address, port } of the sender
396
+ // In a typical “server” scenario, you might:
397
+ // 1. Inspect msg
398
+ // 2. Possibly forward to some real backend if needed
399
+ // 3. Or just echo it back
400
+ // For a real forward, do something like:
401
+ // const backendHost = 'some-other-host-or-ip';
402
+ // const backendPort = 9999;
403
+ // socket.send(msg, 0, msg.length, backendPort, backendHost);
404
+ // For a basic echo server:
405
+ socket.send(msg, 0, msg.length, rinfo.port, rinfo.address, err => {
406
+ if (err) {
407
+ log.er(`UDP server send error: ${err}`);
408
+ }
631
409
  });
632
410
  });
633
- };
411
+ socket.on('listening', () => {
412
+ const address = socket.address();
413
+ log.i(`UDP server listening at ${address.address}:${address.port}`);
414
+ });
415
+ socket.bind(port);
416
+ }
634
417
  /**
635
418
  * Start a UDP socket for “client” mode on a given port.
636
419
  * This example also just does a trivial pass-through or echo,
637
420
  * but you can adapt to forward to a remote server.
638
421
  */
639
- VpnSplit.prototype.clientUdpPassthrough = function (port, vpnServerTargets, hostsArr) {
640
- return tslib_1.__awaiter(this, void 0, void 0, function () {
641
- var socket, primaryTarget, targetHost, targetPort, clientMap;
642
- return tslib_1.__generator(this, function (_a) {
643
- return [2 /*return*/];
644
- });
422
+ async clientUdpPassthrough(port, vpnServerTargets, hostsArr) {
423
+ return;
424
+ // console.log(`Client UDP passthrough, port ${port}` );
425
+ // In client mode, we typically intercept local UDP traffic on “port”
426
+ // and forward it to the remote server. Then we forward the remote
427
+ // server's response back to the local client.
428
+ const socket = dgram.createSocket('udp4');
429
+ // await Helpers.killProcessByPort(port, { silent: true }).catch(() => {});
430
+ // For simplicity, pick the first server from the array
431
+ // Or add your own logic to choose among multiple.
432
+ const primaryTarget = vpnServerTargets[0];
433
+ const targetHost = primaryTarget.hostname;
434
+ // Choose the same port or a custom port
435
+ const targetPort = port;
436
+ // A map to remember who originally sent us a packet,
437
+ // so we can route the response back properly.
438
+ // Key could be “targetHost:targetPort => { address, port }”
439
+ // or “clientAddress:clientPort” => { remoteAddress, remotePort }.
440
+ // Adapt to your scenario.
441
+ const clientMap = new Map();
442
+ socket.on('message', (msg, rinfo) => {
443
+ //
444
+ // If the message is from a local client, forward to server.
445
+ // If the message is from the server, forward back to the correct client.
446
+ //
447
+ // Check if it’s from local or remote by address. This is simplistic:
448
+ const isFromLocal = !tnp_core_1._.includes(hostsArr.map(h => h.ipOrDomain), rinfo.address);
449
+ if (isFromLocal) {
450
+ // Received from local => forward to “server” (the VPN server)
451
+ // Keep track of who we got this from (the local client)
452
+ const key = `local-${rinfo.address}:${rinfo.port}`;
453
+ clientMap.set(key, rinfo);
454
+ // Forward to remote
455
+ socket.send(msg, 0, msg.length, targetPort, targetHost, err => {
456
+ if (err) {
457
+ log.er(`UDP client forward error: ${err}`);
458
+ }
459
+ });
460
+ }
461
+ else {
462
+ // Probably from remote => forward back to whichever local client sent it
463
+ // In a more advanced scenario, parse the payload or maintain a bigger table
464
+ // with NAT-like sessions.
465
+ //
466
+ // For now, we guess it’s from the “VPN server”
467
+ // We'll just route it back to the single local client that we stored
468
+ // or do multiple if we had a better NAT map.
469
+ // If you have multi-target or multi-client logic, adapt here.
470
+ // For example, search clientMap by something in the msg or a NAT key.
471
+ clientMap.forEach((localRinfo, key) => {
472
+ socket.send(msg, 0, msg.length, localRinfo.port, localRinfo.address, err => {
473
+ if (err) {
474
+ log.er(`UDP client re-send error: ${err}`);
475
+ }
476
+ });
477
+ });
478
+ }
645
479
  });
646
- };
480
+ socket.on('listening', () => {
481
+ const address = socket.address();
482
+ log.i(`UDP client listening at ${address.address}:${address.port}, forwarding to ${targetHost}:${targetPort}`);
483
+ });
484
+ socket.bind(port);
485
+ }
647
486
  //#endregion
648
487
  //#region private methods / get port from request
649
- VpnSplit.prototype.getPortFromRequest = function (req) {
650
- var host = req.headers.host;
651
- var protocol = req.protocol;
488
+ getPortFromRequest(req) {
489
+ const host = req.headers.host;
490
+ const protocol = req.protocol;
652
491
  if (host) {
653
- var hostParts = host.split(':');
492
+ const hostParts = host.split(':');
654
493
  if (hostParts.length === 2) {
655
494
  return Number(hostParts[1]);
656
495
  }
@@ -659,39 +498,38 @@ var VpnSplit = /** @class */ (function () {
659
498
  }
660
499
  }
661
500
  return 80;
662
- };
501
+ }
663
502
  //#endregion
664
503
  //#region private methods / prevent bad target for client
665
- VpnSplit.prototype.preventBadTargetForClient = function (vpnServerTarget) {
504
+ preventBadTargetForClient(vpnServerTarget) {
666
505
  if (!vpnServerTarget) {
667
- var currentLocalIp = tnp_helpers_1.Helpers.localIpAddress();
668
- tnp_helpers_1.Helpers.error("[vpn-server] Please provide a correct target server.\n" +
669
- "Example:\n" +
670
- "vpn-server ".concat(currentLocalIp, "\n\n") +
671
- "Your local IP is: ".concat(currentLocalIp), false, true);
506
+ const currentLocalIp = tnp_helpers_1.Helpers.localIpAddress();
507
+ tnp_helpers_1.Helpers.error(`[vpn-server] Please provide a correct target server.\n` +
508
+ `Example:\n` +
509
+ `vpn-server ${currentLocalIp}\n\n` +
510
+ `Your local IP is: ${currentLocalIp}`, false, true);
672
511
  }
673
- };
674
- //#endregion
675
- //#region singleton
676
- VpnSplit._instances = {};
677
- return VpnSplit;
678
- }());
512
+ }
513
+ }
679
514
  exports.VpnSplit = VpnSplit;
680
515
  //#region helper / gen msg
681
- var genMsg = "\n################################################\n## This file is generated #####################\n################################################\n".trim() + EOL;
516
+ const genMsg = `
517
+ ################################################
518
+ ## This file is generated #####################
519
+ ################################################
520
+ `.trim() + EOL;
682
521
  //#endregion
683
522
  //#region helpers / save hosts
684
523
  function saveHosts(hosts, options) {
685
- var saveHostInUserFolder = (options || {}).saveHostInUserFolder;
524
+ const { saveHostInUserFolder } = options || {};
686
525
  if (tnp_core_1._.isArray(hosts)) {
687
- hosts = hosts.reduce(function (prev, curr) {
688
- var _a;
689
- return tnp_core_1._.merge(prev, (_a = {},
690
- _a[curr.name] = curr,
691
- _a));
526
+ hosts = hosts.reduce((prev, curr) => {
527
+ return tnp_core_1._.merge(prev, {
528
+ [curr.name]: curr,
529
+ });
692
530
  }, {});
693
531
  }
694
- var toSave = parseHost(hosts, !!saveHostInUserFolder);
532
+ const toSave = parseHost(hosts, !!saveHostInUserFolder);
695
533
  if (saveHostInUserFolder) {
696
534
  tnp_helpers_1.Helpers.writeFile(HOST_FILE_PATHUSER, toSave);
697
535
  }
@@ -700,16 +538,15 @@ function saveHosts(hosts, options) {
700
538
  }
701
539
  }
702
540
  function saveHostsLocal(hosts, options) {
703
- var saveHostInUserFolder = (options || {}).saveHostInUserFolder;
541
+ const { saveHostInUserFolder } = options || {};
704
542
  if (tnp_core_1._.isArray(hosts)) {
705
- hosts = hosts.reduce(function (prev, curr) {
706
- var _a;
707
- return tnp_core_1._.merge(prev, (_a = {},
708
- _a[curr.name] = curr,
709
- _a));
543
+ hosts = hosts.reduce((prev, curr) => {
544
+ return tnp_core_1._.merge(prev, {
545
+ [curr.name]: curr,
546
+ });
710
547
  }, {});
711
548
  }
712
- var toSave = parseHost(hosts, !!saveHostInUserFolder, true);
549
+ const toSave = parseHost(hosts, !!saveHostInUserFolder, true);
713
550
  if (saveHostInUserFolder) {
714
551
  tnp_helpers_1.Helpers.writeFile(HOST_FILE_PATHUSER, toSave);
715
552
  }
@@ -719,27 +556,26 @@ function saveHostsLocal(hosts, options) {
719
556
  }
720
557
  //#endregion
721
558
  //#region helpers / parse hosts
722
- function parseHost(hosts, saveHostInUserFolder, useLocal) {
723
- if (useLocal === void 0) { useLocal = false; }
724
- tnp_core_1._.keys(hosts).forEach(function (hostName) {
725
- var v = hosts[hostName];
559
+ function parseHost(hosts, saveHostInUserFolder, useLocal = false) {
560
+ tnp_core_1._.keys(hosts).forEach(hostName => {
561
+ const v = hosts[hostName];
726
562
  v.name = hostName;
727
563
  });
728
564
  return (genMsg +
729
565
  EOL +
730
566
  tnp_core_1._.keys(hosts)
731
- .map(function (hostName) {
732
- var v = hosts[hostName];
733
- var aliasesStr = v.aliases.join(' ');
567
+ .map(hostName => {
568
+ const v = hosts[hostName];
569
+ const aliasesStr = v.aliases.join(' ');
734
570
  if (saveHostInUserFolder) {
735
571
  // For a user-specific hosts file:
736
572
  return useLocal
737
- ? "127.0.0.1 ".concat(aliasesStr)
738
- : "".concat(v.disabled ? '#' : '').concat(v.ipOrDomain, " ").concat(aliasesStr);
573
+ ? `127.0.0.1 ${aliasesStr}`
574
+ : `${v.disabled ? '#' : ''}${v.ipOrDomain} ${aliasesStr}`;
739
575
  }
740
576
  return useLocal
741
- ? "127.0.0.1 ".concat(aliasesStr)
742
- : "".concat(v.disabled ? '#' : '').concat(v.ipOrDomain, " ").concat(aliasesStr, " # ").concat(v.name, " ").concat(GENERATED);
577
+ ? `127.0.0.1 ${aliasesStr}`
578
+ : `${v.disabled ? '#' : ''}${v.ipOrDomain} ${aliasesStr} # ${v.name} ${GENERATED}`;
743
579
  })
744
580
  .join(EOL) +
745
581
  EOL +