|
| 1 | +# MSC3173: Expose stripped state events to any potential joiner |
| 2 | + |
| 3 | +It can be useful to view the partial state of a room before joining to allow a user |
| 4 | +to know *what* they're joining. For example, it improves the user experience to |
| 5 | +show the user the room name and avatar before joining. |
| 6 | + |
| 7 | +It is already allowed to partially view the room state without being joined to |
| 8 | +the room in some situations: |
| 9 | + |
| 10 | +* If the room has `history_visibility: world_readable`, then anyone can inspect |
| 11 | + it (by calling `/state` on it). |
| 12 | +* Rooms in the [room directory](https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-publicrooms) |
| 13 | + expose some of their state publicly. |
| 14 | +* [Invited users](https://matrix.org/docs/spec/server_server/r0.1.4#put-matrix-federation-v2-invite-roomid-eventid) |
| 15 | + and [knocking users](https://github.com/matrix-org/matrix-doc/pull/2403) |
| 16 | + receive stripped state events to display metadata to users. |
| 17 | + |
| 18 | +This MSC proposes formalizing that the stripped state that is currently available |
| 19 | +to invited and knocking users is available to any user who could potentially join |
| 20 | +a room. It also defines "stripped state" and consolidates the recommendation on |
| 21 | +which events to include in the stripped state. |
| 22 | + |
| 23 | +## Background |
| 24 | + |
| 25 | +When creating an invite it is [currently recommended](https://matrix.org/docs/spec/server_server/r0.1.4#put-matrix-federation-v2-invite-roomid-eventid) |
| 26 | +to include stripped state events which are useful for displaying the invite to a user: |
| 27 | + |
| 28 | +> An optional list of simplified events to help the receiver of the invite identify |
| 29 | +> the room. The recommended events to include are the join rules, canonical alias, |
| 30 | +> avatar, and name of the room. |
| 31 | +
|
| 32 | +The invited user receives these [stripped state events](https://spec.matrix.org/unstable/client-server-api/#get_matrixclientr0sync) |
| 33 | +as part of the `/sync` response: |
| 34 | + |
| 35 | +> The state of a room that the user has been invited to. These state events may |
| 36 | +> only have the `sender`, `type`, `state_key` and `content` keys present. These |
| 37 | +> events do not replace any state that the client already has for the room, for |
| 38 | +> example if the client has archived the room. |
| 39 | +
|
| 40 | +These are sent as part of the [`unsigned` content of the `m.room.member` event](https://spec.matrix.org/unstable/client-server-api/#mroommember) |
| 41 | +containing the invite. |
| 42 | + |
| 43 | +[MSC2403: Add "knock" feature](https://github.com/matrix-org/matrix-doc/pull/2403) |
| 44 | +extends this concept to also include the stripped state events in the `/sync` response |
| 45 | +for knocking users: |
| 46 | + |
| 47 | +> It is proposed to add a fourth possible key to rooms, called `knock`. Its value |
| 48 | +> is a mapping from room ID to room information. The room information is a mapping |
| 49 | +> from a key `knock_state` to another mapping with key events being a list of |
| 50 | +> `StrippedStateEvent`. |
| 51 | +
|
| 52 | +It is also provides an extended rationale of why this is useful: |
| 53 | + |
| 54 | +> These stripped state events contain information about the room, most notably the |
| 55 | +> room's name and avatar. A client will need this information to show a nice |
| 56 | +> representation of pending knocked rooms. The recommended events to include are the |
| 57 | +> join rules, canonical alias, avatar, name and encryption state of the room, rather |
| 58 | +> than all room state. This behaviour matches the information sent to remote |
| 59 | +> homeservers when remote users are invited to a room. |
| 60 | +
|
| 61 | +[MSC1772: Spaces](https://github.com/matrix-org/matrix-doc/pull/1772) additionally |
| 62 | +recommends including the `m.room.create` event as one of the stripped state events: |
| 63 | + |
| 64 | +> Join rules, invites and 3PID invites work as for a normal room, with the exception |
| 65 | +> that `invite_state` sent along with invites should be amended to include the |
| 66 | +> `m.room.create` event, to allow clients to discern whether an invite is to a |
| 67 | +> space-room or not. |
| 68 | +
|
| 69 | +## Proposal |
| 70 | + |
| 71 | +The specification does not currently define what "stripped state" is or formally |
| 72 | +describe who can access it, instead it is specified that certain situations (e.g. |
| 73 | +an invite or knock) provide a potential joiner with the stripped state of a room. |
| 74 | + |
| 75 | +This MSC clarifies what "stripped state" is and formalizes who can access the |
| 76 | +stripped state of a room in future cases. |
| 77 | + |
| 78 | +Potential ways that a user might be able to join a room include, but are not |
| 79 | +limited to, the following mechanisms: |
| 80 | + |
| 81 | +* A room that has `join_rules` set to `public` or `knock`. |
| 82 | +* A room that the user is in possession of an invite to (regardless of the `join_rules`). |
| 83 | + |
| 84 | +This MSC proposes a formal definition for the stripped state of a room<sup id="a1">[1](#f1)</sup>: |
| 85 | + |
| 86 | +> The stripped state of a room is a list of simplified state events to help a |
| 87 | +> potential joiner identify the room. These state events may only have the |
| 88 | +> `sender`, `type`, `state_key` and `content` keys present. |
| 89 | +
|
| 90 | +### Client behavior |
| 91 | + |
| 92 | +These events do not replace any state that the client already has for the room, |
| 93 | +for example if the client has archived the room. Instead the client should keep |
| 94 | +two separate copies of the state: the one from the stripped state and one from the |
| 95 | +archived state. If the client joins the room then the current state will be given |
| 96 | +as a delta against the archived state not the stripped state. |
| 97 | + |
| 98 | +### Server behavior |
| 99 | + |
| 100 | +It is recommended (although not required<sup id="a2">[2](#f2)</sup>) that |
| 101 | +homeserver implementations include the following events as part of the stripped |
| 102 | +state of a room: |
| 103 | + |
| 104 | +* Create event (`m.room.create`)<sup id="a3">[3](#f3)</sup> |
| 105 | +* Join rules (`m.room.join_rules`) |
| 106 | +* Canonical alias (`m.room.canonical_alias`) |
| 107 | +* Room avatar (`m.room.avatar`) |
| 108 | +* Room name (`m.room.name`) |
| 109 | +* Encryption information (`m.room.encryption`)<sup id="a4">[4](#f4)</sup> |
| 110 | +* Room topic (`m.room.topic`)<sup id="a5">[5](#f5)</sup> |
| 111 | + |
| 112 | +## Potential issues |
| 113 | + |
| 114 | +This is a formalization of current behavior and should not introduce new issues. |
| 115 | + |
| 116 | +## Alternatives |
| 117 | + |
| 118 | +A different approach would be to continue with what is done today for invites, |
| 119 | +knocking, the room directory: separately specify that a user is allowed to see |
| 120 | +the stripped state (and what events the stripped state should contain). |
| 121 | + |
| 122 | +## Security considerations |
| 123 | + |
| 124 | +This would allow for invisibly accessing the stripped state of a room with `public` |
| 125 | +or `knock` join rules. |
| 126 | + |
| 127 | +In the case of a public room, if the room has `history_visibility` set to `world_readable` |
| 128 | +then this is no change. Additionally, this information is already provided by the |
| 129 | +room directory (if the room is listed there). Otherwise, it is trivial to access |
| 130 | +the state of the room by joining, but currently users in the room would know |
| 131 | +that the join occurred. |
| 132 | + |
| 133 | +Similarly, in the case of knocking, a user is able to trivially access the |
| 134 | +stripped state of the room by knocking, but users in the room would know that |
| 135 | +the knock occurred. |
| 136 | + |
| 137 | +This does not seem to weaken the security expectations of either join rule. |
| 138 | + |
| 139 | +## Future extensions |
| 140 | + |
| 141 | +### Revisions to the room directory |
| 142 | + |
| 143 | +A future MSC could include additional information from the stripped state events |
| 144 | +in the [room directory](https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-publicrooms). |
| 145 | +The main missing piece seems to be the encryption information, but there may also |
| 146 | +be other pieces of information to include. |
| 147 | + |
| 148 | +### Additional ways to access the stripped state |
| 149 | + |
| 150 | +[MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946) proposes including |
| 151 | +the stripped state in the spaces summary. Not needing to rationalize what state |
| 152 | +can be included for a potential joiner would simplify this (and future) MSCs. |
| 153 | + |
| 154 | +### Additional ways to join a room |
| 155 | + |
| 156 | +[MSC3083](https://github.com/matrix-org/matrix-doc/pull/3083) proposes a new |
| 157 | +join rule due to membership in a space. This MSC would clarify that the stripped |
| 158 | +state of a room is available to those joiners. |
| 159 | + |
| 160 | +### Dedicated API for accessing the stripped state |
| 161 | + |
| 162 | +Dedicated client-server and server-server APIs could be added to request the |
| 163 | +stripped state events, but that is considered out-of-scope for the current |
| 164 | +proposal. |
| 165 | + |
| 166 | +This API would allow any potential joiner to query for the stripped state. If |
| 167 | +the server does not know the room's state it would need to query other servers |
| 168 | +for it. |
| 169 | + |
| 170 | +## Unstable prefix |
| 171 | + |
| 172 | +N/A |
| 173 | + |
| 174 | +## Footnotes |
| 175 | + |
| 176 | +<a id="f1"/>[1]: No changes are proposed to |
| 177 | +[the definition of `history_visibility`](https://matrix.org/docs/spec/client_server/latest#room-history-visibility). |
| 178 | +The state of a room which is `world_readable` is available to anyone. This somewhat |
| 179 | +implies that the stripped state is also available to anyone, regardless of the join |
| 180 | +rules, but having a `world_readable`, `invite` room does not seem valuable. [↩](#a1) |
| 181 | + |
| 182 | +<a id="f2"/>[2]: Privacy conscious deployments may wish to limit the metadata |
| 183 | +available to users who are not in a room as the trade-off against user experience. |
| 184 | +There seems to be no reason to not allow this. [↩](#a2) |
| 185 | + |
| 186 | +<a id="f3"/>[3]: As updated in [MSC1772](https://github.com/matrix-org/matrix-doc/pull/1772). [↩](#a3) |
| 187 | + |
| 188 | +<a id="f4"/>[4]: The encryption information (`m.room.encryption`) is already sent |
| 189 | +from Synapse and generally seems useful for a user to know before joining a room. |
| 190 | +[↩](#a4) |
| 191 | + |
| 192 | +<a id="f5"/>[5]: The room topic (`m.room.topic`) is included as part of the |
| 193 | +[room directory](https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-publicrooms) |
| 194 | +response for public rooms. It is also planned to be included as part of [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946) |
| 195 | +in the spaces summary response. [↩](#a5) |
0 commit comments