|
|
|
|
---
|
|
|
|
|
title: Room Version 1
|
|
|
|
|
type: docs
|
|
|
|
|
weight: 10
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
This room version is the first ever version for rooms, and contains the
|
|
|
|
|
building blocks for other room versions.
|
|
|
|
|
|
|
|
|
|
## Client considerations
|
|
|
|
|
|
|
|
|
|
Clients which implement the redaction algorithm locally should refer to the
|
|
|
|
|
[redactions](#redactions) section below.
|
|
|
|
|
|
|
|
|
|
### Redactions
|
|
|
|
|
|
|
|
|
|
{{% rver-fragment name="v1-redactions" %}}
|
|
|
|
|
|
|
|
|
|
## Server implementation components
|
|
|
|
|
|
|
|
|
|
{{% boxes/warning %}}
|
|
|
|
|
The information contained in this section is strictly for server
|
|
|
|
|
implementors. Applications which use the Client-Server API are generally
|
|
|
|
|
unaffected by the intricacies contained here. The section above
|
|
|
|
|
regarding client considerations is the resource that Client-Server API
|
|
|
|
|
use cases should reference.
|
|
|
|
|
{{% /boxes/warning %}}
|
|
|
|
|
|
|
|
|
|
The algorithms defined here should only apply to version 1 rooms. Other
|
|
|
|
|
algorithms may be used by other room versions, and as such servers
|
|
|
|
|
should be aware of which version room they are dealing with prior to
|
|
|
|
|
executing a given algorithm.
|
|
|
|
|
|
|
|
|
|
{{% boxes/warning %}}
|
|
|
|
|
Although there are many rooms using room version 1, it is known to have
|
|
|
|
|
undesirable effects. Servers implementing support for room version 1
|
|
|
|
|
should be aware that restrictions should be generally relaxed and that
|
|
|
|
|
inconsistencies may occur.
|
|
|
|
|
{{% /boxes/warning %}}
|
|
|
|
|
|
|
|
|
|
### Redactions
|
|
|
|
|
|
|
|
|
|
[See above](#redactions).
|
|
|
|
|
|
|
|
|
|
### Event format
|
|
|
|
|
|
|
|
|
|
Events in version 1 rooms have the following structure:
|
|
|
|
|
|
|
|
|
|
{{% definition path="api/server-server/definitions/pdu" %}}
|
|
|
|
|
|
|
|
|
|
#### Deprecated event content schemas
|
|
|
|
|
|
|
|
|
|
{{% rver-fragment name="v1-deprecated-formatting-off-spec" %}}
|
|
|
|
|
|
|
|
|
|
{{% rver-fragment name="v1-stringy-power-levels" %}}
|
|
|
|
|
|
|
|
|
|
### Authorization rules
|
|
|
|
|
|
|
|
|
|
{{% rver-fragment name="v1-auth-rules" %}}
|
|
|
|
|
|
|
|
|
|
### State resolution
|
|
|
|
|
|
|
|
|
|
{{% boxes/warning %}}
|
|
|
|
|
Room version 1 is known to have bugs that can cause the state of rooms
|
|
|
|
|
to reset to older versions of the room's state. For example this could
|
|
|
|
|
mean that users who had joined the room may be removed from the room,
|
|
|
|
|
admins and moderators could lose their power level, and users who have
|
|
|
|
|
been banned from the room may be able to rejoin. Other state events such
|
|
|
|
|
as the the room's name or topic could also reset to a previous version.
|
|
|
|
|
|
|
|
|
|
This is fixed in the state resolution algorithm introduced in room
|
|
|
|
|
version 2.
|
|
|
|
|
{{% /boxes/warning %}}
|
|
|
|
|
|
|
|
|
|
The room state *S′*(*E*) after an event *E* is defined in terms of the
|
|
|
|
|
room state *S*(*E*) before *E*, and depends on whether *E* is a state
|
|
|
|
|
event or a message event:
|
|
|
|
|
|
|
|
|
|
- If *E* is a message event, then *S′(E)* = *S(E)*.
|
|
|
|
|
- If *E* is a state event, then *S′(E)* is *S(E)*, except that its
|
|
|
|
|
entry corresponding to the `event_type` and `state_key` of *E* is
|
|
|
|
|
replaced by the `event_id` of *E*.
|
|
|
|
|
|
|
|
|
|
The room state *S(E)* before *E* is the *resolution* of the set of
|
|
|
|
|
states {*S′(E′)*, *S′(E″)*, …} after the `prev_events` {*E′*, *E″*, …}.
|
|
|
|
|
of *E*.
|
|
|
|
|
|
|
|
|
|
The *resolution* of a set of states is defined as follows. The resolved
|
|
|
|
|
state is built up in a number of passes; here we use *R* to refer to the
|
|
|
|
|
results of the resolution so far.
|
|
|
|
|
|
|
|
|
|
- Start by setting *R* to the union of the states to be resolved,
|
|
|
|
|
excluding any *conflicting* events.
|
|
|
|
|
- First we resolve conflicts between `m.room.power_levels` events. If
|
|
|
|
|
there is no conflict, this step is skipped, otherwise:
|
|
|
|
|
- Assemble all the `m.room.power_levels` events from the states to
|
|
|
|
|
be resolved into a list.
|
|
|
|
|
- Sort the list by ascending `depth` then descending
|
|
|
|
|
`sha1(event_id)`.
|
|
|
|
|
- Add the first event in the list to *R*.
|
|
|
|
|
- For each subsequent event in the list, check that the event
|
|
|
|
|
would be allowed by the authorization rules for a room in state
|
|
|
|
|
*R*. If the event would be allowed, then update *R* with the
|
|
|
|
|
event and continue with the next event in the list. If it would
|
|
|
|
|
not be allowed, stop and continue below with `m.room.join_rules`
|
|
|
|
|
events.
|
|
|
|
|
- Repeat the above process for conflicts between `m.room.join_rules`
|
|
|
|
|
events.
|
|
|
|
|
- Repeat the above process for conflicts between `m.room.member`
|
|
|
|
|
events.
|
|
|
|
|
- No other events affect the authorization rules, so for all other
|
|
|
|
|
conflicts, just pick the event with the highest depth and lowest
|
|
|
|
|
`sha1(event_id)` that passes authentication in *R* and add it to
|
|
|
|
|
*R*.
|
|
|
|
|
|
|
|
|
|
A *conflict* occurs between states where those states have different
|
|
|
|
|
`event_ids` for the same `(event_type, state_key)`. The events thus
|
|
|
|
|
affected are said to be *conflicting* events.
|
|
|
|
|
|
|
|
|
|
### Canonical JSON
|
|
|
|
|
|
|
|
|
|
{{% rver-fragment name="v1-canonical-json" %}}
|