- Referer 开放重定向:safeRedirectPath 仅放行同站相对路径, 外部 URL/协议跳转一律回退 /inbox - 发信配额 TOCTOU:新增 TryReserveQuota 原子预扣 (UPDATE ... WHERE used_bytes + n <= quota_bytes),超配额即拒发; 附件保存失败按大小补偿回退 - 移除危险模板函数 safeHTML/safeJS:新增 jsonify(json.Marshal, < > & 转义为 \u003c 等,无法逃出 </script>),compose 页 quill.innerHTML 改用 jsonify;srcdoc 改回默认属性转义 - 会话治理:登录成功后 session.Clear() 清旧状态;记录 loginAt, 绝对过期 7 天 + 滑动续期(活跃会话 12h 写回刷新) - 确认 #15 Content-Disposition 编码随 P1 #4 已完成 - 新增 12 个测试:重定向路径矩阵、配额原子性(含超额不部分扣费)、 jsonify 逃逸防护、会话绝对过期/有效访问(签名会话构造) 至此 16 项安全审计项(P0-P3)全部修复完成。
71 lines
3.4 KiB
HTML
71 lines
3.4 KiB
HTML
{{define "admin_mail_view"}}
|
|
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
|
<title>查看邮件 - MailGo 管理后台</title>
|
|
{{template "styles" .}}
|
|
<style>
|
|
.mail-body-iframe {
|
|
width: 100%;
|
|
min-height: 300px;
|
|
border: 1px solid #e0e0e0;
|
|
border-radius: 4px;
|
|
background: #fff;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
{{template "navbar" .}}
|
|
<div class="container">
|
|
<div class="clearfix">
|
|
<div class="sidebar">
|
|
<a href="/inbox">返回邮箱</a>
|
|
<a href="/admin" {{if eq .activeFolder "admin"}}class="active"{{end}}>控制面板</a>
|
|
<a href="/admin/domains" {{if eq .activeFolder "domains"}}class="active"{{end}}>域名管理</a>
|
|
<a href="/admin/users" {{if eq .activeFolder "users"}}class="active"{{end}}>用户管理</a>
|
|
<a href="/admin/mails" class="active">所有邮件</a>
|
|
<a href="/admin/outbound" {{if eq .activeFolder "outbound"}}class="active"{{end}}>外发队列</a>
|
|
<a href="/admin/bans" {{if eq .activeFolder "bans"}}class="active"{{end}}>IP黑名单</a>
|
|
</div>
|
|
<div class="content">
|
|
<div class="card">
|
|
<div style="margin-bottom:16px;">
|
|
<a href="/admin/mails" class="btn" style="background:#bdc3c7;color:#fff;">返回邮件列表</a>
|
|
</div>
|
|
<h2>{{if .message.Subject}}{{.message.Subject}}{{else}}(无主题){{end}}</h2>
|
|
<div class="mail-meta" style="margin-top:12px;">
|
|
<p><strong>发件人:</strong> {{decodeHeader .message.FromAddr}}</p>
|
|
<p><strong>收件人:</strong> {{.message.ToAddr}}</p>
|
|
{{if .message.CcAddr}}<p><strong>抄送:</strong> {{.message.CcAddr}}</p>{{end}}
|
|
<p><strong>所属用户:</strong> {{if .message.User.ID}}{{.message.User.Username}}{{else}}—{{end}}</p>
|
|
<p><strong>文件夹:</strong> {{.message.Folder}}</p>
|
|
<p><strong>时间:</strong> {{.message.Date.Format "2006-01-02 15:04:05"}}</p>
|
|
</div>
|
|
<div class="mail-body">
|
|
{{if .message.HtmlBody}}
|
|
<iframe class="mail-body-iframe" srcdoc="{{.message.HtmlBody}}" sandbox="allow-same-origin" onload="this.style.height=this.contentDocument.body.scrollHeight+20+'px'"></iframe>
|
|
{{else}}
|
|
<pre style="white-space:pre-wrap;font-family:inherit;">{{.message.TextBody}}</pre>
|
|
{{end}}
|
|
</div>
|
|
{{if .attachments}}
|
|
<div class="attachment-list">
|
|
<h4 style="margin-bottom:8px;">附件</h4>
|
|
{{range .attachments}}
|
|
<div class="attachment-item">
|
|
📎 <a href="/admin/attachment/{{.ID}}">{{.FileName}}</a>
|
|
<span style="color:#7f8c8d;font-size:12px;">({{formatBytes .FileSize}})</span>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
{{end}}
|