feat: in-panel logout and change-password widget

- webServer.tapIndex injects a floating widget (logout + change-password
  buttons and a modal) into the panel's index.html; scoped styles, vanilla
  JS, endpoints embedded safely.
- New /panel-auth/change-password endpoint: requires a valid session,
  verifies the old password (failures count toward lockout), enforces
  length/novelty policy, generates a fresh scrypt hash, writes it back to
  the profile patch file, and hot-applies it to the running loader entry.
- Audit: password-change events with per-step results; old-password
  mismatches logged as login-fail/password-change-old-mismatch.
- Config: changePasswordPath, patchFilePath.
- Tests: widget rendering/injection, anonymous rejection, old-password
  mismatch, policy rejection, success flow and credential switch.
This commit is contained in:
dsh
2026-08-16 03:00:47 -04:00
parent 873b712774
commit f9883150e0
3 changed files with 324 additions and 8 deletions
+19 -1
View File
@@ -88,7 +88,25 @@ dsh.example.com {
- panel-auth 的来源校验在 Host 为回环时自动跳过(代理场景);对外域名下的
真实跨站提交仍会被拒绝(`非法请求来源`)。
## 修改密码
## 面板内小组件(登出 / 修改密码
插件通过 `webServer.tapIndex` 在面板页面的右下角注入两个悬浮按钮:
- **退出登录**:跳转 `/panel-auth/logout`,清除 Cookie 并回到登录页。
- **修改密码**:弹窗输入当前密码 + 新密码(≥8 位、不得与旧密码相同),
POST 到 `/panel-auth/change-password`
1. 校验会话(Cookie/Basic)与旧密码(错误计入防爆破);
2. 生成新 scrypt 哈希,**写回 `patchFilePath`**cordis.patch.yml,永续);
3. 通过 loader 热更新运行配置(`live-updated`,无需重启面板);
4. 审计记录 `password-change` 事件(含结果明细)。
- 改密不影响已登录会话(签名密钥不变,Cookie 继续有效)。
- 新增配置项:
```yaml
changePasswordPath: '/panel-auth/change-password'
patchFilePath: '/root/.dsh/profiles/web/cordis.patch.yml'
```
## 修改密码(命令行)
```bash
cd /root/.dsh/profiles/web/panel-auth