feat(mail): 重构邮箱权限体系并细化前台能力控制

- 新增邮箱前台权限与默认普通用户权限迁移,拆分读信、发信、草稿、定时、整理、标签、附件、联系人等能力。
- 收紧后端路由与处理逻辑,按权限限制邮箱前台、个人中心和定时发送相关接口。
- 前端根据权限动态隐藏或禁用邮件、个人中心中的对应功能入口与操作。
- 补充权限迁移与访问控制测试,覆盖普通用户邮箱前台、发信和定时发送的权限校验。
This commit is contained in:
LanQin_
2026-06-22 15:54:15 +08:00
parent 5571dcc511
commit 0b982a5ff4
8 changed files with 507 additions and 153 deletions
+6 -1
View File
@@ -277,7 +277,7 @@ func (a *App) handleMailMessage(w http.ResponseWriter, r *http.Request) {
respondError(w, http.StatusNotFound, "message not found")
return
}
if r.URL.Query().Get("markRead") != "0" && !msg.IsRead {
if r.URL.Query().Get("markRead") != "0" && !msg.IsRead && userHasPermission(currentUser(r), PermissionMailOrganize) {
_, _ = a.db.ExecContext(r.Context(), `UPDATE messages SET is_read=1, updated_at=? WHERE id=?`, a.now().UTC().Format(time.RFC3339Nano), msg.ID)
msg.IsRead = true
}
@@ -770,6 +770,11 @@ func (a *App) processScheduledSend(ctx context.Context, id, mailboxID, draftID,
a.markScheduledSendFailed(ctx, id, "mailbox not found")
return
}
user, err := a.userByID(ctx, mb.UserID)
if err != nil || !userHasPermission(user, PermissionMailSchedule) || !userHasPermission(user, PermissionMailSend) {
a.markScheduledSendFailed(ctx, id, "mail send permission revoked")
return
}
compose := mailComposeInput{MailboxID: payload.MailboxID, To: payload.To, CC: payload.CC, BCC: payload.BCC, Subject: payload.Subject, Text: payload.Text, HTML: payload.HTML, Attachments: payload.Attachments}
if _, err := a.sendMailNow(ctx, mb, compose); err != nil {
a.markScheduledSendFailed(ctx, id, err.Error())