dsh-mobile 0.6.7 → 0.6.8
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/CHANGELOG.md +10 -0
- package/CONTRIBUTORS.md +3 -1
- package/README.en.md +17 -11
- package/README.md +17 -11
- package/SECURITY.md +9 -0
- package/lib/index.d.mts +18 -2
- package/lib/index.mjs +113 -36
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
- package/packages/question-fixes/package.json +1 -1
package/lib/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { basename, dirname, extname, isAbsolute, join, relative, resolve, win32
|
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
5
|
import z from "@deepseek-ai/schemastery";
|
|
6
6
|
import { connect, createServer } from "node:net";
|
|
7
|
-
import { chmod, copyFile, lstat, mkdir, mkdtemp, open, opendir, readFile, readdir, realpath, rename, rm, rmdir, stat, unlink, writeFile } from "node:fs/promises";
|
|
7
|
+
import { chmod, copyFile, link, lstat, mkdir, mkdtemp, open, opendir, readFile, readdir, realpath, rename, rm, rmdir, stat, unlink, writeFile } from "node:fs/promises";
|
|
8
8
|
import { performance as performance$1 } from "node:perf_hooks";
|
|
9
9
|
import { execFile, spawn } from "node:child_process";
|
|
10
10
|
import { createSocket } from "node:dgram";
|
|
@@ -144,10 +144,14 @@ var AccessController = class {
|
|
|
144
144
|
}
|
|
145
145
|
snapshot(devices) {
|
|
146
146
|
return Object.freeze({
|
|
147
|
-
version:
|
|
147
|
+
version: 2,
|
|
148
148
|
devices: Object.freeze([...devices])
|
|
149
149
|
});
|
|
150
150
|
}
|
|
151
|
+
nativeIdentity(device) {
|
|
152
|
+
const nativeInstanceId = device.nativeInstanceId ?? this.options.legacyInstanceId ?? this.options.pairingInstanceId;
|
|
153
|
+
return nativeInstanceId === void 0 ? {} : { nativeInstanceId };
|
|
154
|
+
}
|
|
151
155
|
emitSessionEnded(session, reason) {
|
|
152
156
|
const authorization = Object.freeze({
|
|
153
157
|
sessionKey: session.key,
|
|
@@ -165,7 +169,7 @@ var AccessController = class {
|
|
|
165
169
|
pruneSessions(now) {
|
|
166
170
|
for (const [key, session] of this.sessions) if (session.expiresAt <= now) this.removeSession(key, "expired");
|
|
167
171
|
}
|
|
168
|
-
createSession(
|
|
172
|
+
createSession(device, now) {
|
|
169
173
|
this.pruneSessions(now);
|
|
170
174
|
if (this.sessions.size >= this.options.maxSessions) {
|
|
171
175
|
const oldest = [...this.sessions.values()].sort((left, right) => left.createdAt - right.createdAt)[0];
|
|
@@ -176,14 +180,15 @@ var AccessController = class {
|
|
|
176
180
|
const key = digestHex(sessionToken);
|
|
177
181
|
const record = Object.freeze({
|
|
178
182
|
key,
|
|
179
|
-
deviceId,
|
|
183
|
+
deviceId: device.id,
|
|
180
184
|
csrfDigest: digest$1(csrfToken),
|
|
181
185
|
createdAt: now,
|
|
182
|
-
expiresAt: Math.min(now + this.options.sessionTtlMs,
|
|
186
|
+
expiresAt: Math.min(now + this.options.sessionTtlMs, device.expiresAt)
|
|
183
187
|
});
|
|
184
188
|
this.sessions.set(key, record);
|
|
185
189
|
return Object.freeze({
|
|
186
|
-
|
|
190
|
+
...this.nativeIdentity(device),
|
|
191
|
+
deviceId: device.id,
|
|
187
192
|
sessionToken,
|
|
188
193
|
csrfToken,
|
|
189
194
|
sessionExpiresAt: record.expiresAt
|
|
@@ -228,12 +233,13 @@ var AccessController = class {
|
|
|
228
233
|
tokenDigest: digestHex(deviceToken),
|
|
229
234
|
createdAt: now,
|
|
230
235
|
expiresAt: now + this.options.deviceTtlMs,
|
|
231
|
-
lastSeenAt: now
|
|
236
|
+
lastSeenAt: now,
|
|
237
|
+
...this.options.pairingInstanceId === void 0 ? {} : { nativeInstanceId: this.options.pairingInstanceId }
|
|
232
238
|
});
|
|
233
239
|
const next = [...this.devices.filter((candidate) => candidate.revokedAt === void 0 && candidate.expiresAt > now), device];
|
|
234
240
|
await this.store.save(this.snapshot(next));
|
|
235
241
|
this.devices = next;
|
|
236
|
-
const session = this.createSession(device
|
|
242
|
+
const session = this.createSession(device, now);
|
|
237
243
|
return Object.freeze({
|
|
238
244
|
...session,
|
|
239
245
|
deviceToken,
|
|
@@ -256,7 +262,7 @@ var AccessController = class {
|
|
|
256
262
|
next[index] = updated;
|
|
257
263
|
await this.store.save(this.snapshot(next));
|
|
258
264
|
this.devices = next;
|
|
259
|
-
return this.createSession(device
|
|
265
|
+
return this.createSession(device, now);
|
|
260
266
|
});
|
|
261
267
|
}
|
|
262
268
|
/** Validate a persistent device credential without consuming a Session slot. */
|
|
@@ -275,6 +281,7 @@ var AccessController = class {
|
|
|
275
281
|
await this.store.save(this.snapshot(next));
|
|
276
282
|
this.devices = next;
|
|
277
283
|
return Object.freeze({
|
|
284
|
+
...this.nativeIdentity(device),
|
|
278
285
|
deviceId: device.id,
|
|
279
286
|
deviceExpiresAt: device.expiresAt
|
|
280
287
|
});
|
|
@@ -285,6 +292,7 @@ var AccessController = class {
|
|
|
285
292
|
this.requireInitialized();
|
|
286
293
|
const device = this.requireDevice(deviceToken, this.now());
|
|
287
294
|
return Object.freeze({
|
|
295
|
+
...this.nativeIdentity(device),
|
|
288
296
|
deviceId: device.id,
|
|
289
297
|
deviceExpiresAt: device.expiresAt
|
|
290
298
|
});
|
|
@@ -5289,6 +5297,8 @@ var MobileAccessGateway = class {
|
|
|
5289
5297
|
this.listenerTlsEnabled = config.tls.mode === "provided";
|
|
5290
5298
|
this.tlsEnabled = config.publicTls;
|
|
5291
5299
|
this.access = new AccessController(store, {
|
|
5300
|
+
pairingInstanceId: config.instanceId,
|
|
5301
|
+
...config.legacyInstanceId === void 0 ? {} : { legacyInstanceId: config.legacyInstanceId },
|
|
5292
5302
|
pairingTtlMs: config.pairingTtlMs,
|
|
5293
5303
|
deviceTtlMs: config.deviceTtlMs,
|
|
5294
5304
|
sessionTtlMs: config.sessionTtlMs,
|
|
@@ -5665,12 +5675,16 @@ var MobileAccessGateway = class {
|
|
|
5665
5675
|
sessionExpiresAt: result.sessionExpiresAt
|
|
5666
5676
|
}, this.tlsEnabled);
|
|
5667
5677
|
}
|
|
5678
|
+
/** CA-backed entries retain their pin; public entries project the authenticated credential's identity. */
|
|
5679
|
+
nativeResponseInstanceId(result) {
|
|
5680
|
+
return this.config.pairingCaFile === void 0 ? result.nativeInstanceId ?? this.config.instanceId : this.config.instanceId;
|
|
5681
|
+
}
|
|
5668
5682
|
async handleNativePair(request, response) {
|
|
5669
5683
|
const body = await readJsonObject(request, MAX_CONTROL_BODY_BYTES);
|
|
5670
5684
|
if (typeof body.token !== "string" || body.label !== void 0 && typeof body.label !== "string") throw new HttpError(400, "bad_request");
|
|
5671
5685
|
const result = await this.access.pair(request.socket.remoteAddress ?? "unknown", body.token, body.label);
|
|
5672
5686
|
sendJson(response, 201, {
|
|
5673
|
-
instanceId: this.
|
|
5687
|
+
instanceId: this.nativeResponseInstanceId(result),
|
|
5674
5688
|
deviceId: result.deviceId,
|
|
5675
5689
|
deviceToken: result.deviceToken,
|
|
5676
5690
|
deviceExpiresAt: result.deviceExpiresAt,
|
|
@@ -5685,7 +5699,7 @@ var MobileAccessGateway = class {
|
|
|
5685
5699
|
if (typeof body.deviceToken !== "string") throw new HttpError(400, "bad_request");
|
|
5686
5700
|
const result = await this.access.renew(body.deviceToken);
|
|
5687
5701
|
sendJson(response, 200, {
|
|
5688
|
-
instanceId: this.
|
|
5702
|
+
instanceId: this.nativeResponseInstanceId(result),
|
|
5689
5703
|
deviceId: result.deviceId,
|
|
5690
5704
|
sessionToken: result.sessionToken,
|
|
5691
5705
|
csrfToken: result.csrfToken,
|
|
@@ -5698,7 +5712,7 @@ var MobileAccessGateway = class {
|
|
|
5698
5712
|
if (typeof body.deviceToken !== "string") throw new HttpError(400, "bad_request");
|
|
5699
5713
|
const result = await this.access.probe(body.deviceToken);
|
|
5700
5714
|
sendJson(response, 200, {
|
|
5701
|
-
instanceId: this.
|
|
5715
|
+
instanceId: this.nativeResponseInstanceId(result),
|
|
5702
5716
|
deviceId: result.deviceId,
|
|
5703
5717
|
deviceExpiresAt: result.deviceExpiresAt
|
|
5704
5718
|
}, this.tlsEnabled);
|
|
@@ -7367,6 +7381,7 @@ function parseDevice(value) {
|
|
|
7367
7381
|
if (typeof record.id !== "string" || !/^[a-f\d]{32}$/u.test(record.id)) throw new Error("device state contains an invalid id");
|
|
7368
7382
|
if (typeof record.label !== "string" || record.label.length < 1 || record.label.length > 64 || /[\u0000-\u001f\u007f]/u.test(record.label)) throw new Error("device state contains an invalid label");
|
|
7369
7383
|
if (typeof record.tokenDigest !== "string" || !/^[a-f\d]{64}$/u.test(record.tokenDigest)) throw new Error("device state contains an invalid credential digest");
|
|
7384
|
+
if (record.nativeInstanceId !== void 0 && (typeof record.nativeInstanceId !== "string" || !/^[a-f\d]{64}$/u.test(record.nativeInstanceId))) throw new Error("device state contains an invalid native instance id");
|
|
7370
7385
|
assertInteger(record.createdAt, "createdAt");
|
|
7371
7386
|
assertInteger(record.expiresAt, "expiresAt");
|
|
7372
7387
|
assertInteger(record.lastSeenAt, "lastSeenAt");
|
|
@@ -7379,6 +7394,7 @@ function parseDevice(value) {
|
|
|
7379
7394
|
createdAt: record.createdAt,
|
|
7380
7395
|
expiresAt: record.expiresAt,
|
|
7381
7396
|
lastSeenAt: record.lastSeenAt,
|
|
7397
|
+
...record.nativeInstanceId === void 0 ? {} : { nativeInstanceId: record.nativeInstanceId },
|
|
7382
7398
|
...record.revokedAt === void 0 ? {} : { revokedAt: record.revokedAt }
|
|
7383
7399
|
});
|
|
7384
7400
|
}
|
|
@@ -7386,14 +7402,21 @@ function parseDevice(value) {
|
|
|
7386
7402
|
function parseDeviceSnapshot(value, maximumDevices = 256) {
|
|
7387
7403
|
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error("device state must be an object");
|
|
7388
7404
|
const snapshot = value;
|
|
7389
|
-
if (snapshot.version !== 1 || !Array.isArray(snapshot.devices) || snapshot.devices.length > maximumDevices) throw new Error("device state has an unsupported version or device count");
|
|
7405
|
+
if (snapshot.version !== 1 && snapshot.version !== 2 || !Array.isArray(snapshot.devices) || snapshot.devices.length > maximumDevices) throw new Error("device state has an unsupported version or device count");
|
|
7390
7406
|
const devices = snapshot.devices.map(parseDevice);
|
|
7391
7407
|
if (new Set(devices.map((device) => device.id)).size !== devices.length || new Set(devices.map((device) => device.tokenDigest)).size !== devices.length) throw new Error("device state contains duplicate device identities");
|
|
7392
7408
|
return Object.freeze({
|
|
7393
|
-
version:
|
|
7409
|
+
version: snapshot.version,
|
|
7394
7410
|
devices: Object.freeze(devices)
|
|
7395
7411
|
});
|
|
7396
7412
|
}
|
|
7413
|
+
function snapshotForSave(snapshot, maximumDevices) {
|
|
7414
|
+
const validated = parseDeviceSnapshot(snapshot, maximumDevices);
|
|
7415
|
+
return Object.freeze({
|
|
7416
|
+
version: 2,
|
|
7417
|
+
devices: validated.devices
|
|
7418
|
+
});
|
|
7419
|
+
}
|
|
7397
7420
|
/** Atomic JSON implementation with symlink refusal and owner-only file creation. */
|
|
7398
7421
|
var JsonDeviceStore = class {
|
|
7399
7422
|
file;
|
|
@@ -7424,7 +7447,7 @@ var JsonDeviceStore = class {
|
|
|
7424
7447
|
return parseDeviceSnapshot(parsed, this.maximumDevices);
|
|
7425
7448
|
}
|
|
7426
7449
|
async save(snapshot) {
|
|
7427
|
-
const validated =
|
|
7450
|
+
const validated = snapshotForSave(snapshot, this.maximumDevices);
|
|
7428
7451
|
const directory = dirname(this.file);
|
|
7429
7452
|
await mkdir(directory, {
|
|
7430
7453
|
recursive: true,
|
|
@@ -7468,7 +7491,7 @@ var MemoryDeviceStore = class {
|
|
|
7468
7491
|
return structuredClone(this.snapshot);
|
|
7469
7492
|
}
|
|
7470
7493
|
async save(snapshot) {
|
|
7471
|
-
this.snapshot = structuredClone(
|
|
7494
|
+
this.snapshot = structuredClone(snapshotForSave(snapshot));
|
|
7472
7495
|
}
|
|
7473
7496
|
/** Return a defensive copy for assertions or administrative export. */
|
|
7474
7497
|
inspect() {
|
|
@@ -16691,23 +16714,75 @@ async function readInstallationId(file) {
|
|
|
16691
16714
|
await restrictPrivateFile(file);
|
|
16692
16715
|
return contents.slice(0, -1);
|
|
16693
16716
|
}
|
|
16694
|
-
/** Keep one random plugin identity across setup changes, restarts, and FRP resets. */
|
|
16717
|
+
/** Keep one random plugin identity across setup changes, restarts, and FRP resets; creation requires hard-link support in the state directory. */
|
|
16695
16718
|
async function loadOrCreateInstallationId(file) {
|
|
16696
16719
|
if (!isAbsolute(file)) throw new Error("installation ID path must be absolute");
|
|
16697
16720
|
const target = resolve(file);
|
|
16698
|
-
|
|
16699
|
-
|
|
16700
|
-
mode: 448
|
|
16701
|
-
});
|
|
16721
|
+
const directory = dirname(target);
|
|
16722
|
+
await ensureManagedDirectory(directory, directory, "installation_id");
|
|
16702
16723
|
try {
|
|
16703
|
-
await
|
|
16704
|
-
flag: "wx",
|
|
16705
|
-
mode: 384
|
|
16706
|
-
});
|
|
16724
|
+
return await readInstallationId(target);
|
|
16707
16725
|
} catch (error) {
|
|
16708
|
-
if (error.code !== "
|
|
16726
|
+
if (error.code !== "ENOENT") throw error;
|
|
16709
16727
|
}
|
|
16710
|
-
|
|
16728
|
+
const temporary = join(directory, `.${basename(target)}.${randomBytes(12).toString("hex")}.tmp`);
|
|
16729
|
+
let created = false;
|
|
16730
|
+
let failure;
|
|
16731
|
+
try {
|
|
16732
|
+
await assertManagedParents(directory, temporary, "installation_id");
|
|
16733
|
+
const handle = await open(temporary, "wx", 384);
|
|
16734
|
+
created = true;
|
|
16735
|
+
let writeFailure;
|
|
16736
|
+
try {
|
|
16737
|
+
await handle.writeFile(`${randomBytes(32).toString("hex")}\n`, "utf8");
|
|
16738
|
+
} catch (error) {
|
|
16739
|
+
writeFailure = error;
|
|
16740
|
+
throw error;
|
|
16741
|
+
} finally {
|
|
16742
|
+
try {
|
|
16743
|
+
await handle.close();
|
|
16744
|
+
} catch (closeError) {
|
|
16745
|
+
if (writeFailure !== void 0) throw new AggregateError([writeFailure, closeError], "installation ID candidate write and close failed");
|
|
16746
|
+
throw closeError;
|
|
16747
|
+
}
|
|
16748
|
+
}
|
|
16749
|
+
await restrictPrivateFile(temporary);
|
|
16750
|
+
await assertManagedParents(directory, target, "installation_id");
|
|
16751
|
+
try {
|
|
16752
|
+
await link(temporary, target);
|
|
16753
|
+
} catch (error) {
|
|
16754
|
+
if (error.code !== "EEXIST") throw new Error("installation ID publication failed; the state filesystem must support hard links", { cause: error });
|
|
16755
|
+
}
|
|
16756
|
+
return await readInstallationId(target);
|
|
16757
|
+
} catch (error) {
|
|
16758
|
+
failure = error;
|
|
16759
|
+
throw error;
|
|
16760
|
+
} finally {
|
|
16761
|
+
if (created) try {
|
|
16762
|
+
await assertManagedParents(directory, temporary, "installation_id");
|
|
16763
|
+
await unlink(temporary);
|
|
16764
|
+
} catch (cleanupError) {
|
|
16765
|
+
if (failure !== void 0) throw new AggregateError([failure, cleanupError], "installation ID publication and temporary cleanup failed");
|
|
16766
|
+
throw cleanupError;
|
|
16767
|
+
}
|
|
16768
|
+
}
|
|
16769
|
+
}
|
|
16770
|
+
//#endregion
|
|
16771
|
+
//#region src/gateway-identity.ts
|
|
16772
|
+
/**
|
|
16773
|
+
* Use the persisted installation identity for an unpinned, automatically identified entry.
|
|
16774
|
+
* @param config - Validated gateway configuration containing the legacy identity.
|
|
16775
|
+
* @param installationId - Confirmed random identity read from this installation's state.
|
|
16776
|
+
* @param explicitIdentity - Whether the operator supplied the gateway identity.
|
|
16777
|
+
* @returns Configuration retaining certificate/operator identities or the new and legacy public identities.
|
|
16778
|
+
*/
|
|
16779
|
+
function withInstallationIdentity(config, installationId, explicitIdentity) {
|
|
16780
|
+
if (config.pairingCaFile !== void 0 || explicitIdentity) return config;
|
|
16781
|
+
return Object.freeze({
|
|
16782
|
+
...config,
|
|
16783
|
+
instanceId: installationId,
|
|
16784
|
+
legacyInstanceId: config.instanceId
|
|
16785
|
+
});
|
|
16711
16786
|
}
|
|
16712
16787
|
//#endregion
|
|
16713
16788
|
//#region src/lan-setup.ts
|
|
@@ -16955,7 +17030,7 @@ async function stableInstanceId(loaded, template) {
|
|
|
16955
17030
|
if (loaded.kind !== "managed") return loaded.config.instanceId ?? template.instanceId;
|
|
16956
17031
|
return new X509Certificate(await readFile(loaded.setup.tls.caCertFile)).fingerprint256.replaceAll(":", "").toLowerCase();
|
|
16957
17032
|
}
|
|
16958
|
-
function remoteGatewayConfig(template, publicOrigin, stateFile, instanceId, listenPort = 0) {
|
|
17033
|
+
function remoteGatewayConfig(template, publicOrigin, stateFile, instanceId, listenPort = 0, legacyInstanceId) {
|
|
16959
17034
|
const origin = new URL(publicOrigin);
|
|
16960
17035
|
if (origin.protocol !== "https:" || origin.username !== "" || origin.password !== "" || origin.pathname !== "/" || origin.search !== "" || origin.hash !== "") throw new Error("remote public origin must be an HTTPS origin");
|
|
16961
17036
|
const publicAuthority = origin.port === "" ? `${origin.hostname}:443` : origin.host;
|
|
@@ -16968,6 +17043,7 @@ function remoteGatewayConfig(template, publicOrigin, stateFile, instanceId, list
|
|
|
16968
17043
|
allowedCidrs: Object.freeze([parseCidr("127.0.0.0/8")]),
|
|
16969
17044
|
stateFile,
|
|
16970
17045
|
instanceId,
|
|
17046
|
+
...legacyInstanceId === void 0 ? {} : { legacyInstanceId },
|
|
16971
17047
|
tls: Object.freeze({ mode: "disabled" }),
|
|
16972
17048
|
publicTls: true,
|
|
16973
17049
|
discovery: false
|
|
@@ -17028,11 +17104,11 @@ async function readFrpIngressTrustAnchor(settings, stateFile, ownedRoot = dirnam
|
|
|
17028
17104
|
}
|
|
17029
17105
|
}
|
|
17030
17106
|
/** Reuse remote HTTPS policy while binding a separately validated private HTTP origin. */
|
|
17031
|
-
function originGatewayConfig(template, settings, stateFile, instanceId, listenPort = settings.listenPort) {
|
|
17107
|
+
function originGatewayConfig(template, settings, stateFile, instanceId, listenPort = settings.listenPort, legacyInstanceId) {
|
|
17032
17108
|
const validated = parseOriginSettings(settings);
|
|
17033
17109
|
if (listenPort !== 0) validateOriginListenPort(listenPort);
|
|
17034
17110
|
return Object.freeze({
|
|
17035
|
-
...remoteGatewayConfig(template, validated.publicOrigin, stateFile, instanceId, listenPort),
|
|
17111
|
+
...remoteGatewayConfig(template, validated.publicOrigin, stateFile, instanceId, listenPort, legacyInstanceId),
|
|
17036
17112
|
listenHost: validated.listenHost,
|
|
17037
17113
|
allowedCidrs: Object.freeze(validated.allowedCidrs.map(parseCidr))
|
|
17038
17114
|
});
|
|
@@ -17115,6 +17191,7 @@ async function apply(ctx, config) {
|
|
|
17115
17191
|
const frpComponent = new FrpComponentManager({ stateDirectory });
|
|
17116
17192
|
await frpComponent.initialize();
|
|
17117
17193
|
const frpIdentity = await loadOrCreateInstallationId(join(stateDirectory, "installation-id"));
|
|
17194
|
+
const remoteInstanceId = loaded.kind === "managed" ? frpIdentity : loaded.config.instanceId ?? frpIdentity;
|
|
17118
17195
|
const frpConfig = new FrpConfigStore(join(remoteDirectory, "frp", "config"), frpProxyName(frpIdentity), stateDirectory);
|
|
17119
17196
|
await frpConfig.initialize();
|
|
17120
17197
|
const originConfig = new OriginConfigStore(join(remoteDirectory, "origin", "config"), stateDirectory);
|
|
@@ -17166,10 +17243,10 @@ async function apply(ctx, config) {
|
|
|
17166
17243
|
let trustedNetworksWrite = Promise.resolve();
|
|
17167
17244
|
let adminClosing = false;
|
|
17168
17245
|
const startGateway = async (candidateConfig) => {
|
|
17169
|
-
const resolved = parseGatewayConfig({
|
|
17246
|
+
const resolved = withInstallationIdentity(parseGatewayConfig({
|
|
17170
17247
|
...candidateConfig,
|
|
17171
17248
|
upstreamOrigin: template.upstreamOrigin.origin
|
|
17172
|
-
});
|
|
17249
|
+
}), frpIdentity, candidateConfig.instanceId !== void 0);
|
|
17173
17250
|
const candidate = new MobileAccessGateway(resolved, new JsonDeviceStore(resolved.stateFile, resolved.maxDevices), mobileAccess, upstreamLoginUrl, webSocketPaths, blockedUpgradePaths, (source, code) => {
|
|
17174
17251
|
logger.warn("%s discovery degraded while DSH remains available: %s", source, code);
|
|
17175
17252
|
}, clientModulePreferences);
|
|
@@ -17227,7 +17304,7 @@ async function apply(ctx, config) {
|
|
|
17227
17304
|
}
|
|
17228
17305
|
}
|
|
17229
17306
|
const createRemoteGateway = async (publicOrigin, listenPort = 0) => {
|
|
17230
|
-
const resolved = remoteGatewayConfig(template, publicOrigin, remoteDeviceFile,
|
|
17307
|
+
const resolved = remoteGatewayConfig(template, publicOrigin, remoteDeviceFile, remoteInstanceId, listenPort, instanceId);
|
|
17231
17308
|
const candidate = new MobileAccessGateway(resolved, new JsonDeviceStore(resolved.stateFile, resolved.maxDevices), mobileAccess, upstreamLoginUrl, webSocketPaths, blockedUpgradePaths, void 0, clientModulePreferences);
|
|
17232
17309
|
await candidate.start();
|
|
17233
17310
|
return candidate;
|
|
@@ -17254,7 +17331,7 @@ async function apply(ctx, config) {
|
|
|
17254
17331
|
return candidate;
|
|
17255
17332
|
};
|
|
17256
17333
|
const createOriginGateway = async (settings) => {
|
|
17257
|
-
const resolved = originGatewayConfig(template, settings, remoteDeviceFile, instanceId);
|
|
17334
|
+
const resolved = originGatewayConfig(template, settings, remoteDeviceFile, remoteInstanceId, settings.listenPort, instanceId);
|
|
17258
17335
|
const candidate = new MobileAccessGateway(resolved, new JsonDeviceStore(resolved.stateFile, resolved.maxDevices), mobileAccess, upstreamLoginUrl, webSocketPaths, blockedUpgradePaths, void 0, clientModulePreferences);
|
|
17259
17336
|
try {
|
|
17260
17337
|
await candidate.start();
|
|
@@ -17273,7 +17350,7 @@ async function apply(ctx, config) {
|
|
|
17273
17350
|
store: createVolatileRemoteControlStore(),
|
|
17274
17351
|
component: caddyComponent,
|
|
17275
17352
|
config: caddyConfig,
|
|
17276
|
-
instanceId,
|
|
17353
|
+
instanceId: remoteInstanceId,
|
|
17277
17354
|
createGateway: (settings) => createRemoteGateway(settings.publicOrigin)
|
|
17278
17355
|
});
|
|
17279
17356
|
const originController = new ManagedOriginController({
|
|
@@ -17313,7 +17390,7 @@ async function apply(ctx, config) {
|
|
|
17313
17390
|
store: frpStore,
|
|
17314
17391
|
executable: frpComponent.executable,
|
|
17315
17392
|
config: frpConfig,
|
|
17316
|
-
instanceId,
|
|
17393
|
+
instanceId: remoteInstanceId,
|
|
17317
17394
|
createGateway: createFrpGateway,
|
|
17318
17395
|
/**
|
|
17319
17396
|
* Hand the start-up self-check the CA the app itself pins.
|