--- title: 房间版本 11 type: docs weight: 100 version: 11 --- {{< boxes/warning >}} 本页面的翻译未经核对,可能存在翻译质量不佳、错翻、漏翻等情况。您可以在 Forgejo 存储库 打开 Issue、提交 Pull Request 或邮件联系我们提出改进建议和参与翻译与核对。 {{< /boxes/warning >}} 本房间版本基于[版本 10](/rooms/v10) ,并进一步明确了撤回(redaction)规则。 ## 客户端注意事项 ### 撤回 {{% added-in v=11 %}} 顶层的 `origin`、`membership` 和 `prev_state` 属性不再受到撤回保护。[`m.room.create`](/client-server-api#mroomcreate) 事件现在会保留整个 `content` 属性。[`m.room.redaction`](/client-server-api#mroomredaction) 事件保留 `content` 下的 `redacts` 属性。[`m.room.power_levels`](/client-server-api#mroompower_levels) 事件保留 `content` 下的 `invite` 属性。 完整的撤回算法如下。 {{% rver-fragment name="v11-redactions" %}} ### 事件格式 客户端不应再依赖 [`m.room.create`](/client-server-api#mroomcreate) 事件的 `content` 中的 `creator` 属性。在所有房间版本中,客户端可以通过 `sender` 属性来确定房间的创建者。 [`m.room.redaction`](/client-server-api#mroomredaction) 事件的格式已被修改。客户端应当在 `content` 下查找 `redacts` 键,而不是顶层属性。 [`m.room.member`](/client-server-api#mroommember) 事件的 `third_party_invite` 键不再被撤回,但撤回后仅包含 `signed` 键。 ## 服务端实现组件 {{% boxes/warning %}} 本部分内容仅供服务端实现者参考。使用 Client-Server API 的应用通常不受此处细节影响。上面“客户端注意事项”部分才是 Client-Server API 使用场景应关注的内容。 {{% /boxes/warning %}} 本房间版本更新了撤回算法,并修改了服务端应如何创建 `m.room.create` 和 `m.room.redaction` 事件。 房间版本 11 以版本 10 为基础,并有以下要点。 ### 撤回 [见上文](#redactions)。 ### 事件格式 核心事件格式与[房间版本 10](/rooms/v10#event-format) 相同。不过,该房间版本改变了某些事件类型的部分属性。 {{% rver-fragment name="v11-event-format" %}} #### 移除 `m.room.create` 事件的 `creator` 属性 `m.room.create` 事件的 `content` 不再包含 `creator` 属性,此前它总是与事件的 `sender` 属性等同。 #### 将 `m.room.redaction` 事件的 `redacts` 属性移入 `content` `m.room.redaction` 事件的 `redacts` 属性已从事件的顶层属性移到事件的 `content` 属性下。 为向后兼容旧版客户端,服务端在通过 Client-Server API 提供此类事件时,应在顶层添加 `redacts` 属性。 为更好兼容新版客户端,服务端在向*旧版*房间版本提供此类事件时,应在 `content` 下添加 `redacts` 属性。 ### 授权规则 事件必须由 `sender` 属性指定的服务器签名。 影响授权的状态事件类型有: - [`m.room.create`](/client-server-api#mroomcreate) - [`m.room.member`](/client-server-api#mroommember) - [`m.room.join_rules`](/client-server-api#mroomjoin_rules) - [`m.room.power_levels`](/client-server-api#mroompower_levels) - [`m.room.third_party_invite`](/client-server-api#mroomthird_party_invite) {{% boxes/note %}} 未显式设置时,权限级别会采用默认值。例如,提及 `sender` 的权限级别,也可以指代房间内用户的默认权限级别。 {{% /boxes/note %}} {{% boxes/note %}} `m.room.redaction` 事件与其它事件一样受到授权规则约束。实际上,除非 `m.room.power_levels` 事件通过 `events` 或 `events_default` 属性对 `m.room.redaction` 事件设置了权限要求,否则这些事件通常会被允许。特别注意,撤回权限(_redact level_)**不会**被授权规则考虑。 具有发送撤回事件的能力,并不意味着该撤回一定会被执行。接收服务器必须按[撤回处理](#handling-redactions)部分所述进行额外检查。 {{% /boxes/note %}} 规则如下: 1. {{% changed-in v=11 %}} 如果类型为 `m.room.create`: 1. 如果有任何 `prev_events`,则拒绝。 2. 如果 `room_id` 的域名与 `sender` 的域名不一致,则拒绝。 3. 如果 `content.room_version` 存在且不是已知版本,则拒绝。 4. 其他情况,允许。 2. 针对事件的 `auth_events`: 1. 如果某一对 `type` 和 `state_key` 存在重复项,则拒绝。 2. 如果有 `type` 和 `state_key` 未按[授权事件选择](/server-server-api#auth-events-selection)算法选取,拒绝。 3. 如果有条目在[PDU接收时的检查](/server-server-api/#checks-performed-on-receipt-of-a-pdu)中被拒绝,则拒绝。 4. 如果没有 `m.room.create` 事件,被拒绝。 3. 如果房间状态下 `m.room.create` 事件的 `content` 的 `m.federate` 属性为 `false`,且当前事件的 `sender` 域与创建事件的 `sender` 域不一致,则拒绝。 4. 如果类型为 `m.room.member`: 1. 如果没有 `state_key` 属性,或 `content` 中没有 `membership` 属性,拒绝。 2. 如果 `content` 包含 `join_authorised_via_users_server`: 1. 如果事件未被该属性指定用户的 homeserver 合法签名,则拒绝。 3. 如果 `membership` 为 `join`: 1. {{% changed-in v=11 %}} 若唯一的前序事件是 `m.room.create` 且 `state_key` 为 `m.room.create` 的 sender,则允许。 2. 如果 `sender` 不等于 `state_key`,拒绝。 3. 如果 `sender` 被禁言,拒绝。 4. 若 `join_rule` 为 `invite` 或 `knock`,且会员状态为 `invite` 或 `join`,则允许。 5. 若 `join_rule` 为 `restricted` 或 `knock_restricted`: 1. 若会员状态为 `join` 或 `invite`,允许。 2. 如果 `content` 中的 `join_authorised_via_users_server` 不是有权邀请用户的用户,拒绝。 3. 其他情况,允许。 6. 若 `join_rule` 为 `public`,允许。 7. 其他情况,拒绝。 4. 如果 `membership` 为 `invite`: 1. 如果 `content` 有 `third_party_invite` 属性: 1. 如目标用户已被禁言,拒绝。 2. 如果 `content.third_party_invite` 缺少 `signed` 属性,拒绝。 3. 如果 `signed` 不包含 `mxid` 和 `token` 属性,拒绝。 4. 如果 `mxid` 不等于 `state_key`,拒绝。 5. 若当前房间状态没有 `state_key` 匹配 `token` 的 `m.room.third_party_invite` 事件,拒绝。 6. 如果 `sender` 不等于 `m.room.third_party_invite` 的 sender,拒绝。 7. 若 `signed` 中任何签名匹配 `m.room.third_party_invite` 事件中的公钥,则允许。公钥位于 `content` 的如下属性中: 1. `public_key` 属性内的单个公钥; 2. `public_keys` 属性内的公钥列表。 8. 否则,拒绝。 2. 如果 `sender` 当前会员状态不是 `join`,拒绝。 3. 如果目标用户当前会员状态为 `join` 或 `ban`,拒绝。 4. 如果 `sender` 的权限级别大于等于邀请级别,允许。 5. 否则,拒绝。 5. 如果 `membership` 为 `leave`: 1. 若 `sender` 等于 `state_key`,仅当此用户当前会员状态为 `invite`、`join` 或 `knock` 时允许。 2. 如果 `sender` 的当前会员状态不是 `join`,拒绝。 3. 若目标用户当前会员状态为 `ban`,且 `sender` 权限小于禁言级别,拒绝。 4. 若 `sender` 权限大于等于踢出级别,且目标用户权限低于 `sender` 权限,允许。 5. 否则,拒绝。 6. 如果 `membership` 为 `ban`: 1. 若 `sender` 当前会员状态不是 `join`,拒绝。 2. 若 `sender` 权限大于等于禁言级别,且目标用户权限低于 `sender` 权限,允许。 3. 否则,拒绝。 7. 如果 `membership` 为 `knock`: 1. 若 `join_rule` 不是 `knock` 或 `knock_restricted`,拒绝。 2. 若 `sender` 不等于 `state_key`,拒绝。 3. 若 `sender` 当前会员状态不是 `ban`、`invite` 或 `join`,允许。 4. 否则,拒绝。 8. 其他未知会员状态,拒绝。 5. 如果 `sender` 当前会员状态不是 `join`,拒绝。 6. 若类型为 `m.room.third_party_invite`: 1. 仅当 `sender` 当前权限大于等于邀请级别时允许。 7. 如事件类型所需权限级别大于 `sender` 权限级别,拒绝。 8. 如果事件有 `state_key` 以 `@` 开头,且不等于 `sender`,拒绝。 9. 若类型为 `m.room.power_levels`: 1. 如果 `content` 内的 `users_default`、`events_default`、`state_default`、`ban`、`redact`、`kick` 或 `invite` 属性存在且不是整数,拒绝。 2. 如果 `content` 内的 `events` 或 `notifications` 属性存在,且不是值为整数的对象,拒绝。 3. 如果 `content` 内的 `users` 属性不是键为合法用户ID、值为整数的对象,拒绝。 4. 如果房间中不存在先前的 `m.room.power_levels` 事件,允许。 5. 对于 `users_default`、`events_default`、`state_default`、`ban`、`redact`、`kick`、`invite`,如有添加、变更或删除,每项需检查: 1. 当前值大于 `sender` 当前权限,拒绝。 2. 新值大于 `sender` 当前权限,拒绝。 6. 对于 `events` 或 `notifications` 属性中被更改或移除的每一项: 1. 当前值大于 `sender` 当前权限,拒绝。 7. 对于 `events` 或 `notifications` 中被添加或更改的每一项: 1. 新值大于 `sender` 当前权限,拒绝。 8. 对于除自身外的 `users` 属性中被更改或移除的每一项: 1. 当前值大于等于 `sender` 当前权限,拒绝。 9. 对于 `users` 属性中被添加或更改的每一项: 1. 新值大于 `sender` 当前权限,拒绝。 10. 其他情况,允许。 10. 其他情况,允许。 {{% boxes/note %}} 这些规则的部分结果: - 除非你是房间成员,唯一允许的操作(除初始创建/加入外)只有加入公开房间,以及接受或拒绝房间邀请。 - 取消禁言某人,你必须同时具有不小于踢出和禁言级别的权限,且权限要高于目标用户。 {{% /boxes/note %}} ## 与 v10 一致 以下章节自 v10 起未修改,为完整性而保留。 ### 撤回处理 {{% rver-fragment name="v3-handling-redactions" %}} ### 事件 ID {{% rver-fragment name="v4-event-ids" %}} ### 状态解析 {{% rver-fragment name="v2-state-res" %}} ### 规范化 JSON {{% rver-fragment name="v6-canonical-json" %}} ### 签名密钥有效期 {{% rver-fragment name="v5-signing-requirements" %}}