dsh-mobile 0.3.5 → 0.3.7
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 +12 -0
- package/README.en.md +8 -7
- package/README.md +8 -7
- package/lib/cli.js +42 -18
- package/lib/cli.js.map +1 -1
- package/lib/index.d.mts +1 -10
- package/lib/index.mjs +46 -33
- package/lib/index.mjs.map +1 -1
- package/package.json +5 -5
package/lib/index.mjs
CHANGED
|
@@ -6,13 +6,13 @@ import z from "@deepseek-ai/schemastery";
|
|
|
6
6
|
import { connect, createServer, isIP } from "node:net";
|
|
7
7
|
import { chmod, copyFile, lstat, mkdir, mkdtemp, opendir, readFile, readdir, realpath, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
8
8
|
import { execFile, spawn } from "node:child_process";
|
|
9
|
-
import { promisify } from "node:util";
|
|
10
9
|
import { createSocket } from "node:dgram";
|
|
11
10
|
import { homedir, hostname, networkInterfaces } from "node:os";
|
|
12
11
|
import { createServer as createServer$1, request } from "node:http";
|
|
13
12
|
import { createServer as createServer$2 } from "node:https";
|
|
14
13
|
import { Transform, finished } from "node:stream";
|
|
15
14
|
import { pipeline } from "node:stream/promises";
|
|
15
|
+
import { promisify } from "node:util";
|
|
16
16
|
import { createGzip, gzip } from "node:zlib";
|
|
17
17
|
import Bonjour from "bonjour-service";
|
|
18
18
|
import * as QRCode from "qrcode";
|
|
@@ -703,41 +703,50 @@ function parseGatewayConfig(raw) {
|
|
|
703
703
|
});
|
|
704
704
|
}
|
|
705
705
|
//#endregion
|
|
706
|
-
//#region src/
|
|
707
|
-
/**
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
706
|
+
//#region src/exec-file.ts
|
|
707
|
+
/** Capture both output streams even when a desktop host wraps execFile without Node's promisify metadata. */
|
|
708
|
+
function execFileText(file, args, options = {}) {
|
|
709
|
+
return new Promise((resolve, reject) => {
|
|
710
|
+
execFile(file, [...args], {
|
|
711
|
+
windowsHide: true,
|
|
712
|
+
...options,
|
|
713
|
+
encoding: "utf8"
|
|
714
|
+
}, (error, stdout, stderr) => {
|
|
715
|
+
if (error !== null) {
|
|
716
|
+
reject(error);
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
if (typeof stdout !== "string" || typeof stderr !== "string") {
|
|
720
|
+
reject(/* @__PURE__ */ new Error("subprocess returned invalid text output"));
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
resolve({
|
|
724
|
+
stdout,
|
|
725
|
+
stderr
|
|
726
|
+
});
|
|
727
|
+
});
|
|
728
|
+
});
|
|
723
729
|
}
|
|
724
730
|
//#endregion
|
|
725
731
|
//#region src/private-file.ts
|
|
726
|
-
const execFile$3 = promisify(execFile);
|
|
727
732
|
let userSidTask;
|
|
728
733
|
async function currentWindowsUserSid() {
|
|
729
|
-
userSidTask ??=
|
|
734
|
+
userSidTask ??= execFileText("whoami.exe", [
|
|
730
735
|
"/user",
|
|
731
736
|
"/fo",
|
|
732
737
|
"csv",
|
|
733
738
|
"/nh"
|
|
734
739
|
], {
|
|
735
740
|
encoding: "utf8",
|
|
736
|
-
windowsHide: true
|
|
741
|
+
windowsHide: true,
|
|
742
|
+
timeout: 1e4
|
|
737
743
|
}).then(({ stdout }) => {
|
|
738
744
|
const match = /,"(S-\d(?:-\d+)+)"\s*$/u.exec(stdout.trim());
|
|
739
745
|
if (match?.[1] === void 0) throw new Error("unable to resolve the current Windows user SID");
|
|
740
746
|
return match[1];
|
|
747
|
+
}).catch((error) => {
|
|
748
|
+
userSidTask = void 0;
|
|
749
|
+
throw error;
|
|
741
750
|
});
|
|
742
751
|
return userSidTask;
|
|
743
752
|
}
|
|
@@ -745,12 +754,11 @@ async function currentWindowsUserSid() {
|
|
|
745
754
|
async function restrictPrivateFile(file, mode = 384) {
|
|
746
755
|
await chmod(file, mode);
|
|
747
756
|
if (process.platform !== "win32") return;
|
|
748
|
-
|
|
749
|
-
await execFile$3("icacls.exe", [
|
|
757
|
+
await execFileText("icacls.exe", [
|
|
750
758
|
file,
|
|
751
759
|
"/inheritance:r",
|
|
752
760
|
"/grant:r",
|
|
753
|
-
`*${
|
|
761
|
+
`*${await currentWindowsUserSid()}:(F)`,
|
|
754
762
|
"*S-1-5-18:(F)",
|
|
755
763
|
"*S-1-5-32-544:(F)",
|
|
756
764
|
"/remove:g",
|
|
@@ -759,7 +767,8 @@ async function restrictPrivateFile(file, mode = 384) {
|
|
|
759
767
|
"*S-1-5-32-545"
|
|
760
768
|
], {
|
|
761
769
|
encoding: "utf8",
|
|
762
|
-
windowsHide: true
|
|
770
|
+
windowsHide: true,
|
|
771
|
+
timeout: 1e4
|
|
763
772
|
});
|
|
764
773
|
}
|
|
765
774
|
//#endregion
|
|
@@ -5364,7 +5373,6 @@ var FrpController = class {
|
|
|
5364
5373
|
};
|
|
5365
5374
|
//#endregion
|
|
5366
5375
|
//#region src/diagnostics.ts
|
|
5367
|
-
const execFile$2 = promisify(execFile);
|
|
5368
5376
|
const REMOTE_ERROR_GUIDANCE = Object.freeze({
|
|
5369
5377
|
component_missing: "重新安装完整插件包。",
|
|
5370
5378
|
funnel_permission_required: "继续完成 Tailscale Funnel 授权。",
|
|
@@ -5453,7 +5461,7 @@ function defaultFirewallProbe(platform = process.platform) {
|
|
|
5453
5461
|
"if ($ready) { 'ready' } else { 'missing' }"
|
|
5454
5462
|
].join("; ");
|
|
5455
5463
|
try {
|
|
5456
|
-
return { state: (await
|
|
5464
|
+
return { state: (await execFileText("powershell.exe", [
|
|
5457
5465
|
"-NoProfile",
|
|
5458
5466
|
"-NonInteractive",
|
|
5459
5467
|
"-Command",
|
|
@@ -6999,7 +7007,8 @@ var PluginReleaseManager = class {
|
|
|
6999
7007
|
});
|
|
7000
7008
|
}
|
|
7001
7009
|
};
|
|
7002
|
-
|
|
7010
|
+
//#endregion
|
|
7011
|
+
//#region src/managed-setup.ts
|
|
7003
7012
|
const VIRTUAL_INTERFACE_MARKERS = [
|
|
7004
7013
|
"bridge",
|
|
7005
7014
|
"docker",
|
|
@@ -7227,9 +7236,14 @@ function upstreamAuthenticatedUrl(ctx, upstreamOrigin) {
|
|
|
7227
7236
|
return typeof connection?.authenticatedUrl === "function" ? connection.authenticatedUrl(upstreamOrigin.origin) : void 0;
|
|
7228
7237
|
}
|
|
7229
7238
|
function installedDshVersion() {
|
|
7230
|
-
|
|
7231
|
-
|
|
7232
|
-
|
|
7239
|
+
try {
|
|
7240
|
+
const manifest = createRequire(import.meta.url)("@deepseek-ai/dsh-host-webserver/package.json");
|
|
7241
|
+
if (manifest === null || typeof manifest !== "object") return "unknown";
|
|
7242
|
+
const version = manifest.version;
|
|
7243
|
+
return typeof version === "string" && version !== "" ? version : "unknown";
|
|
7244
|
+
} catch {
|
|
7245
|
+
return "unknown";
|
|
7246
|
+
}
|
|
7233
7247
|
}
|
|
7234
7248
|
function mapAdminError(error) {
|
|
7235
7249
|
if (error instanceof HttpError) return error;
|
|
@@ -7375,7 +7389,6 @@ function remoteControlPayload(provider, status, gateway, providerStatuses, cpola
|
|
|
7375
7389
|
/** Mount the resident control route and its optional authenticated LAN gateway. */
|
|
7376
7390
|
async function apply(ctx, config) {
|
|
7377
7391
|
const dshVersion = installedDshVersion();
|
|
7378
|
-
assertSupportedDshVersion(dshVersion);
|
|
7379
7392
|
const loaded = await loadSetup(config);
|
|
7380
7393
|
const mobileAccess = createMobileAccessService(ctx);
|
|
7381
7394
|
const template = loopbackTemplate(loaded);
|
|
@@ -7755,6 +7768,6 @@ async function apply(ctx, config) {
|
|
|
7755
7768
|
}, "dsh-mobile: independent LAN and selectable remote providers with /mobile command");
|
|
7756
7769
|
}
|
|
7757
7770
|
//#endregion
|
|
7758
|
-
export { AUTH_PREFIX, AccessController, AccessError, BoundedRateLimiter, CSRF_COOKIE, CSRF_HEADER, Config, FRP_VHOST_HTTP_PORT as DEFAULT_VHOST_HTTP_PORT, FRP_VHOST_HTTP_PORT, DEVICE_COOKIE, EXTENSION_LIMITS, FRP_COMPONENT_RELEASES, FrpComponentManager, FrpConfigStore, FrpController, JsonDeviceStore, JsonMobileAccessControlStore, JsonRemoteProviderStore, LOCAL_ADMIN_PREFIX, MemoryDeviceStore, MobileAccessGateway, MobileAccessGatewayController, MobileAccessService, MobileExtensionError, RequestTrustPolicy, SESSION_COOKIE,
|
|
7771
|
+
export { AUTH_PREFIX, AccessController, AccessError, BoundedRateLimiter, CSRF_COOKIE, CSRF_HEADER, Config, FRP_VHOST_HTTP_PORT as DEFAULT_VHOST_HTTP_PORT, FRP_VHOST_HTTP_PORT, DEVICE_COOKIE, EXTENSION_LIMITS, FRP_COMPONENT_RELEASES, FrpComponentManager, FrpConfigStore, FrpController, JsonDeviceStore, JsonMobileAccessControlStore, JsonRemoteProviderStore, LOCAL_ADMIN_PREFIX, MemoryDeviceStore, MobileAccessGateway, MobileAccessGatewayController, MobileAccessService, MobileExtensionError, RequestTrustPolicy, SESSION_COOKIE, WS_PATHS, addressAllowed, apply, assertExtensionId, configuredRemoteProvider, createFrpServerTemplate, createFrpcToml, createMobileAccessService, createRestrictedFrpServerTemplate, inject, isLoopbackAddress, name, parseAuthority, parseCidr, parseControlFile, parseDeviceSnapshot, parseExtensionManifest, parseFrpSettings, parseGatewayConfig, parseMobileAccessControlState, parseRemoteProviderState, resolveAuthority, rewriteMobileIndex, validateFrpPublicOrigin, validateFrpServerAddress, validateFrpServerPort, validateFrpToken };
|
|
7759
7772
|
|
|
7760
7773
|
//# sourceMappingURL=index.mjs.map
|