dsh-mobile 0.1.0-alpha.1 → 0.1.0-alpha.10

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/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="https://unpkg.com/dsh-mobile@0.1.0-alpha.1/assets/brand/repository-hero.png" alt="A lively whale girl using a phone beside a desktop running DSH" width="100%">
2
+ <img src="https://unpkg.com/dsh-mobile@latest/assets/brand/repository-hero.png" alt="A lively whale girl using a phone beside a desktop running DSH" width="100%">
3
3
  </p>
4
4
 
5
5
  <h1 align="center">DSH Mobile</h1>
@@ -26,6 +26,8 @@
26
26
 
27
27
  DSH Mobile reuses DSH's own Web application, sessions, and plugin slots. It adds an authenticated HTTPS gateway, device pairing, session revocation, and a small responsive Client face. Use the Android shell without browser chrome, or open the same LAN address directly in any mobile browser.
28
28
 
29
+ The mobile client is self-editable: ask DSH in an ordinary conversation to change `mobile.css` for presentation or `mobile.js` for behavior, keep the phone open, and watch the Android app or mobile browser apply the result automatically within about one second.
30
+
29
31
  ## Features
30
32
 
31
33
  | Capability | Android app | Mobile browser |
@@ -33,7 +35,7 @@ DSH Mobile reuses DSH's own Web application, sessions, and plugin slots. It adds
33
35
  | Live DSH Web UI | Yes | Yes |
34
36
  | Authenticated HTTPS LAN access | Yes | Yes |
35
37
  | One-time device pairing | Yes | Yes |
36
- | Custom mobile CSS | Yes | Yes |
38
+ | Extend mobile UI and Web functions through a DSH conversation with live preview | Yes | Yes |
37
39
  | File selection and downloads | Yes | Browser-dependent |
38
40
  | iOS native app | Not yet | Safari can use the Web UI |
39
41
 
@@ -41,99 +43,94 @@ Host-native actions such as opening desktop files remain subject to stock DSH an
41
43
 
42
44
  ## Quick start
43
45
 
44
- Prerequisites: stock DSH can run through either an installed `dsh` command or the source checkout's `pnpm dsh` script, and the computer and Android device share a trusted private LAN. DSH requires Node.js 22.19.x or Node.js 24 or later.
45
-
46
- ### Choose the DSH command
47
-
48
- If `dsh` is available in the terminal, use the commands below as written.
49
-
50
- If you cloned the DSH source and do not have a global `dsh` command, first install its workspace dependencies from the DSH repository root:
46
+ Use the first block when `dsh` is available globally:
51
47
 
52
48
  ```powershell
53
- corepack enable
54
- pnpm install
49
+ dsh plugin --profile web add dsh-mobile
50
+ dsh plugin --profile web exec dsh-mobile setup
51
+ dsh --profile web
55
52
  ```
56
53
 
57
- Then replace `dsh` in every example with `pnpm dsh`. The complete source-checkout flow is:
54
+ If you cloned the DSH source, run the second block from its repository root:
58
55
 
59
56
  ```powershell
57
+ corepack enable
58
+ pnpm install
60
59
  pnpm dsh plugin --profile web add dsh-mobile
61
60
  pnpm dsh plugin --profile web exec dsh-mobile setup
62
61
  pnpm dsh --profile web
63
62
  ```
64
63
 
65
- You may also invoke the source checkout from another directory without creating a global command:
64
+ Both paths install the public npm package into stock DSH without patching its source. Setup remembers the selected LAN interface, creates one local CA, stores plugin data under `$DSH_HOME/mobile-access/`, and on Windows requests administrator approval once for TCP/UDP rules limited to Windows' dynamic `LocalSubnet`. Use `--no-firewall` only when those rules are managed separately. While DSH is running, the plugin follows DHCP, Wi-Fi, and phone-hotspot address changes on that interface, rebinds the gateway, and signs a matching server certificate from the same CA. Paired devices and the Android app-private certificate pin remain valid.
66
65
 
67
- ```powershell
68
- pnpm --dir "<path-to-deepseek-harness>" dsh --profile web
69
- ```
66
+ 1. Open the Mobile card in the lower-left corner of the desktop DSH UI.
67
+ 2. Start access and select **Create pairing key**. The fingerprint-bound key is copied to the clipboard; the same card also shows a complete browser link.
68
+ 3. Open the Android app, select **Scan**, then select the discovered DSH. Paste the key and connect.
69
+ 4. Connect. The app fingerprint-pins this DSH inside its encrypted private storage; it does not install a CA into Android settings. Mobile browsers still require an HTTPS certificate they already trust.
70
70
 
71
- ### 1. Install
71
+ The key and browser link expire after two minutes and work once. After pairing, Android stores a revocable device credential encrypted by Android Keystore. The app can rediscover the same DSH installation on the default port after its LAN address changes and renew its short Web session without another key. Browser profiles still pair separately.
72
72
 
73
- Install the public package directly from npm:
73
+ ## Everyday control
74
74
 
75
- ```powershell
76
- dsh plugin --profile web add dsh-mobile
77
- ```
75
+ The Mobile card remains in DSH's lower-left corner. Stopping mobile access closes only the external HTTPS listener and active mobile sessions; the local DSH Web UI keeps running. Starting it again does not reinstall the plugin.
78
76
 
79
- Repository collaborators and offline installations may instead install an exact tarball:
77
+ The two access modes are equivalent:
80
78
 
81
- ```powershell
82
- dsh plugin --profile web add "<path-to-dsh-mobile.tgz>"
83
- ```
79
+ - Android app: a thin system WebView shell without browser address and tab bars.
80
+ - Mobile browser: open the setup origin directly; no app installation is required.
84
81
 
85
- No DSH source patch or custom DSH build is required.
82
+ While Mobile Access is running, DSH publishes a small DNS-SD/mDNS service and a periodic UDP announcement. Each contains only the computer name, HTTPS origin, port, protocol version, and stable installation identifier. Android listens to both, also sends the original UDP query, and keeps HTTPS `/24` probing as a last compatibility fallback. Results are merged by installation identifier, so a new Wi-Fi or hotspot address updates the existing device instead of requiring another pairing. No pairing key, CA, device token, Cookie, or DSH data is discoverable. The first screen contains only Scan and the discovered DSH list; the pairing-key field appears after selecting one result.
86
83
 
87
- ### 2. Run setup once
84
+ After the user selects a result and enters its fingerprint-bound pairing key, the app fetches the public CA from that selected HTTPS origin without sending the key or any credential. It keeps the CA only inside the app and accepts the DSH certificate only when its chain, hostname, validity, and SHA-256 fingerprint match the key and discovered installation identifier. Nothing is installed into Android's system trust settings. Mobile browsers cannot use this app-private trust and therefore still need an already trusted certificate.
88
85
 
89
- ```powershell
90
- dsh plugin --profile web exec dsh-mobile setup
91
- ```
86
+ ## Customize the mobile Web UI
92
87
 
93
- The setup command selects a private LAN address, creates a local TLS certificate, and stores all plugin-owned configuration under `$DSH_HOME/mobile-access/`. If more than one LAN address is available, select one explicitly:
88
+ This is a same-origin Web extension surface, not a fixed theme editor. DSH can edit two files on the computer:
94
89
 
95
- ```powershell
96
- dsh plugin --profile web exec dsh-mobile setup --address 192.168.1.20
97
- ```
90
+ - `mobile.css` controls layout, visual hierarchy, safe areas, typography, and responsive behavior.
91
+ - `mobile.js` mounts mobile-only DOM and behavior, can use browser capabilities, and can call the same-origin DSH Web API as the paired page.
98
92
 
99
- For a non-default DSH Web port:
93
+ That is enough to build a one-handed command dock, a gesture command palette, a session dashboard, terminal shortcut keys, a floating context panel, voice input, a camera or QR workflow, or a completely different mobile navigation model. Camera, microphone, notifications, and similar capabilities still require browser or Android permission.
100
94
 
101
- ```powershell
102
- dsh plugin --profile web exec dsh-mobile setup --dsh-port 39080
103
- dsh --profile web --port 39080
104
- ```
95
+ The easiest workflow stays entirely inside DSH. In a conversation with filesystem write access, try a broad request:
105
96
 
106
- ### 3. Start and pair
97
+ ```text
98
+ Turn DSH Mobile into a one-handed field console by editing
99
+ $DSH_HOME/mobile-access/mobile.css and mobile.js.
107
100
 
108
- ```powershell
109
- dsh --profile web
101
+ Add a bottom command dock, swipe shortcuts for switching conversations,
102
+ a push-to-talk button when the browser supports speech input, and a collapsible
103
+ session monitor. Keep every feature mobile-only. Register JavaScript through
104
+ window.dshMobile.register(), return a cleanup function, and do not modify DSH source.
110
105
  ```
111
106
 
112
- 1. Copy the generated `dsh-mobile-ca.cer` to Android and install it as a user CA certificate.
113
- 2. Open the Mobile card in the lower-left corner of the desktop DSH UI.
114
- 3. Start access and create a pairing link. The link is copied to the clipboard.
115
- 4. Paste the link into the Android app, or open it directly in a mobile browser.
116
-
117
- Pairing links expire after two minutes and work once. The app and each browser have separate cookie stores, so pair them separately.
107
+ Keep the phone page open while DSH edits. The Android app and mobile browser check both authenticated files once per second and apply saved changes automatically—no DSH restart, new pairing, or manual page refresh. Invalid JavaScript does not replace the last successfully mounted extension.
118
108
 
119
- ## Everyday control
109
+ Setup creates:
120
110
 
121
- The Mobile card remains in DSH's lower-left corner. Stopping mobile access closes only the external HTTPS listener and active mobile sessions; the local DSH Web UI keeps running. Starting it again does not reinstall the plugin.
111
+ ```text
112
+ $DSH_HOME/mobile-access/mobile.css
113
+ $DSH_HOME/mobile-access/mobile.js
114
+ ```
122
115
 
123
- The two access modes are equivalent:
116
+ The files load only through the authenticated mobile gateway. They do not modify the DSH installation and survive DSH upgrades. Continue the same conversation with requests such as “turn the dock into a radial menu,” “add a full-screen monitoring view,” or “use the camera to prepare an attachment,” and inspect each revision directly on the phone.
124
117
 
125
- - Android app: a thin system WebView shell without browser address and tab bars.
126
- - Mobile browser: open the setup origin directly; no app installation is required.
118
+ `mobile.js` uses a small lifecycle entry point:
127
119
 
128
- ## Customize the mobile Web UI
120
+ ```js
121
+ window.dshMobile.register(({ root, document, request }) => {
122
+ const workspace = document.createElement('section')
123
+ workspace.ariaLabel = 'My mobile workspace'
124
+ root.append(workspace)
129
125
 
130
- Setup creates:
126
+ // Build any mobile Web UI and behavior inside workspace. Use request()
127
+ // for same-origin DSH API calls with the paired Session and CSRF protection.
131
128
 
132
- ```text
133
- $DSH_HOME/mobile-access/mobile.css
129
+ return () => workspace.remove()
130
+ })
134
131
  ```
135
132
 
136
- This file loads only through the authenticated mobile gateway. It does not modify the DSH installation and survives DSH upgrades.
133
+ The supplied `root` isolates mobile-only DOM, while `request()` rejects cross-origin targets and carries the paired session plus the gateway's CSRF header. An extension may still use ordinary secure-context browser APIs directly when the device grants permission.
137
134
 
138
135
  Basic theme controls:
139
136
 
@@ -154,7 +151,7 @@ Narrow-screen adjustments:
154
151
  }
155
152
  ```
156
153
 
157
- Prefer CSS variables, spacing, typography, and touch sizes. Do not depend on generated class names. Delete `mobile.css` and refresh to return to the built-in defaults.
154
+ Prefer stable Web APIs and DSH extension points over generated class names. Delete `mobile.css` to restore the visual defaults and replace `mobile.js` with an empty registered mount to remove custom behavior; the open phone page updates automatically.
158
155
 
159
156
  ## A native DSH plugin
160
157
 
@@ -169,10 +166,11 @@ flowchart LR
169
166
  ## Security model
170
167
 
171
168
  - The gateway accepts only the selected private LAN CIDR, exact Host, and same-origin browser requests.
172
- - The Android app never bypasses TLS validation. The certificate must cover the LAN address in use.
169
+ - The Android app pins the pairing-key CA privately. Native requests use that trust anchor; WebView accepts only an otherwise-untrusted leaf signed by it for the exact host and validity period.
173
170
  - Pairing creates an HttpOnly session; devices and active sessions can be revoked from the computer.
174
171
  - Control and device-management routes are loopback-only.
175
172
  - Authentication happens before any request reaches the stock DSH loopback server. DSH itself is never rebound to `0.0.0.0`.
173
+ - `mobile.js` runs as application code inside the paired DSH page. Only let trusted DSH conversations edit it, and review generated integrations before keeping them.
176
174
 
177
175
  Do not expose this gateway through public Wi-Fi, port forwarding, a public IP, or an untrusted VPN. See [SECURITY.md](SECURITY.md).
178
176
 
package/README.zh.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="https://unpkg.com/dsh-mobile@0.1.0-alpha.1/assets/brand/repository-hero.png" alt="鲸鱼娘拿着手机连接桌面上的 DSH" width="100%">
2
+ <img src="https://unpkg.com/dsh-mobile@latest/assets/brand/repository-hero.png" alt="鲸鱼娘拿着手机连接桌面上的 DSH" width="100%">
3
3
  </p>
4
4
 
5
5
  <h1 align="center">DSH Mobile</h1>
@@ -26,6 +26,8 @@
26
26
 
27
27
  DSH Mobile 不是另一套远程控制面板。插件直接复用 DSH 自己的 Web 应用、会话和插件槽位,在外层增加 HTTPS、设备配对、会话撤销和移动端样式。你可以用 Android App 获得无浏览器栏的体验,也可以直接用手机浏览器访问同一个局域网地址。
28
28
 
29
+ 移动端客户端可以“自己改自己”:直接在普通 DSH 对话中要求 DSH 修改负责外观的 `mobile.css` 或负责功能的 `mobile.js`,手机页面保持打开,Android App 和手机浏览器通常会在一秒内自动应用结果。
30
+
29
31
  ## 主要能力
30
32
 
31
33
  | 能力 | Android App | 手机浏览器 |
@@ -33,7 +35,7 @@ DSH Mobile 不是另一套远程控制面板。插件直接复用 DSH 自己的
33
35
  | 实时访问 DSH Web UI | 支持 | 支持 |
34
36
  | HTTPS 局域网入口 | 支持 | 支持 |
35
37
  | 一次性设备配对 | 支持 | 支持 |
36
- | 自定义移动端 CSS | 支持 | 支持 |
38
+ | 在 DSH 对话中扩展移动 UI与网页功能并实时预览 | 支持 | 支持 |
37
39
  | 文件选择与下载 | 支持 | 由浏览器决定 |
38
40
  | iOS | 暂不支持 | 可用 Safari 访问网页 |
39
41
 
@@ -41,99 +43,93 @@ DSH Mobile 不是另一套远程控制面板。插件直接复用 DSH 自己的
41
43
 
42
44
  ## 快速开始
43
45
 
44
- 前置条件:能够通过已经安装的 `dsh` 命令或源码仓库中的 `pnpm dsh` 启动原生 DSH,电脑和 Android 手机位于同一可信局域网。DSH 需要 Node.js 22.19.x,或 Node.js 24 以上版本。
45
-
46
- ### 选择 DSH 命令
47
-
48
- 如果终端中能够直接运行 `dsh`,后续命令保持原样即可。
49
-
50
- 如果你直接克隆了 DSH 源码,没有全局 `dsh` 命令,请先在 DSH 源码根目录安装工作区依赖:
46
+ 终端中可以直接运行 `dsh` 时,使用第一组命令:
51
47
 
52
48
  ```powershell
53
- corepack enable
54
- pnpm install
49
+ dsh plugin --profile web add dsh-mobile
50
+ dsh plugin --profile web exec dsh-mobile setup
51
+ dsh --profile web
55
52
  ```
56
53
 
57
- 然后把后续示例中的 `dsh` 全部替换为 `pnpm dsh`。源码版的完整快速启动命令如下:
54
+ 如果你直接克隆了 DSH 源码,则在 DSH 源码根目录使用第二组命令:
58
55
 
59
56
  ```powershell
57
+ corepack enable
58
+ pnpm install
60
59
  pnpm dsh plugin --profile web add dsh-mobile
61
60
  pnpm dsh plugin --profile web exec dsh-mobile setup
62
61
  pnpm dsh --profile web
63
62
  ```
64
63
 
65
- 如果当前终端不在 DSH 源码目录,也不需要创建全局命令:
64
+ 两种方式都会把公开 npm 包安装到原生 DSH,不修改 DSH 源码。设置向导会记住所选局域网网卡、生成一份稳定的本地 CA,并把插件数据保存到 `$DSH_HOME/mobile-access/`。Windows 只在首次设置时请求管理员批准两条受动态 `LocalSubnet` 限制的 TCP/UDP 规则;只有自行管理规则时才使用 `--no-firewall`。DSH 运行期间,如果该网卡因 DHCP、切换 Wi-Fi 或手机热点而改变地址,插件会自动重绑网关,并用同一 CA 签发匹配的新服务器证书;已有设备配对和 Android App 私有证书固定不会失效。
66
65
 
67
- ```powershell
68
- pnpm --dir "<DSH源码目录>" dsh --profile web
69
- ```
66
+ 1. 在电脑 DSH 左下角打开“移动端”卡片。
67
+ 2. 确认服务已开启,点击“生成配对密钥”。绑定 CA 指纹的密钥会复制到剪贴板,同一卡片也会显示完整的浏览器链接。
68
+ 3. 打开 Android App,点击“扫描”并选择发现的 DSH,再粘贴密钥连接。
69
+ 4. 直接连接。App 会把这台 DSH 的证书指纹固定在自身加密存储中,不会向 Android 系统安装 CA。手机浏览器仍需要它本身已经信任的 HTTPS 证书。
70
70
 
71
- ### 1. 安装插件
71
+ 密钥和浏览器链接两分钟内有效且只能使用一次。配对后,Android 会用 Android Keystore 加密保存可随时撤销的设备凭据。局域网 IP 变化后,App 能在默认端口重新找到同一个 DSH,并自动续期短期 Web 会话,不需要新密钥。浏览器仍需单独配对。
72
72
 
73
- 直接从公开 npm 安装:
73
+ ## 日常使用
74
74
 
75
- ```powershell
76
- dsh plugin --profile web add dsh-mobile
77
- ```
75
+ 安装后,“移动端”卡片会常驻 DSH 左下角。关闭移动访问只会停止外部 HTTPS 监听并断开移动会话,不会停止 DSH 本身;重新开启不需要再次安装插件。
78
76
 
79
- 仓库协作者或离线环境也可以安装指定 tarball:
77
+ 手机有两种等价入口:
80
78
 
81
- ```powershell
82
- dsh plugin --profile web add "<插件安装包路径>"
83
- ```
79
+ - Android App:使用系统 WebView 打开同一 DSH 页面,没有浏览器地址栏和标签栏。
80
+ - 手机浏览器:直接访问向导显示的 `https://局域网地址:端口`,无需安装 App。
84
81
 
85
- 这两种方式都使用 DSH 官方插件命令,不需要修改或替换 DSH 源码。
82
+ “移动访问”运行时,DSH 会同时发布小型 DNS-SD/mDNS 服务和周期性 UDP 公告。二者只包含电脑名称、HTTPS 地址、端口、协议版本和稳定安装标识。Android 同时监听两种公告,也保留原有的主动 UDP 查询,最后再以 HTTPS `/24` 网段探测兼容特殊热点。结果按安装标识合并,因此切换 Wi-Fi、热点或 DHCP 地址后只会更新同一设备的 IP,不需要重新配对。发现阶段不会传输配对密钥、CA、设备令牌、Cookie 或任何 DSH 数据。首页仍然只有扫描按钮和设备列表,点击设备后才显示密钥输入框。
86
83
 
87
- ### 2. 运行一次设置向导
84
+ 用户选中设备并输入带指纹的配对密钥后,App 才从所选 HTTPS 地址获取公开 CA;这个引导请求不会携带密钥或任何凭据。App 只把 CA 保存在自身加密存储中,并且仅在证书链、主机名、有效期和 SHA-256 指纹同时匹配密钥及安装标识时连接,不会向 Android 系统信任设置安装任何内容。手机浏览器无法使用这份 App 私有信任,因此仍需浏览器本身已信任的 HTTPS 证书。
88
85
 
89
- ```powershell
90
- dsh plugin --profile web exec dsh-mobile setup
91
- ```
86
+ ## 自定义移动端 Web UI
92
87
 
93
- 向导会自动选择唯一的私有局域网地址,生成本地 TLS 证书,并把配置保存到 `$DSH_HOME/mobile-access/`。如果电脑有多个可用网卡,向导会列出候选地址并要求明确选择:
88
+ 这不是一个只能换颜色的主题编辑器,而是与 DSH 页面同源的 Web 扩展面。电脑上的 DSH 可以编辑两个文件:
94
89
 
95
- ```powershell
96
- dsh plugin --profile web exec dsh-mobile setup --address 192.168.1.20
97
- ```
90
+ - `mobile.css` 控制布局、视觉层级、安全区、字体和响应式行为。
91
+ - `mobile.js` 挂载移动端专属 DOM 与交互,可以使用浏览器能力,也可以用已配对页面的身份调用同源 DSH Web API。
98
92
 
99
- 如果 DSH Web 使用非默认端口,也可以一次指定:
93
+ 自由度并不限于几个预设组件。你可以让 DSH 创建单手指令坞、手势命令面板、会话仪表盘、终端快捷键、悬浮上下文面板、语音输入、相机或二维码工作流,乃至完全不同的移动端导航。相机、麦克风、通知等能力仍需要浏览器或 Android 授权。
100
94
 
101
- ```powershell
102
- dsh plugin --profile web exec dsh-mobile setup --dsh-port 39080
103
- dsh --profile web --port 39080
104
- ```
95
+ 最简单的方式是不离开 DSH。打开一个具备文件写入权限的 DSH 对话,给它一个更大胆的目标:
105
96
 
106
- ### 3. 启动、配对与连接
97
+ ```text
98
+ 请编辑 $DSH_HOME/mobile-access/mobile.css 和 mobile.js,
99
+ 把 DSH Mobile 改造成适合单手操作的现场工作台。
107
100
 
108
- ```powershell
109
- dsh --profile web
101
+ 增加底部指令坞、左右滑动切换会话、浏览器支持时可用的按住说话按钮,
102
+ 以及可折叠的会话监控面板。所有功能只在移动端出现;JavaScript 通过
103
+ window.dshMobile.register() 注册并返回清理函数,不要修改 DSH 源码。
110
104
  ```
111
105
 
112
- 1. 将向导输出的 `dsh-mobile-ca.cer` 复制到 Android,并在系统设置中安装为用户 CA 证书。
113
- 2. 在电脑 DSH 左下角打开“移动端”卡片。
114
- 3. 确认服务已开启,点击“生成配对链接”。链接会复制到剪贴板。
115
- 4. 在 Android App 中粘贴链接,或直接在手机浏览器中打开链接。
116
-
117
- 配对链接两分钟内有效且只能使用一次。App 与浏览器拥有各自的 Cookie 存储,因此需要分别配对。
106
+ DSH 修改文件时让手机页面保持打开。Android App 和手机浏览器每秒检查一次这两个已认证文件,保存后的变化会自动应用,不需要重启 DSH、重新配对或手动刷新页面。JavaScript 写错时会保留上一次成功挂载的功能。
118
107
 
119
- ## 日常使用
108
+ 设置向导会创建:
120
109
 
121
- 安装后,“移动端”卡片会常驻 DSH 左下角。关闭移动访问只会停止外部 HTTPS 监听并断开移动会话,不会停止 DSH 本身;重新开启不需要再次安装插件。
110
+ ```text
111
+ $DSH_HOME/mobile-access/mobile.css
112
+ $DSH_HOME/mobile-access/mobile.js
113
+ ```
122
114
 
123
- 手机有两种等价入口:
115
+ 它们只通过已认证的移动网关加载,不修改 DSH 安装目录,升级或卸载 DSH 时也不会覆盖。你可以继续在同一个对话中说“把指令坞改成环形菜单”“增加全屏监控视图”或“用相机准备附件”,并直接在手机上观察每次修改。
124
116
 
125
- - Android App:使用系统 WebView 打开同一 DSH 页面,没有浏览器地址栏和标签栏。
126
- - 手机浏览器:直接访问向导显示的 `https://局域网地址:端口`,无需安装 App。
117
+ `mobile.js` 只有一个很小的生命周期入口:
127
118
 
128
- ## 自定义移动端 Web UI
119
+ ```js
120
+ window.dshMobile.register(({ root, document, request }) => {
121
+ const workspace = document.createElement('section')
122
+ workspace.ariaLabel = '我的移动工作台'
123
+ root.append(workspace)
129
124
 
130
- 设置向导会创建:
125
+ // 在 workspace 中构建任意移动 Web UI 和交互。调用同源 DSH API 时使用
126
+ // request(),它会携带已配对 Session 和 CSRF 防护信息。
131
127
 
132
- ```text
133
- $DSH_HOME/mobile-access/mobile.css
128
+ return () => workspace.remove()
129
+ })
134
130
  ```
135
131
 
136
- 它只在通过移动网关访问时加载,不修改 DSH 安装目录,升级或卸载 DSH 时也不会覆盖它。修改后刷新手机页面即可看到效果。
132
+ 传入的 `root` 用来承载移动端专属 DOM;`request()` 会拒绝跨源目标,并自动携带已配对会话和网关 CSRF 请求头。需要设备权限的能力仍可直接使用安全上下文中的标准浏览器 API。
137
133
 
138
134
  ### 最简单的主题调整
139
135
 
@@ -160,7 +156,7 @@ $DSH_HOME/mobile-access/mobile.css
160
156
  }
161
157
  ```
162
158
 
163
- 建议优先调整 CSS 变量、字体比例、间距和触控尺寸,不要依赖构建后生成的类名。写错样式不会影响 Host 网关;删除 `mobile.css` 后刷新即可恢复插件默认样式。
159
+ 建议优先使用稳定的 Web API 和 DSH 扩展点,不要依赖构建后生成的类名。删除 `mobile.css` 可恢复默认外观;将 `mobile.js` 替换为空的注册函数即可移除自定义功能,打开的手机页面会自动更新。
164
160
 
165
161
  ## 为什么符合 DSH 的插件理念
166
162
 
@@ -175,10 +171,11 @@ flowchart LR
175
171
  ## 安全模型
176
172
 
177
173
  - 网关只接受设置向导选定的私有局域网 CIDR、精确 Host 和同源浏览器请求。
178
- - Android App 不跳过 TLS 校验;证书必须覆盖实际访问的局域网 IP。
174
+ - Android App 在自身内部固定配对密钥对应的 CA;原生请求使用该信任锚,WebView 只接受它为精确主机和有效期签发的服务器证书。
179
175
  - 配对设备获得短期 HttpOnly Session,设备和会话都可在电脑端撤销。
180
176
  - 管理接口只允许从电脑回环地址访问,移动端无法打开、关闭网关或管理其他设备。
181
177
  - 外层网关在认证后才代理到原生 DSH 的回环端口,不会把 DSH 自身绑定到 `0.0.0.0`。
178
+ - `mobile.js` 会作为应用代码在已配对的 DSH 页面中运行。只允许可信的 DSH 对话编辑它,并在长期保留前检查生成的集成。
182
179
 
183
180
  不要在公共 Wi-Fi、端口转发、公网 IP 或不可信 VPN 中开放本插件。更多说明见 [SECURITY.md](SECURITY.md)。
184
181
 
package/SECURITY.md CHANGED
@@ -15,12 +15,15 @@ The maintainer will acknowledge a complete report within seven days. Publication
15
15
  ## Deployment requirements
16
16
 
17
17
  - Keep the ordinary DSH Web listener on loopback.
18
- - Expose only the plugin-owned HTTPS listener to the LAN.
19
- - Use a certificate trusted by every client platform; never instruct a WebView to ignore TLS errors.
18
+ - Expose only the plugin-owned HTTPS listener to the LAN.
19
+ - DNS-SD/mDNS, periodic UDP announcements, active UDP query replies, and HTTPS discovery return only the device name, public HTTPS origin, port, protocol version, and stable non-secret installation identifier. Discovery never returns the CA, a pairing key, a device token, Cookies, credentials, or private configuration.
20
+ - Only after a user selects a device and enters the fingerprint-bound pairing key may Android fetch the public CA from that exact HTTPS origin. The bootstrap GET sends no key or credential. The app retains the CA in its encrypted credential record and never adds it to Android's system trust settings. Native requests use a private trust store; WebView accepts only the otherwise-untrusted leaf signed by that CA, for the exact origin and validity period. Every other TLS error is cancelled.
21
+ - Browser clients require a certificate trusted by that browser platform. Android uses the pairing-key-bound app-private CA. Its WebView exception is restricted to `SSL_UNTRUSTED` for an exact-origin, currently valid leaf signed by that CA; hostname, validity, signature, and every other TLS error remain fail-closed.
20
22
  - Keep pairing closed except during a short local onboarding action.
21
23
  - Revoke a lost device immediately and rotate the device registry if credential theft is suspected.
22
24
  - Do not expose the gateway directly to the public Internet.
23
25
  - Treat every paired device as a fully trusted operator. Stock DSH methods reached through the authenticated loopback proxy may read configuration or run tools with the desktop user's authority.
26
+ - Treat `mobile.js` as application code with the paired page's same-origin authority. Restrict write access to trusted host-side DSH sessions and review generated API calls or browser-permission use.
24
27
 
25
28
  ## Known alpha limitation
26
29
 
Binary file
package/cordis.patch.yml CHANGED
@@ -9,6 +9,7 @@
9
9
  stateFile: !!js dshHomePath('mobile-access/devices.json')
10
10
  controlFile: !!js dshHomePath('mobile-access/control.json')
11
11
  customCssFile: !!js dshHomePath('mobile-access/mobile.css')
12
+ customScriptFile: !!js dshHomePath('mobile-access/mobile.js')
12
13
  initiallyEnabled: false
13
14
  listenHost: 127.0.0.1
14
15
  listenPort: 3443