# xmail **Repository Path**: chenlinos/xmail ## Basic Information - **Project Name**: xmail - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-08 - **Last Updated**: 2026-06-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README
一个基于 NextJS + Cloudflare 技术栈构建的临时邮箱服务🎉
在线演示 • 文档 • 特性 • 技术栈 • 本地运行 • 部署 • 邮箱域名配置 • 权限系统 • 运维中心 • 卡密系统 • 系统设置 • 发件功能 • Webhook 集成 • OpenAPI • 环境变量 • Github OAuth App 配置 • 贡献 • 许可证 • 交流群 • 支持
## 在线演示 [https://mail.xiyangone.cn/](https://mail.xiyangone.cn/) > 本项目最初基于 [MoeMail](https://github.com/beilunyang/moemail) 进行二次开发,当前以 `XiYang Mail` 品牌持续维护和演进 > > 开发者哔哩哔哩主页: [https://space.bilibili.com/272756942](https://space.bilibili.com/272756942) ## 文档 **当前文档入口**: 本仓库 README(即当前文件) **当前版本**: `v1.6.7` 当前版本暂未单独维护外部文档站点,部署、API、配置与示例请以本仓库内容为准。 ### 命名约定(默认值,可自定义) - 产品名:`XiYang Mail` - GitHub 仓库 / Worker 前缀:`xmail` - 默认示例域名:`mail.xiyangone.cn` 上述命名不是强制固定。 如果你需要换品牌名、Worker 名、D1 名、KV 名或自定义域名,可以通过 `PROJECT_NAME`、`DATABASE_NAME`、`KV_NAMESPACE_NAME`、`CUSTOM_DOMAIN` 等配置覆盖默认值;仓库当前这组命名只是默认推荐口径。 ## 特性 - 🔒 **隐私保护**:保护您的真实邮箱地址,远离垃圾邮件和不必要的订阅 - ⚡ **实时收件**:可配置的自动轮询,即时接收邮件通知(支持 5-60 秒刷新间隔,失败时自动指数退避) - ⏱️ **灵活有效期**:支持 1 小时、24 小时、3 天或永久有效,默认过期时间为 3 天 - 🎨 **多主题系统**:支持日间 / 夜间 / 樱花 / 琥珀四种主题,下拉菜单切换,支持跟随系统 - 📱 **响应式设计**:完美适配桌面和移动设备 - 🔄 **自动清理**:自动清理过期的邮箱和邮件 - 💸 **免费自部署**:基于 Cloudflare 构建, 可实现免费自部署,无需任何费用 - 🎉 **可爱的 UI**:简洁可爱萌萌哒 UI 界面,集成 JetBrains Mono Nerd Font 字体 - 📤 **发件功能**:支持使用临时邮箱发送邮件,基于 Resend 服务 - 🔔 **Webhook 通知**:支持通过 webhook 接收新邮件通知 - 🛡️ **策略化权限系统**:支持基于角色、数据库权限表、路由策略和 API Key Scope 的细粒度访问控制 - 🧭 **运维中心**:管理后台内置 Worker 运行、清理历史、Webhook 日志、邮件接收日志、审计日志、权限变更审计和配置诊断 - 🔑 **OpenAPI**:支持通过 API Key 访问 OpenAPI,新创建的 API Key 可在个人中心后续查看、隐藏和复制 - 🎫 **卡密系统**:支持通过卡密快速创建临时账号,支持单邮箱和多邮箱模式,支持卡密重置和重复登录 - 🏷️ **域名标签管理**:优化的域名配置界面,支持标签式显示和批量添加,智能分组排序(顶级域名优先,同级别按字母顺序,同组内按长度排序) - 🚀 **性能优化**:React.memo、useMemo、useCallback 优化,更快的渲染速度 - 🎯 **智能聚焦**:所有页面和对话框自动聚焦到合适的输入框,提升用户体验 - 📦 **批量操作**:邮箱列表和用户管理支持批量选择和批量删除功能 - 🔄 **无感刷新**:删除操作后自动无感刷新列表,保持用户体验流畅 - ⏱️ **倒计时同步**:邮件列表倒计时与后端轮询完美同步,避免时间差;页面切到后台时会暂停轮询,恢复后自动刷新 - 🔢 **智能验证码识别**:自动识别邮件中的验证码并替换发件人位置显示,一键复制,支持多种格式("Your verification code is: 672246"、"验证码: 123456" 等) - 🔀 **邮箱切换优化**:切换邮箱时立即清空消息列表和重置状态,避免显示上一个邮箱的内容,提升切换体验 - 🤖 **智能验证码获取 API**:提供 API 接口自动从邮件列表中提取验证码,支持发件人过滤、轮询间隔和超时配置,适用于自动化测试和注册流程 - 🔗 **分享功能**:支持生成邮箱分享链接,可设置有效期(1小时/24小时/3天/永久),支持桌面端双栏布局和移动端单栏布局,完整的错误处理和过期状态显示 - 🎨 **优雅的对话框遮罩**:对话框打开时背景半透明暗化,选择器下拉菜单正确显示在最上层,支持鼠标滚轮快速切换域名 - ⚡ **性能优化加载**:Profile页面使用动态导入优化加载速度,配置组件按需加载,提升首屏渲染性能 - 🛡️ **皇帝用户保护**:用户管理页面皇帝用户无法被删除、无法被选中批量删除,确保系统管理员账号安全 - 🔄 **实时UI更新**:邮箱删除后立即更新列表和选中状态,无需等待轮询,提供即时反馈 - 🎯 **优雅的加载状态**:邮件列表加载时显示明显的"加载中..."提示和旋转动画,配合半透明骨架屏 - 🌐 **域名验证增强**:支持带数字的顶级域名(如 `aaugment.de5.net`),更灵活的域名配置 - 🔐 **OAuth注册控制**:关闭注册时同时阻止GitHub OAuth创建新用户,防止绕过注册限制 - 🔤 **纯字母前缀格式**:新增纯随机字母(无数字)的邮箱前缀生成选项 - 🛡️ **安全加固**:PBKDF2 密码哈希、API Key 认证哈希校验、iframe XSS 防护(srcdoc + sandbox + CSP)、安全响应头 - 🤖 **Turnstile 人机验证**:集成 Cloudflare Turnstile,登录/注册/卡密登录全链路防机器人 - ⚛️ **数据一致性**:卡密激活使用 D1 db.batch() 原子操作,杜绝中途失败导致的脏数据 - 🌐 **国际化 (i18n)**:基于 next-intl 的中英文双语支持,cookie 切换语言,无路由前缀,全页面覆盖 - 🖼️ **自定义背景**:支持按主题(日间/夜间/樱花/琥珀)分别设置背景图片 URL,全局背景(皇帝设置)+ 用户个人背景(骑士及以上),随机图源会在当前标签页内固定缓存,左下角查看原图与当前背景保持一致 - 🔕 **Cloudflare 统计提示**:控制台里出现 `static.cloudflareinsights.com/beacon.min.js` 连接关闭属于 Cloudflare 外部统计脚本,不影响背景图、邮箱功能或登录流程 - 🏢 **统一管理后台**:卡密管理、用户管理、清理设置集成至 `/admin` 单页面,折叠面板交互 ## 技术栈 - **框架**: [Next.js](https://nextjs.org/) 15.5.15 (App Router) - **部署**: [@opennextjs/cloudflare](https://opennext.js.org/cloudflare) - **平台**: [Cloudflare Workers](https://workers.cloudflare.com/) - **数据库**: [Cloudflare D1](https://developers.cloudflare.com/d1/) (SQLite) - **认证**: [NextAuth](https://authjs.dev/getting-started/installation?framework=Next.js) 配合 GitHub 登录 - **样式**: [Tailwind CSS](https://tailwindcss.com/) - **UI 组件**: 基于 [Radix UI](https://www.radix-ui.com/) 的自定义组件 - **邮件处理**: [Cloudflare Email Workers](https://developers.cloudflare.com/email-routing/) - **类型安全**: [TypeScript](https://www.typescriptlang.org/) - **ORM**: [Drizzle ORM](https://orm.drizzle.team/) - **国际化**: [next-intl](https://next-intl.dev/) (中英双语) ## 本地运行 ### 前置要求 - Node.js 24+ - Pnpm - Wrangler CLI - Cloudflare 账号 ### 安装 1. 克隆仓库: ```bash git clone https://github.com/xiyangone/xmail.git cd xmail ``` 2. 安装依赖: ```bash pnpm install ``` 3. 设置 wrangler: ```bash cp wrangler.example.json wrangler.json cp wrangler.email.example.json wrangler.email.json cp wrangler.cleanup.example.json wrangler.cleanup.json ``` > 以上方式适合手动维护 `wrangler*.json`。 > 如果你希望通过环境变量自定义 Worker / D1 / KV 名称,建议优先使用下方“本地 Wrangler 部署”流程,并在首次执行 `pnpm deploy:worker` 前先设置 `.env` 中的 `PROJECT_NAME` / `DATABASE_NAME` / `KV_NAMESPACE_NAME`。 设置 Cloudflare D1 数据库名以及数据库 ID 4. 设置环境变量: ```bash cp .env.example .env.local ``` 设置 AUTH_GITHUB_ID, AUTH_GITHUB_SECRET, AUTH_SECRET, INTERNAL_WORKER_SECRET 5. 创建本地数据库表结构 ```bash pnpm db:migrate-local ``` ### 开发 1. 启动开发服务器: ```bash pnpm dev ``` 2. 测试邮件 worker: 目前无法本地运行并测试,请使用 wrangler 部署邮件 worker 并测试 ```bash pnpm deploy:email ``` 3. 测试清理 worker: ```bash pnpm dev:cleanup pnpm test:cleanup ``` 4. 生成 Mock 数据(邮箱以及邮件消息) ```bash pnpm generate-test-data ``` ### 本地测试 在提交代码前,建议运行以下命令进行测试: 1. **代码检查**: ```bash pnpm lint ``` 2. **生产构建测试**: ```bash pnpm build ``` 3. **权限与运维回归测试**: ```bash pnpm test:permissions pnpm test:operations ``` 4. **验证码提取回归测试**: ```bash pnpm test:verification-code ``` 5. **维护性检查**: ```bash pnpm test:maintainability ``` > `pnpm build:worker` 仍保留用于 GitHub Actions / Linux / WSL 环境下的 OpenNext Worker 打包校验,不再作为 Windows 本机日常必跑项。 ## 部署 ### 视频版保姆级部署教程 https://www.bilibili.com/video/BV19wrXY2ESM/ ### 本地 Wrangler 部署 > 生产环境默认推荐使用下方 GitHub Actions 部署链路直连 Cloudflare。Windows 本机更适合日常开发和通用检查;如需执行 OpenNext Worker 打包,请优先放到 WSL / Linux / CI 环境验证。 1. 创建 .env 文件 ```bash cp .env.example .env ``` 2. 在 .env 文件中设置[环境变量](#环境变量) > `pnpm deploy:worker` 会读取 `.env` 中的 `PROJECT_NAME` / `DATABASE_NAME` / `KV_NAMESPACE_NAME`,并在 `wrangler*.json` 不存在时按这些值生成默认配置。 > 如果相关 `wrangler*.json` 已存在,脚本会保留现有文件,不会自动覆盖;此时如需改名,请手动修改对应配置,或删除后重新生成。 > 如果你要复用已存在的 D1 / KV 资源,建议同时设置 `DATABASE_ID` / `KV_NAMESPACE_ID`,避免脚本按名称重新查找或创建资源。 3. 构建并部署 OpenNext Worker ```bash pnpm deploy:worker ``` ### Github Actions 部署 本项目可使用 GitHub Actions 实现自动化部署。支持以下触发方式: > 当前仓库默认生产部署环境为 GitHub Actions `ubuntu-latest` + Node.js 24,Cloudflare Worker 打包与发布以该 Linux CI 链路为准。 1. **自动触发**:推送新的 tag 时自动触发部署流程 2. **手动触发**:在 GitHub Actions 页面手动触发 #### 部署步骤 1. 在 GitHub 仓库设置中添加以下 Secrets: - `CLOUDFLARE_API_TOKEN`: Cloudflare API 令牌 - `CLOUDFLARE_ACCOUNT_ID`: Cloudflare 账户 ID - `AUTH_GITHUB_ID`: GitHub OAuth App ID - `AUTH_GITHUB_SECRET`: GitHub OAuth App Secret - `AUTH_SECRET`: NextAuth Secret,用来加密 session,请设置一个随机字符串 - `INTERNAL_WORKER_SECRET`: 内部 Worker 调用密钥,主 Worker 与临时账号清理 Worker 必须使用相同值 - `CUSTOM_DOMAIN`: 网站自定义域名,用于访问 XiYang Mail (可选,如果不填,则使用 Workers 默认域名 *.workers.dev) - `PROJECT_NAME`: Worker 名称(可选,如果不填,则为 xmail) - `DATABASE_NAME`: D1 数据库名称 (可选,如果不填,则为 xmail-db) - `KV_NAMESPACE_NAME`: Cloudflare KV namespace 名称,用于存储网站配置 (可选,如果不填,则为 xmail-kv) - `NEXT_PUBLIC_TURNSTILE_SITE_KEY`: Cloudflare Turnstile 站点密钥(可选,不配置则跳过人机验证) - `TURNSTILE_SECRET_KEY`: Cloudflare Turnstile 密钥(可选,与站点密钥配对使用) 2. 选择触发方式: **方式一:推送 tag 触发** ```bash # 创建新的 tag git tag v1.0.0 # 推送 tag 到远程仓库 git push origin v1.0.0 ``` **方式二:手动触发** - 进入仓库的 Actions 页面 - 选择 "Deploy" workflow - 点击 "Run workflow" 3. 部署进度可以在仓库的 Actions 标签页查看 #### 注意事项 - 确保所有 Secrets 都已正确设置 - 使用 tag 触发时,tag 必须以 `v` 开头(例如:v1.0.0) [](https://deploy.workers.cloudflare.com/?url=https://github.com/xiyangone/xmail) ## 邮箱域名配置 在 XiYang Mail 个人中心页面,可以配置网站的邮箱域名,支持多域名配置。 ### 域名管理界面优化 新版本采用了更直观的标签式域名管理界面: - 🏷️ **标签式显示**:每个域名显示为独立的标签,清晰明了 - ➕ **快速添加**:点击"添加域名"按钮即可输入新域名 - 🗑️ **一键删除**:每个域名标签带有删除按钮,点击即可移除 - 📋 **批量操作**:支持粘贴多个域名(逗号、空格、换行分隔),自动识别并批量添加 - ✅ **格式验证**:自动验证域名格式,防止输入错误 - 📏 **滚动显示**:域名数量过多时自动显示滚动条,节省空间  ### Cloudflare 邮件路由配置 为了使邮箱域名生效,还需要在 Cloudflare 控制台配置邮件路由,将收到的邮件转发给 Email Worker 处理。 1. 登录 [Cloudflare 控制台](https://dash.cloudflare.com/) 2. 选择您的域名 3. 点击左侧菜单的 "电子邮件" -> "电子邮件路由" 4. 如果显示 “电子邮件路由当前被禁用,没有在路由电子邮件”,请点击 "启用电子邮件路由"  5. 点击后,会提示你添加电子邮件路由 DNS 记录,点击 “添加记录并启用” 即可  6. 配置路由规则: - Catch-all 地址: 启用 "Catch-all" - 编辑 Catch-all 地址 - 操作: 选择 "发送到 Worker" - 目标位置: 选择刚刚部署的 "xmail-email-receiver-worker" - 保存  ### 注意事项 - 确保域名的 DNS 托管在 Cloudflare - Email Worker 必须已经部署成功 - 如果 Catch-All 状态不可用(一直 loading),请点击`路由规则`旁边的`目标地址`, 进去绑定一个邮箱 ## 权限系统 本项目采用基于角色的权限控制系统(RBAC)。 ### 角色配置 新用户默认角色由皇帝在个人中心的网站设置中配置: - 公爵:新用户将获得临时邮箱、Webhook 配置权限以及 API Key 管理权限 - 骑士:新用户将获得临时邮箱和 Webhook 配置权限 - 平民:新用户无任何权限,需要等待皇帝册封为骑士或公爵 ### 角色等级 系统包含五个角色等级: 1. **皇帝(Emperor)** - 网站所有者 - 拥有所有权限 - 每个站点只能有一个皇帝 2. **公爵(Duke)** - 超级用户 - 可以使用临时邮箱功能 - 可以配置 Webhook - 可以使用创建 API Key 调用 OpenAPI - 可以被皇帝贬为骑士或平民 3. **骑士(Knight)** - 高级用户 - 可以使用临时邮箱功能 - 可以配置 Webhook - 可以被皇帝贬为平民或册封为公爵 4. **平民(Civilian)** - 普通用户 - 无任何权限 - 可以被皇帝册封为骑士或者公爵 5. **临时用户(Temp User)** - 通过卡密创建的临时账号 - 只能接收邮件,无法发送邮件 - 无法删除或修改绑定的邮箱地址 - 账号有效期为 7 天,到期自动删除 ### 角色升级 1. **成为皇帝** - 第一个访问 `/api/roles/init-emperor` 接口的用户将成为皇帝,即网站所有者 - 站点已有皇帝后,无法再提升其他用户为皇帝 2. **角色变更** - 皇帝可以在个人中心页面将其他用户设为公爵、骑士或平民 ### 权限说明 - **邮箱管理**:创建和管理临时邮箱 - **Webhook 管理**:配置邮件通知的 Webhook - **API Key 管理**:创建和管理 API 访问密钥 - **用户管理**:升降用户角色 - **系统设置**:管理系统全局设置 ### 动态权限策略 权限系统现在同时包含静态角色兜底和数据库动态策略: - `permission`:系统内所有权限点定义,例如 `manage_permissions`、`view_operations`、`view_audit_logs` - `role_permission`:角色到权限点的动态授权关系,管理后台的“权限策略”页可调整非 emperor 角色权限 - `route_policy`:API 路由访问策略,支持 `public`、`authenticated`、`permission`、`internal` 四类访问模式 - `api_key_scope`:API Key 可选权限范围;未配置 scope 时继承持有人权限,配置后只允许命中的权限路由 默认权限和路由策略会在迁移脚本中写入。运行 `pnpm db:migrate-local` 或 `pnpm db:migrate-remote` 后,迁移流程会同时补齐权限定义、默认角色授权和路由策略。 ## 运维中心 管理后台 `/admin` 已扩展为运维中心。拥有 `view_operations` 或 `manage_operations` 权限的用户可以查看: - **运维概览**:汇总 Worker 失败、Webhook 失败、邮件接收失败和审计事件数量 - **Worker 运行**:读取 `worker_run`,展示定时任务和手动清理任务的运行状态、耗时、计数和错误摘要 - **清理历史**:读取 `worker_run` 中的清理任务记录,展示最近 20 条清理运行状态、触发方式、耗时、计数和错误摘要 - **Webhook 日志**:读取 `webhook_log`,只展示状态、事件、URL、重试次数和错误摘要,不返回请求 payload - **邮件接收日志**:读取 `email_receiver_log`,查看收件人、发件人、主题、Webhook 状态和错误摘要 - **审计日志**:读取 `admin_audit_log`,记录用户删除、卡密生成/重置/删除、配置变更、权限策略和 API Key Scope 变更等高风险管理操作 - **配置诊断**:检查 D1、KV、Resend、Turnstile、GitHub OAuth、Auth Secret 和 `INTERNAL_WORKER_SECRET` 是否已配置,不展示密钥原文 临时账号清理 Worker 调用 `/api/cleanup/temp-accounts` 时会携带 `X-Internal-Worker-Secret` 请求头。生产环境应为主 Worker 和 `wrangler.temp-cleanup.json` 配置相同的 `INTERNAL_WORKER_SECRET`,避免外部请求伪造内部清理任务。 ## 卡密系统 XiYang Mail 支持通过卡密快速创建临时账号,用户可以跳过注册流程直接获得临时邮箱访问权限。 ### 功能特性 - 🎫 **快速入门**:通过卡密跳过注册,直接获得临时账号 - 📧 **邮箱绑定**:支持单邮箱和多邮箱两种模式 - **单邮箱模式**:一个卡密绑定一个特定邮箱地址 - **多邮箱模式**:一个卡密绑定多个预设邮箱地址 - ⏰ **自动过期**:临时账号有效期可配置(默认 7 天),到期自动删除 - 🔒 **权限限制**:只能接收邮件,无法发送邮件或删除邮箱 - 🛡️ **安全管控**:管理员可以生成、查看、重置和删除卡密 - 🔄 **卡密重置**:支持重置卡密状态,允许重复登录(保留用户数据) ### 卡密格式 卡密采用统一格式:`XYMAIL-XXXX-XXXX-XXXX` ### 管理员功能 **皇帝**角色可以在 `/admin` 页面管理卡密: 1. **生成卡密** - 选择卡密模式(单邮箱/多邮箱) - **单邮箱模式**:输入一个绑定的邮箱地址 - **多邮箱模式**:输入多个邮箱地址(逗号或换行分隔) - 设置有效期(支持分钟/小时/天单位,默认 7 天) - 支持批量生成 - 生成后显示在卡密列表中 2. **卡密管理** - 查看所有卡密列表 - 显示卡密状态(未使用/已使用/已过期) - 显示卡密模式和绑定的邮箱地址 - 一键复制卡密到剪贴板 - 重置已使用的卡密(允许重复登录) - 删除卡密(级联删除关联数据) 3. **自动清理** - 系统会自动清理过期的临时账号 - 支持手动触发清理操作 - 可配置定时清理任务 ### 用户使用流程 1. **获取卡密** - 从管理员处获得卡密 2. **卡密登录** - 访问登录页面 - 切换到"卡密登录"标签 - 输入卡密并登录 3. **使用临时账号** - 自动创建临时账号并绑定邮箱 - **单邮箱模式**:只能接收邮件到绑定的邮箱地址 - **多邮箱模式**:可以接收邮件到所有绑定的邮箱地址 - 无法创建新邮箱或发送邮件 - 默认 7 天后账号自动删除(可配置) ### 权限限制 临时用户的权限受到严格限制: - ✅ **可以做的**: - 接收邮件到绑定的邮箱地址(单邮箱或多邮箱) - 查看收到的邮件内容 - 查看邮箱列表(仅显示绑定的邮箱) - ❌ **不能做的**: - 创建新的邮箱地址 - 删除或修改绑定的邮箱 - 发送邮件 - 配置 Webhook - 创建 API Key - 访问管理功能 ### 自动清理机制 系统提供自动清理过期临时账号的功能: 1. **API 清理** - 提供 `/api/cleanup/temp-accounts` 接口 - 支持手动调用清理过期账号 2. **定时清理** - 可配置 Cloudflare Worker 定时任务 - **每 30 分钟**自动执行清理过期账号 - 清理时会删除相关用户数据和邮箱 3. **配置定时任务** ```bash # 复制配置文件 cp wrangler.temp-cleanup.example.json wrangler.temp-cleanup.json # 修改配置中的 SITE_URL 和 KV_NAMESPACE_ID # 部署定时清理 Worker(默认每 30 分钟执行一次) wrangler deploy --config wrangler.temp-cleanup.json ``` ### 注意事项 - 🔐 **安全性**:卡密一次性使用,使用后无法重复使用 - ⏰ **有效期**:临时账号严格按照 7 天有效期执行 - 📧 **邮箱绑定**:每个卡密只能绑定一个邮箱地址 - 🗑️ **自动清理**:过期账号会被自动删除,无法恢复 - 👑 **管理权限**:只有皇帝角色可以生成和管理卡密 ## 系统设置 系统设置存储在 Cloudflare KV 中,包括以下内容: - `DEFAULT_ROLE`: 新注册用户默认角色,可选值为 `CIVILIAN`、`KNIGHT`、`DUKE` - `EMAIL_DOMAINS`: 支持的邮箱域名,多个域名用逗号分隔 - `ADMIN_CONTACT`: 管理员联系方式 - `MAX_EMAILS`: 每个用户可创建的最大邮箱数量 - `EMAIL_PREFIX_LENGTH`: 邮箱前缀长度(4-20 位,默认 8 位) - `EMAIL_PREFIX_FORMAT`: 邮箱前缀生成格式 - `MESSAGE_POLL_INTERVAL`: 消息自动刷新间隔(毫秒,默认 15000,建议 5000-30000) **皇帝**角色可以在个人中心页面设置 ### 消息自动刷新配置 系统支持可配置的消息自动刷新功能,管理员可以在网站设置中调整刷新间隔。前端倒计时和后端轮询完全同步,确保刷新时间准确一致;当轮询失败时前端会自动退避重试,并在标签页隐藏时暂停轮询以减少无效请求。 **配置方式**: 1. 皇帝角色登录系统 2. 进入个人中心 → 网站设置 3. 找到"消息自动刷新配置"部分 4. 设置刷新间隔(3000-60000 毫秒) 5. 保存配置 **同步机制**: - 前端倒计时每秒递减,归零时自动触发刷新 - 手动刷新后倒计时自动重置 - 倒计时进度环形图实时显示刷新进度 **Cloudflare 免费套餐限制**: - Workers 请求:100,000 次/天 - 假设 100 个活跃用户,5 秒刷新会产生约 1,728,000 次/天请求 - 建议根据实际用户数量调整: - 小规模(<10 用户):5 秒安全 ✅ - 中等规模(10-50 用户):10-15 秒 ⚠️ - 大规模(>50 用户):20-30 秒或升级套餐 ❌ ### 邮箱前缀生成配置 当用户创建邮箱时不输入前缀,系统会根据配置自动生成。支持以下格式: | 格式选项 | 说明 | 示例 | | --------------- | --------------------------- | ------------------------ | | 随机字符串 | 字母+数字的随机组合(默认) | `Rx4Tn2kP` | | 纯随机字母 | 纯字母随机组合(无数字) | `abcdefgh`、`xyzwvuts` | | 名字+随机数字 | 常见英文名+3-5 位数字 | `james123`、`emma4567` | | 名字+日期 | 常见英文名+月份日期(MMDD) | `john0524`、`mary1208` | | 名字+年份 | 常见英文名+随机年份(YYYY) | `david1995`、`sarah2001` | | 随机字符串+日期 | 随机字符+月份日期(MMDD) | `abc0524`、`xyz1208` | | 随机字符串+年份 | 随机字符+随机年份(YYYY) | `xyz1995`、`abc2001` | **配置方式**: 1. 皇帝角色登录系统 2. 进入个人中心 → 网站设置 3. 找到"邮箱前缀生成配置"部分 4. 设置前缀长度(4-20 位) 5. 选择生成格式 6. 保存配置 **使用说明**: - 前端创建邮箱时可以留空前缀,系统会自动生成 - 点击刷新按钮可预览当前配置生成的前缀 - 用户也可以手动输入自定义前缀 **名字生成库**: 当前使用内置的常见英文名字列表(共 120 个名字:60 个男性名字 + 60 个女性名字)。 - **优势**: 零依赖,无额外包大小,符合 Cloudflare Edge Runtime 限制 - **扩展**: 可以在 `app/lib/email-generator.ts` 中的 `COMMON_NAMES` 数组添加更多名字 - **替代方案**: 如需使用第三方库,推荐轻量级的 `casual` (约 100KB) 或 `chance` (约 200KB) - **不推荐**: `@faker-js/faker` 完整版约 5MB,会超出 Edge Runtime 1MB 代码限制 ## 发件功能 XiYang Mail 支持使用临时邮箱发送邮件,基于 [Resend](https://resend.com/) 服务。 ### 功能特性 - 📨 **临时邮箱发件**:可以使用创建的临时邮箱作为发件人发送邮件 - 🎯 **角色权限控制**:不同角色有不同的每日发件限制 - 💌 **支持 HTML**:支持发送富文本格式邮件 ### 角色发件权限 | 角色 | 每日发件限制 | 说明 | | -------------------- | ------------ | ----------------------- | | 皇帝 (Emperor) | 无限制 | 网站管理员,无发件限制 | | 公爵 (Duke) | 5 封/天 | 默认每日可发送 5 封邮件 | | 骑士 (Knight) | 2 封/天 | 默认每日可发送 2 封邮件 | | 平民 (Civilian) | 禁止发件 | 无发件权限 | | 临时用户 (Temp User) | 禁止发件 | 卡密用户无发件权限 | > 💡 **提示**:皇帝可以在个人中心的邮件服务配置中自定义公爵和骑士的每日发件限制。 ### 配置发件服务 1. **获取 Resend API Key** - 访问 [Resend 官网](https://resend.com/) 注册账号 - 在控制台中创建 API Key - 复制 API Key 供后续配置使用 2. **配置发件服务** - 皇帝角色登录 XiYang Mail - 进入个人中心页面 - 在"Resend 发件服务配置"部分: - 启用发件服务开关 - 填入 Resend API Key - 设置公爵和骑士的每日发件限制(可选) - 点击保存配置 3. **验证配置** - 配置保存后,有权限的用户在邮箱列表页面会看到"发送邮件"按钮 - 点击按钮可以打开发件对话框进行测试 ### 使用发件功能 1. **创建临时邮箱** - 在邮箱页面创建一个新的临时邮箱 2. **发送邮件** - 在邮箱列表中找到要使用的邮箱 - 点击邮箱旁边的"发送邮件"按钮 - 在弹出的对话框中填写: - 收件人邮箱地址 - 邮件主题 - 邮件内容(支持 HTML 格式) - 点击"发送"按钮 3. **查看发送记录** - 发送的邮件会自动保存到对应邮箱的消息列表中 - 可以在邮箱详情页面查看所有发送和接收的邮件 ### 注意事项 - 📋 **Resend 限制**:请注意 Resend 服务的发送限制和定价政策 - 🔐 **域名验证**:使用自定义域名发件需要在 Resend 中验证域名 - 🚫 **反垃圾邮件**:请遵守邮件发送规范,避免发送垃圾邮件 - 📊 **配额监控**:系统会自动统计每日发件数量,达到限额后将无法继续发送 - 🔄 **配额重置**:每日发件配额在每天 00:00 自动重置 ## Webhook 集成 当收到新邮件时,系统会向用户配置并且已启用的 Webhook URL 发送 POST 请求。 ### 请求头 ```http Content-Type: application/json X-Webhook-Event: new_message ``` ### 请求体 ```json { "emailId": "email-uuid", "messageId": "message-uuid", "fromAddress": "sender@example.com", "subject": "邮件主题", "content": "邮件文本内容", "html": "邮件HTML内容", "receivedAt": "2024-01-01T12:00:00.000Z", "toAddress": "your-email@mail.xiyangone.cn" } ``` ### 配置说明 1. 点击个人头像,进入个人中心 2. 在个人中心启用 Webhook 3. 设置接收通知的 URL 4. 点击测试按钮验证配置 5. 保存配置后即可接收新邮件通知 ### 测试 项目提供了一个简单的测试服务器, 可以通过如下命令运行: ```bash pnpm webhook-test-server ``` 测试服务器会在本地启动一个 HTTP 服务器,监听 3001 端口(http://localhost:3001), 并打印收到的 Webhook 消息详情。 如果需要进行外网测试,可以通过 Cloudflare Tunnel 将服务暴露到外网: ```bash pnpx cloudflared tunnel --url http://localhost:3001 ``` ### 注意事项 - Webhook 接口应在 10 秒内响应 - 非 2xx 响应码会触发重试 ## 分享功能 XiYang Mail 支持生成邮箱分享链接,方便与他人分享邮件内容。 ### 功能特性 - 📧 **邮箱分享**:分享整个邮箱,他人可查看该邮箱的所有邮件 - ⏰ **灵活有效期**:支持 1小时、24小时、3天或永久有效 - 🔗 **一键复制**:快速复制分享链接到剪贴板 - 📱 **响应式设计**:桌面端双栏布局,移动端单栏布局 - 🎨 **主题支持**:支持日间、夜间、樱花、琥珀四种主题 - ⚠️ **过期提示**:链接过期后显示明确的错误提示 ### 使用方法 1. 在邮箱列表中找到要分享的邮箱 2. 点击邮箱旁边的"分享"按钮 3. 在弹出的对话框中: - 选择链接有效期(1小时/24小时/3天/永久) - 点击"创建链接"按钮 4. 创建成功后,可以: - 点击链接在新标签页中预览 - 点击"复制"按钮复制链接 - 点击"删除"按钮删除分享链接 ### 分享链接格式 - **邮箱分享链接**:`https://your-domain.com/shared/{token}` ### 分享页面功能 - 显示邮箱地址和过期时间 - 显示该邮箱的所有邮件列表 - 桌面端:左侧邮件列表,右侧邮件详情 - 移动端:单栏布局,支持返回导航 - 支持HTML和纯文本两种查看模式 - 支持刷新邮件列表 ### 安全说明 - 🔒 **Token 安全**:分享链接使用 16 位随机 token,难以猜测 - ⏰ **自动过期**:链接到期后自动失效,无法访问 - 🗑️ **随时删除**:可以随时删除分享链接,立即失效 - 👁️ **只读访问**:分享链接只能查看内容,无法修改或删除 ### 注意事项 - 分享链接可以被任何人访问,请谨慎分享敏感信息 - 建议为敏感邮件设置较短的有效期 - 删除分享链接后,该链接将立即失效 - 过期的分享链接会显示 410 Gone 错误页面 ## OpenAPI 本项目提供了 OpenAPI 接口,支持通过 API Key 进行访问。API Key 可以在个人中心页面创建(需要是公爵或皇帝角色)。 ### 使用 API Key 在请求头中添加 API Key: ```http X-API-Key: YOUR_API_KEY ``` ### API 接口 #### 获取系统配置 ```http GET /api/config ``` 返回响应: ```json { "defaultRole": "CIVILIAN", "emailDomains": "mail.xiyangone.cn,example.com", "adminContact": "admin@example.com", "maxEmails": "10" } ``` 响应字段说明: - `defaultRole`: 新用户默认角色,可选值:`CIVILIAN`(平民)、`KNIGHT`(骑士)、`DUKE`(公爵) - `emailDomains`: 支持的邮箱域名,多个域名用逗号分隔 - `adminContact`: 管理员联系方式 - `maxEmails`: 每个用户可创建的最大邮箱数量 #### 创建临时邮箱 ```http POST /api/emails/generate Content-Type: application/json { "name": "test", "expiryTime": 3600000, "domain": "mail.xiyangone.cn" } ``` 参数说明: - `name`: 邮箱前缀,可选 - `expiryTime`: 有效期(毫秒),可选值:3600000(1 小时)、86400000(1 天)、604800000(7 天)、0(永久) - `domain`: 邮箱域名,可通过 `/api/config` 接口获取 返回响应: ```json { "id": "email-uuid-123", "email": "test@mail.xiyangone.cn" } ``` 响应字段说明: - `id`: 邮箱的唯一标识符 - `email`: 创建的邮箱地址 #### 获取邮箱列表 ```http GET /api/emails?cursor=xxx ``` 参数说明: - `cursor`: 分页游标,可选 返回响应: ```json { "emails": [ { "id": "email-uuid-123", "address": "test@mail.xiyangone.cn", "createdAt": "2024-01-01T12:00:00.000Z", "expiresAt": "2024-01-02T12:00:00.000Z", "userId": "user-uuid-456" } ], "nextCursor": "encoded-cursor-string", "total": 5 } ``` 响应字段说明: - `emails`: 邮箱列表数组 - `nextCursor`: 下一页游标,用于分页请求 - `total`: 邮箱总数量 #### 获取指定邮箱邮件列表 ```http GET /api/emails/{emailId}?cursor=xxx ``` 参数说明: - `emailId`: 邮箱的唯一标识符,必填 - `cursor`: 分页游标,可选 返回响应: ```json { "messages": [ { "id": "message-uuid-789", "from_address": "sender@example.com", "subject": "邮件主题", "received_at": 1704110400000 } ], "nextCursor": "encoded-cursor-string", "total": 3 } ``` 响应字段说明: - `messages`: 邮件列表数组 - `nextCursor`: 下一页游标,用于分页请求 - `total`: 邮件总数量 #### 删除邮箱 ```http DELETE /api/emails/{emailId} ``` 参数说明: - `emailId`: 邮箱的唯一标识符,必填 返回响应: ```json { "success": true } ``` 响应字段说明: - `success`: 删除操作是否成功 #### 获取单封邮件内容 ```http GET /api/emails/{emailId}/{messageId} ``` 参数说明: - `emailId`: 邮箱的唯一标识符,必填 - `messageId`: 邮件的唯一标识符,必填 返回响应: ```json { "message": { "id": "message-uuid-789", "from_address": "sender@example.com", "subject": "邮件主题", "content": "邮件文本内容", "html": "邮件HTML内容
", "received_at": 1704110400000 } } ``` 响应字段说明: - `message`: 邮件详细信息对象 - `id`: 邮件的唯一标识符 - `from_address`: 发件人邮箱地址 - `subject`: 邮件主题 - `content`: 邮件纯文本内容 - `html`: 邮件 HTML 内容 - `received_at`: 接收时间(时间戳) #### 智能获取验证码 ```http POST /api/emails/{emailId}/verification-code Content-Type: application/json { "fromAddress": "verify.windsurf.ai", "interval": 3000, "timeout": 60000 } ``` 参数说明: - `emailId`: 邮箱的唯一标识符,必填 - `fromAddress`: 发件人地址过滤(可选),例如 "verify.windsurf.ai",如果不指定则从最新邮件中提取 - `interval`: 轮询间隔(毫秒),可选,默认 3000ms - `timeout`: 超时时间(毫秒),可选,默认 60000ms `fromAddress` 会优先按邮件的可见发件人(`From` 头)匹配;如果某些旧邮件仍显示中继投递地址,可先查看返回的 `stats.sampleSenders`,或者先用域名过滤再确认。 返回响应: ```json { "code": "123456", "success": true } ``` 响应字段说明: - `code`: 提取到的验证码 - `success`: 操作是否成功 错误响应: ```json { "error": "已收到邮件,但未能识别出验证码", "hint": "请直接查看邮件正文确认验证码格式,或适当延长 timeout 后重试", "reason": "timeout_no_code_match", "stats": { "timeoutMs": 60000, "intervalMs": 3000, "messagesSeen": 3, "senderMatchedMessages": 1, "lastMessageAt": 1737012345678, "fromAddress": "verify.windsurf.ai", "sampleSenders": [ "Windsurf