Files
tamabox/internal/mail/mail_alert_test.go
T
tamakyi e94c2b57ce 新增:安全告警邮件展示来源 IP 网络归属(CDN/云厂商/WAF)
- 新增 internal/security/ipinfo:基于 projectdiscovery/cdncheck v1.3.0
  (离线指纹、零外部请求)识别来源 IP 归属,识别失败折叠为展示标签,
  不中断告警链路
- autoban 告警回调注入归属识别;告警邮件新增「网络归属」行,
  命中 CDN/代理网络时提示「封禁可能无法拦截真实来源」
- 新增邮件模板渲染回归测试 internal/mail/mail_alert_test.go
- dev/s3stub:webp(cgo) 本地类型检查桩,替换 s3.go 做全模块编译验证,
  生产 Linux 构建不受影响;dev/overlay.json 指向该桩
- go mod tidy 顺带升级共享依赖(lipgloss/xid/testify 等),
  全模块类型检查与相关包测试通过
2026-09-08 13:25:20 +08:00

60 lines
1.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package mail
import (
"bytes"
"html/template"
"testing"
"github.com/tamakyi/TamaBox/templates"
)
// TestSecurityAlertTemplateRenders 保证 security-alert.html 模板可解析,
// 且新增的「网络归属 / 代理网络提示」字段在参数齐全时正确渲染、
// proxy_hint 为空时不渲染提示块。
func TestSecurityAlertTemplateRenders(t *testing.T) {
tmpl, err := template.ParseFS(templates.FS, "mail/security-alert.html")
if err != nil {
t.Fatalf("parse template: %v", err)
}
base := map[string]string{
"ip": "203.0.113.7",
"provider": "Cloudflare(CDN)",
"paths": "/admin、/.env",
"duration": "15",
"time": "2026-09-08 12:00:00",
"year": "2026",
}
// 1. 代理网络命中:应有归属行 + 代理提示
var withHint bytes.Buffer
params := cloneParams(base)
params["proxy_hint"] = "1"
if err := tmpl.Execute(&withHint, params); err != nil {
t.Fatalf("execute with proxy_hint: %v", err)
}
out := withHint.String()
for _, want := range []string{"203.0.113.7", "网络归属", "Cloudflare(CDN)", "代理网络"} {
if !bytes.Contains([]byte(out), []byte(want)) {
t.Errorf("rendered mail missing %q", want)
}
}
// 2. 普通网络:不应出现代理提示块
var noHint bytes.Buffer
if err := tmpl.Execute(&noHint, cloneParams(base)); err != nil {
t.Fatalf("execute without proxy_hint: %v", err)
}
if bytes.Contains(noHint.Bytes(), []byte("代理网络")) {
t.Errorf("proxy hint rendered without proxy_hint param")
}
}
func cloneParams(src map[string]string) map[string]string {
dst := make(map[string]string, len(src))
for k, v := range src {
dst[k] = v
}
return dst
}