dsh-mesh-access 1.4.0 → 1.4.1

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 CHANGED
@@ -157,3 +157,10 @@
157
157
  - 拿不到有效凭据的请求一律 404 伪装(密钥模式)/ 401 弹窗(账号密码模式),WebSocket 升级同样先过门锁。
158
158
  - `x-forwarded-proto` 透传:https 域名下种 cookie 自动带 `Secure`。
159
159
  - frps-setup.sh 不再生成 nginx Basic 账密(认证归插件)。
160
+
161
+ ## 1.4.1 — 修复面板空白
162
+
163
+ - 1.4.0 的 client.js 使用了未声明的 `authMsg` state(补插卡片脚本失败遗留),
164
+ 渲染「入口登录」卡片即抛 `ReferenceError`,导致整个「组网访问」面板空白。
165
+ 已补上 `const [authMsg, setAuthMsg] = react.useState('')`,
166
+ 三种模式(密钥/账号密码/关闭)各完成组件树渲染冒烟验证。
package/README.en.md CHANGED
@@ -52,6 +52,18 @@ Restart the profile. A **组网访问 / Mesh access** entry appears in the left
52
52
  | Public tunnel (optional) | use **your own** server as a public entry point: start/stop frpc, show the public URL, probe it for real |
53
53
  | 第一次用星空组网? | the referral sign-up link and the member-account rule |
54
54
 
55
+ ## Entry auth (since 1.4.0)
56
+
57
+ The lock on the public entry now lives in the plugin panel — the server needs zero auth config:
58
+
59
+ | Mode | Experience | For |
60
+ | --- | --- | --- |
61
+ | Key (recommended) | One-time URL from the panel; that device stays signed in for 30 days, no popup ever | Your own devices |
62
+ | Password | Browser popup once; that device stays signed in for 24 h | Borrowed devices |
63
+ | Off | No lock (only DSH's own token) | Not recommended |
64
+
65
+ Reset the key any time — the old key dies instantly. Changing the password kicks every signed-in device. In key mode, unauthorized requests get a plain 404.
66
+
55
67
  ## HTTP surface
56
68
 
57
69
  The panel is a view over two routes kept deliberately small:
package/README.md CHANGED
@@ -75,6 +75,21 @@ sudo ./tools/frps-setup.sh --port 7000 --http-port 21081
75
75
  完整说明(前置条件、域名/TLS/Basic 认证、故障表、卸载)见 **[docs/VPS.md](docs/VPS.md)**。
76
76
  想让 AI 帮你配:把 **[docs/AI-SETUP.md](docs/AI-SETUP.md)** 整份丢给它,它就知道该跑什么、怎么验证。
77
77
 
78
+ ## 入口登录(1.4.0 起)
79
+
80
+ 公网地址的门锁做在**插件面板**里(「入口登录」卡片),服务器零配置——nginx 不再需要账密:
81
+
82
+ | 模式 | 体验 | 适合 |
83
+ | --- | --- | --- |
84
+ | 密钥(推荐) | 面板给一次性地址,手机打开一次,**30 天内免登录、全程无弹窗** | 自己的设备 |
85
+ | 账号密码 | 浏览器弹窗登录一次,**24 小时内仅该设备免登录**,其他设备各自登录 | 偶尔借别人设备 |
86
+ | 关闭 | 不加门锁(只剩 DSH 自己的 token 一层) | 不推荐 |
87
+
88
+ - 密钥怀疑泄露 → 面板点「重置」,旧密钥立即作废,所有设备重新认证。
89
+ - 改账号密码 → 所有已登录设备立刻下线。
90
+ - 密钥模式下无效请求一律返回 404,不暴露这里有个服务。
91
+ - 认证状态存本机 `~/.config/frp/dsh-mesh-access.json`(侧车文件),密码 scrypt 哈希存储。
92
+
78
93
  ## HTTP 接口
79
94
 
80
95
  面板只是两个接口的外壳,故意做得极小:
@@ -82,6 +97,8 @@ sudo ./tools/frps-setup.sh --port 7000 --http-port 21081
82
97
  ```
83
98
  GET /api/dsh-mesh-access/status → { ok, host:{upstream,port}, interfaces[], mesh[], proxy{...}, referral }
84
99
  POST /api/dsh-mesh-access/proxy → { action:'start' | 'stop', port? }
100
+ GET /api/dsh-mesh-access/tunnel → frpc 隧道状态(1.1.0+)
101
+ GET /api/dsh-mesh-access/auth → 入口登录状态;POST 切换模式 / 改账密 / 重置密钥(1.4.0+)
85
102
  ```
86
103
 
87
104
  不开浏览器也能排查:
package/docs/AI-SETUP.md CHANGED
@@ -9,7 +9,7 @@ their StarVPN/Tailscale/WireGuard network — a public entry point is optional.
9
9
 
10
10
  ## 0. Hard rules
11
11
 
12
- 1. **Never invent credentials.** The frp token and the Basic-auth password are generated by the scripts on the
12
+ 1. **Never invent credentials.** The frp token is generated by the scripts on the
13
13
  human's machine. Do not type your own, do not reuse one from a doc example.
14
14
  2. **Only touch the human's own machines.** The server must be theirs. Do not point `frpc` at a server you cannot
15
15
  justify, and do not run these scripts on a host they have not named.
@@ -30,7 +30,7 @@ phone ──https──> their server: frps ──frp tunnel──> their comput
30
30
  ```
31
31
 
32
32
  - `tools/frps-setup.sh` — runs on the **server** (root). Installs `frps`, writes `/etc/frp/frps.toml`, systemd unit,
33
- firewall rule; with `--domain` also writes the nginx reverse proxy + Let's Encrypt cert + Basic auth.
33
+ firewall rule; with `--domain` also writes the nginx reverse proxy + Let's Encrypt cert (auth lives in the plugin panel since 1.4.0).
34
34
  - `tools/frpc-setup.sh` — runs on the **computer** (normal user). Installs `frpc` if missing, writes
35
35
  `~/.config/frp/frpc.toml`, writes the systemd **user** unit.
36
36
  - The plugin reads `~/.config/frp/frpc.toml` and shows a "public tunnel" card: start / stop / live status / public URL.
@@ -74,7 +74,7 @@ tail -20 ~/.config/frp/frpc.log # expect: "login to server success" + "[d
74
74
 
75
75
  # 4. end to end from outside — plain HTTP entry:
76
76
  curl -s -o /dev/null -w '%{http_code}\n' "http://<server>:21081/" # 401 (DSH wants a token) is correct
77
- # with the domain + Basic auth:
77
+ # with the domain (auth is configured later in the plugin panel):
78
78
  curl -s -o /dev/null -w '%{http_code}\n' -u dsh:<password> "https://<domain>/" # 401 again, still correct
79
79
 
80
80
  # 5. WebSocket path must answer 101, not 403/404 (this is what "keeps reconnecting" looks like when broken):
@@ -98,7 +98,6 @@ the computer shows up on the phone within a second.
98
98
  | `curl http://server:21081/` times out | security group blocks 21081 | console → allow TCP 21081 (and 7000) |
99
99
  | `connection refused` on 21081 | frpc never connected | `journalctl -u frps -n 50`, check token equality |
100
100
  | 502 from nginx | nothing listening on the local port | open the port in the DSH panel; `ss -Hltn \| grep 3081` |
101
- | 500 from nginx | `.dsh_htpasswd` unreadable by the worker | `chown root:<nginx group>` + `chmod 640` |
102
101
  | page loads, then "reconnecting" | WebSocket not forwarded | `proxy_http_version 1.1` + `Upgrade`/`Connection` headers |
103
102
  | `start error: port already used` | two frpc on one `remotePort` | stop the systemd unit **or** the panel tunnel, keep one |
104
103
  | certbot fails | 80 blocked, or DNS not pointing here yet | check A record, open 80, rerun with `--domain` |
package/docs/VPS.md CHANGED
@@ -53,7 +53,7 @@ sudo ./tools/frps-setup.sh --port 7000 --http-port 21081
53
53
  2. 写 `/etc/frp/frps.toml`:`bindPort`、`auth.token`(没给就随机生成 24 位)、日志、本机管理面板 `127.0.0.1:7500`
54
54
  3. 建 `frps.service` 并 enable + start,核对 `:7000` 真的在听
55
55
  4. firewalld / ufw 有就放行 7000
56
- 5. 给了 `--domain` 且有 nginx:写 ACME 探针、申请 Let's Encrypt 证书、写 443 反代、加 Basic 认证(随机密码)
56
+ 5. 给了 `--domain` 且有 nginx:写 ACME 探针、申请 Let's Encrypt 证书、写 443 反代(认证由插件面板「入口登录」接管,服务器不再配账密)
57
57
 
58
58
  `tools/frpc-setup.sh`(你的电脑上,普通用户):
59
59
 
@@ -66,8 +66,10 @@ sudo ./tools/frps-setup.sh --port 7000 --http-port 21081
66
66
  ## 认证是两层
67
67
 
68
68
  1. **DSH 自己的 token**:面板里「访问地址」那一行就是带 `?token=` 的完整地址,换完 cookie 30 天有效。
69
- 2. **你加的入口认证**(推荐):`frps-setup.sh --domain` 会顺手配好 nginx Basic 认证,浏览器打开先弹账号密码框。
70
- 不用 Basic 也可以只暴露 IP:端口——但那样等于把 DSH 登录页直接挂在公网,靠 token 一层兜底。
69
+ 2. **入口认证**(推荐,1.4.0+):装好插件后,在面板「入口登录」卡片里选模式:
70
+ - 密钥(推荐):面板给出带 `?meshkey=` 的一次性地址,手机打开一次,30 天内免登录、无弹窗;可随时重置。
71
+ - 账号密码:浏览器弹窗登录一次,24 小时内仅该设备免登录;改密码会踢掉所有已登录设备。
72
+ 认证状态存本机侧车文件,服务器零配置。
71
73
 
72
74
  想更硬一点:把 nginx 换成 mTLS(客户端证书)或者只允许公司 IP 访问(`allow`/`deny`),这些都在 nginx 那一层做,
73
75
  插件不用改。
package/lib/client.js CHANGED
@@ -103,6 +103,7 @@ window.__ModuleLoader__.load({
103
103
  const [authBusy, setAuthBusy] = react.useState(false)
104
104
  const [authErr, setAuthErr] = react.useState(null)
105
105
  const [authForm, setAuthForm] = react.useState({ username: '', password: '' })
106
+ const [authMsg, setAuthMsg] = react.useState('')
106
107
  const [busy, setBusy] = react.useState(false)
107
108
  const [tunnelBusy, setTunnelBusy] = react.useState(false)
108
109
  const [err, setErr] = react.useState(null)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-mesh-access",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "Control your DSH from your phone: opens a port on the mesh/VPN interface from inside the running server process, so a phone browser gets the same instance and the same session list — no SSH, no second dsh. Also reachable from another PC, a GUI NAS, or a TV box.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",