dsh-mesh-access 1.2.1 → 1.3.0

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
@@ -1,5 +1,13 @@
1
1
  # 更新日志
2
2
 
3
+ ## 1.3.0 — 面板显示登录弹窗状态,讲清账号密码在哪改
4
+
5
+ 用户问「网页的账号密码没有配置项,我上哪知道是啥、也没法改?」——账号密码是服务器端 nginx 的 Basic 认证(`/etc/nginx/.dsh_htpasswd`),插件改不了服务器文件,但至少要把状态和操作说清楚:
6
+
7
+ - 状态区新增第四颗 pill:真实 GET 一次公网入口,`401 + WWW-Authenticate: Basic` → 「有登录弹窗(Basic)」;200/303 → 「无登录弹窗」(此时给出安全提醒:知道地址的人都能打开你的 DSH 登录页);
8
+ - 有弹窗时提示:账号密码是服务器上跑 `tools/frps-setup.sh` 时它打印给你的(默认账号 `dsh`);忘了就 `sudo htpasswd /etc/nginx/.dsh_htpasswd dsh` 重设;
9
+ - 无弹窗时提示:加登录的两条命令(同上)。
10
+
3
11
  ## 1.2.1 — 表单里写清服务器端怎么装
4
12
 
5
13
  用户问「服务器端的 frps / nginx 是面板一键装还是让 AI 装?」——面板够不着你的服务器,写明白:
package/lib/client.js CHANGED
@@ -274,6 +274,10 @@ window.__ModuleLoader__.load({
274
274
  tn.running ? 'frpc 运行中(本插件)' : tn.external ? 'frpc 运行中(外部进程)' : 'frpc 未运行'),
275
275
  h('span', { style: S.pill(Boolean(tn.reachable)) }, h('span', { style: S.dot(Boolean(tn.reachable)) }), tn.reachable ? '公网可达' : '公网不可达'),
276
276
  h('span', { style: S.pill(Boolean(tn.url)) }, h('span', { style: S.dot(Boolean(tn.url)) }), tn.domain ? '域名 ' + tn.domain : tn.remotePort ? '端口 ' + tn.remotePort : '未配置'),
277
+ (tn.reachable && tn.webAuth
278
+ ? h('span', { style: S.pill(tn.webAuth !== 'none') }, h('span', { style: S.dot(tn.webAuth !== 'none') }),
279
+ tn.webAuth === 'basic' ? '有登录弹窗(Basic)' : tn.webAuth === 'none' ? '无登录弹窗' : '有访问控制')
280
+ : null),
277
281
  ),
278
282
  h('div', { style: S.row, marginTop: 12 },
279
283
  h('button', {
@@ -342,6 +346,11 @@ window.__ModuleLoader__.load({
342
346
  ? ' 现在这个隧道是你自己的外部进程在跑(多半是 systemd 单元 dsh-frpc),所以这里显示为「外部进程」并且不让重复启动,免得抢同一个 remotePort。想停:systemctl --user stop dsh-frpc。'
343
347
  : '',
344
348
  ' 组网走中继时 RTT 800–990 ms(最坏 3.7 s),长连接会被心跳判死;你自己的服务器通常 30–60 ms。',
349
+ tn.reachable && tn.webAuth === 'none'
350
+ ? ' 注意:这个入口现在没有登录弹窗,知道地址的人都能打开你的 DSH 登录页。给入口加登录:SSH 到服务器跑 tools/frps-setup.sh --domain 你的域名(会生成随机账号密码并打印出来);已有账号想改密码:sudo htpasswd /etc/nginx/.dsh_htpasswd dsh。账号密码是服务器端的东西,面板这里只负责告诉你状态,改要上服务器。'
351
+ : tn.webAuth === 'basic'
352
+ ? ' 打开地址时浏览器会先弹账号密码框(nginx Basic 认证)。账号密码是你在服务器上跑 tools/frps-setup.sh 时它打印给你的(默认账号 dsh);忘了就上服务器 sudo htpasswd /etc/nginx/.dsh_htpasswd dsh 重设。'
353
+ : '',
345
354
  ),
346
355
  tn.log && tn.log.length
347
356
  ? h('div', { style: { ...S.hint, ...S.mono, marginTop: 8, whiteSpace: 'pre-wrap', opacity: 0.5 } }, tn.log.slice(-4).join('\n'))
package/lib/index.js CHANGED
@@ -627,8 +627,18 @@ transport.useEncryption = true
627
627
  const port = t.domain ? 443 : t.remotePort
628
628
  const snap = tunnelSnapshot()
629
629
  const reachable = await probe(host, port)
630
+ let webAuth = null
631
+ if (reachable) {
632
+ try {
633
+ const r = await fetch(`${t.domain ? 'https' : 'http'}://${host}${t.domain ? '' : ':' + t.remotePort}/`, { redirect: 'manual', signal: AbortSignal.timeout(4000) })
634
+ const www = r.headers.get('www-authenticate') || ''
635
+ if (r.status === 401 && /basic/i.test(www)) webAuth = 'basic'
636
+ else if (r.status === 401 || r.status === 403) webAuth = 'other'
637
+ else webAuth = 'none'
638
+ } catch { webAuth = null }
639
+ }
630
640
  // external:公网已经通了,但 frpc 不是这个进程拉起来的(用户自己的 systemd 单元在跑)
631
- return json(res, 200, { ok: true, ...snap, reachable, external: reachable && !snap.running })
641
+ return json(res, 200, { ok: true, ...snap, reachable, webAuth, external: reachable && !snap.running })
632
642
  }
633
643
  if (req.method !== 'POST') return json(res, 405, { ok: false, error: 'GET or POST only' })
634
644
  let body = {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-mesh-access",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
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",