|
@@ -0,0 +1,147 @@
|
|
|
|
|
+# 第三轮审计整改 · R3 恢复组(R3-10 / R3-3 / R3-2)改动说明
|
|
|
|
|
+
|
|
|
|
|
+## ① 头部
|
|
|
|
|
+
|
|
|
|
|
+| 项 | 值 |
|
|
|
|
|
+|---|---|
|
|
|
|
|
+| 对照网址 | http://39.97.59.228:8013/hrx/mky-vent-base/compare/master...fix/audit-r3-restore-20260921 |
|
|
|
|
|
+| 依据文档 | `代码审核-第三轮-mky-vent-base-20260921.md`(B 批·修复恢复组) |
|
|
|
|
|
+| 分支 | `fix/audit-r3-restore-20260921` |
|
|
|
|
|
+| 基线 | `upstream/master` = `4e311cb6`(behind=0,分支起点) |
|
|
|
|
|
+| 日期 | 2026-09-21(Asia/Shanghai) |
|
|
|
|
|
+| 交付版本 | 本地提交,未推送 |
|
|
|
|
|
+| 状态 | 已完成自测(静态检查通过),**未推送、未部署**,待人工审核 |
|
|
|
|
|
+
|
|
|
|
|
+> **总原则**:本分支只恢复「地址配置化 / 凭据外置」两类**形态**,**不动自动登录/免密流程**。
|
|
|
|
|
+> 恢复来源为 09-14 已被人工审核"采纳"、但被团队 `7e9858ec`(回滚 13 文件)/`c913dbf9` 回退的
|
|
|
|
|
+> `4b94efbd`、`dd5e7d80`、`8f87ade5` 三个提交的内容。
|
|
|
|
|
+> 红线文件 `src/hooks/vent/useAutoLogin.ts`、`src/router/guard/permissionGuard.ts`、`src/store/modules/user.ts`
|
|
|
|
|
+> 及 `fireBD.vue`/`fire-green.vue` 的 `?mock-login=1` 链接**均未改动**(`git diff` 可证)。
|
|
|
|
|
+
|
|
|
|
|
+## ② 提交清单
|
|
|
|
|
+
|
|
|
|
|
+| # | Hash | 标题 |
|
|
|
|
|
+|---|---|---|
|
|
|
|
|
+| 1 | `021f3061` | [Fix R3-10] 恢复 /modelreq 相对路径与 glob.wsUrl(去硬编码 IP:端口) |
|
|
|
|
|
+| 2 | `22ce77a6` | [Fix R3-3] autoLoginToken 回空值(凭据外置,部署注入) |
|
|
|
|
|
+| 3 | `23f5f95a` | [Fix R3-2] .env 删除 mock 免密凭据默认值(外置部署注入) |
|
|
|
|
|
+| 4 | (本文档) | [Docs] 第三轮审计 R3 恢复组改动说明 |
|
|
|
|
|
+
|
|
|
|
|
+## ③ 改动面
|
|
|
|
|
+
|
|
|
|
|
+7 个代码文件 + 本说明(`git diff --stat` 实测:35 插入 / 13 删除):
|
|
|
|
|
+
|
|
|
|
|
+| 文件 | 改动 |
|
|
|
|
|
+|---|---|
|
|
|
|
|
+| `public/mxcad/mxServerConfig.json` | `saveDwgUrl` 硬编码 IP:端口 → 站点相对路径 `/modelreq/...`;`?saveDwgUrl` 说明注释写清来历 |
|
|
|
|
|
+| `src/views/vent/home/configurable/configurable.data.ts` | 3 处 mp4 `link`(mainFan/fanLocal/gate)硬编码 IP:端口 → 相对路径,各加说明注释 |
|
|
|
|
|
+| `src/layouts/default/header/components/VoiceBroadcast.vue` | WS 端点恢复读 `glob.wsUrl` + 加固(见 ④-3) |
|
|
|
|
|
+| `src/layouts/default/header/components/VoiceBroadcastGsd.vue` | 同上 |
|
|
|
|
|
+| `public/fileEdit.html` | OnlyOffice `api.js` 硬编码公网地址 → 运行时配置 `onlyOfficeUrl` 下发(见 ⑦-1) |
|
|
|
|
|
+| `public/js/config.js` | `autoLoginToken: 'MTIzNDU2'` → `''`(空 = 不携带该头) |
|
|
|
|
|
+| `.env` | 删除 `VITE_MOCK_LOGIN_USERNAME/PASSWORD_CHAR_CODE` 两个 mock 免密凭据键(原值 autoAdmin/autoAdmin123) |
|
|
|
|
|
+
|
|
|
|
|
+## ④ 逐项说明
|
|
|
|
|
+
|
|
|
|
|
+### R3-10 硬编码地址回退(恢复 4b94efbd)
|
|
|
|
|
+
|
|
|
|
|
+1. **mxServerConfig.json / configurable.data.ts(4 处)**
|
|
|
|
|
+ - 原行为:CAD 转 DWG 地址与 3 个看板视频写死旧云环境 `IP:8092`,换部署环境必须改代码。
|
|
|
|
|
+ - 现行为:恢复为站点相对路径 `/modelreq/...`,同源经 nginx `/modelreq` 反代至网关(团队既有部署约定)。
|
|
|
|
|
+ - 为什么:该改动 09-14 人工审核已采纳,被 `7e9858ec` 一并回退;属"敏感信息硬编码"口径。
|
|
|
|
|
+ - 差别:仅地址形态变化,无逻辑变化。
|
|
|
|
|
+
|
|
|
|
|
+2. **fileEdit.html(见 ⑦-1,超出 4 文件清单)**:同上原则,恢复运行时配置下发。
|
|
|
|
|
+
|
|
|
|
|
+3. **VoiceBroadcast.vue / VoiceBroadcastGsd.vue(加固点)**
|
|
|
|
|
+ - 原行为(回退后):`'http://' + hostname + ':9999'?.replace('https://','wss://').replace('http://','ws://') + ...`。
|
|
|
|
|
+ 这里 `?.` 优先级使 replace 只作用于 `':9999'` 字面量,返回仍是 `':9999'`——**协议改写从未生效**,
|
|
|
|
|
+ 实际拼出的是 `http://<host>:9999/websocket/...`(WS 构造器收到 http 协议头,行为依赖浏览器容错)。
|
|
|
|
|
+ - 现行为:恢复 `useGlobSetting().wsUrl`(`public/js/config.js` 单点配置,当前值
|
|
|
|
|
+ `window.location.origin + '/modelreq'`),并把 `https://→wss://`、`http://→ws://` 替换**锚定在完整 URL 的协议头**
|
|
|
|
|
+ (`/ ^https:\/\//`、`/^http:\/\//`,避免误改 URL 体内出现的 "http://" 子串);
|
|
|
|
|
+ `glob.wsUrl` 缺失时回退 `window.location.origin + '/modelreq'`(协议取自 `location.protocol`,
|
|
|
|
|
+ replace 后即正确推导 ws/wss)。
|
|
|
|
|
+ - 为什么:既恢复运行期配置(去 :9999 硬编码直连),又修复从未生效的协议改写。
|
|
|
|
|
+ - 差别:WS 端点由"网关端口 http 直连"变为"同源 /modelreq 反代(wss)"。前提:nginx 已把
|
|
|
|
|
+ `/modelreq` 的 WS 升级到网关——与 `config.js` 里 `wsUrl` 的既有约定一致,非新引入依赖。
|
|
|
|
|
+
|
|
|
|
|
+### R3-3 autoLoginToken 回空值(撤销 c913dbf9,恢复 dd5e7d80)
|
|
|
|
|
+
|
|
|
|
|
+- 原行为:`c913dbf9` 在仓库里写死 `autoLoginToken: 'MTIzNDU2'`(=123456,公开弱票据),
|
|
|
|
|
+ 且部署 6 条 `config.js` 补丁不含该键 → 生产永远携带该弱票据。
|
|
|
|
|
+- 现行为:回 `''`。`src/api/sys/user.ts:76` 已实现
|
|
|
|
|
+ `headers: VUE_APP_URL.autoLoginToken ? { token: ... } : {}`——**空 = 不携带该头**,
|
|
|
|
|
+ 服务端按"未配置自动登录令牌"明确拒绝(fail-closed)。
|
|
|
|
|
+- 为什么:`autoLoginToken` 是**可选语义**——空值即不携带该头,**不能改成强制登录**;
|
|
|
|
|
+ 凭据应由部署环境注入(与服务端 `SDJT_AUTO_LOGIN_TOKEN` 配套),**不应在仓库写死默认值**。
|
|
|
|
|
+- 差别:仅凭据形态(仓库内无默认票据)。**未改动** `src/api/sys/user.ts` 的读取逻辑与任何免密流程。
|
|
|
|
|
+
|
|
|
|
|
+### R3-2 .env mock 免密凭据外置(恢复 8f87ade5 做法)
|
|
|
|
|
+
|
|
|
|
|
+- 原行为:`.env` 里 `VITE_MOCK_LOGIN_USERNAME_CHAR_CODE/PASSWORD_CHAR_CODE` = autoAdmin/autoAdmin123,
|
|
|
|
|
+ 随构建注入产物(`.env` 的 `VITE_*` 必进 dist)。
|
|
|
|
|
+- 现行为:删除两个键(8f87ade5 的原始做法即删键;已验证删键不破坏构建)。
|
|
|
|
|
+ 缺失时 `src/store/constant.ts` → `fromEnvCharCodes(undefined)` → 返回 `''`,**不抛错**。
|
|
|
|
|
+- 为什么:mock 免密凭据属"前端硬编码敏感信息"口径(§7.2 口径 1 明确"凭据仍按口径 1 审"),
|
|
|
|
|
+ 流程本身不审(冻结项)。
|
|
|
|
|
+- 差别:仅删凭据默认值;`user.ts`/`permissionGuard.ts` 代码一行未动。
|
|
|
|
|
+
|
|
|
|
|
+## ⑤ 验收证据
|
|
|
|
|
+
|
|
|
|
|
+1. **WS URL 拼接逻辑实测**(node 复现改后代码,4 个用例全对):
|
|
|
|
|
+ - `glob.wsUrl='http://a.b/modelreq'` → `ws://a.b/modelreq/websocket/u1` ✅
|
|
|
|
|
+ - `glob.wsUrl='https://a.b/modelreq'` → `wss://a.b/modelreq/websocket/u1` ✅
|
|
|
|
|
+ - 缺失 + `http:` → `ws://a.b/modelreq/websocket/u1` ✅(回退推导正确)
|
|
|
|
|
+ - 缺失 + `https:` → `wss://a.b/modelreq/websocket/u1` ✅
|
|
|
|
|
+2. **`public/js/config.js` 的 `wsUrl` 键确认存在**:`grep -n wsUrl public/js/config.js` →
|
|
|
|
|
+ 第 4 行 `wsUrl: window.location.origin + '/modelreq'`(`types/global.d.ts:8` 类型声明、`src/hooks/setting/index.ts:87` 读取均在)。
|
|
|
|
|
+3. **`.env` 空值安全性验证结论(R3-2 前置验证,全部通过)**:
|
|
|
|
|
+ - `src/store/constant.ts:3-4` 经 `fromEnvCharCodes` 读取,其实现(`src/utils/env.ts`)首行
|
|
|
|
|
+ `if (!charCodeStr) return '';`——**缺失/空串安全,返回空串,不抛错**。
|
|
|
|
|
+ - 使用点全量排查(`grep -rn "MOCK_LOGIN_UESRNAME\|MOCK_LOGIN_PASSWORD" src/`):
|
|
|
|
|
+ `user.ts:93`(`getIsMockLogin`,空串与真实用户名比对恒 false,无副作用)、
|
|
|
|
|
+ `user.ts:378-379`(`mockLogin` 参数,空串 → 免密请求带空凭据被服务端拒绝 = 预期行为)、
|
|
|
|
|
+ `CADModal.vue` 两处均已注释掉。`build/`、`vite.config.ts` **无**对这两个键的强制校验。
|
|
|
|
|
+ - 除"凭据为空导致免密请求失败"外**无**其它行为变化:无类型错误(参数声明即 `string | undefined` 兼容)、
|
|
|
|
|
+ 无构建失败、无 NPE(`undefined === ''` 为 false)。
|
|
|
|
|
+ - 残余理论边角:`getIsMockLogin` 在"服务端返回的用户名恰为空串"时恒真,进而 401 时触发 `redoMockLogin` 重试——
|
|
|
|
|
+ 前提是真实用户名不可能为空串,判定为可接受风险,仅记录。
|
|
|
|
|
+4. **红线核对**:`git diff 4e311cb6..HEAD --name-only` 不含 `useAutoLogin.ts`/`permissionGuard.ts`/`user.ts`/
|
|
|
|
|
+ `fireBD.vue`/`fire-green.vue`/`tools/`。
|
|
|
|
|
+
|
|
|
|
|
+## ⑥ 静态检查
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+# Babel 语法检查(worktree node_modules 软链,@babel/parser 走 .pnpm 路径)
|
|
|
|
|
+node -e "...parse(VoiceBroadcast.vue / VoiceBroadcastGsd.vue script / configurable.data.ts)..."
|
|
|
|
|
+→ OK × 3
|
|
|
|
|
+
|
|
|
|
|
+node --check public/js/config.js → config.js syntax OK
|
|
|
|
|
+node -e "JSON.parse(...mxServerConfig.json)" → JSON OK(该文件 "?key" 注释风格键名是合法 JSON 键,可严格解析)
|
|
|
|
|
+
|
|
|
|
|
+# 残留复核(必须零命中)
|
|
|
|
|
+grep -rn "182\.92\.126\.35\|47\.94\.222\.6" src public → 0 命中(exit 1)
|
|
|
|
|
+grep -rn ":9999" src/layouts → 0 命中(exit 1)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+说明:改动处的说明注释**刻意不写 IP/端口字面量**(原值在 git 历史 4b94efbd/7e9858ec 可查),
|
|
|
|
|
+以保证"残留 grep 零命中"这一验收口径本身可作为持续检查手段。未跑构建(按任务要求)。
|
|
|
|
|
+
|
|
|
|
|
+## ⑦ 已知取舍
|
|
|
|
|
+
|
|
|
|
|
+1. **`public/fileEdit.html` 超出任务所列 4 文件清单**:任务验收要求"残留 grep 零命中",
|
|
|
|
|
+ 而 `fileEdit.html` 的 `47.94.222.6:9050` 同属 `7e9858ec` 回退的 R3-10 范畴(`4b94efbd` 已含该文件),
|
|
|
|
|
+ 故一并恢复并在本节显式声明;如审核认为应拆分,可单独 revert `021f3061` 中该文件。
|
|
|
|
|
+2. **部署注入由父方处理**:8092 的 6 条 `config.js` 补丁扩为 7 条(含 `autoLoginToken`)由父方在
|
|
|
|
|
+ `tools/deploy/lib.sh` 完成,本分支未触碰 `tools/`。
|
|
|
|
|
+3. **免密/自动登录流程未动**:`?mock-login=1` 链接、`useAutoLogin.ts`、`permissionGuard.ts`、`user.ts`
|
|
|
|
|
+ 保持仓库现状;本分支只恢复"地址/凭据形态"。
|
|
|
|
|
+4. 说明注释中"原硬编码值"一律指向 git 历史而非直接书写,便于 grep 口径持续生效。
|
|
|
|
|
+
|
|
|
|
|
+## ⑧ 交付状态与上游同步
|
|
|
|
|
+
|
|
|
|
|
+- 仅本地 4 个提交(`021f3061` / `22ce77a6` / `23f5f95a` + 本文档),**未推送任何远端**;
|
|
|
|
|
+- 未部署、未触碰生产;
|
|
|
|
|
+- 基线 `4e311cb6` = 当前 `upstream/master`,behind=0;
|
|
|
|
|
+- 待人工审核后由人工决定推送/合并。
|