fix(security): 告警渠道 webhook 与 Bark Device Key 响应脱敏

AlertNotifyChannel.Config 原先以真值返回。钉钉/飞书/企微的 webhook URL 与 Bark
的 device key 本身就是凭据,泄露即可直接向对应群或设备推送消息,而列表接口对
具备 recharge:manage 的商户成员可见。

- 新增 service.MaskAlertChannel(s):在 HTTP 响应层脱敏,只保留密钥末 4 位。
  webhook 保留域名与路径以便辨认是哪一台机器人(钉钉/企微的 token 在查询串,
  飞书的 uuid 在路径末段),Server 属主机地址不遮蔽
- UpdateAlertChannel 识别回传的脱敏占位值并沿用库中真实密钥,使「只改名称/开关」
  不会被掩码覆盖;填写新值则正常替换
- 脱敏刻意不放在 service 层:CheckLowBalanceAndNotify 复用 ListAlertChannels
  的结果真正去发消息,在那一层脱敏会直接打断告警发送
- 前端表单补充说明文案

验证:新增 6 组测试,覆盖脱敏规则、三种机器人 URL 形态、脱敏结果仍能通过校验、
掩码回传不覆盖真实密钥,以及「service 层必须返回真值」这条关键边界。
This commit is contained in:
yml2213
2026-10-06 19:49:11 +08:00
parent 14d297a591
commit 7f984b0f4e
4 changed files with 342 additions and 7 deletions
+7 -1
View File
@@ -416,7 +416,12 @@ export default function AlertSettings() {
<Form.Item name="server" label="Bark 服务器地址(可选)">
<Input placeholder="https://api.day.app(默认官方服务器)" />
</Form.Item>
<Form.Item name="key" label="Bark 设备 Key" rules={[{ required: true, message: '请填写 Bark 设备 Key' }]}>
<Form.Item
name="key"
label="Bark 设备 Key"
rules={[{ required: true, message: '请填写 Bark 设备 Key' }]}
extra="出于安全考虑,密钥只显示末 4 位;保持原样即不修改,填入新值则替换。"
>
<Input placeholder="安装 Bark 后生成的设备 Key" />
</Form.Item>
</>
@@ -425,6 +430,7 @@ export default function AlertSettings() {
name="webhook_url"
label="Webhook URL"
rules={[{ required: true, message: '请填写 Webhook URL' }]}
extra="出于安全考虑,密钥只显示末 4 位;保持原样即不修改,填入新值则替换。"
>
<Input placeholder={channelOptions.find((item) => item.value === channelType)?.placeholder} />
</Form.Item>