Files
mail-rs/README.md
2026-04-25 20:57:24 +08:00

382 lines
7.6 KiB
Markdown
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.
# 多邮箱帐号收发系统
一个基于 Node.js + Express + SQLite 的多邮箱工作台,支持在网页中统一管理多个邮箱渠道与邮箱帐号,进行收信、查看邮件、发信,以及通过 API 调用邮件能力。
## 功能特性
- 支持配置多个邮箱渠道,如 QQ 邮箱、163 邮箱和自定义 IMAP/SMTP 渠道
- 支持导入邮箱帐号与授权码
- 三栏式 Web 界面:邮箱帐号、邮件列表、邮件详情
- 支持网页写邮件、发邮件、查看邮件详情
- 支持拉取多文件夹邮件,不限于 `INBOX`
- 支持按需补拉单封邮件正文,避免全量同步过慢
- 支持批量导入导出邮箱信息
- 支持访问密码保护,未输入密码无法进入功能页面
- 提供 API 用于发邮件、获取邮件列表、获取最新一封邮件
## 技术栈
- Node.js
- Express
- SQLite `better-sqlite3`
- SMTP `nodemailer`
- IMAP `imapflow`
- 前端:原生 HTML / CSS / JavaScript
## 目录结构
```text
mail-sr/
├── public/
│ ├── index.html
│ ├── styles.css
│ └── app.js
├── db.js
├── mailService.js
├── server.js
├── Dockerfile
├── docker-compose.yml
└── README.md
```
## 本地启动
### 1. 安装依赖
```bash
npm install
```
### 2. 配置环境变量
```bash
cp .env.example .env
```
默认环境变量:
```env
PORT=3000
DB_PATH=./mail.db
APP_PASSWORD=change-this-password
```
说明:
- `APP_PASSWORD` 用于控制页面和 API 访问
- 设置后,必须先在登录页输入正确密码才能进入系统
- 如果留空,则不启用密码保护
### 3. 启动服务
```bash
npm start
```
访问地址:`http://localhost:3000`
## Docker 部署
项目已经提供 `Dockerfile``docker-compose.yml`,可以直接用 Docker Compose 部署。
### 1. 准备环境变量
```bash
cp .env.example .env
```
如果你不需要额外环境变量,默认配置即可。
如果启用访问密码,请在 `.env` 中设置:
```env
APP_PASSWORD=your-strong-password
```
### 2. 构建并启动
```bash
docker compose up -d --build
```
启动后访问:`http://localhost:3000`
### 3. 停止服务
```bash
docker compose down
```
### 4. 查看日志
```bash
docker compose logs -f
```
### 5. 数据持久化
Docker Compose 默认使用命名卷 `mail-sr-data` 持久化 SQLite 数据库,容器重建后数据不会丢失。
容器内数据库路径:
```text
/data/mail.db
```
## 内置邮箱渠道
系统默认会初始化以下渠道:
- QQ邮箱
- IMAP: `imap.qq.com:993`
- SMTP: `smtp.qq.com:465`
- 163邮箱
- IMAP: `imap.163.com:993`
- SMTP: `smtp.163.com:465`
说明:通常需要在邮箱后台开启 IMAP/SMTP并使用授权码而不是邮箱登录密码。
## Web 使用说明
### 0. 登录保护
如果 `.env` 中设置了 `APP_PASSWORD`,打开首页后会先进入登录页。
- 输入正确密码后,服务端会写入 `HttpOnly Cookie`
- 后续页面请求会基于该 Cookie 校验访问权限
- 点击左下角退出按钮可清除登录状态
### 1. 渠道管理
在设置弹窗中可以新增渠道,填写:
- 渠道名称
- 渠道标识 code
- IMAP 主机、端口、是否 SSL
- SMTP 主机、端口、是否 SSL
### 2. 单个邮箱帐号导入
在设置弹窗中填写:
- 渠道
- 邮箱帐号
- 授权码
- 发件人名称,可选
### 3. 批量导入导出
支持以下格式,每行一条:
```text
渠道名----帐号----授权码
```
例如:
```text
QQ邮箱----demo@qq.com----abcd1234
163邮箱----demo@163.com----efgh5678
```
说明:
- 导入时按“渠道名”匹配已有渠道
- 如果渠道不存在,会直接报错
- 如果同一渠道下邮箱已存在,则更新授权码
- 导出会导出全部帐号,格式同上
### 4. 收信
点击左侧邮箱帐号后会:
- 复制邮箱号到剪贴板
- 立即触发收信
- 拉取全部可读文件夹中的最近邮件
- 在中间栏展示邮件列表
- 在右侧显示邮件详情
为了避免 IMAP 全量拉取过慢,系统使用“两阶段策略”:
- 先同步邮件列表与头信息
- 打开某封邮件时再按需拉取正文详情
### 5. 发信
点击左上角“写邮件”按钮,选择当前邮箱帐号后即可发信。
## API 文档
`健康检查``登录状态``登录接口` 外,其余 API 在启用 `APP_PASSWORD` 时都需要先登录。
### 健康检查
```bash
curl http://localhost:3000/api/health
```
### 登录状态
```bash
curl http://localhost:3000/api/auth/status
```
### 登录
```bash
curl -X POST http://localhost:3000/api/auth/login \
-H 'Content-Type: application/json' \
-d '{
"password": "your-strong-password"
}'
```
### 退出登录
```bash
curl -X POST http://localhost:3000/api/auth/logout
```
### 查询渠道
```bash
curl http://localhost:3000/api/channels
```
### 新增渠道
```bash
curl -X POST http://localhost:3000/api/channels \
-H 'Content-Type: application/json' \
-d '{
"name": "企业邮箱",
"code": "corp",
"imap_host": "imap.example.com",
"imap_port": 993,
"imap_secure": true,
"smtp_host": "smtp.example.com",
"smtp_port": 465,
"smtp_secure": true
}'
```
### 查询帐号列表
```bash
curl http://localhost:3000/api/accounts
```
### 新增邮箱帐号
```bash
curl -X POST http://localhost:3000/api/accounts \
-H 'Content-Type: application/json' \
-d '{
"channel_id": 1,
"email": "your-account@qq.com",
"auth_code": "邮箱授权码",
"display_name": "业务邮箱"
}'
```
### 删除邮箱帐号
```bash
curl -X DELETE http://localhost:3000/api/accounts/1
```
### 批量导出帐号
```bash
curl http://localhost:3000/api/accounts/export
```
### 批量导入帐号
```bash
curl -X POST http://localhost:3000/api/accounts/import \
-H 'Content-Type: application/json' \
-d '{
"content": "QQ邮箱----demo@qq.com----abcd1234\n163邮箱----demo@163.com----efgh5678"
}'
```
### 发送邮件
```bash
curl -X POST http://localhost:3000/api/send \
-H 'Content-Type: application/json' \
-d '{
"accountId": 1,
"to": "target@example.com",
"subject": "测试邮件",
"text": "这是一封来自 API 的测试邮件"
}'
```
### 获取邮件列表
首次建议带 `refresh=true`,从远程 IMAP 同步最新邮件。
```bash
curl "http://localhost:3000/api/messages?accountId=1&limit=20&refresh=true"
```
### 获取最新一封邮件
```bash
curl "http://localhost:3000/api/messages/latest?accountId=1&refresh=true"
```
### 获取单封邮件详情
```bash
curl "http://localhost:3000/api/accounts/1/messages/INBOX%3A123?refresh=true"
```
说明:`uid` 需要使用 URL 编码。
## 数据说明
- `channels`:邮箱渠道配置
- `accounts`:邮箱帐号和授权码
- `mail_cache`:同步后的邮件缓存
默认本地数据库文件为:
```text
./mail.db
```
如果通过 Docker 运行,则默认为:
```text
/data/mail.db
```
## 部署建议
- 生产环境建议使用反向代理,如 Nginx 或 Traefik
- 建议通过 HTTPS 暴露服务
- 当前授权码存储在 SQLite 中,生产环境建议改为加密存储
- 建议增加访问控制与登录认证,避免未授权访问
## 当前实现边界
- 当前未实现附件上传与下载
- 当前未实现用户登录、权限和多租户隔离
- 当前邮件缓存为本地 SQLite不适合超大规模并发
- 当前 HTML 邮件正文做了基础清理,但不是完整沙箱渲染
## 后续建议
如果准备继续往生产方向演进,建议优先补以下能力:
1. 用户登录与权限管理
2. 授权码加密存储
3. 附件收发
4. 邮件标签、已读未读、分页
5. 定时自动拉取邮件
6. 发信模板和批量发信
7. 更完整的 HTML 邮件安全隔离策略