Skip to content

feat: 增强多域名邮箱管理、Catch-all 与按域名发件配置 - #136

Open
huzheyi wants to merge 3 commits into
beilunyang:masterfrom
huzheyi:master
Open

feat: 增强多域名邮箱管理、Catch-all 与按域名发件配置#136
huzheyi wants to merge 3 commits into
beilunyang:masterfrom
huzheyi:master

Conversation

@huzheyi

@huzheyi huzheyi commented Aug 5, 2026

Copy link
Copy Markdown

背景

本次更新主要完善 MoeMail 在多域名部署场景下的邮箱接收、发件权限、用户域名权限和邮件管理能力,同时优化邮箱页面的使用体验与查询开销。

主要改动

1. 按域名配置 Catch-all 邮箱

  • 皇帝可以在网站设置中分别为每个邮箱域名启用或停用 Catch-all。
  • 每个域名可以独立设置 Catch-all 邮箱名称。
  • Catch-all 邮箱由系统创建并归属于皇帝,不设置过期时间。
  • 可以分别配置 Catch-all 停用后是否仍显示在邮箱列表中。
  • Catch-all 邮箱在邮箱列表中置顶并使用独立图标展示。
  • 未知收件地址不会被自动加入 email 表,避免随机地址攻击导致 D1 数据膨胀。
  • 未配置、已停用或配置异常时,Worker 会记录日志并安全丢弃邮件,不影响正常收件地址。
  • 邮件记录和 Webhook 始终保留完整的原始收件地址 message.to
  • Email Worker 新增与主应用相同的 SITE_CONFIG KV binding。
  • 自动部署脚本会为 Email Worker 写入对应的 KV namespace ID。

2. 按域名配置 Resend 发件服务

  • Resend 不再只能全局启用,可以为不同域名分别配置:
    • 启用状态
    • Resend API Key
  • 未启用发件服务的域名不会显示发送邮件按钮。
  • 已从站点域名列表移除、但仍保留 Resend 配置的域名会显示失效提示。
  • 用户下次保存配置时自动清理失效域名的 Resend 配置。
  • 兼容已有的全局 Resend 配置,升级后不会因旧配置格式导致发件功能直接失效。

3. Catch-all 自定义发件地址

  • 皇帝使用 Catch-all 邮箱发件时,可以自定义发件地址前缀。
  • 发件域名仍限定为当前 Catch-all 邮箱所属域名。
  • 普通邮箱继续使用自身邮箱地址发件,不受该能力影响。

4. 用户可用域名权限

  • 皇帝可以在角色管理中为其他用户配置允许使用的邮箱域名。
  • 创建邮箱时,用户只能选择自己有权限使用的域名。
  • 后端创建接口同步校验域名权限,避免绕过前端直接创建。
  • 皇帝仍可使用全部已配置域名。

5. 邮箱和邮件列表优化

  • 邮箱列表增加域名页签:
    • “全部”页签默认显示所有邮箱。
    • 其余页签按域名筛选邮箱。
  • 增加每个邮箱的“未读邮件数 / 总邮件数”。
  • 新收到的邮件标题以未读样式加粗显示。
  • 打开邮件后自动标记为已读,并同步更新未读数量。
  • Catch-all 邮箱在列表中置顶,与普通邮箱之间增加分隔线。
  • 优化三栏布局标题栏、按钮和分隔线的高度与对齐。
  • 普通用户无邮箱权限时不再额外向用户弹出内部代码错误。

6. 增量刷新与查询优化

  • 当前选中邮箱每 30 秒增量查询新邮件。
  • 轮询只查询上次游标之后的记录,不重复读取完整邮件列表。
  • 浏览器页面不可见时跳过网络请求。
  • 使用请求锁避免多个轮询请求重叠。
  • 新邮件到达后在前端增量更新当前邮箱的未读数和总数。
  • 邮箱列表的统计信息使用聚合查询,避免为每个邮箱分别查询邮件数量。
  • 保留分页加载,降低邮箱和邮件数量较多时的 D1 查询压力。

7. 修复收到邮件时发件人显示错误

原收件 Worker 将 Cloudflare Email Worker 的 message.from 直接保存为发件人地址。

该字段实际是 SMTP 信封发件人(Envelope From / Return-Path)。经 Resend 发送时,它可能是类似以下格式的退信地址:

xxxxxxxx@send.example.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant