Files
office365-mail/README.md
2026-04-02 21:16:23 +08:00

99 lines
3.3 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.
# Office 365 Mail Console
一个最小化的 Web 控制台,用于:
- 列出租户中的成员账号
- 点击账号后读取该账号收件箱中的最新一封邮件
## 环境要求
- Node.js 18+
- Microsoft Entra 应用注册
- 已授予并管理员同意以下 Microsoft Graph Application Permissions:
- `Mail.Read`
- `User.Read.All`
## 配置
1. 复制 `.env.example``.env`
2. 填入以下值:
```env
TENANT_ID=your-tenant-id
CLIENT_ID=your-client-id
CLIENT_SECRET=your-client-secret
MAILBOX_ADDRESS=
ACCESS_PASSWORD=change-this-password
PORT=3000
```
说明:
- `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 权限」 |
| `ACCESS_PASSWORD` | 可选 | 控制台访问密码,设置后访问页面前必须先登录 | 自定义 |
补充说明:
- 这两个 Graph 权限都要选择「应用程序权限」,并完成管理员同意。
- 本项目采用 `client_credentials` 模式,不需要配置重定向 URI。
- 如果只配置 `Mail.Read`,页面可以读邮件,但无法列出所有账号;如果只配置 `User.Read.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`
- 返回该账号收件箱最新一封邮件
## 注意事项
- 账号列表依赖 `User.Read.All`,否则无法拉取租户用户。
- 某些账号虽然存在于租户中,但不一定拥有 Exchange 邮箱;这类账号读取邮件时可能返回空结果或权限错误。
- 当前页面以邮件全文为主,保留发件人和接收时间,并显示完整 HTML / 纯文本正文。
- 当前版本使用基于 Cookie 的本地访问验证;更换 `ACCESS_PASSWORD` 后,旧登录会话会失效。