pinggy 0.2.3 → 0.3.0
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.
- package/.github/workflows/publish-binaries.yml +60 -61
- package/dist/index.cjs +144 -84
- package/dist/index.d.cts +30 -10
- package/dist/index.d.ts +30 -10
- package/dist/index.js +133 -71
- package/package.json +2 -2
- package/src/cli/buildConfig.ts +1 -1
- package/src/cli/defaults.ts +1 -2
- package/src/remote_management/handler.ts +3 -1
- package/src/remote_management/remote_schema.ts +9 -8
- package/src/tunnel_manager/TunnelManager.ts +151 -71
- package/src/types.ts +2 -0
|
@@ -36,59 +36,6 @@ jobs:
|
|
|
36
36
|
- name: Run caxa build to produce `bin/`
|
|
37
37
|
run: make pack
|
|
38
38
|
|
|
39
|
-
- name: Import Code Signing Certificate
|
|
40
|
-
env:
|
|
41
|
-
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
|
|
42
|
-
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
|
|
43
|
-
run: |
|
|
44
|
-
# Create temporary keychain
|
|
45
|
-
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
|
|
46
|
-
KEYCHAIN_PASSWORD=$(openssl rand -base64 32)
|
|
47
|
-
|
|
48
|
-
# Decode certificate and import to keychain
|
|
49
|
-
echo "$MACOS_CERTIFICATE" | base64 --decode > certificate.p12
|
|
50
|
-
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
|
51
|
-
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
|
|
52
|
-
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
|
53
|
-
security import certificate.p12 -k "$KEYCHAIN_PATH" -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign
|
|
54
|
-
security list-keychain -d user -s "$KEYCHAIN_PATH"
|
|
55
|
-
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
|
56
|
-
|
|
57
|
-
# Clean up certificate file
|
|
58
|
-
rm certificate.p12
|
|
59
|
-
|
|
60
|
-
- name: Code Sign Binary
|
|
61
|
-
env:
|
|
62
|
-
DEVELOPER_ID: ${{ secrets.MACOS_DEVELOPER_ID }}
|
|
63
|
-
run: |
|
|
64
|
-
FILE=$(ls bin)
|
|
65
|
-
echo "Code signing: $FILE"
|
|
66
|
-
codesign --force --options runtime --sign "$DEVELOPER_ID" --timestamp "bin/$FILE"
|
|
67
|
-
codesign --verify --verbose "bin/$FILE"
|
|
68
|
-
|
|
69
|
-
- name: Notarize Binary (Optional)
|
|
70
|
-
env:
|
|
71
|
-
APPLE_ID: ${{ secrets.APPLE_ID }}
|
|
72
|
-
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
|
|
73
|
-
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
|
74
|
-
run: |
|
|
75
|
-
FILE=$(ls bin)
|
|
76
|
-
|
|
77
|
-
# Create a zip for notarization
|
|
78
|
-
ditto -c -k --keepParent "bin/$FILE" "bin/$FILE.zip"
|
|
79
|
-
|
|
80
|
-
# Submit for notarization
|
|
81
|
-
xcrun notarytool submit "bin/$FILE.zip" \
|
|
82
|
-
--apple-id "$APPLE_ID" \
|
|
83
|
-
--password "$APPLE_APP_SPECIFIC_PASSWORD" \
|
|
84
|
-
--team-id "$APPLE_TEAM_ID" \
|
|
85
|
-
--wait
|
|
86
|
-
|
|
87
|
-
# Remove zip file
|
|
88
|
-
rm "bin/$FILE.zip"
|
|
89
|
-
|
|
90
|
-
echo "Notarization complete"
|
|
91
|
-
|
|
92
39
|
- name: Show bin directory
|
|
93
40
|
run: ls -R ./bin
|
|
94
41
|
|
|
@@ -109,14 +56,6 @@ jobs:
|
|
|
109
56
|
|
|
110
57
|
echo "Uploading $FILE to GitHub Release…"
|
|
111
58
|
gh release upload "$VERSION" "bin/$FILE" --clobber
|
|
112
|
-
|
|
113
|
-
- name: Cleanup Keychain
|
|
114
|
-
if: always()
|
|
115
|
-
run: |
|
|
116
|
-
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
|
|
117
|
-
if [ -f "$KEYCHAIN_PATH" ]; then
|
|
118
|
-
security delete-keychain "$KEYCHAIN_PATH"
|
|
119
|
-
fi
|
|
120
59
|
|
|
121
60
|
Windows:
|
|
122
61
|
name: Build on ${{ matrix.name }} and upload
|
|
@@ -205,6 +144,59 @@ jobs:
|
|
|
205
144
|
|
|
206
145
|
- name: Run caxa build to produce `bin/`
|
|
207
146
|
run: make pack
|
|
147
|
+
|
|
148
|
+
- name: Import Code Signing Certificate
|
|
149
|
+
env:
|
|
150
|
+
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
|
|
151
|
+
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
|
|
152
|
+
run: |
|
|
153
|
+
# Create temporary keychain
|
|
154
|
+
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
|
|
155
|
+
KEYCHAIN_PASSWORD=$(openssl rand -base64 32)
|
|
156
|
+
|
|
157
|
+
# Decode certificate and import to keychain
|
|
158
|
+
echo "$MACOS_CERTIFICATE" | base64 --decode > certificate.p12
|
|
159
|
+
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
|
160
|
+
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
|
|
161
|
+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
|
162
|
+
security import certificate.p12 -k "$KEYCHAIN_PATH" -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign
|
|
163
|
+
security list-keychain -d user -s "$KEYCHAIN_PATH"
|
|
164
|
+
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
|
165
|
+
|
|
166
|
+
# Clean up certificate file
|
|
167
|
+
rm certificate.p12
|
|
168
|
+
|
|
169
|
+
- name: Code Sign Binary
|
|
170
|
+
env:
|
|
171
|
+
DEVELOPER_ID: ${{ secrets.MACOS_DEVELOPER_ID }}
|
|
172
|
+
run: |
|
|
173
|
+
FILE=$(ls bin)
|
|
174
|
+
echo "Code signing: $FILE"
|
|
175
|
+
codesign --force --options runtime --sign "$DEVELOPER_ID" --timestamp "bin/$FILE"
|
|
176
|
+
codesign --verify --verbose "bin/$FILE"
|
|
177
|
+
|
|
178
|
+
- name: Notarize Binary (Optional)
|
|
179
|
+
env:
|
|
180
|
+
APPLE_ID: ${{ secrets.APPLE_ID }}
|
|
181
|
+
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
|
|
182
|
+
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
|
183
|
+
run: |
|
|
184
|
+
FILE=$(ls bin)
|
|
185
|
+
|
|
186
|
+
# Create a zip for notarization
|
|
187
|
+
ditto -c -k --keepParent "bin/$FILE" "bin/$FILE.zip"
|
|
188
|
+
|
|
189
|
+
# Submit for notarization
|
|
190
|
+
xcrun notarytool submit "bin/$FILE.zip" \
|
|
191
|
+
--apple-id "$APPLE_ID" \
|
|
192
|
+
--password "$APPLE_APP_SPECIFIC_PASSWORD" \
|
|
193
|
+
--team-id "$APPLE_TEAM_ID" \
|
|
194
|
+
--wait
|
|
195
|
+
|
|
196
|
+
# Remove zip file
|
|
197
|
+
rm "bin/$FILE.zip"
|
|
198
|
+
|
|
199
|
+
echo "Notarization complete"
|
|
208
200
|
|
|
209
201
|
- name: See bin directory
|
|
210
202
|
run: ls -R ./bin
|
|
@@ -226,3 +218,10 @@ jobs:
|
|
|
226
218
|
echo "Uploading $FILE to GitHub Release…"
|
|
227
219
|
gh release upload "$VERSION" "bin/$FILE" --clobber
|
|
228
220
|
|
|
221
|
+
- name: Cleanup Keychain
|
|
222
|
+
if: always()
|
|
223
|
+
run: |
|
|
224
|
+
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
|
|
225
|
+
if [ -f "$KEYCHAIN_PATH" ]; then
|
|
226
|
+
security delete-keychain "$KEYCHAIN_PATH"
|
|
227
|
+
fi
|
package/dist/index.cjs
CHANGED
|
@@ -962,6 +962,18 @@ _CLIPrinter.errorDefinitions = [
|
|
|
962
962
|
var CLIPrinter = _CLIPrinter;
|
|
963
963
|
var printer_default = CLIPrinter;
|
|
964
964
|
|
|
965
|
+
// src/utils/util.ts
|
|
966
|
+
init_cjs_shims();
|
|
967
|
+
var import_module = require("module");
|
|
968
|
+
function isValidPort(p) {
|
|
969
|
+
return Number.isInteger(p) && p > 0 && p < 65536;
|
|
970
|
+
}
|
|
971
|
+
var require2 = (0, import_module.createRequire)(importMetaUrl);
|
|
972
|
+
var pkg = require2("../package.json");
|
|
973
|
+
function getVersion() {
|
|
974
|
+
return pkg.version ?? "";
|
|
975
|
+
}
|
|
976
|
+
|
|
965
977
|
// src/tunnel_manager/TunnelManager.ts
|
|
966
978
|
var __filename2 = (0, import_node_url.fileURLToPath)(importMetaUrl);
|
|
967
979
|
var __dirname = import_node_path.default.dirname(__filename2);
|
|
@@ -984,6 +996,7 @@ var TunnelManager = class _TunnelManager {
|
|
|
984
996
|
}
|
|
985
997
|
/**
|
|
986
998
|
* Creates a new managed tunnel instance with the given configuration.
|
|
999
|
+
* Builds the config with forwarding rules and creates the tunnel instance.
|
|
987
1000
|
*
|
|
988
1001
|
* @param config - The tunnel configuration options
|
|
989
1002
|
* @param config.configid - Unique identifier for the tunnel configuration
|
|
@@ -1005,42 +1018,97 @@ var TunnelManager = class _TunnelManager {
|
|
|
1005
1018
|
throw new Error(`Tunnel with configId "${configid}" already exists`);
|
|
1006
1019
|
}
|
|
1007
1020
|
const tunnelid = config.tunnelid || await getUuid();
|
|
1021
|
+
const configWithForwarding = this.buildPinggyConfig(config, additionalForwarding);
|
|
1022
|
+
return this._createTunnelWithProcessedConfig({
|
|
1023
|
+
configid,
|
|
1024
|
+
tunnelid,
|
|
1025
|
+
tunnelName,
|
|
1026
|
+
originalConfig: config,
|
|
1027
|
+
configWithForwarding,
|
|
1028
|
+
additionalForwarding,
|
|
1029
|
+
serve: config.serve,
|
|
1030
|
+
autoReconnect: config.autoReconnect !== void 0 ? config.autoReconnect : false
|
|
1031
|
+
});
|
|
1032
|
+
}
|
|
1033
|
+
/**
|
|
1034
|
+
* Internal method to create a tunnel with an already-processed configuration.
|
|
1035
|
+
* This is used by createTunnel, restartTunnel, and updateConfig to avoid config processing.
|
|
1036
|
+
*
|
|
1037
|
+
* @param params - Configuration parameters with already-processed forwarding rules
|
|
1038
|
+
* @returns The created ManagedTunnel instance
|
|
1039
|
+
* @private
|
|
1040
|
+
*/
|
|
1041
|
+
async _createTunnelWithProcessedConfig(params) {
|
|
1008
1042
|
let instance;
|
|
1009
1043
|
try {
|
|
1010
|
-
instance = await import_pinggy2.pinggy.createTunnel(
|
|
1044
|
+
instance = await import_pinggy2.pinggy.createTunnel(params.configWithForwarding);
|
|
1011
1045
|
} catch (e) {
|
|
1012
1046
|
logger.error("Error creating tunnel instance:", e);
|
|
1013
1047
|
throw e;
|
|
1014
1048
|
}
|
|
1015
1049
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1016
|
-
let autoReconnect = config.autoReconnect !== void 0 ? config.autoReconnect : false;
|
|
1017
1050
|
const managed = {
|
|
1018
|
-
tunnelid,
|
|
1019
|
-
configid,
|
|
1020
|
-
tunnelName,
|
|
1051
|
+
tunnelid: params.tunnelid,
|
|
1052
|
+
configid: params.configid,
|
|
1053
|
+
tunnelName: params.tunnelName,
|
|
1021
1054
|
instance,
|
|
1022
|
-
tunnelConfig:
|
|
1023
|
-
|
|
1024
|
-
|
|
1055
|
+
tunnelConfig: params.originalConfig,
|
|
1056
|
+
configWithForwarding: params.configWithForwarding,
|
|
1057
|
+
additionalForwarding: params.additionalForwarding,
|
|
1058
|
+
serve: params.serve,
|
|
1025
1059
|
warnings: [],
|
|
1026
1060
|
isStopped: false,
|
|
1027
1061
|
createdAt: now,
|
|
1028
1062
|
startedAt: null,
|
|
1029
1063
|
stoppedAt: null,
|
|
1030
|
-
autoReconnect
|
|
1064
|
+
autoReconnect: params.autoReconnect
|
|
1031
1065
|
};
|
|
1032
|
-
instance.
|
|
1066
|
+
instance.setTunnelEstablishedCallback(({}) => {
|
|
1033
1067
|
managed.startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1034
1068
|
});
|
|
1035
|
-
this.setupStatsCallback(tunnelid, managed);
|
|
1036
|
-
this.setupErrorCallback(tunnelid, managed);
|
|
1037
|
-
this.setupDisconnectCallback(tunnelid, managed);
|
|
1038
|
-
this.setUpTunnelWorkerErrorCallback(tunnelid, managed);
|
|
1039
|
-
this.tunnelsByTunnelId.set(tunnelid, managed);
|
|
1040
|
-
this.tunnelsByConfigId.set(configid, managed);
|
|
1041
|
-
logger.info("Tunnel created", { configid, tunnelid });
|
|
1069
|
+
this.setupStatsCallback(params.tunnelid, managed);
|
|
1070
|
+
this.setupErrorCallback(params.tunnelid, managed);
|
|
1071
|
+
this.setupDisconnectCallback(params.tunnelid, managed);
|
|
1072
|
+
this.setUpTunnelWorkerErrorCallback(params.tunnelid, managed);
|
|
1073
|
+
this.tunnelsByTunnelId.set(params.tunnelid, managed);
|
|
1074
|
+
this.tunnelsByConfigId.set(params.configid, managed);
|
|
1075
|
+
logger.info("Tunnel created", { configid: params.configid, tunnelid: params.tunnelid });
|
|
1042
1076
|
return managed;
|
|
1043
1077
|
}
|
|
1078
|
+
/**
|
|
1079
|
+
* Builds the Pinggy configuration by merging the default forwarding rule
|
|
1080
|
+
* with additional forwarding rules from additionalForwarding array.
|
|
1081
|
+
*
|
|
1082
|
+
* @param config - The base Pinggy configuration
|
|
1083
|
+
* @param additionalForwarding - Optional array of additional forwarding rules
|
|
1084
|
+
* @returns Modified PinggyOptions
|
|
1085
|
+
*/
|
|
1086
|
+
buildPinggyConfig(config, additionalForwarding) {
|
|
1087
|
+
const forwardingRules = [];
|
|
1088
|
+
if (config.forwarding) {
|
|
1089
|
+
forwardingRules.push({
|
|
1090
|
+
type: config.tunnelType && config.tunnelType[0] || "http",
|
|
1091
|
+
address: config.forwarding
|
|
1092
|
+
});
|
|
1093
|
+
}
|
|
1094
|
+
if (Array.isArray(additionalForwarding) && additionalForwarding.length > 0) {
|
|
1095
|
+
for (const rule of additionalForwarding) {
|
|
1096
|
+
if (rule && rule.localDomain && rule.localPort && rule.remoteDomain && isValidPort(rule.localPort)) {
|
|
1097
|
+
const forwardingRule = {
|
|
1098
|
+
type: import_pinggy2.TunnelType.Http,
|
|
1099
|
+
// In Future we can make this dynamic based on user input
|
|
1100
|
+
address: `${rule.localDomain}:${rule.localPort}`,
|
|
1101
|
+
listenAddress: rule.remotePort && isValidPort(rule.remotePort) ? `${rule.remoteDomain}:${rule.remotePort}` : rule.remoteDomain
|
|
1102
|
+
};
|
|
1103
|
+
forwardingRules.push(forwardingRule);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
return {
|
|
1108
|
+
...config,
|
|
1109
|
+
forwarding: forwardingRules.length > 0 ? forwardingRules : config.forwarding
|
|
1110
|
+
};
|
|
1111
|
+
}
|
|
1044
1112
|
/**
|
|
1045
1113
|
* Start a tunnel that was created but not yet started
|
|
1046
1114
|
*/
|
|
@@ -1056,22 +1124,6 @@ var TunnelManager = class _TunnelManager {
|
|
|
1056
1124
|
throw error;
|
|
1057
1125
|
}
|
|
1058
1126
|
logger.info("Tunnel started", { tunnelId, urls });
|
|
1059
|
-
if (Array.isArray(managed.additionalForwarding) && managed.additionalForwarding.length > 0) {
|
|
1060
|
-
for (const f of managed.additionalForwarding) {
|
|
1061
|
-
try {
|
|
1062
|
-
if (!f || typeof f.remoteDomain !== "string" || !f.localDomain || typeof f.localPort !== "number") {
|
|
1063
|
-
logger.warn(`Skipping invalid additional forwarding rule: ${JSON.stringify(f)}`);
|
|
1064
|
-
continue;
|
|
1065
|
-
}
|
|
1066
|
-
const hostname = f.remoteDomain;
|
|
1067
|
-
const target = `${f.localDomain}:${f.localPort}`;
|
|
1068
|
-
await managed.instance.tunnelRequestAdditionalForwarding(hostname, target);
|
|
1069
|
-
logger.info("Applied additional forwarding", { tunnelId, hostname, target });
|
|
1070
|
-
} catch (e) {
|
|
1071
|
-
logger.warn(`Failed to apply additional forwarding (${JSON.stringify(f)}):`, e);
|
|
1072
|
-
}
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1075
1127
|
if (managed.serve) {
|
|
1076
1128
|
this.startStaticFileServer(managed);
|
|
1077
1129
|
}
|
|
@@ -1320,22 +1372,32 @@ var TunnelManager = class _TunnelManager {
|
|
|
1320
1372
|
const tunnelName = existingTunnel.tunnelName;
|
|
1321
1373
|
const currentConfigId = existingTunnel.configid;
|
|
1322
1374
|
const currentConfig = existingTunnel.tunnelConfig;
|
|
1375
|
+
const configWithForwarding = existingTunnel.configWithForwarding;
|
|
1323
1376
|
const additionalForwarding = existingTunnel.additionalForwarding;
|
|
1377
|
+
const currentServe = existingTunnel.serve;
|
|
1378
|
+
const autoReconnect = existingTunnel.autoReconnect || false;
|
|
1324
1379
|
this.tunnelsByTunnelId.delete(tunnelid);
|
|
1325
1380
|
this.tunnelsByConfigId.delete(existingTunnel.configid);
|
|
1326
1381
|
this.tunnelStats.delete(tunnelid);
|
|
1327
1382
|
this.tunnelStatsListeners.delete(tunnelid);
|
|
1328
|
-
|
|
1329
|
-
|
|
1383
|
+
this.tunnelErrorListeners.delete(tunnelid);
|
|
1384
|
+
this.tunnelDisconnectListeners.delete(tunnelid);
|
|
1385
|
+
this.tunnelWorkerErrorListeners.delete(tunnelid);
|
|
1386
|
+
this.tunnelStartListeners.delete(tunnelid);
|
|
1387
|
+
const newTunnel = await this._createTunnelWithProcessedConfig({
|
|
1330
1388
|
configid: currentConfigId,
|
|
1331
1389
|
tunnelid,
|
|
1390
|
+
tunnelName,
|
|
1391
|
+
originalConfig: currentConfig,
|
|
1392
|
+
configWithForwarding,
|
|
1332
1393
|
additionalForwarding,
|
|
1333
|
-
|
|
1394
|
+
serve: currentServe,
|
|
1395
|
+
autoReconnect
|
|
1334
1396
|
});
|
|
1335
1397
|
if (existingTunnel.createdAt) {
|
|
1336
1398
|
newTunnel.createdAt = existingTunnel.createdAt;
|
|
1337
1399
|
}
|
|
1338
|
-
this.startTunnel(newTunnel.tunnelid);
|
|
1400
|
+
await this.startTunnel(newTunnel.tunnelid);
|
|
1339
1401
|
} catch (error) {
|
|
1340
1402
|
logger.error("Failed to restart tunnel", {
|
|
1341
1403
|
tunnelid,
|
|
@@ -1351,18 +1413,10 @@ var TunnelManager = class _TunnelManager {
|
|
|
1351
1413
|
* its state. If the tunnel is running, it will be stopped, updated, and restarted.
|
|
1352
1414
|
* In case of failure, it attempts to restore the original configuration.
|
|
1353
1415
|
*
|
|
1354
|
-
* @param tunnelId - The unique identifier of the tunnel to update
|
|
1355
1416
|
* @param newConfig - The new configuration to apply, including configid and optional additional forwarding
|
|
1356
|
-
* @param preserveAdditionalForwarding - Whether to preserve existing additional forwarding rules (default: true)
|
|
1357
1417
|
*
|
|
1358
|
-
* @returns Promise resolving to
|
|
1418
|
+
* @returns Promise resolving to the updated ManagedTunnel
|
|
1359
1419
|
* @throws Error if the tunnel is not found or if the update process fails
|
|
1360
|
-
*
|
|
1361
|
-
* @example
|
|
1362
|
-
* const result = await tunnelManager.updateConfig('tunnel123', {
|
|
1363
|
-
* configid: 'config456',
|
|
1364
|
-
* port: 8080
|
|
1365
|
-
* });
|
|
1366
1420
|
*/
|
|
1367
1421
|
async updateConfig(newConfig) {
|
|
1368
1422
|
const { configid, tunnelName: newTunnelName, additionalForwarding } = newConfig;
|
|
@@ -1375,27 +1429,41 @@ var TunnelManager = class _TunnelManager {
|
|
|
1375
1429
|
}
|
|
1376
1430
|
const isStopped = existingTunnel.isStopped;
|
|
1377
1431
|
const currentTunnelConfig = existingTunnel.tunnelConfig;
|
|
1432
|
+
const currentConfigWithForwarding = existingTunnel.configWithForwarding;
|
|
1378
1433
|
const currentTunnelId = existingTunnel.tunnelid;
|
|
1379
1434
|
const currentTunnelConfigId = existingTunnel.configid;
|
|
1380
1435
|
const currentAdditionalForwarding = existingTunnel.additionalForwarding;
|
|
1381
1436
|
const currentTunnelName = existingTunnel.tunnelName;
|
|
1382
1437
|
const currentServe = existingTunnel.serve;
|
|
1438
|
+
const currentAutoReconnect = existingTunnel.autoReconnect || false;
|
|
1383
1439
|
try {
|
|
1384
1440
|
if (!isStopped) {
|
|
1385
1441
|
existingTunnel.instance.stop();
|
|
1386
1442
|
}
|
|
1387
1443
|
this.tunnelsByTunnelId.delete(currentTunnelId);
|
|
1388
1444
|
this.tunnelsByConfigId.delete(currentTunnelConfigId);
|
|
1389
|
-
const
|
|
1445
|
+
const mergedBaseConfig = {
|
|
1390
1446
|
...newConfig,
|
|
1391
1447
|
configid,
|
|
1392
1448
|
tunnelName: newTunnelName !== void 0 ? newTunnelName : currentTunnelName,
|
|
1393
|
-
additionalForwarding: additionalForwarding !== void 0 ? additionalForwarding : currentAdditionalForwarding,
|
|
1394
1449
|
serve: newConfig.serve !== void 0 ? newConfig.serve : currentServe
|
|
1395
1450
|
};
|
|
1396
|
-
const
|
|
1451
|
+
const newConfigWithForwarding = this.buildPinggyConfig(
|
|
1452
|
+
mergedBaseConfig,
|
|
1453
|
+
additionalForwarding !== void 0 ? additionalForwarding : currentAdditionalForwarding
|
|
1454
|
+
);
|
|
1455
|
+
const newTunnel = await this._createTunnelWithProcessedConfig({
|
|
1456
|
+
configid,
|
|
1457
|
+
tunnelid: currentTunnelId,
|
|
1458
|
+
tunnelName: newTunnelName !== void 0 ? newTunnelName : currentTunnelName,
|
|
1459
|
+
originalConfig: mergedBaseConfig,
|
|
1460
|
+
configWithForwarding: newConfigWithForwarding,
|
|
1461
|
+
additionalForwarding: additionalForwarding !== void 0 ? additionalForwarding : currentAdditionalForwarding,
|
|
1462
|
+
serve: newConfig.serve !== void 0 ? newConfig.serve : currentServe,
|
|
1463
|
+
autoReconnect: currentAutoReconnect
|
|
1464
|
+
});
|
|
1397
1465
|
if (!isStopped) {
|
|
1398
|
-
this.startTunnel(newTunnel.tunnelid);
|
|
1466
|
+
await this.startTunnel(newTunnel.tunnelid);
|
|
1399
1467
|
}
|
|
1400
1468
|
logger.info("Tunnel configuration updated", {
|
|
1401
1469
|
tunnelId: newTunnel.tunnelid,
|
|
@@ -1409,12 +1477,15 @@ var TunnelManager = class _TunnelManager {
|
|
|
1409
1477
|
error: error instanceof Error ? error.message : String(error)
|
|
1410
1478
|
});
|
|
1411
1479
|
try {
|
|
1412
|
-
const originalTunnel = await this.
|
|
1413
|
-
|
|
1414
|
-
configid: existingTunnel.configid,
|
|
1480
|
+
const originalTunnel = await this._createTunnelWithProcessedConfig({
|
|
1481
|
+
configid: currentTunnelConfigId,
|
|
1415
1482
|
tunnelid: currentTunnelId,
|
|
1416
1483
|
tunnelName: currentTunnelName,
|
|
1417
|
-
|
|
1484
|
+
originalConfig: currentTunnelConfig,
|
|
1485
|
+
configWithForwarding: currentConfigWithForwarding,
|
|
1486
|
+
additionalForwarding: currentAdditionalForwarding,
|
|
1487
|
+
serve: currentServe,
|
|
1488
|
+
autoReconnect: currentAutoReconnect
|
|
1418
1489
|
});
|
|
1419
1490
|
if (!isStopped) {
|
|
1420
1491
|
await this.startTunnel(originalTunnel.tunnelid);
|
|
@@ -1931,14 +2002,12 @@ init_cjs_shims();
|
|
|
1931
2002
|
|
|
1932
2003
|
// src/cli/defaults.ts
|
|
1933
2004
|
init_cjs_shims();
|
|
1934
|
-
var import_pinggy3 = require("@pinggy/pinggy");
|
|
1935
2005
|
var defaultOptions = {
|
|
1936
2006
|
token: void 0,
|
|
1937
2007
|
// No default token
|
|
1938
2008
|
serverAddress: "a.pinggy.io",
|
|
1939
2009
|
forwarding: "localhost:8000",
|
|
1940
2010
|
webDebugger: "",
|
|
1941
|
-
tunnelType: [import_pinggy3.TunnelType.Http],
|
|
1942
2011
|
ipWhitelist: [],
|
|
1943
2012
|
basicAuth: [],
|
|
1944
2013
|
bearerTokenAuth: [],
|
|
@@ -2082,21 +2151,7 @@ function isValidIpV6Cidr(input) {
|
|
|
2082
2151
|
|
|
2083
2152
|
// src/cli/buildConfig.ts
|
|
2084
2153
|
init_logger();
|
|
2085
|
-
|
|
2086
|
-
// src/utils/util.ts
|
|
2087
|
-
init_cjs_shims();
|
|
2088
|
-
var import_module = require("module");
|
|
2089
|
-
function isValidPort(p) {
|
|
2090
|
-
return Number.isInteger(p) && p > 0 && p < 65536;
|
|
2091
|
-
}
|
|
2092
|
-
var require2 = (0, import_module.createRequire)(importMetaUrl);
|
|
2093
|
-
var pkg = require2("../package.json");
|
|
2094
|
-
function getVersion() {
|
|
2095
|
-
return pkg.version ?? "";
|
|
2096
|
-
}
|
|
2097
|
-
|
|
2098
|
-
// src/cli/buildConfig.ts
|
|
2099
|
-
var import_pinggy4 = require("@pinggy/pinggy");
|
|
2154
|
+
var import_pinggy3 = require("@pinggy/pinggy");
|
|
2100
2155
|
var import_fs2 = __toESM(require("fs"), 1);
|
|
2101
2156
|
var import_path2 = __toESM(require("path"), 1);
|
|
2102
2157
|
var domainRegex = /^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;
|
|
@@ -2112,7 +2167,7 @@ function parseUserAndDomain(str) {
|
|
|
2112
2167
|
server = domain;
|
|
2113
2168
|
const parts = user.split("+");
|
|
2114
2169
|
for (const part of parts) {
|
|
2115
|
-
if ([
|
|
2170
|
+
if ([import_pinggy3.TunnelType.Http, import_pinggy3.TunnelType.Tcp, import_pinggy3.TunnelType.Tls, import_pinggy3.TunnelType.Udp, import_pinggy3.TunnelType.TlsTcp].includes(part.toLowerCase())) {
|
|
2116
2171
|
type = part;
|
|
2117
2172
|
} else if (part === "force") {
|
|
2118
2173
|
token = (token ? token + "+" : "") + part;
|
|
@@ -2167,7 +2222,7 @@ function parseUsers(positionalArgs, explicitToken) {
|
|
|
2167
2222
|
}
|
|
2168
2223
|
function parseType(finalConfig, values, inferredType) {
|
|
2169
2224
|
const t = inferredType || values.type || finalConfig.tunnelType;
|
|
2170
|
-
if (t ===
|
|
2225
|
+
if (t === import_pinggy3.TunnelType.Http || t === import_pinggy3.TunnelType.Tcp || t === import_pinggy3.TunnelType.Tls || t === import_pinggy3.TunnelType.Udp || t === import_pinggy3.TunnelType.TlsTcp) {
|
|
2171
2226
|
finalConfig.tunnelType = [t];
|
|
2172
2227
|
}
|
|
2173
2228
|
}
|
|
@@ -2370,7 +2425,7 @@ async function buildFinalConfig(values, positionals) {
|
|
|
2370
2425
|
configid: await getUuid(),
|
|
2371
2426
|
token: token || (typeof values.token === "string" ? values.token : ""),
|
|
2372
2427
|
serverAddress: server || defaultOptions.serverAddress,
|
|
2373
|
-
tunnelType: initialTunnel ? [initialTunnel] :
|
|
2428
|
+
tunnelType: initialTunnel ? [initialTunnel] : [import_pinggy3.TunnelType.Http],
|
|
2374
2429
|
NoTUI: values.notui || false,
|
|
2375
2430
|
qrCode: qrCode || false,
|
|
2376
2431
|
autoReconnect: values.autoreconnect || false
|
|
@@ -2496,7 +2551,7 @@ init_cjs_shims();
|
|
|
2496
2551
|
|
|
2497
2552
|
// src/remote_management/remote_schema.ts
|
|
2498
2553
|
init_cjs_shims();
|
|
2499
|
-
var
|
|
2554
|
+
var import_pinggy4 = require("@pinggy/pinggy");
|
|
2500
2555
|
var import_zod = require("zod");
|
|
2501
2556
|
var HeaderModificationSchema = import_zod.z.object({
|
|
2502
2557
|
key: import_zod.z.string(),
|
|
@@ -2505,6 +2560,7 @@ var HeaderModificationSchema = import_zod.z.object({
|
|
|
2505
2560
|
});
|
|
2506
2561
|
var AdditionalForwardingSchema = import_zod.z.object({
|
|
2507
2562
|
remoteDomain: import_zod.z.string().optional(),
|
|
2563
|
+
remotePort: import_zod.z.number().optional(),
|
|
2508
2564
|
localDomain: import_zod.z.string(),
|
|
2509
2565
|
localPort: import_zod.z.number()
|
|
2510
2566
|
});
|
|
@@ -2537,11 +2593,11 @@ var TunnelConfigSchema = import_zod.z.object({
|
|
|
2537
2593
|
token: import_zod.z.string(),
|
|
2538
2594
|
tunnelTimeout: import_zod.z.number(),
|
|
2539
2595
|
type: import_zod.z.enum([
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2596
|
+
import_pinggy4.TunnelType.Http,
|
|
2597
|
+
import_pinggy4.TunnelType.Tcp,
|
|
2598
|
+
import_pinggy4.TunnelType.Udp,
|
|
2599
|
+
import_pinggy4.TunnelType.Tls,
|
|
2600
|
+
import_pinggy4.TunnelType.TlsTcp
|
|
2545
2601
|
]),
|
|
2546
2602
|
webdebuggerport: import_zod.z.number(),
|
|
2547
2603
|
xff: import_zod.z.string(),
|
|
@@ -2578,7 +2634,6 @@ function tunnelConfigToPinggyOptions(config) {
|
|
|
2578
2634
|
serverAddress: config.serveraddress || "free.pinggy.io",
|
|
2579
2635
|
forwarding: `${config.forwardedhost || "localhost"}:${config.localport}`,
|
|
2580
2636
|
webDebugger: config.webdebuggerport ? `localhost:${config.webdebuggerport}` : "",
|
|
2581
|
-
tunnelType: Array.isArray(config.type) ? config.type : [config.type || import_pinggy5.TunnelType.Http],
|
|
2582
2637
|
ipWhitelist: config.ipwhitelist || [],
|
|
2583
2638
|
basicAuth: config.basicauth ? config.basicauth : [],
|
|
2584
2639
|
bearerTokenAuth: config.bearerauth ? [config.bearerauth] : [],
|
|
@@ -2599,7 +2654,7 @@ function pinggyOptionsToTunnelConfig(opts, configid, configName, localserverTls,
|
|
|
2599
2654
|
const forwarding = Array.isArray(opts.forwarding) ? String(opts.forwarding[0].address).replace("//", "").replace(/\/$/, "") : String(opts.forwarding).replace("//", "").replace(/\/$/, "");
|
|
2600
2655
|
const parsedForwardedHost = forwarding.split(":").length == 3 ? forwarding.split(":")[1] : forwarding.split(":")[0];
|
|
2601
2656
|
const parsedLocalPort = forwarding.split(":").length == 3 ? parseInt(forwarding.split(":")[2], 10) : parseInt(forwarding.split(":")[1], 10);
|
|
2602
|
-
const tunnelType = Array.isArray(opts.
|
|
2657
|
+
const tunnelType = (Array.isArray(opts.forwarding) ? opts.forwarding[0]?.type : void 0) ?? import_pinggy4.TunnelType.Http;
|
|
2603
2658
|
const parsedTokens = opts.bearerTokenAuth ? Array.isArray(opts.bearerTokenAuth) ? opts.bearerTokenAuth : JSON.parse(opts.bearerTokenAuth) : [];
|
|
2604
2659
|
return {
|
|
2605
2660
|
allowPreflight: opts.allowPreflight ?? false,
|
|
@@ -2637,6 +2692,7 @@ function pinggyOptionsToTunnelConfig(opts, configid, configName, localserverTls,
|
|
|
2637
2692
|
}
|
|
2638
2693
|
|
|
2639
2694
|
// src/remote_management/handler.ts
|
|
2695
|
+
var import_pinggy5 = require("@pinggy/pinggy");
|
|
2640
2696
|
var TunnelOperations = class {
|
|
2641
2697
|
constructor() {
|
|
2642
2698
|
this.tunnelManager = TunnelManager.getInstance();
|
|
@@ -2684,6 +2740,8 @@ var TunnelOperations = class {
|
|
|
2684
2740
|
const additionalForwardingParsed = config.additionalForwarding || [];
|
|
2685
2741
|
const { tunnelid, instance, tunnelName, additionalForwarding, serve } = await this.tunnelManager.createTunnel({
|
|
2686
2742
|
...opts,
|
|
2743
|
+
tunnelType: Array.isArray(config.type) ? config.type : config.type ? [config.type] : [import_pinggy5.TunnelType.Http],
|
|
2744
|
+
// Temporary fix in future we will not use this field.
|
|
2687
2745
|
configid: config.configid,
|
|
2688
2746
|
tunnelName: config.configname,
|
|
2689
2747
|
additionalForwarding: additionalForwardingParsed,
|
|
@@ -2702,6 +2760,8 @@ var TunnelOperations = class {
|
|
|
2702
2760
|
const opts = tunnelConfigToPinggyOptions(config);
|
|
2703
2761
|
const tunnel = await this.tunnelManager.updateConfig({
|
|
2704
2762
|
...opts,
|
|
2763
|
+
tunnelType: Array.isArray(config.type) ? config.type : config.type ? [config.type] : [import_pinggy5.TunnelType.Http],
|
|
2764
|
+
// // Temporary fix in future we will not use this field.
|
|
2705
2765
|
configid: config.configid,
|
|
2706
2766
|
tunnelName: config.configname,
|
|
2707
2767
|
additionalForwarding: config.additionalForwarding || [],
|
|
@@ -3127,7 +3187,7 @@ function setRemoteManagementState(state, errorMessage) {
|
|
|
3127
3187
|
|
|
3128
3188
|
// src/utils/parseArgs.ts
|
|
3129
3189
|
init_cjs_shims();
|
|
3130
|
-
var
|
|
3190
|
+
var import_util3 = require("util");
|
|
3131
3191
|
var os = __toESM(require("os"), 1);
|
|
3132
3192
|
function isInlineColonFlag(arg) {
|
|
3133
3193
|
return /^-([RL])[A-Za-z0-9._-]*:?$/.test(arg);
|
|
@@ -3157,7 +3217,7 @@ function preprocessWindowsArgs(args) {
|
|
|
3157
3217
|
function parseCliArgs(options) {
|
|
3158
3218
|
const rawArgs = process.argv.slice(2);
|
|
3159
3219
|
const processedArgs = preprocessWindowsArgs(rawArgs);
|
|
3160
|
-
const parsed = (0,
|
|
3220
|
+
const parsed = (0, import_util3.parseArgs)({
|
|
3161
3221
|
args: processedArgs,
|
|
3162
3222
|
options,
|
|
3163
3223
|
allowPositionals: true
|