firmiana introduction
基于 Micronaut 4.10.1 和 GraalVM JDK 21 构建的本地优先 Matrix homeserver 实现。
Firmiana 已实现 Client-Server homeserver 全流程,并覆盖联邦、应用服务、身份服务集成和生产运维基础。
✨ 亮点
- Matrix Client-Server API (P0) — 注册、登录、登出、创建房间、邀请/加入、状态事件、发送消息、
/sync、/messages、/context、撤回、在线状态、正在输入、已读回执、账户数据、过滤器和用户目录。 - 端到端加密 (P1) — 设备密钥上传/查询/申请、备用密钥、设备签名、密钥备份、同步中的设备列表变更以及房间密钥备份端点。
- 媒体与推送 (P1) — 上传/下载、缩略图缓存、远程媒体缓存、带 SSRF 防护的 URL 预览缓存、隔离、保留清理、推送规则引擎、
/notifications和上下文搜索。 - 联邦 (P2) — 服务器发现、签名密钥、规范化 JSON 请求签名、
PUT /send、加入/邀请/离开模板、状态/回填查询以及设备/密钥联邦端点。 - 应用服务 (P2) — 注册加载、
as_token认证、命名空间匹配、带重试的事务推送以及查询端点。 - 身份服务 (P2) — 禁用/外部/嵌入式策略模式,外部代理用于 lookup/hash-details/store-invite/validateToken。
- 存储、运维与测试 (P3) — 23 个 Flyway 迁移、查询索引、health 端点、速率限制器、结构化日志/JVM 指标、244 个测试覆盖矩阵。
- 客户端兼容 (P4) — Space 与房间层级、关系/线程/聚合、Sliding Sync、房间版本 1–10、默认推送规则、公开房间元数据。
- 生产联邦与管理 (P5) — 带退避的联邦目标队列、事件哈希校验、restricted join、EDU 处理、管理 API(whois/用户/房间/踢出/封禁/清理)、安全响应头、基于环境变量的密钥覆盖。
🚀 快速开始
前置条件
- GraalVM JDK 21+
- Maven 3.9+(本项目不附带
mvnw)
本地运行
1
2
3
4
5
6
7
8
9
10
11
# 编译
mvn compile
# 运行测试
mvn test
# 在 8899 端口启动服务
mvn exec:java
# 构建可运行 JAR
mvn package
服务默认监听 http://localhost:8899。
验证运行
1
curl http://localhost:8899/_matrix/client/versions
⚙️ 配置
主要配置位于 src/main/resources/application.yml。
| 属性 | 默认值 | 说明 |
|---|---|---|
micronaut.server.port | 8899 | HTTP 服务端口 |
datasources.default.url | jdbc:h2:file:./data/matrix;... | H2 数据库 URL |
h2.path | ./data/matrix | H2 文件路径(遗留属性) |
h2.schema-initializer.enabled | false | 默认使用 Flyway;遗留 H2 DDL 回退 |
matrix.server-name | — | Homeserver 名称(例如 localhost:8899) |
src/main/resources/application.properties 已加入 gitignore,可用于本地密钥/覆盖。请勿提交生产环境密钥。
🗄️ 数据库
- 引擎: 基于文件的 H2 数据库(
./data/matrix.mv.db) - Schema 管理:
src/main/resources/db/migration/中的 Flyway 迁移脚本(V1–V23) - 访问: 使用 H2 方言的 Micronaut Data JDBC 仓库
- 遗留回退:
H2SchemaInitializer默认禁用,仅作参考
关键表:users、user_devices、user_passwords、user_access_tokens、user_refresh_tokens、user_uiaa_data、user_data、user_filter、room、room_user、event、event_dag、state_group、server_signing_key、appservice_registration 等。
📡 API 概览
Client-Server API (/_matrix/client/v3)
| 端点 | 说明 |
|---|---|
POST /register | 用户注册(含 UIAA) |
POST /login | 登录(密码、令牌) |
POST /logout | 使访问令牌失效 |
POST /refresh | 刷新访问令牌轮换 |
POST /createRoom | 创建房间 |
POST /join/{roomId} | 加入房间 |
POST /rooms/{roomId}/invite | 邀请用户 |
PUT /rooms/{roomId}/send/{eventType}/{txnId} | 发送消息/事件 |
PUT /rooms/{roomId}/state/{eventType}/{stateKey} | 发送状态事件 |
PUT /rooms/{roomId}/redact/{eventId}/{txnId} | 撤回事件 |
GET /sync | 同步房间数据 |
GET /rooms/{roomId}/messages | 分页获取房间历史 |
GET /rooms/{roomId}/context/{eventId} | 事件上下文 |
GET /user_directory/search | 搜索用户 |
GET /keys/upload / POST /keys/query / POST /keys/claim | 端到端加密密钥管理 |
Federation API (/_matrix/federation/v1)
GET /_matrix/key/v2/serverPUT /_matrix/federation/v1/send/{txnId}GET /_matrix/federation/v1/make_join/{roomId}/{userId}PUT /_matrix/federation/v1/send_join/{roomId}/{eventId}GET /_matrix/federation/v1/state/{roomId}GET /_matrix/federation/v1/backfill/{roomId}GET /_matrix/federation/v1/user/devices/{userId}GET /_matrix/federation/v1/query/{queryType}
Application Service API (/_matrix/app/v1)
PUT /transactions/{txnId}GET /users/{userId}GET /rooms/{roomAlias}GET /thirdparty/{protocol}
Media API (/_matrix/media/v3)
POST /uploadGET /download/{serverName}/{mediaId}GET /thumbnail/{serverName}/{mediaId}GET /preview_url
Space 与层级 (/_matrix/client/v1)
POST /rooms/{roomId}/hierarchyGET /rooms/{roomId}/hierarchy- 通过
creation_content.type: m.space创建 Space
关系与线程 (/_matrix/client/v1)
GET /rooms/{roomId}/relations/{eventId}GET /rooms/{roomId}/relations/{eventId}/{relationType}GET /rooms/{roomId}/relations/{eventId}/{relationType}/{eventType}- 同步中的聚合 (
m.annotation、m.replace、m.thread)
Sliding Sync (/_matrix/client/unstable)
POST /org.matrix.msc3575/sync- 房间列表、extensions、subscriptions
管理 API (/_matrix/client/v3/admin)
GET /admin/whois/{userId}GET /admin/usersGET /admin/roomsPOST /admin/rooms/{roomId}/kick、/ban、/unbanPOST /admin/users/{userId}/purgePOST /admin/users/{userId}/block、/unblock
🏗️ 项目结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
src/main/java/com/firmiana/matrix/
├── Application.java # Micronaut 入口
├── config/ # 配置、属性、启动监听器
├── controller/
│ ├── V3Controller.java # 顶层 Client-Server 路由
│ ├── V3SyncController.java # /sync 长轮询
│ ├── auth/ # 注册、登录、登出、刷新
│ ├── room/ # 房间事件、成员、消息、撤回
│ ├── user/ # 资料、在线状态、账户、第三方身份
│ ├── device/ # 设备管理
│ ├── media/ # 媒体上传/下载/预览
│ ├── key/ # 端到端加密密钥端点
│ ├── push/ # 推送器与通知
│ ├── search/ # 用户/事件搜索
│ ├── federation/ # 联邦控制器
│ └── appservice/ # 应用服务控制器
├── entity/ # Micronaut Data 实体
├── repository/ # Micronaut Data JDBC 仓库
├── request/ & response/ # Matrix 请求/响应 DTO
├── security/ # Bearer 令牌验证、密码哈希、UIAA
├── service/ # 业务逻辑(RoomEventService、SyncNotifier 等)
└── exception/ # BaseException、BaseErrorEnum、处理器
🧪 测试
测试位于 src/test/java/com/firmiana/matrix/。使用 @MicronautTest(transactional = false),每个测试类拥有独立的内存 H2 数据库。
1
mvn test
当前状态:244 个测试,0 失败,0 错误。
覆盖范围:
- P0 认证、房间事件、同步、账户/UIAA、错误响应
- P1 端到端加密密钥/签名/备份、媒体缩略图/预览/隔离、推送规则/通知、搜索
- P2 联邦发现/签名/发送/状态/回填、应用服务注册/认证/查询、身份服务禁用/外部/嵌入式模式
- P3 health 端点、速率限制器、指标、清理
- P4 Space/层级、关系/线程/聚合、Sliding Sync
- P5 联邦目标队列、事件哈希校验、restricted join、管理 API、安全响应头
🛣️ 路线图
| 阶段 | 状态 | 范围 |
|---|---|---|
| P0 | ✅ 完成 | Client-Server 核心流程 |
| P1 | ✅ 完成 | 端到端加密、媒体、推送、搜索 |
| P2 | ✅ 完成 | 联邦、应用服务、身份服务 |
| P3 | ✅ 完成 | 存储/运维加固、health、速率限制、测试矩阵 |
| P4 | ✅ 完成 | Space、关系/线程、Sliding Sync、客户端兼容 |
| P5 | ✅ 完成 | 联邦合规、管理/审核、生产安全 |
详细实现计划见 docs/plan/,最新进度见 docs/plan/STATUS.md。
🔐 安全说明
- 这是一个原型/本地 homeserver。在未做额外加固前,请勿直接暴露到公网。
application.yml中的 JWT 密钥仅为本地开发硬编码;可通过环境变量覆盖。- CORS 配置为宽松模式(
allowed-origins-regex: .*),仅用于本地开发。 - 基础生产功能已实现(速率限制、安全响应头、管理 API、指标),但直接暴露公网仍需审查联邦信任、管理员 ACL 和滥用防护。
🤝 贡献
欢迎贡献。添加新表或字段时,请在 src/main/resources/db/migration/ 中提供新的 Flyway 迁移脚本,而不是修改现有脚本。遵循现有代码风格,并为新行为添加测试。
📄 许可证
MIT
Firmiana — 一个进行中的 Matrix homeserver 实验项目。