dsh-mobile 0.8.1 → 0.8.3
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 +33 -0
- package/CONTRIBUTORS.md +30 -2
- package/README.en.md +7 -5
- package/README.md +7 -5
- package/SECURITY.md +1 -1
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/apps/mobile/README.md +8 -4
- package/apps/mobile/README.zh-CN.md +8 -4
- package/apps/mobile/release.json +3 -3
- package/docs/ATTACH_EXISTING_FRPS.en.md +2 -0
- package/docs/ATTACH_EXISTING_FRPS.md +2 -0
- package/docs/CLIENT_MODULES.en.md +6 -2
- package/docs/CLIENT_MODULES.md +6 -2
- package/docs/CONNECTION_DIAGNOSTICS.en.md +56 -0
- package/docs/CONNECTION_DIAGNOSTICS.md +56 -0
- package/docs/IROH.en.md +7 -1
- package/docs/IROH.md +7 -1
- package/docs/MOBILE_PLUGIN_ADAPTATION.en.md +1 -1
- package/docs/MOBILE_PLUGIN_ADAPTATION.md +1 -1
- package/docs/README.md +1 -0
- package/docs/SKIN_COMPATIBILITY.en.md +1 -1
- package/docs/SKIN_COMPATIBILITY.md +1 -1
- package/docs/SLOW_CONNECTIONS.en.md +6 -2
- package/docs/SLOW_CONNECTIONS.md +6 -2
- package/lib/cli.js +6 -12
- package/lib/cli.js.map +1 -1
- package/lib/client.js +772 -248
- package/lib/client.js.map +1 -1
- package/lib/extension-worker-runtime.mjs +4 -8
- package/lib/extension-worker-runtime.mjs.map +1 -1
- package/lib/index.d.mts +19 -89
- package/lib/index.mjs +397 -273
- package/lib/index.mjs.map +1 -1
- package/lib/mobile-compat.js +2 -2
- package/lib/mobile-compat.js.map +1 -1
- package/lib/mobile-layout.js +116 -33
- package/lib/mobile-layout.js.map +1 -1
- package/package.json +9 -7
- package/packages/question-fixes/lib/client.js +1 -2
- package/packages/question-fixes/lib/index.mjs +1 -2
- package/packages/question-fixes/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
Notable changes are recorded here. GitHub Releases provide the downloadable packages and generated commit notes.
|
|
4
4
|
|
|
5
|
+
## 0.8.3 - 2026-11-05
|
|
6
|
+
|
|
7
|
+
- Move the current DSH 0.2.2 compatibility test lane to 0.2.2-rc.1. Preserve the dedicated Mobile layout by default, and route App Back on a foreground upstream drawer to DSH's own dismissal handler.
|
|
8
|
+
- Keep a landscape phone's drawer and panel return action even above the wide-window threshold; a tablet's keyboard does not change its layout band. Update sidebar scroll ownership after the new layout commits. Thanks @LUgABeEEE for [#346](https://github.com/saya-ch/dsh-mobile/pull/346).
|
|
9
|
+
- Align the Plugins panel heading with its content and restore compact built-in plugin cards while keeping their full-card tap area. Stack Web Push categories and actions in General settings without changing delivery or consent. Thanks @chintoleung for [#351](https://github.com/saya-ch/dsh-mobile/pull/351) and [#353](https://github.com/saya-ch/dsh-mobile/pull/353).
|
|
10
|
+
- Support the optional frpc username for shared servers. Clear a saved username without reentering the token when the frps address and control port are unchanged. Thanks @xaxka for [#344](https://github.com/saya-ch/dsh-mobile/pull/344).
|
|
11
|
+
- Update the optional managed cloudflared component from 2026.9.1 to 2026.10.7. Install the new component explicitly from the desktop panel; it is not fetched automatically. Existing tunnel settings are not deleted.
|
|
12
|
+
- Describe Funnel listener startup separately from verified public access. The bundled Funnel remains public-ingress-only; this change neither enables tailnet ingress nor fixes an unverified public-route failure.
|
|
13
|
+
- Add optional folder-permission guidance to the remote panel on macOS. It does not probe or request Full Disk Access, change system settings, or block pairing. Thanks @LunarFeller for [#354](https://github.com/saya-ch/dsh-mobile/issues/354).
|
|
14
|
+
- Render iroh pairing QR codes with a four-module quiet zone and keep the copy action available when a valid pairing descriptor has no QR image. Do not reuse the previous image after opening a new pairing window. This does not establish the cause of the transport failures in [#338](https://github.com/saya-ch/dsh-mobile/issues/338).
|
|
15
|
+
- Update the browser-bundled SHA-256 dependency, noble-hashes, to 2.4.0 and adapt its imports and UTF-8 input without changing native notification tags. [#334](https://github.com/saya-ch/dsh-mobile/pull/334)
|
|
16
|
+
- Plugin-only update. Android 0.7.2 remains the published App; this update does not introduce a native WebView cache.
|
|
17
|
+
|
|
18
|
+
## Android 0.7.2 - 2026-11-04
|
|
19
|
+
|
|
20
|
+
- Android: accept a pinned gateway's WebSocket certificate callback when the secure authority and verified leaf match the paired HTTPS origin. Host, port, CA, certificate validity, signature and SAN checks remain required. Cleartext, foreign authorities and URL credentials remain rejected. Thanks @LUgABeEEE for [#343](https://github.com/saya-ch/dsh-mobile/pull/343).
|
|
21
|
+
|
|
22
|
+
## 0.8.2 - 2026-11-04
|
|
23
|
+
|
|
24
|
+
- Move the current preview compatibility lane to DSH0.2.2-alpha.3, retaining the same packed settings, module recovery, picker, attachment, sidebar and compressed Workspace checks. Fresh alpha.2 installs have an independently reproduced upstream settings-write failure; upgrade to alpha.3. No DSH source patch, dependency override or ignored test failure is used.
|
|
25
|
+
- Let newer stock DSH own its responsive modal sidebar instead of adapting its hidden desktop column. Keep upstream focus, inert state and Escape dismissal; the dedicated Mobile layout and older stock fallback remain separate.
|
|
26
|
+
|
|
27
|
+
- Restore Android Back dismissal of current DSH settings dialogs whose empty backdrop omits `aria-hidden`. Retain older backdrop support and refuse interactive, labelled or editable sibling content rather than clicking arbitrary dialog actions. No Android App update is required.
|
|
28
|
+
- Correct the FRP attach-mode step heading and hide the SSH deployment fields. Switching modes preserves unsaved SSH values without saving or deploying. Thanks @LunarFeller for [#341](https://github.com/saya-ch/dsh-mobile/issues/341) and [#342](https://github.com/saya-ch/dsh-mobile/pull/342).
|
|
29
|
+
- Separate provider-reported readiness, system DNS and computer-egress observations. Distinguish tailnet, Fake-IP, private, mixed and unavailable DNS context; a failed Funnel-only private path no longer declares public ingress down. Preserve real TLS/HTTP failures and mark phone, authenticated pages, resources and WebSockets unverified. Cards and copied reports share localized scope and guidance. Thanks @z2140014118-stack for [#340](https://github.com/saya-ch/dsh-mobile/issues/340). This diagnostic change does not enable private tailnet ingress or silently use public DoH.
|
|
30
|
+
- Supply the authenticated request Peer to newer DSH index-injection collectors. This fixes the diagnostic API's reproduced 500 on DSH0.2.2-alpha.2 without creating a replacement Peer or bypassing authentication. An optional script-inspection failure is reported as unverified while other checks remain available.
|
|
31
|
+
|
|
32
|
+
- Separate inbound transport resets from HTTP parser rejections. Transport diagnostics carry no HTTP status; malformed methods and other fixed parser codes remain distinguishable without logging raw packets, URLs or credentials. Thanks @smlfx for the diagnostic report in [#338](https://github.com/saya-ch/dsh-mobile/issues/338); the reported iroh customization/scanning failure remains under investigation.
|
|
33
|
+
- Identify customization manifest request/body failures separately from extension resource failures while retaining explicit retry, cancellation and existing working customization.
|
|
34
|
+
- Refuse module selections computed against an older catalog, retain the draft for explicit rereading, and explain the measured gzip subtotal and unknown sizes before applying the minimal preset. Keep required Mobile modules and their dependencies; default loading is unchanged. Thanks @LUgABeEEE for [#328](https://github.com/saya-ch/dsh-mobile/pull/328).
|
|
35
|
+
- Protect the installed General settings provider during minimal loading, keeping its sidebar launcher available after reopening. Old exclusions of that now-required provider use the existing explicit device recovery without opening settings first. Loading all modules affects only the current device; restoring defaults instead inherits computer/profile exclusions. This addresses a reproduced settings-inaccessibility case related to [#324](https://github.com/saya-ch/dsh-mobile/issues/324) and the follow-up in [#337](https://github.com/saya-ch/dsh-mobile/issues/337), not every reported layout symptom.
|
|
36
|
+
- Update artifact-download actions, development maintenance dependencies and eventsource-parser; clarify skin module-selection limits and iroh failure diagnostics. Android0.7.2/build87 is released independently with its notes above; native startup caching is not restored.
|
|
37
|
+
|
|
5
38
|
## 0.8.1 - 2026-11-01
|
|
6
39
|
|
|
7
40
|
- Recognize the four-seat settings grid introduced in DSH 0.2.2-alpha.2. Preserve upstream navigation and grid placement while retaining Mobile's accessible close-button target; older two-column settings keep their existing mobile layout.
|
package/CONTRIBUTORS.md
CHANGED
|
@@ -1,8 +1,36 @@
|
|
|
1
1
|
# 贡献者 / Contributors
|
|
2
2
|
|
|
3
|
-
GitHub 的 [Contributors 图表](https://github.com/saya-ch/dsh-mobile/graphs/contributors) 按进入默认分支的提交自动统计,无法手动加入仅提交 issue 或 PR
|
|
3
|
+
GitHub 的 [Contributors 图表](https://github.com/saya-ch/dsh-mobile/graphs/contributors) 按进入默认分支的提交自动统计,无法手动加入仅提交 issue 或 PR 提案的成员。本页按实际参与方式感谢社区成员;仓库维护者与自动依赖更新仍可在 GitHub 历史记录中查看。
|
|
4
4
|
|
|
5
|
-
GitHub's Contributors graph counts commits on the default branch; issue reports and PR proposals cannot be manually added to it. This page credits community members by how they contributed
|
|
5
|
+
GitHub's Contributors graph counts commits on the default branch; issue reports and PR proposals cannot be manually added to it. This page credits community members by how they contributed. The repository maintainer and automated dependency updates remain visible in GitHub's history.
|
|
6
|
+
|
|
7
|
+
## 0.8.3 贡献 / Contributions for 0.8.3
|
|
8
|
+
|
|
9
|
+
感谢 [@xaxka](https://github.com/xaxka) 在 [#344](https://github.com/saya-ch/dsh-mobile/pull/344) 提供共享 FRP 用户名支持,[@LUgABeEEE](https://github.com/LUgABeEEE) 在 [#346](https://github.com/saya-ch/dsh-mobile/pull/346) 提供横屏布局判断,以及 [@chintoleung](https://github.com/chintoleung) 在 [#351](https://github.com/saya-ch/dsh-mobile/pull/351) 和 [#353](https://github.com/saya-ch/dsh-mobile/pull/353) 修复推送设置与插件页布局。原作者提交保留,维护者修正另记。
|
|
10
|
+
|
|
11
|
+
Thanks [@xaxka](https://github.com/xaxka) for the shared-FRP username in [#344](https://github.com/saya-ch/dsh-mobile/pull/344), [@LUgABeEEE](https://github.com/LUgABeEEE) for the landscape layout in [#346](https://github.com/saya-ch/dsh-mobile/pull/346), and [@chintoleung](https://github.com/chintoleung) for the push-settings and Plugins-page layout fixes in [#351](https://github.com/saya-ch/dsh-mobile/pull/351) and [#353](https://github.com/saya-ch/dsh-mobile/pull/353). Original commits are retained, with maintainer corrections recorded separately.
|
|
12
|
+
|
|
13
|
+
## 0.8.2 贡献 / Contributions for 0.8.2
|
|
14
|
+
|
|
15
|
+
感谢 [@LUgABeEEE](https://github.com/LUgABeEEE) 通过 [#343](https://github.com/saya-ch/dsh-mobile/pull/343) 修正 Android 固定证书的 WebSocket 地址判断。原作者提交保留;维护者补充完整证书决策组合回归。该原生改动归入独立编号的 Android 0.7.2 候选,不由 npm 升级替代。
|
|
16
|
+
|
|
17
|
+
Thanks [@LUgABeEEE](https://github.com/LUgABeEEE) for the Android pinned-WebSocket authority fix in [#343](https://github.com/saya-ch/dsh-mobile/pull/343). Original commits are retained alongside maintainer combined-certificate regressions. This native change belongs to the independently versioned Android 0.7.2 candidate, not an npm-only update.
|
|
18
|
+
|
|
19
|
+
感谢 [@LunarFeller](https://github.com/LunarFeller) 在 [#341](https://github.com/saya-ch/dsh-mobile/issues/341) 定位 FRP 接入模式的标题与 SSH 字段残留,并通过 [#342](https://github.com/saya-ch/dsh-mobile/pull/342) 提交修复;候选保留原作者提交,并补充浏览器回归。
|
|
20
|
+
|
|
21
|
+
Thanks [@LunarFeller](https://github.com/LunarFeller) for diagnosing the FRP attach-mode heading and SSH-field remnants in [#341](https://github.com/saya-ch/dsh-mobile/issues/341) and contributing the fix in [#342](https://github.com/saya-ch/dsh-mobile/pull/342). The candidate preserves the original commit and adds browser regression coverage.
|
|
22
|
+
|
|
23
|
+
感谢 [@madlogos](https://github.com/madlogos) 在[后续反馈](https://github.com/saya-ch/dsh-mobile/issues/337#issuecomment-6593356950)中指出最小加载后的设置访问与全量恢复问题,推动旧选择重启恢复流程的验收和说明。
|
|
24
|
+
|
|
25
|
+
Thanks [@madlogos](https://github.com/madlogos) for the [follow-up report](https://github.com/saya-ch/dsh-mobile/issues/337#issuecomment-6593356950) about settings access and loading all modules after minimal loading, informing restart-recovery acceptance and guidance.
|
|
26
|
+
|
|
27
|
+
感谢 [@z2140014118-stack](https://github.com/z2140014118-stack) 在 [#340](https://github.com/saya-ch/dsh-mobile/issues/340) 提供 MagicDNS 前后对照,帮助定位诊断的测量范围误报。诊断修正不表示 tailnet 内的连接限制已解除。
|
|
28
|
+
|
|
29
|
+
Thanks [@z2140014118-stack](https://github.com/z2140014118-stack) for the MagicDNS comparison in [#340](https://github.com/saya-ch/dsh-mobile/issues/340), helping identify misleading diagnostic scope. Correcting the report does not remove the private-tailnet connection limitation.
|
|
30
|
+
|
|
31
|
+
感谢 [@LUgABeEEE](https://github.com/LUgABeEEE) 在 [#328](https://github.com/saya-ch/dsh-mobile/pull/328) 提供模块目录版本校验,以及 [@smlfx](https://github.com/smlfx) 在 [#338](https://github.com/saya-ch/dsh-mobile/issues/338) 提供 iroh 与 HTTP 诊断报告。报告原始故障仍在调查,不因署名而视为已解决。
|
|
32
|
+
|
|
33
|
+
Thanks [@LUgABeEEE](https://github.com/LUgABeEEE) for module-catalog revision validation in [#328](https://github.com/saya-ch/dsh-mobile/pull/328), and [@smlfx](https://github.com/smlfx) for the iroh/HTTP diagnostic report in [#338](https://github.com/saya-ch/dsh-mobile/issues/338). The original reported failure remains under investigation; credit does not imply resolution.
|
|
6
34
|
|
|
7
35
|
## 0.6.18 代码贡献与反馈 / Code contributions and reports for 0.6.18
|
|
8
36
|
|
package/README.en.md
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
<a href="#compatibility">Compatibility</a> ·
|
|
29
29
|
<a href="docs/README.md">Documentation</a> ·
|
|
30
30
|
<a href="#contributors">Contributors</a> ·
|
|
31
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.8.
|
|
31
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.8.3">Release notes</a> ·
|
|
32
32
|
<a href="README.md">简体中文</a>
|
|
33
33
|
</p>
|
|
34
34
|
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
>
|
|
37
37
|
> **Using an iPhone or iPad?** Use Safari or [add DSH Mobile to your Home Screen as a web app (PWA)](<#iphone-and-ipad-home-screen-web-app-pwa>)—no native iOS download needed.
|
|
38
38
|
>
|
|
39
|
-
> **Current stable release: 0.8.
|
|
39
|
+
> **Current stable release: 0.8.3**. Adapt to DSH 0.2.2-rc.1, fix landscape, Plugins and Web Push settings layouts, support shared FRP usernames, and improve iroh pairing. Plugin and Android App releases remain independent. [Plugin release notes and downloads](https://github.com/saya-ch/dsh-mobile/releases/tag/v0.8.3) · [Full changelog](CHANGELOG.md).
|
|
40
40
|
>
|
|
41
41
|
> **Version policy**: since plugin **0.6.2**, the Android app and plugin use independent version numbers and releases. Their numbers do not need to match, and a plugin update does not imply an app update. [Compatibility notes](#compatibility).
|
|
42
42
|
|
|
43
43
|
<p align="center">
|
|
44
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.
|
|
45
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.
|
|
46
|
-
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.
|
|
44
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.2/dsh-mobile-android-v0.7.2.apk"><img src="https://raw.githubusercontent.com/saya-ch/dsh-mobile/main/assets/brand/app-icon-rounded.svg" alt="DSH Mobile Android app icon" width="72" height="72"></a><br>
|
|
45
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.2/dsh-mobile-android-v0.7.2.apk"><strong>Download Android app 0.7.2 (compatibility)</strong></a><br>
|
|
46
|
+
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.2/dsh-mobile-android-v0.7.2-iroh.apk">64-bit full APK (experimental iroh)</a> · <a href="https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.2">Release notes and checksums</a></sub>
|
|
47
47
|
</p>
|
|
48
48
|
|
|
49
49
|
DSH Mobile is a DeepSeek Harness plugin that lets a mobile browser or the Android app connect over a protected LAN or an optional Tailscale Funnel, cpolar, cloudflared, self-hosted FRP, or own reverse-proxy remote path. The full Android App also supports experimental iroh encrypted direct connections with relay fallback. The phone reaches the computer's sessions, Workspaces, messages and tools. The computer manages LAN and remote switches and pairing authorizations separately; the Android app lists paired computers together. The plugin does not modify DeepSeek Harness source.
|
|
@@ -445,6 +445,8 @@ On macOS, local network, cloudflared, self-hosted FRP and the own reverse proxy
|
|
|
445
445
|
|
|
446
446
|
| DSH Mobile plugin | Verified DeepSeek Harness version |
|
|
447
447
|
| --- | --- |
|
|
448
|
+
| `0.8.3` | The current DSH 0.2.2 test target is `0.2.2-rc.1`, alongside existing checks including `0.2.1-rc.5`. The upstream rc.1 npm CLI requires Node.js 24.9 or later |
|
|
449
|
+
| `0.8.2` | The DSH 0.2.2 preview target for this release was `0.2.2-alpha.3`. Fresh `0.2.2-alpha.2` installs can fail to save settings because of an upstream dependency mismatch; see the [independent reproduction](https://github.com/deepseek-ai/deepseek-harness/discussions/11994#discussioncomment-19373554). Users still on alpha.2 should upgrade to rc.1 |
|
|
448
450
|
| `0.8.1` | Add packed boot, settings, directory selection, attachments, sidebar and compressed Workspace checks on `0.2.1-rc.5` and `0.2.2-alpha.2`; see [CI](https://github.com/saya-ch/dsh-mobile/actions/workflows/ci.yml) for the complete version matrix |
|
|
449
451
|
| `0.8.0` | Push public-contract, settings, encrypted-payload and tap-ownership checks are pinned to `0.2.1-rc.2 / rc.3`; see [CI](https://github.com/saya-ch/dsh-mobile/actions/workflows/ci.yml) for the general boot/layout matrix. iOS device results accept contributor testing; browser checks do not establish every phone, plugin or public route |
|
|
450
452
|
|
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
<a href="#兼容性">兼容性</a> ·
|
|
29
29
|
<a href="docs/README.md">文档</a> ·
|
|
30
30
|
<a href="#贡献者">贡献者</a> ·
|
|
31
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.8.
|
|
31
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.8.3">更新记录</a> ·
|
|
32
32
|
<a href="README.en.md">English</a>
|
|
33
33
|
</p>
|
|
34
34
|
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
>
|
|
37
37
|
> **使用 iPhone 或 iPad?** 可以用 Safari 访问,或[添加到主屏幕作为 Web App(PWA)使用](<#iphone-与-ipad主屏幕-web-apppwa>),无需下载原生 iOS App。
|
|
38
38
|
>
|
|
39
|
-
> **当前正式版本:0.8.
|
|
39
|
+
> **当前正式版本:0.8.3**。适配 DSH 0.2.2-rc.1,修复横屏、插件页和网页推送设置布局,支持共享 FRP 用户名,并改进 iroh 配对。插件与 Android App 独立更新。[插件更新与下载](https://github.com/saya-ch/dsh-mobile/releases/tag/v0.8.3) · [完整更新记录](CHANGELOG.md)。
|
|
40
40
|
>
|
|
41
41
|
> **版本说明**:自插件 **0.6.2** 起,Android App 与插件独立编号、独立发布,版本号无需一致;插件升级不代表 App 需要同步升级。[兼容说明](#兼容性)。
|
|
42
42
|
|
|
43
43
|
<p align="center">
|
|
44
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.
|
|
45
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.
|
|
46
|
-
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.
|
|
44
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.2/dsh-mobile-android-v0.7.2.apk"><img src="https://raw.githubusercontent.com/saya-ch/dsh-mobile/main/assets/brand/app-icon-rounded.svg" alt="DSH Mobile 安卓应用图标" width="72" height="72"></a><br>
|
|
45
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.2/dsh-mobile-android-v0.7.2.apk"><strong>下载 Android App 0.7.2(兼容版)</strong></a><br>
|
|
46
|
+
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.7.2/dsh-mobile-android-v0.7.2-iroh.apk">64 位完整版(含实验性 iroh)</a> · <a href="https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.2">版本说明与校验文件</a></sub>
|
|
47
47
|
</p>
|
|
48
48
|
|
|
49
49
|
DSH Mobile 是一个 DeepSeek Harness 插件,让手机浏览器或 Android App 通过局域网,或可选的 Tailscale Funnel、cpolar、cloudflared、自建 FRP、自有反向代理远程通道连接电脑;Android 完整版还支持实验性 iroh 加密直连与中继。手机可以继续使用电脑上的会话、工作区、消息和工具。电脑端分别启停局域网与远程访问、分别管理配对授权;Android App 统一显示已配对电脑。插件不修改 DeepSeek Harness 源码。
|
|
@@ -447,6 +447,8 @@ macOS 上局域网、cloudflared、自建 FRP 与自有反向代理可用;Funn
|
|
|
447
447
|
|
|
448
448
|
| DSH Mobile 插件 | 已验证的 DeepSeek Harness 版本与范围 |
|
|
449
449
|
| --- | --- |
|
|
450
|
+
| `0.8.3` | 当前 DSH 0.2.2 验证目标为 `0.2.2-rc.1`,同时保留 `0.2.1-rc.5` 等既有版本检查。使用 rc.1 的 npm CLI 时,按上游要求使用 Node.js 24.9 或更新版本 |
|
|
451
|
+
| `0.8.2` | 当时的 DSH 0.2.2 预览目标是 `0.2.2-alpha.3`。`0.2.2-alpha.2` 全新安装可能因上游依赖组合不一致而无法保存设置;[独立复现](https://github.com/deepseek-ai/deepseek-harness/discussions/11994#discussioncomment-19373554)。仍在使用 alpha.2 的用户建议升级到 rc.1 |
|
|
450
452
|
| `0.8.1` | 新增 `0.2.1-rc.5`、`0.2.2-alpha.2` 的打包启动与设置、目录选择、附件、侧栏、压缩 Workspace 连接检查;完整版本矩阵见 [CI](https://github.com/saya-ch/dsh-mobile/actions/workflows/ci.yml) |
|
|
451
453
|
| `0.8.0` | 网页推送的公共接口、设置、加密载荷与点击归属检查固定在 `0.2.1-rc.2 / rc.3`;通用启动与布局矩阵见 [CI](https://github.com/saya-ch/dsh-mobile/actions/workflows/ci.yml)。iOS 真机结果采信贡献者实测;浏览器检查不代表所有手机、第三方插件或公网线路已验收 |
|
|
452
454
|
|
package/SECURITY.md
CHANGED
|
@@ -53,7 +53,7 @@ The maintainer will acknowledge a complete report within seven days. Publication
|
|
|
53
53
|
- The Funnel node stores its Tailscale login state under `$DSH_HOME/mobile-access/remote/tailscale/`. The plugin does not request or store a Tailscale password, Auth Key, or OAuth secret.
|
|
54
54
|
- The proxy-assisted remote diagnostic probes only the public `/mobile-access/health` path. It tries direct HTTPS first and, only after direct failure, may use an HTTP CONNECT proxy named by the DSH process environment unless `NO_PROXY` excludes the target. The probe sends no device token or session Cookie; configured proxy credentials are sent to that proxy for CONNECT, not placed in the diagnostic report. A proxy-only success is a warning to test from the phone, not proof that the phone or the provider route is available. This diagnostic does not change the remote provider's traffic path.
|
|
55
55
|
- Plugin 0.6.11 and later record limited HTTP authorization and CSRF rejection metadata. It omits credential values and query strings, categorizes arbitrary paths, normalizes Origin and admits only recognized fetch-site values. Each Gateway keeps two fixed diagnostic categories with 30-second repeat aggregation, not an unbounded per-client/path history. Diagnostic-callback failures do not change the rejection response. These records are not complete WebSocket or native-pairing traces, and absence of a record does not establish successful authentication. Review even bounded metadata before sharing logs.
|
|
56
|
-
-
|
|
56
|
+
- Per-Gateway HTTP diagnostics use four fixed categories: parser rejection, transport failure, invalid target, and an authenticated exact `POST /api/session/prompt` rejected upstream. Each has 30-second sampling with suppressed counts. Parser and transport codes are allowlisted; transport failures carry no HTTP status. Raw packets, headers, request bodies, error messages, arbitrary URLs and query strings are excluded. A diagnostic failure cannot change the response or retry a write. Request timeout and header overflow remain rejected, using 408 and 431 rather than a generic 400; receive limits are not relaxed.
|
|
57
57
|
- cpolar is downloaded only after confirmation from a pinned official artifact whose size and SHA-256 are verified. Its Authtoken is stored in a private, self-update-disabled configuration under `$DSH_HOME/mobile-access/`, never returned by the admin API or written to logs. Component removal deletes its managed executable, Authtoken configuration, logs and staging files, but retains LAN and shared remote pairing records.
|
|
58
58
|
- Self-hosted FRP accepts a VPS address, frps control port, operator-generated high-entropy shared token, and standard-port public HTTPS origin. The 0.4.6 self-signed entry additionally selects a non-reserved public TCP port on a globally routable IPv4 address. The plugin validates token length and format; the operator remains responsible for its entropy. Managed deployment creates one HTTP vhost and Caddy; existing-frps attachment changes no VPS files or services and allows either a restricted HTTP vhost with a public CA or one TCP passthrough to a computer-side HTTPS gateway. Arbitrary FRP configuration, general TCP/UDP forwarding, FRP plugins, PATH entries, and startup tasks are not supported.
|
|
59
59
|
- For an HTTP-vhost entry, the generated managed-frps template binds the plaintext listener to `127.0.0.1` and uses Caddy for public HTTPS. An existing frps must have its actual `vhostHTTPPort` entered explicitly and its plaintext vhost kept off the public network; the plugin probes the configured port before starting `frpc`. frps `proxyBindAddr` governs proxy listeners globally: exposing a TCP passthrough on the same instance must not accidentally expose another plaintext vhost. A separate frps instance may be required. For self-signed ingress, the computer-side CA lasts five years and the leaf lasts 397 days; the leaf is renewed under the same CA, but an expired or replaced CA is not silently trusted and requires fresh pairing. A local readiness probe does not establish phone reachability; verify the public entry from an independent network.
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -18,7 +18,7 @@ The optional managed Caddy component is not included in the npm package or Andro
|
|
|
18
18
|
|
|
19
19
|
The experimental Rust transport is adapted from [dsh-mobile-iroh](https://github.com/saya-ch/dsh-mobile-iroh), copyright 2026 Guangqi Zhang, under the MIT License, and the host baseline preserves zexadev's MIT-licensed dsh-tether attribution. The source notices and complete licenses are retained under `native/iroh-host/` and included with the npm package. The optional sidecar is not bundled: explicit installation reuses a verified companion copy or downloads the size- and SHA-256-pinned companion release payload. Enabling the channel alone does not download it.
|
|
20
20
|
|
|
21
|
-
The npm package declares direct runtime dependencies on [Schemastery](https://github.com/shigma/schemastery) `^3.18.1`, [@noble/hashes](https://github.com/paulmillr/noble-hashes) `
|
|
21
|
+
The npm package declares direct runtime dependencies on [Schemastery](https://github.com/shigma/schemastery) `^3.18.1`, [@noble/hashes](https://github.com/paulmillr/noble-hashes) `2.4.0`, [bonjour-service](https://github.com/onlxltd/bonjour-service) `1.4.4`, [eventsource-parser](https://github.com/rexxars/eventsource-parser) `4.1.3`, [qrcode](https://github.com/soldair/node-qrcode) `^1.5.4`, [selfsigned](https://github.com/jfromaniello/selfsigned) `^5.5.0`, [ws](https://github.com/websockets/ws) `8.22.0`, and [Zod](https://zod.dev/) `4.6.7`. These packages are distributed under the MIT License; the release checkout's exact transitive versions appear in the attached CycloneDX npm SBOM.
|
|
22
22
|
|
|
23
23
|
Browser Web Push uses [web-push](https://github.com/web-push-libs/web-push) `3.6.7`, distributed under the Mozilla Public License 2.0 (MPL-2.0), for payload encryption and VAPID signing/key generation. It remains an unmodified, external Node runtime dependency, not part of the browser bundle; its npm package supplies the covered source and license. DSH Mobile owns the bounded HTTPS transport and endpoint validation. Exact transitive versions appear in the [npm lockfile](<package-lock.json>) and release SBOM.
|
|
24
24
|
|
package/apps/mobile/README.md
CHANGED
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
DeepSeek Harness is the display name of this community-maintained Android WebView app. It opens the plugin's authenticated HTTPS page rather than bundling another DSH frontend. The app and mobile browsers receive the same DSH features and computer-side mobile customizations.
|
|
6
6
|
|
|
7
|
-
The current stable app is **0.7.
|
|
7
|
+
The current stable app is **0.7.2** (build 87). The npm plugin and Android App have independent versions: a plugin update does not automatically require another APK. See the [0.7.2 changes](#072-update).
|
|
8
8
|
|
|
9
9
|
This APK supports Android 10 or later. iPhone and iPad use the [Safari Home Screen web app and optional Web Push](../../docs/WEB_PUSH.en.md), not this Android package; no native iOS app is distributed.
|
|
10
10
|
|
|
11
11
|
## Install and pair
|
|
12
12
|
|
|
13
13
|
1. Install and enable the plugin using the [project quick start](../../README.en.md#quick-start). Complete LAN setup from the command line or the computer's **Mobile Access** panel.
|
|
14
|
-
2. Install a signed Android APK from [GitHub Releases](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.
|
|
14
|
+
2. Install a signed Android APK from [GitHub Releases](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.2). Choose the compatibility `.apk` for existing HTTPS channels, or the full `-iroh.apk` for experimental iroh on arm64-v8a/x86_64. Both have the same package ID and official signer; install only one and upgrade in place to retain pairings. A differently signed Debug APK cannot replace it; do not uninstall or clear data just to bypass that mismatch.
|
|
15
15
|
3. On the computer, generate a pairing key/link under **Mobile Access → Local network**, or configure a remote provider and generate its remote pairing QR code. In the app, choose the matching connection mode and scan or paste the link.
|
|
16
16
|
4. Name the computer. The app stores each LAN or remote pairing as its own record. The phone does not need a cpolar, Cloudflare or Tailscale app.
|
|
17
17
|
|
|
@@ -36,6 +36,10 @@ Page zoom changes the whole page and is separate from per-address text preferenc
|
|
|
36
36
|
|
|
37
37
|
Deleting a local record removes its saved token and pinned CA, not the computer's authorization or every short-lived WebView cookie. Use **Mobile Access** on the computer to revoke access immediately. A full Android clear-app-data reset removes all pairings and web data and is not a normal reconnection step.
|
|
38
38
|
|
|
39
|
+
## 0.7.2 update
|
|
40
|
+
|
|
41
|
+
Accept the paired gateway's `wss:` certificate callback only when its host and port match the saved HTTPS origin and its certificate passes the pinned CA, validity, signature and SAN checks. Ordinary HTTPS navigation and download rules remain unchanged; third-party WebSocket paths still require computer-side approval. This is an App change and cannot be installed by updating npm. Both APK variants retain the established signer and existing pairings.
|
|
42
|
+
|
|
39
43
|
## 0.7.1 update
|
|
40
44
|
|
|
41
45
|
Update AndroidX WebKit to 1.18.0 and the build toolchain to AGP 9.4.1 / Gradle 9.8.2, retaining Android API 36 and the existing pairing format. Both APK variants keep the established signer and upgrade in place. Plugin 0.8.0's iPhone/iPad Web Push is a computer-side feature, not a reason to update the Android app.
|
|
@@ -168,13 +172,13 @@ Set-Location apps/mobile/android
|
|
|
168
172
|
./gradlew.bat :app:assembleDebug -PirohNdk=C:/Android/Sdk/ndk/25.2.9519653 -x :app:lintAnalyzeDebugUnitTest -x :app:lintAnalyzeDebugAndroidTest
|
|
169
173
|
```
|
|
170
174
|
|
|
171
|
-
Pass `-PirohNative=false` for a fast toolchain-free lane that builds the original HTTPS shell
|
|
175
|
+
Pass `-PirohNative=false` for a fast toolchain-free lane that builds the original HTTPS shell without iroh transport; `IrohNative` reports itself unavailable. Using iroh requires the full build. The transport libraries are generated under `app/build/generated/iroh/jniLibs/` and never committed. A native-enabled build does not change the package identity or the established signer; the independent alpha signer from the iroh experiment is not used here.
|
|
172
176
|
|
|
173
177
|
Native builds also include the JVM TLS verifier matching `native/Cargo.lock`, from the revision-pinned official Maven archive. Preserve its JNI/Proguard rules: compiling and packaging the `.so` alone is insufficient. The APK verifier checks the retained JVM classes and native entry names in both Debug and minified Release builds.
|
|
174
178
|
|
|
175
179
|
Current-source Debug builds use package `io.github.sayach.dshmobile.debug` with a `-debug` version suffix. They install beside the official App with separate storage and pairings. They do not upgrade or migrate an older unsuffixed Debug installation; preserve that app and its data rather than uninstalling or clearing it to switch packages. Release builds keep `io.github.sayach.dshmobile` and the established signer.
|
|
176
180
|
|
|
177
|
-
The verified stable release is [Android 0.7.
|
|
181
|
+
The verified stable release is [Android 0.7.2](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.2), build 87. The compatibility and full APKs each have a matching `.sha256` asset. Both public downloads retain the established release signer and package `io.github.sayach.dshmobile`. Earlier release history belongs in [CHANGELOG](../../CHANGELOG.md).
|
|
178
182
|
|
|
179
183
|
## Acceptance and known limits
|
|
180
184
|
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
DeepSeek Harness 是这个社区维护的 Android WebView App 的显示名称。它直接打开插件提供的已认证 HTTPS 页面,不打包另一套 DSH 前端;App 与手机浏览器获得相同的 DSH 功能,以及电脑端配置的移动页面定制。
|
|
6
6
|
|
|
7
|
-
当前正式 App 为 **0.7.
|
|
7
|
+
当前正式 App 为 **0.7.2**;构建号为 87。npm 插件与 Android App 独立编号、独立更新;插件升级不代表需要重新安装 APK。此次改进见 [0.7.2 更新](#072-更新)。
|
|
8
8
|
|
|
9
9
|
此 APK 支持 Android 10 及以上系统。iPhone 和 iPad 使用 [Safari 主屏幕 Web App 与可选网页推送](../../docs/WEB_PUSH.md),不安装 Android 包;本项目不分发原生 iOS App。
|
|
10
10
|
|
|
11
11
|
## 安装与配对
|
|
12
12
|
|
|
13
13
|
1. 按[项目快速开始](../../README.md#快速开始)安装并启用插件。局域网配置可通过命令行或电脑端的 **移动访问** 面板完成。
|
|
14
|
-
2. 从 [GitHub Releases](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.
|
|
14
|
+
2. 从 [GitHub Releases](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.2) 安装已签名 APK。原有 HTTPS 通道可选兼容版 `.apk`;arm64-v8a/x86_64 设备使用实验性 iroh 时选完整版 `-iroh.apk`。两包使用相同包名和正式签名,选一个原位升级即可保留配对;不同签名的 Debug 包不能直接覆盖正式版,不要为绕过签名不匹配而卸载或清除数据。
|
|
15
15
|
3. 在电脑 **移动访问 → 局域网访问** 中生成密钥/配对链接,或配置远程通道并生成远程配对二维码。在 App 选择对应方式,扫码或粘贴链接。
|
|
16
16
|
4. 为电脑命名。每条局域网或远程配对单独保存;手机无需安装 cpolar、Cloudflare 或 Tailscale App。
|
|
17
17
|
|
|
@@ -36,6 +36,10 @@ DeepSeek Harness 是这个社区维护的 Android WebView App 的显示名称。
|
|
|
36
36
|
|
|
37
37
|
删除本机记录会移除保存的设备令牌和固定 CA,不等于撤销电脑授权或清除所有 WebView 短期 Cookie。需要立即终止访问时,请在电脑的 **移动访问** 中撤销设备。Android“清除应用数据”会删除全部配对和网页数据,不是普通重连的处理步骤。
|
|
38
38
|
|
|
39
|
+
## 0.7.2 更新
|
|
40
|
+
|
|
41
|
+
仅当 `wss:` 证书回调的主机、端口与已保存的 HTTPS 入口一致,且证书通过固定 CA、有效期、签名和 SAN 校验时,才允许该连接。普通 HTTPS 导航与下载规则不变,第三方 WebSocket 路径仍需电脑端明确放行。这是 App 原生改动,仅升级 npm 不会安装;两种 APK 均沿用正式签名,可保留已有配对升级。
|
|
42
|
+
|
|
39
43
|
## 0.7.1 更新
|
|
40
44
|
|
|
41
45
|
更新 AndroidX WebKit 至 1.18.0,构建工具更新为 AGP 9.4.1 / Gradle 9.8.2;保留 Android API 36 和既有配对格式。两种 APK 均沿用正式签名,可原位升级。插件 0.8.0 的 iPhone/iPad 网页推送属于电脑端功能,不要求为此升级 Android App。
|
|
@@ -168,13 +172,13 @@ Set-Location apps/mobile/android
|
|
|
168
172
|
./gradlew.bat :app:assembleDebug -PirohNdk=C:/Android/Sdk/ndk/25.2.9519653 -x :app:lintAnalyzeDebugUnitTest -x :app:lintAnalyzeDebugAndroidTest
|
|
169
173
|
```
|
|
170
174
|
|
|
171
|
-
传 `-PirohNative=false`
|
|
175
|
+
传 `-PirohNative=false` 可走免工具链的快速通道,构建的是不包含 iroh 传输的原 HTTPS 外壳,`IrohNative` 会报告自身不可用。使用 iroh 需要完整版构建。传输库生成在 `app/build/generated/iroh/jniLibs/` 下,永不提交。启用原生库的构建不改变包名与既定正式签名;实验阶段的独立 alpha 签名在这里不使用。
|
|
172
176
|
|
|
173
177
|
原生构建还会从固定提交的官方 Maven 归档引入与 `native/Cargo.lock` 匹配的 JVM TLS 校验组件。必须保留其 JNI/Proguard 规则,仅打包 `.so` 不足以完成接入。APK 验证会检查 Debug 和压缩后的 Release 是否保留所需 JVM 类和原生入口名称。
|
|
174
178
|
|
|
175
179
|
当前源码的 Debug 构建使用包名 `io.github.sayach.dshmobile.debug` 与 `-debug` 版本后缀,可与正式 App 并存,存储和配对彼此独立。它不会升级或迁移旧版无后缀 Debug 应用;切换包名时应保留旧应用和数据,不要为此卸载或清除。Release 构建继续使用 `io.github.sayach.dshmobile` 与既定正式签名。
|
|
176
180
|
|
|
177
|
-
已核验的正式版本为 [Android 0.7.
|
|
181
|
+
已核验的正式版本为 [Android 0.7.2](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.7.2),构建 87。兼容版与完整版分别附有对应的 `.sha256` 校验文件;两个公开下载均沿用正式发布签名及包名 `io.github.sayach.dshmobile`。旧版本历史集中在 [CHANGELOG](../../CHANGELOG.md)。
|
|
178
182
|
|
|
179
183
|
## 验收与已知限制
|
|
180
184
|
|
package/apps/mobile/release.json
CHANGED
|
@@ -25,6 +25,8 @@ Public-CA mode uses HTTPS 443. For self-signed mode, keep `https://PUBLIC_IPV4`
|
|
|
25
25
|
|
|
26
26
|
Plugin 0.6.16 adds Chinese, English and Italian field-level feedback: submission or preview marks invalid fields and focuses the first error; editing rechecks and clears corrected errors. It does not relax the validation above or change server listeners or ports for you.
|
|
27
27
|
|
|
28
|
+
With plugin 0.8.3 or later, fill **frpc user (optional)** only if your shared frps provider supplies a username for proxy registration. The server uses it as a proxy-name prefix; it does not replace the shared token. To remove a saved username, clear the field and save. If the frps address and control port have not changed, you can reuse the saved token without displaying or reentering it.
|
|
29
|
+
|
|
28
30
|
## Public-CA mode
|
|
29
31
|
|
|
30
32
|
1. In **Self-hosted FRP**, choose **Attach to my existing frps** and **Public CA certificate**. Enter the VPS address, frps control port, high-entropy shared token, public domain or IPv4 HTTPS origin, and the frps instance's actual `vhostHTTPPort`. Do not assume the managed deployment's default of 7080.
|
|
@@ -26,6 +26,8 @@
|
|
|
26
26
|
|
|
27
27
|
插件 0.6.16 起提供中文、英文和意大利文字段级提示:提交或预览时标记错误字段、聚焦第一处错误,修改后重新检查并清除已修正的提示。它不放宽上述校验,也不会替你更改服务器监听或端口。
|
|
28
28
|
|
|
29
|
+
插件 0.8.3 起,如果共享 frps 服务商提供了用于代理注册的用户名,可填写 **用户名(可选)**。服务端用它为代理名添加前缀,它不能替代共享 Token。要移除已保存的用户名,清空该字段后保存即可;frps 地址和控制端口未变时,已有 Token 不会显示,也无需重输。
|
|
30
|
+
|
|
29
31
|
## 两档入口证书
|
|
30
32
|
|
|
31
33
|
### A. 公开 CA 证书档(`public-ip-cert`,缺省)
|
|
@@ -19,6 +19,8 @@ Selection precedence is: device override → computer default → the profile's
|
|
|
19
19
|
|
|
20
20
|
**Restore defaults** on a phone removes its override and uses the computer default. On the computer, it removes the computer override and uses plugin configuration. Other device overrides are retained.
|
|
21
21
|
|
|
22
|
+
**Restore defaults is not Load all**: exclusions in the computer default or profile still apply after a reset. The startup recovery page's **Load all modules for this device and retry** instead saves an explicitly empty exclusion list for the current device, without changing computer defaults or other devices.
|
|
23
|
+
|
|
22
24
|
## Find a module
|
|
23
25
|
|
|
24
26
|
**Optional extensions** appear first. **DSH optional components (advanced)** and **Required for boot** are collapsed; required entries cannot be disabled. These groups aid browsing, not source verification, and one frontend module is not necessarily a complete plugin.
|
|
@@ -31,20 +33,22 @@ After a DSH or plugin update, an old exclusion may be missing from the catalog o
|
|
|
31
33
|
|
|
32
34
|
1. Wait for the catalog. A failed or timed-out read has a **Reread settings** action; reopening the modal is unnecessary. Rereading replaces unsaved choices and asks for confirmation when changes exist.
|
|
33
35
|
2. Checked means load on the next open; unchecked means omit next time, not unload the current page. Required boot modules cannot be unchecked. Details show declared dependencies.
|
|
34
|
-
3. Review the unsaved-change count and select **Save selection**; saving stays disabled when nothing changed. A retained module depending on an excluded module is rejected with a conflict: keep the dependency or also exclude its unwanted consumer. Other modules are never unchecked automatically.
|
|
36
|
+
3. Review the unsaved-change count and select **Save selection**; saving stays disabled when nothing changed. A retained module depending on an excluded module is rejected with a conflict: keep the dependency or also exclude its unwanted consumer. Other modules are never unchecked automatically. If the catalog changed after the dialog read it (a plugin or version update), the save is refused with a reread prompt instead of overwriting the current state with a selection computed from the old catalog.
|
|
35
37
|
4. After a successful save, the current page, conversation, and draft are not reloaded automatically. Manually reopen or refresh the DSH page to apply the selection; saving through this control does not require a DSH restart.
|
|
36
38
|
|
|
37
39
|
Close, Escape and the App's Back action ask before discarding unsaved changes. A failed save keeps choices. A write timeout means the result is unconfirmed, not rolled back; reread to confirm. Writes are not retried automatically, and closing cannot undo a completed save. Long lists scroll independently while close and footer actions remain reachable.
|
|
38
40
|
|
|
39
41
|
Computer pages and `?frontend=stock` pages are unaffected. DSH or community-plugin updates can change the catalog and dependencies. When a saved selection prevents the mobile page from starting, the page offers “Load all modules for this device and retry”; it changes this device’s selection only when you click, without changing computer defaults, other devices or pairing authorization. Settings APIs still reject invalid selections and enforce required-module and dependency checks.
|
|
40
42
|
|
|
43
|
+
The plugin 0.8.2 candidate marks the installed General settings provider as required for boot, fixing old minimal selections that made the settings entry unavailable. If an old record excludes that provider, reopening the mobile page shows recovery without requiring settings access first. Only selecting Load all saves and retries; a failure retains the old selection for an explicit retry. Pairings need not be deleted. Version 0.8.2 is not released yet; see [CHANGELOG](../CHANGELOG.md) for release status.
|
|
44
|
+
|
|
41
45
|
## Measure sizes and minimize loading
|
|
42
46
|
|
|
43
47
|
Only **Measure sizes** fetches module resources and calculates their individual gzip sizes. Ordinary reads, saves and resets do not wait for these probes. Measurement can be cancelled without replacing unsaved choices, saving or reloading the page. Each measurement has a five-second budget; completed results remain available and the rest stay unknown. Known results are cached for ten minutes and must be measured again after a DSH module-graph update.
|
|
44
48
|
|
|
45
49
|
Each group lists measured modules largest first and unknown sizes last. Totals always identify any selected modules with unknown sizes rather than presenting a partial result as complete. The mobile layout is measured from the actual Gateway layout file. Batch merging, browser caches, encoding negotiation and plugin versions affect actual transfers, so the numbers compare current modules rather than promise exact next-open downloads or fixed savings.
|
|
46
50
|
|
|
47
|
-
Modules whose package metadata is resolvable in the installation may also show the plugin's own `package.json` description: links removed, collapsed to one line, at most 200 characters. This is not an upstream endorsement. Unexported or unreadable metadata stays absent instead of guessing its purpose. **Required only (minimal load)** keeps required boot entries and their dependencies and marks other entries as not loaded. It edits the draft only; **Save selection** remains a separate action.
|
|
51
|
+
Modules whose package metadata is resolvable in the installation may also show the plugin's own `package.json` description: links removed, collapsed to one line, at most 200 characters. This is not an upstream endorsement. Unexported or unreadable metadata stays absent instead of guessing its purpose. **Required only (minimal load)** keeps required boot entries and their dependencies and marks other entries as not loaded. Its confirmation separates the excluded count, measured gzip subtotal and unmeasured count; partial measurements are not complete savings. It edits the draft only; **Save selection** remains a separate action. Default loading rules do not change and third-party plugins are not automatically blocked.
|
|
48
52
|
|
|
49
53
|
## Data and authorization
|
|
50
54
|
|
package/docs/CLIENT_MODULES.md
CHANGED
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
|
|
20
20
|
手机的“恢复默认”删除自己的覆盖,重新使用电脑默认;电脑的“恢复默认”删除电脑覆盖,重新使用插件配置。其他设备的覆盖保持不变。
|
|
21
21
|
|
|
22
|
+
**“恢复默认”不等于“加载全部”**:如果电脑默认或 profile 本身排除了模块,恢复默认后仍会沿用这些排除项。启动恢复页的“为本设备加载全部模块并重试”则明确为当前设备保存空排除列表,不修改电脑默认和其他设备。
|
|
23
|
+
|
|
22
24
|
## 找到要调整的模块
|
|
23
25
|
|
|
24
26
|
默认先显示**可选扩展**;**DSH 可选组件(高级)**和**启动必需项**折叠显示。后者不能关闭。分类只帮助浏览,不表示来源认证,也不代表每个前端模块就是一个完整插件。
|
|
@@ -31,20 +33,22 @@ DSH 或插件更新后,旧排除项可能已不在目录中,或变为启动
|
|
|
31
33
|
|
|
32
34
|
1. 等待目录读取完成;读取失败或超时可点击“重新读取”,不必关闭弹窗。重新读取会替换未保存选择,存在改动时需先确认。
|
|
33
35
|
2. 勾选表示下次打开时加载,取消勾选表示下次不加载,不表示当前页面中的模块已经卸载。启动必需模块不能取消;可在详情中查看声明依赖。
|
|
34
|
-
3.
|
|
36
|
+
3. 查看“未保存”改动数量,点击“保存选择”;没有改动时保存不可用。若保留模块仍依赖已排除模块,保存会拒绝并说明冲突:保留依赖,或同时排除不再需要的依赖方。不会自动连带取消其他模块。若读取后模块目录发生了变化(插件或版本更新),保存会被拒绝并提示重新读取,避免用旧目录算出的选择覆盖当前状态。
|
|
35
37
|
4. 保存成功后,当前页面、会话和草稿不会被自动刷新。下次手动重新打开或刷新 DSH 页面时应用选择,无需为设置入口的保存重启 DSH。
|
|
36
38
|
|
|
37
39
|
关闭、Escape 或 App 返回动作触发时,有未保存改动会提示确认。保存失败保留选择;保存超时只表示结果尚未确认,不等于服务器已回滚。可重新读取确认保存结果,不会自动重试写入,关闭弹窗也不能撤销已经完成的保存。长列表独立滚动,关闭和底部操作保持可达。
|
|
38
40
|
|
|
39
41
|
电脑页面与 `?frontend=stock` 页面不受模块选择影响。DSH 或社区插件更新可能改变模块目录和依赖;已保存的选择阻止移动页面启动时,页面提供“为本设备加载全部模块并重试”,由你点击后恢复本设备的加载选择,不改变电脑默认、其他设备或配对授权。设置接口仍拒绝无效选择,不绕过启动必需或依赖检查。
|
|
40
42
|
|
|
43
|
+
插件 0.8.2 候选将已安装的“通用设置”入口组件列为启动必需项,修复旧最小加载选择导致设置入口不可用的问题。旧记录若排除了该组件,重新打开移动页面时会先显示恢复页,无需先进入设置。点击加载全部才会保存并重试;失败时保留原选择,可以明确重试,不需要删除配对。0.8.2 尚未发布,发布状态见 [CHANGELOG](../CHANGELOG.md)。
|
|
44
|
+
|
|
41
45
|
## 体积测量与最小加载
|
|
42
46
|
|
|
43
47
|
点击“测量体积”才会读取模块资源并计算各模块独立 gzip 后的体积。普通读取、保存和恢复默认不会等待这些探测;测量期间可随时取消,未保存选择不会被覆盖,也不会保存或刷新页面。每次测量最多使用五秒预算;结束后显示已完成的结果,其余保持未知,已知结果缓存十分钟,DSH 模块图更新后重新测量。
|
|
44
48
|
|
|
45
49
|
每个分组按已测体积从大到小排列,未知项放在最后。合计始终说明仍有多少勾选项未测到,不把部分结果当作完整流量。移动布局测量的是网关实际提供的布局文件。模块合并、浏览器缓存、压缩协商和插件版本都会影响真实下载量,所以数字只帮助比较当前模块,不代表精确的下次下载量或固定节省比例。
|
|
46
50
|
|
|
47
|
-
能通过当前安装环境解析到包元数据的模块还会显示插件自己的 `package.json` 描述:去除链接、压成一行、最长 200
|
|
51
|
+
能通过当前安装环境解析到包元数据的模块还会显示插件自己的 `package.json` 描述:去除链接、压成一行、最长 200 字,不代表上游认证;包未导出元数据或无法读取时不显示,不猜测用途。“仅必需(最小加载)”只保留启动必需项及其依赖,其他项设为不加载;确认框说明将排除的模块数、已测 gzip 小计及体积未知的数量,不把部分测量当作完整节省量。它只修改草稿,仍需点击“保存选择”。默认加载规则不变,不会自动屏蔽所有第三方插件。
|
|
48
52
|
|
|
49
53
|
## 数据与授权
|
|
50
54
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Connection diagnostics and measurement scope
|
|
2
|
+
|
|
3
|
+
[中文](CONNECTION_DIAGNOSTICS.md) · [Documentation](README.md)
|
|
4
|
+
|
|
5
|
+
> Layered reporting is available from plugin 0.8.2; 0.8.1 has fewer diagnostic fields and explanations. This computer-side feature does not require an App update.
|
|
6
|
+
|
|
7
|
+
On the computer, open **Mobile access → Diagnostics** and start the check. It reads configuration, component state and bounded network observations without model requests or changes to DNS, proxies, firewall or pairings. Duplicate actions are disabled while checking; a redacted report can be copied afterward.
|
|
8
|
+
|
|
9
|
+
## Read the result by scope
|
|
10
|
+
|
|
11
|
+
Cards and copied reports identify **Configuration, Computer-side check, and Phone not tested**. Green means that particular local observation succeeded, not that the phone can use the complete application. An error describes the measured path, not every network.
|
|
12
|
+
|
|
13
|
+
| Layer | What it establishes | What remains unverified |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| Versions | Running plugin/DSH and declared minimum App version | Compatibility matrix and physical devices |
|
|
16
|
+
| Adapter and gateway | The computer's selected interface and listener state | Phone routing, hotspot isolation and cross-subnet access |
|
|
17
|
+
| Windows Firewall | Whether the expected enabled rules were found | Other policies, security software or network equipment |
|
|
18
|
+
| Local channel | Provider-reported ready, connecting, login or failure state | Public ingress, phone traffic and application resources |
|
|
19
|
+
| System DNS | Computer-side address categories and IPv4/IPv6, without copying addresses | DNS results do not prove an open port; deadline means context was not obtained |
|
|
20
|
+
| Computer egress | HTTP observation or DNS/connect/TLS/timeout/HTTP failure stage | Checks only the health path's HTTP status, not its body, login, script execution or message delivery |
|
|
21
|
+
| Phone path | Explicitly lists what must still be tested on the phone | Pairing, pages, resources and WebSockets are not accepted by a computer-only test |
|
|
22
|
+
|
|
23
|
+
A successful configured-proxy fallback is labelled as the computer's proxy egress. It does not erase private system-DNS context or establish that the phone uses that proxy. Inactive LAN configuration and firewall items should not be interpreted as remote-entry failures.
|
|
24
|
+
|
|
25
|
+
Script inspection uses the authenticated request's public Peer API without fabricating an identity. A failed optional observation remains explicitly unverified, not a claim that no competing plugin exists, while other network results remain available. Rejected authentication still refuses the report.
|
|
26
|
+
|
|
27
|
+
## Funnel inside the same tailnet
|
|
28
|
+
|
|
29
|
+
The bundled Funnel component uses `tsnet.FunnelOnly()`: it accepts public Funnel ingress, not direct connections from its local tailnet. If MagicDNS resolves the name to the node's `100.64.0.0/10` or Tailscale IPv6 address, the computer takes that private path. Failure there does not prove the public Funnel is down. Other official Funnel configurations need not have this restriction. See [Tailscale Funnel](https://tailscale.com/docs/features/tailscale-funnel) and [MagicDNS](https://tailscale.com/docs/features/magicdns).
|
|
30
|
+
|
|
31
|
+
This result requires comparison rather than marking public ingress failed or healthy. It **does not repair phone access through that private path**. Compare from outside the tailnet using another available network. Any temporary per-device Tailscale DNS adjustment is the user's choice; it can affect private services and should be restored afterward. Do not automatically disable MagicDNS for the entire tailnet.
|
|
32
|
+
|
|
33
|
+
`100.64.0.0/10` is not Fake-IP. Diagnostics distinguish it from the common `198.18.0.0/15` Fake-IP range and do not infer tailnet-only resolution from mixed answers. Real TLS identity failures and HTTP rejection remain failures even when DNS returned a tailnet address.
|
|
34
|
+
|
|
35
|
+
## Investigate the failed stage
|
|
36
|
+
|
|
37
|
+
- **DNS**: compare system resolution and network policy. Public DoH is not silently introduced.
|
|
38
|
+
- **Connect**: check route, port and ingress; a refused TCP connection does not identify a proxy, certificate or pairing problem.
|
|
39
|
+
- **TLS**: check certificate, hostname and proxy path. Never disable certificate or hostname verification.
|
|
40
|
+
- **Timeout**: only establishes that the probe did not finish within its budget, not the failed hop.
|
|
41
|
+
- **HTTP**: check whether provider policy or reverse-proxy routing blocks the health path. No pairing credentials are sent.
|
|
42
|
+
- **Unknown**: insufficient evidence to classify; raw errors, URLs and response contents are not copied into the report.
|
|
43
|
+
|
|
44
|
+
Working conversations with failed customization need separate manifest, CSS, script and event-stream investigation. Transport errors, parser rejection and upstream HTTP rejection are distinct; see [slow-link diagnostics](SLOW_CONNECTIONS.en.md). Local readiness for iroh or an own reverse proxy is not public-route acceptance; see [iroh](IROH.en.md) and [own reverse proxy](SELF_HOSTED_ORIGIN.en.md).
|
|
45
|
+
|
|
46
|
+
## macOS: timeout when opening a workspace folder
|
|
47
|
+
|
|
48
|
+
macOS can ask on the computer whether DSH may access a protected location such as Desktop, Documents or Downloads. If remote access times out just as you open a folder, check the Mac for a pending system prompt. The timeout alone does not show that pairing was lost or that permissions caused the failure.
|
|
49
|
+
|
|
50
|
+
Before leaving the Mac unattended, start DSH the way you normally run it and open the workspace folder you intend to use remotely. Grant only the access you need, and review existing grants in **System Settings → Privacy & Security → Files and Folders**. You can also choose a location for new workspaces that does not require this permission. After addressing a prompt, retry with your existing pairing. Remote access does not require Full Disk Access. See [Apple's guide to file and folder access](https://support.apple.com/en-us/guide/mac-help/mchld5a35146/mac).
|
|
51
|
+
|
|
52
|
+
## Share the report
|
|
53
|
+
|
|
54
|
+
Reports retain versions, interface names, masked endpoint suffixes, failure stages, timings, DNS categories and measurement scope. They do not read conversations or include pairing secrets, Tokens, Cookies, complete hostnames/IPs or proxy credentials. Context such as an interface name can still be identifying; review before posting.
|
|
55
|
+
|
|
56
|
+
Include the actual phone network, failure time and whether the failure occurs during pairing, page loading, resources or conversation connection. Do not upload pairing QR codes or descriptors. “Unverified” does not mean “failed”.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# 连接诊断与测量范围
|
|
2
|
+
|
|
3
|
+
[English](CONNECTION_DIAGNOSTICS.en.md) · [返回文档](README.md)
|
|
4
|
+
|
|
5
|
+
> 分层报告自插件 0.8.2 起提供;0.8.1 的诊断字段与提示较少。这项电脑侧功能不要求更新 App。
|
|
6
|
+
|
|
7
|
+
电脑端打开 **移动访问 → 诊断**,点击开始检查。诊断只读取配置、组件状态和有限的网络结果,不发送模型请求、不修改 DNS、代理、防火墙或配对。运行中的检查会禁用重复操作;报告生成后可复制脱敏结果。
|
|
8
|
+
|
|
9
|
+
## 怎样读结论
|
|
10
|
+
|
|
11
|
+
诊断卡片和复制报告都标明范围:**配置信息、电脑侧检查、手机尚未验证**。绿色只表示对应的本机项目得到成功结果,不表示手机已能完整使用 DSH;错误也只描述被测路径,不能直接推断所有网络都不可达。
|
|
12
|
+
|
|
13
|
+
| 层次 | 能说明什么 | 不能说明什么 |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| 版本信息 | 正在运行的插件、DSH 及声明的最低 App 版本 | 不能代替兼容矩阵或真机验证 |
|
|
16
|
+
| 网卡与网关 | 电脑使用的接口、监听状态 | 不能证明手机路由、热点隔离或跨网段访问正常 |
|
|
17
|
+
| Windows 防火墙 | 是否找到所需的启用规则 | 不能覆盖全部安全软件、策略或交换机限制 |
|
|
18
|
+
| 本机通道状态 | 提供方报告组件就绪、连接中、等待登录或失败 | `ready` 不代表公网、手机或页面资源已验收 |
|
|
19
|
+
| 系统 DNS | 电脑解析到的地址类别及 IPv4/IPv6;不复制具体地址 | DNS 有结果不等于端口可达;等待超时只表示本次未取得上下文 |
|
|
20
|
+
| 电脑出口探测 | 当前出口的 HTTP 结果,或 DNS、连接、TLS、等待、HTTP 阶段失败 | 仅检查健康路径的 HTTP 状态,不验证健康正文、登录、脚本执行或会话投递 |
|
|
21
|
+
| 手机路径 | 明确列出仍需在手机上验证的部分 | 电脑不会代替手机完成配对页面、资源与 WebSocket 验收 |
|
|
22
|
+
|
|
23
|
+
代理兜底成功会单独标注为电脑的代理出口,不会覆盖系统 DNS 的私网分类,也不表示手机使用了相同代理。未开启的 LAN 配置和防火墙项目不应被当作远程入口故障。
|
|
24
|
+
|
|
25
|
+
页面脚本检查使用当前已认证请求的公开 Peer 接口,不伪造身份。某个可选脚本观测失败时会明确显示未完成,不会把它当作“没有其他远程插件”,也不会隐藏其他网络检查结果;认证被拒绝时仍拒绝读取报告。
|
|
26
|
+
|
|
27
|
+
## 同一 tailnet 下的 Funnel
|
|
28
|
+
|
|
29
|
+
内置 Funnel 组件使用 `tsnet.FunnelOnly()`:它只接收公网 Funnel 入口的连接,不接收 tailnet 内部直连。如果 MagicDNS 把这个名称解析到节点的 `100.64.0.0/10` 或 Tailscale IPv6 地址,电脑会走私网路径;该路径失败不代表公网 Funnel 也失败。普通官方 Funnel 配置不一定具有这个限制。参见 [Tailscale Funnel](https://tailscale.com/docs/features/tailscale-funnel) 和 [MagicDNS](https://tailscale.com/docs/features/magicdns)。
|
|
30
|
+
|
|
31
|
+
这类结果显示为需对照确认,而不是把公网标成故障或正常。它**不会修复手机访问私网路径本身**:应先用 tailnet 外的网络验证,例如在条件允许时使用另一条网络。是否临时调整某台设备的 Tailscale DNS,由使用者自行决定;它可能影响其他私网服务,测试后应恢复。不要自动关闭整个 tailnet 的 MagicDNS。
|
|
32
|
+
|
|
33
|
+
`100.64.0.0/10` 不是 Fake-IP。诊断把它与 `198.18.0.0/15` 的常见 Fake-IP 网段分开;混合解析结果也不会仅凭其中一个私网地址就认定是 MagicDNS 遮蔽。即使解析到 tailnet 地址,真实 TLS 身份错误或 HTTP 拒绝仍保留为对应失败,不会被降级提示掩盖。
|
|
34
|
+
|
|
35
|
+
## 按失败阶段排查
|
|
36
|
+
|
|
37
|
+
- **DNS**:检查当前系统解析和网络策略,先与另一条网络对照,不默认改用公共 DoH。
|
|
38
|
+
- **连接**:核对当前路由、端口和入口;不把 TCP 拒绝自动归因为代理、证书或配对。
|
|
39
|
+
- **TLS**:核对证书、主机名和代理路径。不要关闭证书或主机名验证。
|
|
40
|
+
- **等待超时**:只说明探测预算内没有完成,不能定位具体故障节点。
|
|
41
|
+
- **HTTP**:检查健康路径是否被服务商策略或反向代理路由拦截。探测不会发送配对凭据。
|
|
42
|
+
- **未知**:当前证据不足以细分,不把原始异常、URL 或响应内容写入报告来猜原因。
|
|
43
|
+
|
|
44
|
+
会话可用但定制失败,应另外检查清单、CSS、脚本和更新流。`http failure` 的传输错误、解析错误与上游拒绝也不能混在一起;见[慢链路诊断](SLOW_CONNECTIONS.md)。iroh 和自有反向代理的本机就绪信息,不是公网验证;见 [iroh](IROH.md) 与[自有反向代理](SELF_HOSTED_ORIGIN.md)。
|
|
45
|
+
|
|
46
|
+
## macOS:打开工作区目录时超时
|
|
47
|
+
|
|
48
|
+
macOS 可能在电脑上要求 DSH 授权访问「桌面」「文稿」「下载」等受保护的位置。如果远程超时恰好发生在打开目录时,先回到 Mac 检查是否有待确认的系统提示;超时本身不能证明配对失效,也不能单凭它断定是权限问题。
|
|
49
|
+
|
|
50
|
+
无人值守前,在 Mac 上用实际启动方式运行 DSH,并打开远程会用到的工作区目录。若弹出提示,只在确有需要时授权;已有目录权限可在「系统设置 → 隐私与安全性 → 文件与文件夹」检查。也可将新的工作区放在不需要此类授权的目录。处理提示后,先用原有配对重试。远程访问不以开启「完全磁盘访问」为前提。参见 [Apple 的文件与文件夹权限指南](https://support.apple.com/zh-cn/guide/mac-help/mchld5a35146/mac)。
|
|
51
|
+
|
|
52
|
+
## 分享报告
|
|
53
|
+
|
|
54
|
+
报告保留版本、接口名称、脱敏端点后缀、失败阶段、耗时、系统 DNS 类别和测量范围。不读取会话正文,不包含配对密钥、Token、Cookie、完整域名、完整 IP 或代理凭据。接口名称等上下文仍可能具有辨识性,公开前应再检查一遍。
|
|
55
|
+
|
|
56
|
+
建议补充实际手机网络、失败时间,以及停在配对、页面、资源还是会话连接阶段。不要上传原始配对二维码或描述符;报告中的“未验证”不是“验证失败”。
|
package/docs/IROH.en.md
CHANGED
|
@@ -20,7 +20,7 @@ iroh replaces public domains and tunnel accounts with an encrypted direct connec
|
|
|
20
20
|
4. Press **Generate iroh pairing QR code** and scan it with the full App. The descriptor binds the sidecar's six-digit code, the Gateway's one-time token and pinned CA. Generating another descriptor replaces the previous pairing window; pairing a phone redeems the Gateway token through the normal pair endpoint over iroh.
|
|
21
21
|
5. Switching off or switching providers stops the owned process and Gateway without deleting stored pairings. The independent App has a different package identity; its Keystore credentials are not automatically migrated into this App.
|
|
22
22
|
|
|
23
|
-
Main actions stay hidden before component installation. Afterwards, the toggle, QR generation and Copy pairing link buttons share one row. Copy stays visible but disabled without valid pairing data
|
|
23
|
+
Main actions stay hidden before component installation. Afterwards, the toggle, QR generation and Copy pairing link buttons share one row. Copy stays visible but disabled without valid pairing data. From plugin 0.8.3, when pairing data is valid but no QR image was generated, you can copy it and paste it into the App's iroh pairing screen. Copying does not generate another pairing code.
|
|
24
24
|
|
|
25
25
|
To reclaim component storage, turn off iroh remote access, expand the component details and choose **Remove the downloaded iroh component**. This removes only the pinned program downloaded by this plugin, keeping identities, pairings and external companion packages. Later use can reinstall it or reuse a verified external copy. Removal while enabled is refused by the management API as well as the panel.
|
|
26
26
|
|
|
@@ -45,6 +45,12 @@ Before a component release, verify first use with the exact catalog-pinned execu
|
|
|
45
45
|
| `iroh_start_timeout` | Inspect iroh errors in the DSH log and network connectivity, and verify that the pinned component runs; repeated pairing is not a substitute for process diagnosis |
|
|
46
46
|
| Channel `ready` but no phone connects | Check that the App is the full build, the device supports a packaged ABI and the descriptor is fresh. Computer readiness does not establish phone connectivity; a relay-service connection alone does not establish that data uses the relay |
|
|
47
47
|
|
|
48
|
+
## Ready channel but failed mobile customization
|
|
49
|
+
|
|
50
|
+
Desktop `ready` means the local component and endpoint are prepared, not that the phone loaded every manifest, stylesheet, script and event stream. If conversations work but customization fails, distinguish manifest and resource failures using the page notice and contemporaneous redacted HTTP diagnostics. `parser/400/other` does not identify a malformed request; a `transport` reset does not establish a server rejection. See [slow-link diagnostics](SLOW_CONNECTIONS.en.md).
|
|
51
|
+
|
|
52
|
+
If scanning fails while copied content pairs successfully, report the scanner entry, App version and elapsed time since generation separately. Do not upload the descriptor, QR code or pairing key. Channel readiness does not establish a fix; do not disable certificate verification, clear existing pairings or change global proxy settings as a diagnostic shortcut.
|
|
53
|
+
|
|
48
54
|
## VPN, proxies and network environments
|
|
49
55
|
|
|
50
56
|
iroh prefers direct connections with relay fallback. Direct connections use QUIC/UDP; discovery and relays also need their network services to be reachable. The following environment factors **can** interfere; they are troubleshooting directions, not confirmed failure mechanisms for every VPN or network:
|