2026-04-02 21:16:23 +08:00
2026-04-02 21:16:23 +08:00
2026-04-02 21:16:23 +08:00
2026-04-02 21:16:23 +08:00
2026-04-02 21:16:23 +08:00
2026-04-02 21:16:23 +08:00
2026-04-02 21:16:23 +08:00
2026-04-02 21:16:23 +08:00
2026-04-02 21:16:23 +08:00
2026-04-02 21:16:23 +08:00
2026-04-02 21:16:23 +08:00

Office 365 Mail Console

一个最小化的 Web 控制台,用于:

  • 列出租户中的成员账号
  • 点击账号后读取该账号收件箱中的最新一封邮件

环境要求

  • Node.js 18+
  • Microsoft Entra 应用注册
  • 已授予并管理员同意以下 Microsoft Graph Application Permissions:
    • Mail.Read
    • User.Read.All

配置

  1. 复制 .env.example.env
  2. 填入以下值:
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_IDCLIENT_IDCLIENT_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,页面可以列出账号,但无法读取邮件正文。

运行

npm install
npm start

启动后访问:http://localhost:3000

如果已设置 ACCESS_PASSWORD,首次访问会先进入登录页。

Docker Compose 部署

# 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 后,旧登录会话会失效。
Description
No description provided
Readme 71 KiB
Languages
JavaScript 72.1%
CSS 17.5%
HTML 10%
Dockerfile 0.4%