108 lines
3.9 KiB
Markdown
108 lines
3.9 KiB
Markdown
# Office 365 Mail Console
|
||
|
||
一个最小化的 Web 控制台,用于:
|
||
|
||
- 列出租户中的成员账号
|
||
- 点击账号后读取该账号收件箱中的最新一封邮件
|
||
|
||
## 环境要求
|
||
|
||
- Node.js 18+
|
||
- Microsoft Entra 应用注册
|
||
- 已授予并管理员同意以下 Microsoft Graph Application Permissions:
|
||
- `Mail.Read`
|
||
- `User.Read.All`
|
||
- `User.ReadWrite.All`
|
||
|
||
## 配置
|
||
|
||
1. 复制 `.env.example` 为 `.env`
|
||
2. 填入以下值:
|
||
|
||
```env
|
||
TENANT_ID=your-tenant-id
|
||
CLIENT_ID=your-client-id
|
||
CLIENT_SECRET=your-client-secret
|
||
MAILBOX_ADDRESS=
|
||
DEFAULT_DOMAIN=
|
||
ACCESS_PASSWORD=change-this-password
|
||
PORT=3000
|
||
```
|
||
|
||
说明:
|
||
|
||
- `MAILBOX_ADDRESS` 为可选默认选中账号。页面首次加载完成后,如果能在租户中找到这个邮箱地址,会自动展示它的最新邮件。
|
||
- `DEFAULT_DOMAIN` 为创建随机用户时使用的域名。未填写时,程序会尝试从 `MAILBOX_ADDRESS` 提取域名。
|
||
- `ACCESS_PASSWORD` 为访问控制台所需的口令。设置后,用户必须先输入该密码才能打开页面和访问 API。
|
||
- 读取租户账号和邮件实际依赖的是 `TENANT_ID`、`CLIENT_ID`、`CLIENT_SECRET`。
|
||
|
||
### Entra ID (Azure AD) 应用配置参数说明
|
||
|
||
| 参数名 | 必填 | 说明 | 获取方式 |
|
||
| --- | --- | --- | --- |
|
||
| `TENANT_ID` | 是 | Entra 租户 ID,用于向租户申请 Graph 访问令牌 | Azure AD 应用注册概览页 |
|
||
| `CLIENT_ID` | 是 | 应用程序(客户端) ID,用于标识当前应用 | Azure AD 应用注册概览页 |
|
||
| `CLIENT_SECRET` | 是 | 应用客户端密钥,用于应用身份认证 | Azure AD「证书和密码」 |
|
||
| `Mail.Read` | 是 | 读取邮箱内容所需的 Microsoft Graph 应用程序权限 | Azure AD「API 权限」 |
|
||
| `User.Read.All` | 是 | 列出租户成员账号所需的 Microsoft Graph 应用程序权限 | Azure AD「API 权限」 |
|
||
| `User.ReadWrite.All` | 是 | 创建随机用户所需的 Microsoft Graph 应用程序权限 | Azure AD「API 权限」 |
|
||
| `ACCESS_PASSWORD` | 可选 | 控制台访问密码,设置后访问页面前必须先登录 | 自定义 |
|
||
|
||
补充说明:
|
||
|
||
- 这三个 Graph 权限都要选择「应用程序权限」,并完成管理员同意。
|
||
- 本项目采用 `client_credentials` 模式,不需要配置重定向 URI。
|
||
- 如果只配置 `Mail.Read`,页面可以读邮件,但无法列出所有账号;如果只配置 `User.Read.All`,页面可以列出账号,但无法读取邮件正文。
|
||
- 创建随机用户需要 `User.ReadWrite.All`,并且目标域名必须是租户可用域名。
|
||
|
||
## 运行
|
||
|
||
```bash
|
||
npm install
|
||
npm start
|
||
```
|
||
|
||
启动后访问:`http://localhost:3000`
|
||
|
||
如果已设置 `ACCESS_PASSWORD`,首次访问会先进入登录页。
|
||
|
||
## Docker Compose 部署
|
||
|
||
```bash
|
||
# 1. 复制配置文件
|
||
cp .env.example .env
|
||
|
||
# 2. 填入 .env 中的 TENANT_ID / CLIENT_ID / CLIENT_SECRET / ACCESS_PASSWORD
|
||
|
||
# 3. 构建并启动
|
||
docker compose up -d --build
|
||
|
||
# 4. 查看日志
|
||
docker compose logs -f
|
||
|
||
# 5. 停止服务
|
||
docker compose down
|
||
```
|
||
|
||
默认映射端口:`3000`
|
||
|
||
如果需要修改外部端口,调整 `docker-compose.yml` 中的 `ports` 映射即可。
|
||
|
||
## 接口
|
||
|
||
- `GET /api/users`
|
||
- 返回租户成员账号列表
|
||
- `GET /api/users/:userId/latest-email`
|
||
- 返回该账号收件箱最新一封邮件
|
||
- `GET /api/users/:userId/latest-email/body`
|
||
- 返回该账号收件箱最新一封邮件正文
|
||
- `POST /api/users/random`
|
||
- 自动创建一个随机用户名的新用户,并返回用户主体与临时密码
|
||
|
||
## 注意事项
|
||
|
||
- 账号列表依赖 `User.Read.All`,否则无法拉取租户用户。
|
||
- 某些账号虽然存在于租户中,但不一定拥有 Exchange 邮箱;这类账号读取邮件时可能返回空结果或权限错误。
|
||
- 当前页面以邮件全文为主,保留发件人和接收时间,并显示完整 HTML / 纯文本正文。
|
||
- 当前版本使用基于 Cookie 的本地访问验证;更换 `ACCESS_PASSWORD` 后,旧登录会话会失效。
|