编号:W-04 严重级:medium 工作线:后台网页(web/) 来源:审查 A-05、A-06、A-26 依赖:无 被依赖:W-05 (#55)(同改 EndpointsView.vue,本条先合)
采用审查 A-05、A-06、A-26 的方案:
web/src/utils/csv.ts
"
id,name,login_password
'
SecretOnceAlert
mime
text/csv
login_password?: string
writeText
web/src/utils/csv.ts(新)、components/SecretOnceAlert.vue、views/EndpointsView.vue、api/types.ts、api/mock.ts。
components/SecretOnceAlert.vue
views/EndpointsView.vue
api/types.ts
api/mock.ts
EndpointsView.vue 同时被 W-05 修改,网页线内顺序合入。
undefined
以下是本次复审各区审查报告的原文段落。A、M、I、P、S 开头的是原始发现编号(A 管理后台与网页、M 消息核心、I 身份认证群在线、P 传输平台部署、S SDK)。解决方案以本 issue 上方的"结论与统一方案"为准;原文里的方案与之不一致时,按上方执行。
${id},${name},${login_password}
,
= + - @
EndpointsView.vue:320-324
secret: res.items.map((i) => \
,
SecretOnceAlert.vue:18-26
endpoints_csv.go:55-60,296
EndpointsView.vue
SecretOnceAlert.vue
login_password
${res.id}\t${res.login_password}
EndpointsView.vue:208-213
endpoints.go:291-296
if pwGenerated { data[loginPasswordOnceKey] = loginPW }
types.ts:73-76
mock.ts:357,372
types.ts
mock.ts
navigator.clipboard
SecretOnceAlert.vue:14-16
EndpointsView.vue:478-487
复审基线:main 4059a15(2026-09-30)。编号说明、各工作线的合并顺序、共享文件归属见总览 #7。
4059a15
已合入 origin/main 0c9b459。落地提交 15802bf fix: 校正一次性密码展示与 CSV 下载 (#54)。
0c9b459
15802bf
No dependencies set.
The note is not visible to the blocked user.
编号:W-04 严重级:medium 工作线:后台网页(web/) 来源:审查 A-05、A-06、A-26
依赖:无 被依赖:W-05 (#55)(同改 EndpointsView.vue,本条先合)
结论与统一方案
采用审查 A-05、A-06、A-26 的方案:
web/src/utils/csv.ts:按 RFC 4180 给所有字段加引号并把"双写,用 CRLF 换行,文件头加 BOM,第一行写表头id,name,login_password;名称列以公式字符开头时前缀',密码列只加引号、不改值。SecretOnceAlert增加mime属性,导入流程改用text/csv。login_password?: string;有值才显示一次性面板,没有就提示"已开通 {id}";假数据与后端一致。writeText的结果并提示成功或失败;不支持 clipboard 时回退为选中文本再复制。改动文件
web/src/utils/csv.ts(新)、components/SecretOnceAlert.vue、views/EndpointsView.vue、api/types.ts、api/mock.ts。与其他问题的交互 / 冲突说明
EndpointsView.vue 同时被 W-05 修改,网页线内顺序合入。
验收与测试
undefined,也不显示一次性面板。问题明细(各区审查原文,证据含文件与行号)
[A-05] 导入结果下载的 CSV 不做转义,一次性密码文件会错列
${id},${name},${login_password}直接拼接。名称是自由文本(CSV 导入本身允许带引号的逗号),接口原样回显的密码也可能含,、"或换行,都会导致列错位,管理员按列保存的密码就是错的。= + - @开头时,用 Excel 打开会被当成公式执行。EndpointsView.vue:320-324:secret: res.items.map((i) => \${i.id},${i.name},${i.login_password}`).join("\n"),filename: "import-passwords.csv"`。SecretOnceAlert.vue:18-26原样下载。endpoints_csv.go:55-60,296回显原文密码。web/src/utils/csv.ts:按 RFC 4180 给所有字段加引号并把"双写,用 CRLF 换行,文件头加 BOM,第一行写表头id,name,login_password。'。密码列只加引号、不改值,避免破坏密码。SecretOnceAlert增加mime属性,导入流程改用text/csv。web/src/utils/csv.ts(新)、EndpointsView.vue、SecretOnceAlert.vue。[A-06] 开通端时手填了密码,"只显示一次"的密码显示为
undefinedlogin_password,前端却无条件显示${res.id}\t${res.login_password}。结果是"登录密码只显示一次"的框里写着undefined,下载的文件内容也是它。EndpointsView.vue:208-213。endpoints.go:291-296:if pwGenerated { data[loginPasswordOnceKey] = loginPW }。types.ts:73-76把login_password声明为必有。mock.ts:357,372的假数据总是返回密码,掩盖了这个问题。login_password?: string。有值才显示一次性面板,没有就提示"已开通 {id}"。假数据改成与后端一致。types.ts、EndpointsView.vue、mock.ts。undefined,也不显示一次性面板。[A-26] 一次性密钥的"复制"可能静默失败,导入结果弹窗没有下载按钮
navigator.clipboard,"复制"按钮什么都不做也不提示;即使复制成功也没有反馈。导入结果弹窗写着"请下载保存",却只有"关闭"按钮。SecretOnceAlert.vue:14-16;EndpointsView.vue:478-487。writeText的结果,捕获异常,成功或失败都给提示;不支持时回退为选中文本再复制;导入弹窗加"下载"按钮。SecretOnceAlert.vue、EndpointsView.vue。复审基线:main
4059a15(2026-09-30)。编号说明、各工作线的合并顺序、共享文件归属见总览 #7。已合入 origin/main
0c9b459。落地提交15802bffix: 校正一次性密码展示与 CSV 下载 (#54)。