Initial commit for mail-sr

This commit is contained in:
zeer
2026-04-25 20:51:08 +08:00
commit 37907dd2f5
14 changed files with 4628 additions and 0 deletions

335
README.md Normal file
View File

@@ -0,0 +1,335 @@
# 多邮箱帐号收发系统
一个基于 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
```
### 3. 启动服务
```bash
npm start
```
访问地址:`http://localhost:3000`
## Docker 部署
项目已经提供 `Dockerfile``docker-compose.yml`,可以直接用 Docker Compose 部署。
### 1. 准备环境变量
```bash
cp .env.example .env
```
如果你不需要额外环境变量,默认配置即可。
### 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 使用说明
### 1. 渠道管理
在设置弹窗中可以新增渠道,填写:
- 渠道名称
- 渠道标识 code
- IMAP 主机、端口、是否 SSL
- SMTP 主机、端口、是否 SSL
### 2. 单个邮箱帐号导入
在设置弹窗中填写:
- 渠道
- 邮箱帐号
- 授权码
- 发件人名称,可选
### 3. 批量导入导出
支持以下格式,每行一条:
```text
渠道名----帐号----授权码
```
例如:
```text
QQ邮箱----demo@qq.com----abcd1234
163邮箱----demo@163.com----efgh5678
```
说明:
- 导入时按“渠道名”匹配已有渠道
- 如果渠道不存在,会直接报错
- 如果同一渠道下邮箱已存在,则更新授权码
- 导出会导出全部帐号,格式同上
### 4. 收信
点击左侧邮箱帐号后会:
- 复制邮箱号到剪贴板
- 立即触发收信
- 拉取全部可读文件夹中的最近邮件
- 在中间栏展示邮件列表
- 在右侧显示邮件详情
为了避免 IMAP 全量拉取过慢,系统使用“两阶段策略”:
- 先同步邮件列表与头信息
- 打开某封邮件时再按需拉取正文详情
### 5. 发信
点击左上角“写邮件”按钮,选择当前邮箱帐号后即可发信。
## API 文档
### 健康检查
```bash
curl http://localhost:3000/api/health
```
### 查询渠道
```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 邮件安全隔离策略