Merge branch 'main' into neilalexander/mfederate

This commit is contained in:
Neil Alexander 2022-06-14 16:46:16 +01:00
commit 5a58eafd7e
No known key found for this signature in database
GPG key ID: A02A2019A2BB0944
67 changed files with 1756 additions and 277 deletions

View file

@ -0,0 +1 @@
Add timestamp massaging as per [MSC3316](https://github.com/matrix-org/matrix-spec-proposals/pull/3316).

View file

@ -1 +1 @@
Adjust the OpenAPI specification so that the type `Flow information` is explicitly defined when the CS spec is rendered. Adjust the OpenAPI specification so that the type `Flow information` is explicitly defined when the client-server API is rendered.

View file

@ -0,0 +1 @@
Add refresh tokens, per [MSC2918](https://github.com/matrix-org/matrix-spec-proposals/pull/2918).

View file

@ -1 +1 @@
Fix room state 400 code error examples to match known error codes. Fix various typos throughout the specification.

View file

@ -0,0 +1 @@
Relax the restrictions on Rich Replies, as per [MSC3676](https://github.com/matrix-org/matrix-spec-proposals/pull/3676).

View file

@ -0,0 +1 @@
Describe a structured system for event relationships, as per [MSC2674](https://github.com/matrix-org/matrix-spec-proposals/pull/2674).

View file

@ -0,0 +1 @@
Describe how relationships between events can be "aggregated", as per [MSC2675](https://github.com/matrix-org/matrix-spec-proposals/pull/2675) and [MSC3666](https://github.com/matrix-org/matrix-spec-proposals/pull/3666).

View file

@ -0,0 +1 @@
Fix various typos throughout the specification.

View file

@ -0,0 +1 @@
Add support for a new `knock_restricted` join rule in supported room versions, as per [MSC3787](https://github.com/matrix-org/matrix-spec-proposals/pull/3787).

View file

@ -0,0 +1 @@
Clarify that state keys starting with `@` are in fact reserved. Regressed from [#3658](https://github.com/matrix-org/matrix-spec-proposals/pull/3658).

View file

@ -0,0 +1 @@
Deprecate the `sender_key` and `device_id` on `m.megolm.v1.aes-sha2` events, and the `sender_key` on `m.room_key_request` to-device messages, as per [MSC3700](https://github.com/matrix-org/matrix-spec-proposals/pull/3700).

View file

@ -0,0 +1 @@
Fix various typos throughout the specification.

View file

@ -0,0 +1 @@
Add refresh tokens, per [MSC2918](https://github.com/matrix-org/matrix-spec-proposals/pull/2918).

View file

@ -0,0 +1 @@
Fix various typos throughout the specification.

View file

@ -1 +1 @@
Fix broken syntax in Server Access Control Lists definition. Fix various typos throughout the specification.

View file

@ -1,2 +1 @@
Improve readability of definitions in the state resolution v2 algorithm. Improve readability and understanding of the state resolution algorithms.

View file

@ -0,0 +1 @@
Improve readability and understanding of the state resolution algorithms.

View file

@ -1 +1 @@
Adjust mathematical notation used in the description of state resolution to render better in browsers. Improve readability and understanding of the state resolution algorithms.

View file

@ -1 +1 @@
Add cross-references to PDU content definitions from the authorisation rules. Improve readability of the authorization rules.

View file

@ -1 +1 @@
Auth rules: clarify that the resident server must sign a restricted join event. For room versions 8, 9, and 10: clarify which homeserver is required to sign the join event.

View file

@ -0,0 +1 @@
Clarify that room versions 1 through 9 accept stringy power levels, as noted by [MSC3667](https://github.com/matrix-org/matrix-spec-proposals/pull/3667).

View file

@ -0,0 +1 @@
Add room version 10 as per [MSC3604](https://github.com/matrix-org/matrix-spec-proposals/pull/3604).

View file

@ -0,0 +1 @@
Enforce integer power levels in room version 10 as per [MSC3667](https://github.com/matrix-org/matrix-spec-proposals/pull/3667).

View file

@ -0,0 +1 @@
Add a `knock_restricted` join rule supported by room version 10 as per [MSC3787](https://github.com/matrix-org/matrix-spec-proposals/pull/3787).

View file

@ -1 +1 @@
Fix join membership auth rules when `join_rule` is `knock`. For room versions 7, 8, 9, and 10: fix join membership authorization rules when `join_rule` is `knock`.

View file

@ -1 +1 @@
Update the default room version to 9. Update the default room version to 9 as per [MSC3589](https://github.com/matrix-org/matrix-spec-proposals/pull/3589).

View file

@ -1 +1 @@
Fix origin server name in S2S Request Authentication example. Clarify the format for the Authorization header.

View file

@ -1 +0,0 @@
Clarify the meaning of "unconflicted state map" and "auth chain" in state res v2.

View file

@ -1 +1 @@
Expand a little on what it means for a PDU to be valid when discussing checks on PDUs. Clarify what a "valid event" means when performing checks on a received PDU.

View file

@ -1 +1 @@
Clarify that valid_until_ts is in milliseconds, like other timestamps used in Matrix Clarify that `valid_until_ts` is in milliseconds, like other timestamps used in Matrix.

View file

@ -1 +1 @@
Add a destination property to the Authorization header. Add a `destination` property to the Authorization header, as per [MSC3383](https://github.com/matrix-org/matrix-spec-proposals/pull/3383).

View file

@ -1 +1 @@
Clarify that checks on PDUs should refer to the state _before_ an event. Clarify that checks on PDUs should refer to the state *before* an event.

View file

@ -0,0 +1 @@
Clarify the historical handling of non-integer power levels.

View file

@ -0,0 +1 @@
Fix various typos throughout the specification.

View file

@ -1 +1 @@
Remove `origin` field from PDUs which exists on many but not all PDUs in practice and doesn't serve an actual purpose. Remove largely unused `origin` field from PDUs.

View file

@ -300,13 +300,38 @@ An example request would be:
#### Timestamp massaging #### Timestamp massaging
Previous drafts of the Application Service API permitted application {{% added-in v="1.3" %}}
services to alter the timestamp of their sent events by providing a `ts`
query parameter when sending an event. This API has been excluded from Application services can alter the timestamp associated with an event, allowing
the first release due to design concerns, however some servers may still the application service to better represent the "real" time an event was sent
support the feature. Please visit [issue at. While this doesn't affect the server-side ordering of the event, it can allow
\#1585](https://github.com/matrix-org/matrix-doc/issues/1585) for more an application service to better represent when an event would have been sent/received
information. at, such as in the case of bridges where the remote network might have a slight
delay and the application service wishes to bridge the proper time onto the message.
When authenticating requests as an application service, the caller can append a `ts`
query string argument to change the `origin_server_ts` of the resulting event. Attempting
to set the timestamp to anything other than what is accepted by `origin_server_ts` should
be rejected by the server as a bad request.
When not present, the server's behaviour is unchanged: the local system time of the server
will be used to provide a timestamp, representing "now".
The `ts` query string argument is only valid on the following endpoints:
* [`PUT /rooms/{roomId}/send/{eventType}/{txnId}`](/client-server-api/#put_matrixclientv3roomsroomidsendeventtypetxnid)
* [`PUT /rooms/{roomId}/state/{eventType}/{stateKey}`](/client-server-api/#put_matrixclientv3roomsroomidstateeventtypestatekey)
Other endpoints, such as `/kick`, do not support `ts`: instead, callers can use the
`PUT /state` endpoint to mimic the behaviour of the other APIs.
{{% boxes/warning %}}
Changing the time of an event does not change the server-side (DAG) ordering for the
event. The event will still be appended at the tip of the DAG as though the timestamp
was set to "now". Future MSCs, like [MSC2716](https://github.com/matrix-org/matrix-spec-proposals/pull/2716),
are expected to provide functionality which can allow DAG order manipulation (for history
imports and similar behaviour).
{{% /boxes/warning %}}
#### Server admin style permissions #### Server admin style permissions

View file

@ -71,7 +71,7 @@ These error codes can be returned by any API endpoint:
Forbidden access, e.g. joining a room without permission, failed login. Forbidden access, e.g. joining a room without permission, failed login.
`M_UNKNOWN_TOKEN` `M_UNKNOWN_TOKEN`
The access token specified was not recognised. The access or refresh token specified was not recognised.
An additional response parameter, `soft_logout`, might be present on the An additional response parameter, `soft_logout`, might be present on the
response for 401 HTTP status codes. See [the soft logout response for 401 HTTP status codes. See [the soft logout
@ -314,7 +314,8 @@ Most API endpoints require the user to identify themselves by presenting
previously obtained credentials in the form of an `access_token` query previously obtained credentials in the form of an `access_token` query
parameter or through an Authorization Header of `Bearer $access_token`. parameter or through an Authorization Header of `Bearer $access_token`.
An access token is typically obtained via the [Login](#login) or An access token is typically obtained via the [Login](#login) or
[Registration](#account-registration-and-management) processes. [Registration](#account-registration-and-management) processes. Access tokens
can expire; a new access token can be generated by using a refresh token.
{{% boxes/note %}} {{% boxes/note %}}
This specification does not mandate a particular format for the access This specification does not mandate a particular format for the access
@ -338,40 +339,94 @@ inaccessible for the client.
When credentials are required but missing or invalid, the HTTP call will When credentials are required but missing or invalid, the HTTP call will
return with a status of 401 and the error code, `M_MISSING_TOKEN` or return with a status of 401 and the error code, `M_MISSING_TOKEN` or
`M_UNKNOWN_TOKEN` respectively. `M_UNKNOWN_TOKEN` respectively. Note that an error code of `M_UNKNOWN_TOKEN`
could mean one of four things:
1. the access token was never valid.
2. the access token has been logged out.
3. the access token has been [soft logged out](#soft-logout).
4. {{< added-in v="1.3" >}} the access token [needs to be refreshed](#refreshing-access-tokens).
When a client receives an error code of `M_UNKNOWN_TOKEN`, it should:
- attempt to [refresh the token](#refreshing-access-tokens), if it has a refresh
token;
- if [`soft_logout`](#soft-logout) is set to `true`, it can offer to
re-log in the user, retaining any of the client's persisted
information;
- otherwise, consider the user as having been logged out.
### Relationship between access tokens and devices ### Relationship between access tokens and devices
Client [devices](../index.html#devices) are closely related to access Client [devices](../index.html#devices) are closely related to access
tokens. Matrix servers should record which device each access token is tokens and refresh tokens. Matrix servers should record which device
assigned to, so that subsequent requests can be handled correctly. each access token and refresh token are assigned to, so that
subsequent requests can be handled correctly. When a refresh token is
used to generate a new access token and refresh token, the new access
and refresh tokens are now bound to the device associated with the
initial refresh token.
By default, the [Login](#login) and [Registration](#account-registration-and-management) By default, the [Login](#login) and [Registration](#account-registration-and-management)
processes auto-generate a new `device_id`. A client is also free to processes auto-generate a new `device_id`. A client is also free to
generate its own `device_id` or, provided the user remains the same, generate its own `device_id` or, provided the user remains the same,
reuse a device: in either case the client should pass the `device_id` in reuse a device: in either case the client should pass the `device_id` in
the request body. If the client sets the `device_id`, the server will the request body. If the client sets the `device_id`, the server will
invalidate any access token previously assigned to that device. There is invalidate any access and refresh tokens previously assigned to that device.
therefore at most one active access token assigned to each device at any
one time. ### Refreshing access tokens
{{% added-in v="1.3" %}}
Access tokens can expire after a certain amount of time. Any HTTP calls that
use an expired access token will return with an error code `M_UNKNOWN_TOKEN`,
preferably with `soft_logout: true`. When a client receives this error and it
has a refresh token, it should attempt to refresh the access token by calling
[`/refresh`](#post_matrixclientv3refresh). Clients can also refresh their
access token at any time, even if it has not yet expired. If the token refresh
succeeds, the client should use the new token for future requests, and can
re-try previously-failed requests with the new token. When an access token is
refreshed, a new refresh token may be returned; if a new refresh token is
given, the old refresh token will be invalidated, and the new refresh token
should be used when the access token needs to be refreshed.
The old refresh token remains valid until the new access token or refresh token
is used, at which point the old refresh token is revoked. This ensures that if
a client fails to receive or persist the new tokens, it will be able to repeat
the refresh operation.
If the token refresh fails and the error response included a `soft_logout:
true` property, then the client can treat it as a [soft logout](#soft-logout)
and attempt to obtain a new access token by re-logging in. If the error
response does not include a `soft_logout: true` property, the client should
consider the user as being logged out.
Handling of clients that do not support refresh tokens is up to the homeserver;
clients indicate their support for refresh tokens by including a
`refresh_token: true` property in the request body of the
[`/login`](#post_matrixclientv3login) and
[`/register`](#post_matrixclientv3register) endpoints. For example, homeservers
may allow the use of non-expiring access tokens, or may expire access tokens
anyways and rely on soft logout behaviour on clients that don't support
refreshing.
### Soft logout ### Soft logout
When a request fails due to a 401 status code per above, the server can A client can be in a "soft logout" state if the server requires
include an extra response parameter, `soft_logout`, to indicate if the re-authentication before continuing, but does not want to invalidate the
client's persisted information can be retained. This defaults to client's session. The server indicates that the client is in a soft logout
`false`, indicating that the server has destroyed the session. Any state by including a `soft_logout: true` parameter in an `M_UNKNOWN_TOKEN`
error response; the `soft_logout` parameter defaults to `false`. If the
`soft_logout` parameter is omitted or is `false`, this means the server has
destroyed the session and the client should not reuse it. That is, any
persisted state held by the client, such as encryption keys and device persisted state held by the client, such as encryption keys and device
information, must not be reused and must be discarded. information, must not be reused and must be discarded. If `soft_logout` is
`true` the client can reuse any persisted state.
When `soft_logout` is true, the client can acquire a new access token by {{% changed-in v="1.3" %}} A client that receives such a response can try to
specifying the device ID it is already using to the login API. In most [refresh its access token](#refreshing-access-tokens), if it has a refresh
cases a `soft_logout: true` response indicates that the user's session token available. If it does not have a refresh token available, or refreshing
has expired on the server-side and the user simply needs to provide fails with `soft_logout: true`, the client can acquire a new access token by
their credentials again. specifying the device ID it is already using to the login API.
In either case, the client's previously known access token will no
longer function.
### User-Interactive Authentication API ### User-Interactive Authentication API
@ -1105,6 +1160,8 @@ errcode of `M_EXCLUSIVE`.
{{% http-api spec="client-server" api="login" %}} {{% http-api spec="client-server" api="login" %}}
{{% http-api spec="client-server" api="refresh" %}}
{{% http-api spec="client-server" api="logout" %}} {{% http-api spec="client-server" api="logout" %}}
#### Login Fallback #### Login Fallback
@ -1741,6 +1798,16 @@ There are several APIs provided to `GET` events for a room:
### Sending events to a room ### Sending events to a room
{{% boxes/note %}}
{{% added-in v="1.3" %}}
Servers might need to post-process some events if they
[relate to](#forming-relationships-between-events) another event. The event's
relationship type (`rel_type`) determines any restrictions which might apply,
such as the user only being able to send one event of a given type in relation
to another.
{{% /boxes/note %}}
{{% http-api spec="client-server" api="room_state" %}} {{% http-api spec="client-server" api="room_state" %}}
**Examples** **Examples**
@ -1831,6 +1898,216 @@ the topic to be removed from the room.
{{% http-api spec="client-server" api="redaction" %}} {{% http-api spec="client-server" api="redaction" %}}
### Forming relationships between events
{{% changed-in v="1.3" %}}
In some cases it is desirable to logically associate one event's contents with
another event's contents — for example, when replying to a message, editing an
event, or simply looking to add context for an event's purpose.
Events are related to each other in a parent/child structure, where any event can
become a parent by simply having a child event point at it. Parent events do not
define their children, instead relying on the children to describe their parent.
The relationship between a child and its parent event is described in the child
event's `content` as `m.relates_to` (defined below). A child event can point at
any other event, including another child event, to build the relationship so long
as both events are in the same room, however additional restrictions might be imposed
by the type of the relationship (the `rel_type`).
{{% boxes/note %}}
Child events can point at other child events, forming a chain of events. These chains
can naturally take the shape of a tree if two independent children point at a single
parent event, for example.
{{% /boxes/note %}}
To allow the server to aggregate and find child events for a parent, the `m.relates_to`
key of an event MUST be included in the plaintext copy of the event. It cannot be
exclusively recorded in the encrypted payload as the server cannot decrypt the event
for processing.
{{% boxes/warning %}}
If an encrypted event contains an `m.relates_to` in its payload, it should be
ignored and instead favour the plaintext `m.relates_to` copy (including when there
is no plaintext copy). This is to ensure the client's behaviour matches the server's
capability to handle relationships.
{{% /boxes/warning %}}
Relationships which don't match the schema, or which break the rules of a relationship,
are simply ignored. An example might be the parent and child being in different
rooms, or the relationship missing properties required by the schema below. Clients
handling such invalid relationships should show the events independently of each
other, optionally with an error message.
{{% boxes/note %}}
While this specification describes an `m.relates_to` object containing a `rel_type`, there
is not currently any relationship type which uses this structure. Replies, described below,
form their relationship outside of the `rel_type` as a legacy type of relationship. Future
versions of the specification might change replies to better match the relationship structures.
Custom `rel_type`s can, and should, still use the schema described above for relevant
behaviour.
{{% /boxes/note %}}
`m.relates_to` is defined as follows:
{{% definition path="api/client-server/definitions/m.relates_to" %}}
#### Relationship types
This specification describes the following relationship types:
* [Rich replies](#rich-replies) (**Note**: does not use `rel_type`).
#### Aggregations
{{% added-in v="1.3" %}}
Some child events can be "aggregated" by the server, depending on their
`rel_type`. This can allow a set of child events to be summarised to the client without
the client needing the child events themselves.
An example of this might be that a `rel_type` requires an extra `key` field which, when
appropriately specified, would mean that the client receives a total count for the number
of times that `key` was used by child events.
The actual aggregation format depends on the `rel_type`.
{{% boxes/note %}}
This specification does not currently describe any `rel_type`s which require
aggregation. This functionality forms a framework for future extensions.
{{% /boxes/note %}}
Aggregations are sometimes automatically included by a server alongside the parent
event. This is known as a "bundled aggregation" or "bundle" for simplicity. The
act of doing this is "bundling".
When an event is served to the client through the APIs listed below, a `m.relations` property
is included under `unsigned` if the event has child events which can be aggregated and point
at it. The `m.relations` property is an object keyed by `rel_type` and value being the type-specific
aggregated format for that `rel_type`, also known as the bundle.
For example (unimportant fields not included):
```json
{
"event_id": "$my_event",
"unsigned": {
"m.relations": {
"org.example.possible_annotations": [
{
"key": "👍",
"origin_server_ts": 1562763768320,
"count": 3
},
{
"key": "👎",
"origin_server_ts": 1562763768320,
"count": 1
}
],
"org.example.possible_thread": {
"current_server_participated": true,
"count": 7,
"latest_event": {
"event_id": "$another_event",
"content": {
"body": "Hello world"
}
}
}
}
}
}
```
Note how the `org.example.possible_annotations` bundle is an array compared to the
`org.example.possible_thread` bundle where the server is summarising the state of
the relationship in a single object. Both are valid ways to aggregate, and their
exact types depend on the `rel_type`.
{{% boxes/warning %}}
State events do not currently receive bundled aggregations. This is not
necessarily a deliberate design decision, and MSCs which aim to fix this are welcome.
{{% /boxes/warning %}}
The endpoints where the server *should* include bundled aggregations are:
* [`GET /rooms/{roomId}/messages`](#get_matrixclientv3roomsroomidmessages)
* [`GET /rooms/{roomId}/context/{eventId}`](#get_matrixclientv3roomsroomidcontexteventid)
* [`GET /rooms/{roomId}/event/{eventId}`](#get_matrixclientv3roomsroomideventeventid)
* [`GET /rooms/{roomId}/relations/{eventId}`](#get_matrixclientv1roomsroomidrelationseventid)
* [`GET /rooms/{roomId}/relations/{eventId}/{relType}`](#get_matrixclientv1roomsroomidrelationseventidreltype)
* [`GET /rooms/{roomId}/relations/{eventId}/{relType}/{eventType}`](#get_matrixclientv1roomsroomidrelationseventidreltypeeventtype)
* [`GET /sync`](#get_matrixclientv3sync) when the relevant section has a `limited` value
of `true`.
* [`POST /search`](#post_matrixclientv3search) for any matching events under `room_events`.
{{% boxes/note %}}
The server is **not** required to return bundled aggregations on deprecated endpoints
such as `/initialSync`.
{{% /boxes/note %}}
While this functionality allows the client to see what was known to the server at the
time of handling, the client should continue to aggregate locally if it is aware of
the relationship type's behaviour. For example, a client might increment a `count`
on a parent event's bundle if it saw a new child event which referenced that parent.
The bundle provided by the server only includes child events which were known at the
time the client would receive the bundle. For example, in a single `/sync` response
with the parent and multiple child events the child events would have already been
included on the parent's `m.relations` field. Events received in future syncs would
need to be aggregated manually by the client.
{{% boxes/note %}}
Events from [ignored users](#ignoring-users) do not appear in the aggregation
from the server, however clients might still have events from ignored users cached. Like
with normal events, clients will need to de-aggregate child events sent by ignored users to
avoid them being considered in counts. Servers must additionally ensure they do not
consider child events from ignored users when preparing a bundle for the client.
{{% /boxes/note %}}
When a parent event is redacted, the child events which pointed to that parent remain, however
when a child event is redacted then the relationship is broken. Therefore, the server needs
to de-aggregate or disassociate the event once the relationship is lost. Clients with local
aggregation or which handle redactions locally should do the same.
It is suggested that clients perform local echo on aggregations — for instance, aggregating
a new child event into a bundle optimistically until the server returns a failure or the client
gives up on sending the event, at which point the event should be de-aggregated and an
error or similar shown. The client should be cautious to not aggregate an event twice if
it has already optimistically aggregated the event. Clients are encouraged to take this
a step further to additionally track child events which target unsent/pending events,
likely using the transaction ID as a temporary event ID until a proper event ID is known.
{{% boxes/warning %}}
Due to history visibility restrictions, child events might not be visible to the user
if they are in a section of history the user cannot see. This means any bundles which would
normally include those events will be lacking them and the client will not be able to
locally aggregate the events either — relating events of importance (such as votes) should
take into consideration history visibility.
Additionally, if the server is missing portions of the room history then it may not be
able to accurately aggregate the events.
{{% /boxes/warning %}}
#### Relationships API
{{% added-in v="1.3" %}}
To retrieve the child events for a parent from the server, the client can call the
following endpoint.
This endpoint is particularly useful if the client has lost context on the aggregation for
a parent event and needs to rebuild/verify it.
{{% boxes/note %}}
Because replies do not use `rel_type`, they will not be accessible via this API.
{{% /boxes/note %}}
{{% http-api spec="client-server" api="relations" %}}
## Rooms ## Rooms
### Types ### Types
@ -1969,6 +2246,13 @@ room listed in the join rules. If the server cannot verify membership for any
of the listed rooms then you can only join with an invite. Note that this rule of the listed rooms then you can only join with an invite. Note that this rule
is only expected to work in room versions [which support it](/rooms/#feature-matrix). is only expected to work in room versions [which support it](/rooms/#feature-matrix).
{{% added-in v="1.3" %}} `knock_restricted`
This room can be joined as though it was `restricted` *or* `knock`. If you
interact with the room using knocking, the `knock` rule takes effect whereas
trying to join the room without an invite applies the `restricted` join rule.
Note that this rule is only expected to work in room versions
[which support it](/rooms/#feature-matrix).
The allowable state transitions of membership are: The allowable state transitions of membership are:
![membership-flow-diagram](/diagrams/membership.png) ![membership-flow-diagram](/diagrams/membership.png)
@ -1984,6 +2268,15 @@ The allowable state transitions of membership are:
##### Knocking on rooms ##### Knocking on rooms
{{% added-in v="1.1" %}} {{% added-in v="1.1" %}}
{{% changed-in v="1.3" %}}
{{% boxes/note %}}
As of `v1.3`, it is possible to knock on a [restricted room](#restricted-rooms)
if the room supports and is using the `knock_restricted` join rule.
Note that `knock_restricted` is only expected to work in room versions
[which support it](/rooms/#feature-matrix).
{{% /boxes/note %}}
<!-- <!--
This section is here because it's most similar to being invited/joining a This section is here because it's most similar to being invited/joining a
@ -2021,6 +2314,15 @@ server chose to auto-accept.
##### Restricted rooms ##### Restricted rooms
{{% added-in v="1.2" %}} {{% added-in v="1.2" %}}
{{% changed-in v="1.3" %}}
{{% boxes/note %}}
As of `v1.3`, it is possible to [knock](#knocking-on-rooms) on a restricted
room if the room supports and is using the `knock_restricted` join rule.
Note that `knock_restricted` is only expected to work in room versions
[which support it](/rooms/#feature-matrix).
{{% /boxes/note %}}
Restricted rooms are rooms with a `join_rule` of `restricted`. These rooms Restricted rooms are rooms with a `join_rule` of `restricted`. These rooms
are accompanied by "allow conditions" as described in the are accompanied by "allow conditions" as described in the
@ -2212,6 +2514,7 @@ that profile.
| Module / Profile | Web | Mobile | Desktop | CLI | Embedded | | Module / Profile | Web | Mobile | Desktop | CLI | Embedded |
|------------------------------------------------------------|-----------|----------|----------|----------|----------| |------------------------------------------------------------|-----------|----------|----------|----------|----------|
| [Instant Messaging](#instant-messaging) | Required | Required | Required | Required | Optional | | [Instant Messaging](#instant-messaging) | Required | Required | Required | Required | Optional |
| [Rich replies](#rich-replies) | Optional | Optional | Optional | Optional | Optional |
| [Direct Messaging](#direct-messaging) | Required | Required | Required | Required | Optional | | [Direct Messaging](#direct-messaging) | Required | Required | Required | Required | Optional |
| [Mentions](#user-room-and-group-mentions) | Required | Required | Required | Optional | Optional | | [Mentions](#user-room-and-group-mentions) | Required | Required | Required | Optional | Optional |
| [Presence](#presence) | Required | Required | Required | Required | Optional | | [Presence](#presence) | Required | Required | Required | Required | Optional |
@ -2291,6 +2594,7 @@ applications, they are not intended to be fully-fledged communication
systems. systems.
{{% cs-module name="instant_messaging" %}} {{% cs-module name="instant_messaging" %}}
{{% cs-module name="rich_replies" %}}
{{% cs-module name="voip_events" %}} {{% cs-module name="voip_events" %}}
{{% cs-module name="typing_notifications" %}} {{% cs-module name="typing_notifications" %}}
{{% cs-module name="receipts" %}} {{% cs-module name="receipts" %}}

View file

@ -1531,8 +1531,19 @@ For example, Megolm sessions that were sent using the old session would
have been lost. The client can attempt to retrieve the lost sessions have been lost. The client can attempt to retrieve the lost sessions
through `m.room_key_request` messages. through `m.room_key_request` messages.
{{% boxes/note %}}
Clients should send key requests for unknown sessions to all devices for
the user which used the session rather than just the `device_id` or
`sender_key` denoted on the event.
This is due to a deprecation of the fields. See
[`m.megolm.v1.aes-sha2`](#mmegolmv1aes-sha2) for more information.
{{% /boxes/note %}}
##### `m.megolm.v1.aes-sha2` ##### `m.megolm.v1.aes-sha2`
{{% changed-in v="1.3" %}}
The name `m.megolm.v1.aes-sha2` corresponds to version 1 of the Megolm The name `m.megolm.v1.aes-sha2` corresponds to version 1 of the Megolm
ratchet, as defined by the [Megolm ratchet, as defined by the [Megolm
specification](http://matrix.org/docs/spec/megolm.html). This uses: specification](http://matrix.org/docs/spec/megolm.html). This uses:
@ -1580,10 +1591,36 @@ ratchet index that they have already decrypted. Care should be taken in
order to avoid false positives, as a client may decrypt the same event order to avoid false positives, as a client may decrypt the same event
twice as part of its normal processing. twice as part of its normal processing.
As with Olm events, clients must confirm that the `sender_key` belongs Similar to Olm events, clients should confirm that the user who sent the
to the user who sent the message. The same reasoning applies, but the message corresponds to the user the message was expected to come from.
sender ed25519 key has to be inferred from the `keys.ed25519` property For room events, this means ensuring the event's `sender`, `room_id`, and
of the event which established the Megolm session. the recorded `session_id` match a trusted session (eg: the `session_id`
is already known and validated to the client).
{{% boxes/note %}}
As of `v1.3`, the `sender_key` and `device_id` keys are **deprecated**. They
SHOULD continue to be sent, however they MUST NOT be used to verify the
message's source.
Clients MUST NOT store or lookup sessions using the `sender_key` or `device_id`.
In a future version of the specification the keys can be removed completely,
including for sending new messages.
{{% /boxes/note %}}
{{% boxes/rationale %}}
Removing the fields (eventually) improves privacy and security by masking the
device which sent the encrypted message as well as reducing the client's
dependence on untrusted data: a malicious server (or similar attacker) could
change these values, and other devices/users can simply lie about them too.
We can remove the fields, particularly the `sender_key`, because the `session_id`
is already globally unique, therefore making storage and lookup possible without
the need for added context from the `sender_key` or `device_id`.
Removing the dependence on the fields gives a privacy gain while also increasing
the security of messages transmitted over Matrix.
{{% /boxes/rationale %}}
In order to enable end-to-end encryption in a room, clients can send an In order to enable end-to-end encryption in a room, clients can send an
`m.room.encryption` state event specifying `m.megolm.v1.aes-sha2` as its `m.room.encryption` state event specifying `m.megolm.v1.aes-sha2` as its
@ -1596,6 +1633,11 @@ that they can decrypt future messages encrypted using this session. An
`m.room_key` events sent by other devices in order to decrypt their `m.room_key` events sent by other devices in order to decrypt their
messages. messages.
When a client is updating a Megolm session (room key) in its store, the client MUST ensure:
* that the updated session data comes from a trusted source.
* that the new session key has a lower message index than the existing session key.
#### Protocol definitions #### Protocol definitions
##### Events ##### Events

View file

@ -287,169 +287,6 @@ when using the `m.heroes` to calculate the name. Clients SHOULD use
minimum 5 heroes to calculate room names where possible, but may use minimum 5 heroes to calculate room names where possible, but may use
more or less to fit better with their user experience. more or less to fit better with their user experience.
##### Rich replies
In some cases, events may wish to reference other events. This could be
to form a thread of messages for the user to follow along with, or to
provide more context as to what a particular event is describing.
Currently, the only kind of relation defined is a "rich reply" where a
user may reference another message to create a thread-like conversation.
Relationships are defined under an `m.relates_to` key in the event's
`content`. If the event is of the type `m.room.encrypted`, the
`m.relates_to` key MUST NOT be covered by the encryption and instead be
put alongside the encryption information held in the `content`.
A rich reply is formed through use of an `m.relates_to` relation for
`m.in_reply_to` where a single key, `event_id`, is used to reference the
event being replied to. The referenced event ID SHOULD belong to the
same room where the reply is being sent. Clients should be cautious of
the event ID belonging to another room, or being invalid entirely. Rich
replies can only be constructed in the form of `m.room.message` events
with a `msgtype` of `m.text` or `m.notice`. Due to the fallback
requirements, rich replies cannot be constructed for types of `m.emote`,
`m.file`, etc. Rich replies may reference any other `m.room.message`
event, however. Rich replies may reference another event which also has
a rich reply, infinitely.
An `m.in_reply_to` relationship looks like the following:
```
{
...
"type": "m.room.message",
"content": {
"msgtype": "m.text",
"body": "<body including fallback>",
"format": "org.matrix.custom.html",
"formatted_body": "<HTML including fallback>",
"m.relates_to": {
"m.in_reply_to": {
"event_id": "$another:event.com"
}
}
}
}
```
##### Fallbacks for rich replies
Some clients may not have support for rich replies and therefore need a
fallback to use instead. Clients that do not support rich replies should
render the event as if rich replies were not special.
Clients that do support rich replies MUST provide the fallback format on
replies, and MUST strip the fallback before rendering the reply. Rich
replies MUST have a `format` of `org.matrix.custom.html` and therefore a
`formatted_body` alongside the `body` and appropriate `msgtype`. The
specific fallback text is different for each `msgtype`, however the
general format for the `body` is:
> <@alice:example.org> This is the original body
This is where the reply goes
The `formatted_body` should use the following template:
<mx-reply>
<blockquote>
<a href="https://matrix.to/#/!somewhere:example.org/$event:example.org">In reply to</a>
<a href="https://matrix.to/#/@alice:example.org">@alice:example.org</a>
<br />
<!-- This is where the related event's HTML would be. -->
</blockquote>
</mx-reply>
This is where the reply goes.
If the related event does not have a `formatted_body`, the event's
`body` should be considered after encoding any HTML special characters.
Note that the `href` in both of the anchors use a [matrix.to
URI](/appendices#matrixto-navigation).
###### Stripping the fallback
Clients which support rich replies MUST strip the fallback from the
event before rendering the event. This is because the text provided in
the fallback cannot be trusted to be an accurate representation of the
event. After removing the fallback, clients are recommended to represent
the event referenced by `m.in_reply_to` similar to the fallback's
representation, although clients do have creative freedom for their user
interface. Clients should prefer the `formatted_body` over the `body`,
just like with other `m.room.message` events.
To strip the fallback on the `body`, the client should iterate over each
line of the string, removing any lines that start with the fallback
prefix ("&gt; ", including the space, without quotes) and stopping when
a line is encountered without the prefix. This prefix is known as the
"fallback prefix sequence".
To strip the fallback on the `formatted_body`, the client should remove
the entirety of the `mx-reply` tag.
###### Fallback for `m.text`, `m.notice`, and unrecognised message types
Using the prefix sequence, the first line of the related event's `body`
should be prefixed with the user's ID, followed by each line being
prefixed with the fallback prefix sequence. For example:
> <@alice:example.org> This is the first line
> This is the second line
This is the reply
The `formatted_body` uses the template defined earlier in this section.
###### Fallback for `m.emote`
Similar to the fallback for `m.text`, each line gets prefixed with the
fallback prefix sequence. However an asterisk should be inserted before
the user's ID, like so:
> * <@alice:example.org> feels like today is going to be a great day
This is the reply
The `formatted_body` has a subtle difference for the template where the
asterisk is also inserted ahead of the user's ID:
<mx-reply>
<blockquote>
<a href="https://matrix.to/#/!somewhere:example.org/$event:example.org">In reply to</a>
* <a href="https://matrix.to/#/@alice:example.org">@alice:example.org</a>
<br />
<!-- This is where the related event's HTML would be. -->
</blockquote>
</mx-reply>
This is where the reply goes.
###### Fallback for `m.image`, `m.video`, `m.audio`, and `m.file`
The related event's `body` would be a file name, which may not be very
descriptive. The related event should additionally not have a `format`
or `formatted_body` in the `content` - if the event does have a `format`
and/or `formatted_body`, those fields should be ignored. Because the
filename alone may not be descriptive, the related event's `body` should
be considered to be `"sent a file."` such that the output looks similar
to the following:
> <@alice:example.org> sent a file.
This is the reply
<mx-reply>
<blockquote>
<a href="https://matrix.to/#/!somewhere:example.org/$event:example.org">In reply to</a>
<a href="https://matrix.to/#/@alice:example.org">@alice:example.org</a>
<br />
sent a file.
</blockquote>
</mx-reply>
This is where the reply goes.
For `m.image`, the text should be `"sent an image."`. For `m.video`, the
text should be `"sent a video."`. For `m.audio`, the text should be
`"sent an audio file"`.
##### Spoiler messages ##### Spoiler messages
{{% added-in v="1.1" %}} {{% added-in v="1.1" %}}

View file

@ -0,0 +1,182 @@
---
type: module
---
### Rich replies
{{% changed-in v="1.3" %}}
Rich replies are a
special kind of [relationship](#forming-relationships-between-events) which
effectively quotes the referenced event for the client to render/process how
it wishes. They are normally used with [`m.room.message`](#mroommessage) events.
{{% boxes/note %}}
Until v1.3 of the spec, rich replies were limited to `m.room.message` events
which could represent an HTML-formatted body. As of v1.3 this is now expanded
to *all* event types by dropping the requirement that an HTML-formatted body
be included.
Additionally, a rich reply can reference any other event type as of v1.3.
Previously, a rich reply could only reference another `m.room.message` event.
{{% /boxes/note %}}
When possible, events SHOULD include a [fallback representation](#fallbacks-for-rich-replies)
to allow clients which do not render rich replies to still see something which
appears to be a quoted reply.
Though rich replies form a relationship to another event, they do not
use `rel_type` to create this relationship. Instead, a subkey named `m.in_reply_to`
is used to describe the reply's relationship, leaving the other properties of
`m.relates_to` to describe the primary relationship of the event. This means
that if an event is simply in reply to another event, without further relationship,
the `rel_type` and `event_id` properties of `m.relates_to` become *optional*.
An example reply would be:
```json5
{
"content": {
"m.relates_to": {
"m.in_reply_to": {
"event_id": "$another_event"
}
},
"body": "That sounds like a great idea!"
},
// other fields as required by events
}
```
Note that the `event_id` of the `m.in_reply_to` object has the same requirements
as if it were to be under `m.relates_to` directly instead.
#### Fallbacks for rich replies
Some clients may not have support for rich replies and therefore need a
fallback to use instead. Clients that do not support rich replies should
render the event as if rich replies were not special.
Clients that do support rich replies SHOULD provide the fallback format on
replies, and MUST strip the fallback before rendering the reply. The
specific fallback text is different for each `msgtype`, however the
general format for the `body` is:
```text
> <@alice:example.org> This is the original body
This is where the reply goes
```
The `formatted_body`, if present and using an associated `format` of
`org.matrix.custom.html`, should use the following template:
```html
<mx-reply>
<blockquote>
<a href="https://matrix.to/#/!somewhere:example.org/$event:example.org">In reply to</a>
<a href="https://matrix.to/#/@alice:example.org">@alice:example.org</a>
<br />
<!-- This is where the related event's HTML would be. -->
</blockquote>
</mx-reply>
This is where the reply goes.
```
If the related event does not have a `formatted_body`, the event's
`body` should be considered after encoding any HTML special characters.
Note that the `href` in both of the anchors use a [matrix.to
URI](/appendices#matrixto-navigation).
##### Stripping the fallback
Clients which support rich replies MUST strip the fallback from the
event before rendering the event. This is because the text provided in
the fallback cannot be trusted to be an accurate representation of the
event. After removing the fallback, clients are recommended to represent
the event referenced by `m.in_reply_to` similar to the fallback's
representation, although clients do have creative freedom for their user
interface. Clients should prefer the `formatted_body` over the `body`,
just like with other `m.room.message` events.
To strip the fallback on the `body`, the client should iterate over each
line of the string, removing any lines that start with the fallback
prefix ("&gt; ", including the space, without quotes) and stopping when
a line is encountered without the prefix. This prefix is known as the
"fallback prefix sequence".
To strip the fallback on the `formatted_body`, the client should remove
the entirety of the `mx-reply` tag.
##### Fallback for `m.text`, `m.notice`, and unrecognised message types
Using the prefix sequence, the first line of the related event's `body`
should be prefixed with the user's ID, followed by each line being
prefixed with the fallback prefix sequence. For example:
```text
> <@alice:example.org> This is the first line
> This is the second line
This is the reply
```
The `formatted_body` uses the template defined earlier in this section.
##### Fallback for `m.emote`
Similar to the fallback for `m.text`, each line gets prefixed with the
fallback prefix sequence. However an asterisk should be inserted before
the user's ID, like so:
```text
> * <@alice:example.org> feels like today is going to be a great day
This is the reply
```
The `formatted_body` has a subtle difference for the template where the
asterisk is also inserted ahead of the user's ID:
```html
<mx-reply>
<blockquote>
<a href="https://matrix.to/#/!somewhere:example.org/$event:example.org">In reply to</a>
* <a href="https://matrix.to/#/@alice:example.org">@alice:example.org</a>
<br />
<!-- This is where the related event's HTML would be. -->
</blockquote>
</mx-reply>
This is where the reply goes.
```
##### Fallback for `m.image`, `m.video`, `m.audio`, and `m.file`
The related event's `body` would be a file name, which may not be very
descriptive. The related event should additionally not have a `format`
or `formatted_body` in the `content` - if the event does have a `format`
and/or `formatted_body`, those fields should be ignored. Because the
filename alone may not be descriptive, the related event's `body` should
be considered to be `"sent a file."` such that the output looks similar
to the following:
```text
> <@alice:example.org> sent a file.
This is the reply
```
```html
<mx-reply>
<blockquote>
<a href="https://matrix.to/#/!somewhere:example.org/$event:example.org">In reply to</a>
<a href="https://matrix.to/#/@alice:example.org">@alice:example.org</a>
<br />
sent a file.
</blockquote>
</mx-reply>
This is where the reply goes.
```
For `m.image`, the text should be `"sent an image."`. For `m.video`, the
text should be `"sent a video."`. For `m.audio`, the text should be
`"sent an audio file"`.

View file

@ -36,10 +36,11 @@ Alternatively, consider flipping the column/row organization to be features
up top and versions on the left. up top and versions on the left.
--> -->
| Feature \ Version | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | | Feature \ Version | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|-------------------|---|---|---|---|---|---|---|---|---| |-------------------|---|---|---|---|---|---|---|---|---|----|
| **Knocking** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ | | **Knocking** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ |
| **Restricted join rules** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | | **Restricted join rules** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ |
| **`knock_restricted` join rule** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ |
## Complete list of room versions ## Complete list of room versions
@ -73,6 +74,8 @@ The available room versions are:
of another room to join without invite. of another room to join without invite.
- [Version 9](/rooms/v9) - **Stable**. Builds on v8 to fix issues when - [Version 9](/rooms/v9) - **Stable**. Builds on v8 to fix issues when
redacting some membership events. redacting some membership events.
- [Version 10](/rooms/v10) - **Stable**. Enforces integer-only power levels
and adds `knock_restricted` join rule.
## Room version grammar ## Room version grammar

View file

@ -0,0 +1,13 @@
---
toc_hide: true
---
Events sent into rooms of this version can have formats which are different
from their normal schema. Those cases are documented here.
{{% boxes/warning %}}
The behaviour described here is preserved strictly for backwards compatibility
only. A homeserver should take reasonable precautions to prevent users from
sending these so-called "malformed" events, and must never rely on the behaviours
described here as a default.
{{% /boxes/warning %}}

View file

@ -0,0 +1,43 @@
---
toc_hide: true
---
##### `m.room.power_levels` events accept values as strings
In order to maintain backwards compatibility with early implementations,
each of the integer-valued properties within
[`m.room.power_levels`](/client-server-api#mroompower_levels) events can
be encoded as strings instead of integers. This includes the nested values
within the `events`, `notifications` and `users` properties.
For example, the following is a valid `m.room.power_levels` event in this room version:
```json
{
"content": {
"ban": "50",
"events": {
"m.room.power_levels": "100"
},
"events_default": "0",
"state_default": "50",
"users": {
"@example:localhost": "100"
},
"users_default": "0"
},
"origin_server_ts": 1432735824653,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"state_key": "",
"type": "m.room.power_levels"
}
```
When the value is representative of an integer, they must be the following format:
* a single base 10 integer, no float values or decimal points, optionally with
any number of leading zeroes (`"100"`, `"000100"`);
* optionally prefixed with a single `-` or `+` character before the integer (`"+100"`,
`"-100"`).
* optionally with any number of leading or trailing whitespace characters (`" 100 "`,
`" 00100 "`, `" +100 "`, `" -100 "`);

View file

@ -0,0 +1,51 @@
---
toc_hide: true
---
{{% added-in this=true %}} `m.room.member` events now keep `join_authorised_via_users_server`
in addition to other keys in `content` when being redacted.
{{% boxes/rationale %}}
Without the `join_authorised_via_users_server` property, redacted join events
can become invalid when verifying the auth chain of a given event, thus creating
a split-brain scenario where the user is able to speak from one server's
perspective but most others will continually reject their events.
This can theoretically be worked around with a rejoin to the room, being careful
not to use the faulty events as `prev_events`, though instead it is encouraged
to use v9 rooms over v8 rooms to outright avoid the situation.
[Issue #3373](https://github.com/matrix-org/matrix-doc/issues/3373) has further
information.
{{% /boxes/rationale %}}
The full redaction algorithm follows.
Upon receipt of a redaction event, the server must strip off any keys
not in the following list:
- `event_id`
- `type`
- `room_id`
- `sender`
- `state_key`
- `content`
- `hashes`
- `signatures`
- `depth`
- `prev_events`
- `prev_state`
- `auth_events`
- `origin`
- `origin_server_ts`
- `membership`
The content object must also be stripped of all keys, unless it is one
of one of the following event types:
- `m.room.member` allows keys `membership`, `join_authorised_via_users_server`.
- `m.room.create` allows key `creator`.
- `m.room.join_rules` allows keys `join_rule`, `allow`.
- `m.room.power_levels` allows keys `ban`, `events`, `events_default`,
`kick`, `redact`, `state_default`, `users`, `users_default`.
- `m.room.history_visibility` allows key `history_visibility`.

View file

@ -48,6 +48,12 @@ Events in version 1 rooms have the following structure:
{{% definition path="api/server-server/definitions/pdu" %}} {{% 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 ### Authorization rules
{{% rver-fragment name="v1-auth-rules" %}} {{% rver-fragment name="v1-auth-rules" %}}

277
content/rooms/v10.md Normal file
View file

@ -0,0 +1,277 @@
---
title: Room Version 10
type: docs
weight: 100
---
This room version builds on [version 9](/rooms/v9) to enforce that power level
values be integers, and to introduce a new `knock_restricted` join rule, allowing
prospective members to more easily join such a room.
## Client considerations
This room version adds a new `knock_restricted` join rule to allow prospective
members of a room join either through knocking (introduced in [room version 7](/rooms/v7))
or through "join restrictions" (introduced in [room version 8](/rooms/v8) and
refined in [room version 9](/rooms/v9)).
Clients should render the new join rule accordingly for such rooms. For example:
```
This room is:
[ ] Public
[x] Private
Join rules (disabled when Public):
[x] Allow members of `#space:example.org` to join
[x] Allow knocking
```
Clients which implement the redaction algorithm locally should refer to the
[redactions](#redactions) section below for a full overview.
## 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 %}}
[Room version 7](/rooms/v7) added "knocking" and [room version 8](/rooms/v8)
added "join restrictions" (refined by [room version 9](/rooms/v9)) — both allow
prospective members an avenue to join, however it was not possible to use
the two mechanisms together. This room version adds a new
`knock_restricted` join rule as a mix of the two behaviours, allowing a user to
join the room if they meet either the `restricted` join rule criteria or the
`knock` join rule criteria.
This room version additionally requires that values in the power levels event
be integers and not string representations, unlike other room versions.
Room version 10 is based upon room version 9 with the following considerations.
### Event format
The event format is unchanged by this room version. See [below](#event-format-1)
for details on the current event format.
#### Deprecated event content schemas
While this room version does not change the event format specifically, some
deprecated behaviours are strictly no longer supported.
##### Values in `m.room.power_levels` events must be integers
In other room versions, such as [v9](/rooms/v9/#mroompower_levels-events-accept-values-as-strings),
power levels could be represented as strings for backwards compatibility.
This backwards compatibility is removed in this room version - power levels MUST NOT
be represented as strings within this room version. Power levels which are not
correctly structured are rejected under the authorization rules below.
### Authorization rules
Events must be signed by the server denoted by the `sender` key.
`m.room.redaction` events are not explicitly part of the auth rules.
They are still subject to the minimum power level rules, but should always
fall into "10. Otherwise, allow". Instead of being authorized at the time
of receipt, they are authorized at a later stage: see the
[Redactions](#redactions) section below for more information.
The types of state events that affect authorization are:
- [`m.room.create`](/client-server-api#mroomcreate)
- [`m.room.member`](/client-server-api#mroommember)
- [`m.room.join_rules`](/client-server-api#mroom)
- [`m.room.power_levels`](/client-server-api#mroompower_levels)
- [`m.room.third_party_invite`](/client-server-api#mroomthird_party_invite)
{{% boxes/note %}}
Power levels are inferred from defaults when not explicitly supplied.
For example, mentions of the `sender`'s power level can also refer to
the default power level for users in the room.
{{% /boxes/note %}}
The rules are as follows:
1. If type is `m.room.create`:
1. If it has any previous events, reject.
2. If the domain of the `room_id` does not match the domain of the
`sender`, reject.
3. If `content.room_version` is present and is not a recognised
version, reject.
4. If `content` has no `creator` field, reject.
5. Otherwise, allow.
2. Reject if event has `auth_events` that:
1. have duplicate entries for a given `type` and `state_key` pair
2. have entries whose `type` and `state_key` don't match those
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification.
3. If event does not have a `m.room.create` in its `auth_events`,
reject.
4. If type is `m.room.member`:
1. If no `state_key` key or `membership` key in `content`, reject.
2. If `content` has a `join_authorised_via_users_server`
key:
1. If the event is not validly signed by the homeserver of the user ID denoted
by the key, reject.
3. If `membership` is `join`:
1. If the only previous event is an `m.room.create` and the
`state_key` is the creator, allow.
2. If the `sender` does not match `state_key`, reject.
3. If the `sender` is banned, reject.
4. If the `join_rule` is `invite` or `knock` then allow if
membership state is `invite` or `join`.
5. {{< changed-in this="true" >}}
If the `join_rule` is `restricted` or `knock_restricted`:
1. If membership state is `join` or `invite`, allow.
2. If the `join_authorised_via_users_server` key in `content`
is not a user with sufficient permission to invite other
users, reject.
3. Otherwise, allow.
6. If the `join_rule` is `public`, allow.
7. Otherwise, reject.
4. If `membership` is `invite`:
1. If `content` has `third_party_invite` key:
1. If *target user* is banned, reject.
2. If `content.third_party_invite` does not have a `signed`
key, reject.
3. If `signed` does not have `mxid` and `token` keys,
reject.
4. If `mxid` does not match `state_key`, reject.
5. If there is no `m.room.third_party_invite` event in the
current room state with `state_key` matching `token`,
reject.
6. If `sender` does not match `sender` of the
`m.room.third_party_invite`, reject.
7. If any signature in `signed` matches any public key in
the `m.room.third_party_invite` event, allow. The public
keys are in `content` of `m.room.third_party_invite` as:
1. A single public key in the `public_key` field.
2. A list of public keys in the `public_keys` field.
8. Otherwise, reject.
2. If the `sender`'s current membership state is not `join`,
reject.
3. If *target user*'s current membership state is `join` or
`ban`, reject.
4. If the `sender`'s power level is greater than or equal to
the *invite level*, allow.
5. Otherwise, reject.
5. If `membership` is `leave`:
1. If the `sender` matches `state_key`, allow if and only if
that user's current membership state is `invite`, `join`,
or `knock`.
2. If the `sender`'s current membership state is not `join`,
reject.
3. If the *target user*'s current membership state is `ban`,
and the `sender`'s power level is less than the *ban level*,
reject.
4. If the `sender`'s power level is greater than or equal to
the *kick level*, and the *target user*'s power level is
less than the `sender`'s power level, allow.
5. Otherwise, reject.
6. If `membership` is `ban`:
1. If the `sender`'s current membership state is not `join`,
reject.
2. If the `sender`'s power level is greater than or equal to
the *ban level*, and the *target user*'s power level is less
than the `sender`'s power level, allow.
3. Otherwise, reject.
7. If `membership` is `knock`:
1. {{< changed-in this="true" >}}
If the `join_rule` is anything other than `knock` or
`knock_restricted`, reject.
2. If `sender` does not match `state_key`, reject.
3. If the `sender`'s current membership is not `ban`, `invite`,
or `join`, allow.
4. Otherwise, reject.
8. Otherwise, the membership is unknown. Reject.
5. If the `sender`'s current membership state is not `join`, reject.
6. If type is `m.room.third_party_invite`:
1. Allow if and only if `sender`'s current power level is greater
than or equal to the *invite level*.
7. If the event type's *required power level* is greater than the
`sender`'s power level, reject.
8. If the event has a `state_key` that starts with an `@` and does not
match the `sender`, reject.
9. If type is `m.room.power_levels`:
1. {{< added-in this="true" >}}
If any of the keys `users_default`, `events_default`, `state_default`,
`ban`, `redact`, `kick`, or `invite` in `content` are present and
not an integer, reject.
2. {{< added-in this="true" >}}
If either of the keys `events` or `notifications` in `content`
are present and not a dictionary with values that are integers,
reject.
3. If `users` key in `content` is not a dictionary with keys that
are valid user IDs with values that are integers, reject.
2. If there is no previous `m.room.power_levels` event in the room,
allow.
3. For the keys `users_default`, `events_default`, `state_default`,
`ban`, `redact`, `kick`, `invite` check if they were added,
changed or removed. For each found alteration:
1. If the current value is higher than the `sender`'s current
power level, reject.
2. If the new value is higher than the `sender`'s current power
level, reject.
4. For each entry being added, changed or removed in both the
`events`, `users`, and `notifications` keys:
1. If the current value is higher than the `sender`'s current
power level, reject.
2. If the new value is higher than the `sender`'s current power
level, reject.
5. For each entry being changed under the `users` key, other than
the `sender`'s own entry:
1. If the current value is equal to the `sender`'s current
power level, reject.
6. Otherwise, allow.
10. Otherwise, allow.
{{% boxes/note %}}
Some consequences of these rules:
- Unless you are a member of the room, the only permitted operations
(apart from the initial create/join) are: joining a public room;
accepting or rejecting an invitation to a room.
- To unban somebody, you must have power level greater than or equal
to both the kick *and* ban levels, *and* greater than the target
user's power level.
{{% /boxes/note %}}
## Unchanged from v9
The following sections have not been modified since v9, but are included for
completeness.
### Redactions
{{% rver-fragment name="v9-redactions" %}}
### Handling redactions
{{% rver-fragment name="v3-handling-redactions" %}}
### Event IDs
{{% rver-fragment name="v4-event-ids" %}}
### Event format
{{% rver-fragment name="v4-event-format" %}}
### State resolution
{{% rver-fragment name="v2-state-res" %}}
### Canonical JSON
{{% rver-fragment name="v6-canonical-json" %}}
### Signing key validity period
{{% rver-fragment name="v5-signing-requirements" %}}

View file

@ -46,6 +46,12 @@ Events in rooms of this version have the following structure:
{{% definition path="api/server-server/definitions/pdu" %}} {{% 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 ### Authorization rules
{{% rver-fragment name="v1-auth-rules" %}} {{% rver-fragment name="v1-auth-rules" %}}

View file

@ -81,6 +81,12 @@ The complete structure of a event in a v3 room is shown below.
{{% definition path="api/server-server/definitions/pdu_v3" %}} {{% definition path="api/server-server/definitions/pdu_v3" %}}
#### Deprecated event content schemas
{{% rver-fragment name="v1-deprecated-formatting-off-spec" %}}
{{% rver-fragment name="v1-stringy-power-levels" %}}
### Authorization rules ### Authorization rules
{{% added-in this=true %}} `m.room.redaction` events are no longer {{% added-in this=true %}} `m.room.redaction` events are no longer

View file

@ -69,6 +69,12 @@ the changes in this room version.
{{% rver-fragment name="v4-event-format" %}} {{% rver-fragment name="v4-event-format" %}}
#### Deprecated event content schemas
{{% rver-fragment name="v1-deprecated-formatting-off-spec" %}}
{{% rver-fragment name="v1-stringy-power-levels" %}}
### Authorization rules ### Authorization rules
{{% rver-fragment name="v3-auth-rules" %}} {{% rver-fragment name="v3-auth-rules" %}}

View file

@ -51,6 +51,12 @@ completeness.
{{% rver-fragment name="v4-event-format" %}} {{% rver-fragment name="v4-event-format" %}}
#### Deprecated event content schemas
{{% rver-fragment name="v1-deprecated-formatting-off-spec" %}}
{{% rver-fragment name="v1-stringy-power-levels" %}}
### Authorization rules ### Authorization rules
{{% rver-fragment name="v3-auth-rules" %}} {{% rver-fragment name="v3-auth-rules" %}}

View file

@ -212,6 +212,12 @@ completeness.
{{% rver-fragment name="v4-event-format" %}} {{% rver-fragment name="v4-event-format" %}}
#### Deprecated event content schemas
{{% rver-fragment name="v1-deprecated-formatting-off-spec" %}}
{{% rver-fragment name="v1-stringy-power-levels" %}}
### State resolution ### State resolution
{{% rver-fragment name="v2-state-res" %}} {{% rver-fragment name="v2-state-res" %}}

View file

@ -1,7 +1,7 @@
--- ---
title: Room Version 7 title: Room Version 7
type: docs type: docs
weight: 60 weight: 70
--- ---
This room version builds on [version 6](/rooms/v6) to introduce knocking This room version builds on [version 6](/rooms/v6) to introduce knocking
@ -205,6 +205,12 @@ completeness.
{{% rver-fragment name="v4-event-format" %}} {{% rver-fragment name="v4-event-format" %}}
#### Deprecated event content schemas
{{% rver-fragment name="v1-deprecated-formatting-off-spec" %}}
{{% rver-fragment name="v1-stringy-power-levels" %}}
### State resolution ### State resolution
{{% rver-fragment name="v2-state-res" %}} {{% rver-fragment name="v2-state-res" %}}

View file

@ -1,7 +1,7 @@
--- ---
title: Room Version 8 title: Room Version 8
type: docs type: docs
weight: 60 weight: 80
--- ---
This room version builds on [version 7](/rooms/v7) to introduce a new This room version builds on [version 7](/rooms/v7) to introduce a new
@ -110,6 +110,12 @@ completeness.
{{% rver-fragment name="v4-event-format" %}} {{% rver-fragment name="v4-event-format" %}}
#### Deprecated event content schemas
{{% rver-fragment name="v1-deprecated-formatting-off-spec" %}}
{{% rver-fragment name="v1-stringy-power-levels" %}}
### State resolution ### State resolution
{{% rver-fragment name="v2-state-res" %}} {{% rver-fragment name="v2-state-res" %}}

View file

@ -1,7 +1,7 @@
--- ---
title: Room Version 9 title: Room Version 9
type: docs type: docs
weight: 60 weight: 90
--- ---
This room version builds on [version 8](/rooms/v8) to add additional redaction This room version builds on [version 8](/rooms/v8) to add additional redaction
@ -17,55 +17,7 @@ Clients which implement the redaction algorithm locally should refer to the
### Redactions ### Redactions
{{% added-in this=true %}} `m.room.member` now keep `join_authorised_via_users_server` {{% rver-fragment name="v9-redactions" withVersioning="true" %}}
in addition to other keys in `content` when being redacted.
{{% boxes/rationale %}}
Without the `join_authorised_via_users_server` property, redacted join events
can become invalid when verifying the auth chain of a given event, thus creating
a split-brain scenario where the user is able to speak from one server's
perspective but most others will continually reject their events.
This can theoretically be worked around with a rejoin to the room, being careful
not to use the faulty events as `prev_events`, though instead it is encouraged
to use v9 rooms over v8 rooms to outright avoid the situation.
[Issue #3373](https://github.com/matrix-org/matrix-doc/issues/3373) has further
information.
{{% /boxes/rationale %}}
The full redaction algorithm follows.
{{% rver-fragment name="v3-handling-redactions" %}}
Upon receipt of a redaction event, the server must strip off any keys
not in the following list:
- `event_id`
- `type`
- `room_id`
- `sender`
- `state_key`
- `content`
- `hashes`
- `signatures`
- `depth`
- `prev_events`
- `prev_state`
- `auth_events`
- `origin`
- `origin_server_ts`
- `membership`
The content object must also be stripped of all keys, unless it is one
of one of the following event types:
- `m.room.member` allows keys `membership`, `join_authorised_via_users_server`.
- `m.room.create` allows key `creator`.
- `m.room.join_rules` allows keys `join_rule`, `allow`.
- `m.room.power_levels` allows keys `ban`, `events`, `events_default`,
`kick`, `redact`, `state_default`, `users`, `users_default`.
- `m.room.history_visibility` allows key `history_visibility`.
## Server implementation components ## Server implementation components
@ -102,6 +54,12 @@ completeness.
{{% rver-fragment name="v4-event-format" %}} {{% rver-fragment name="v4-event-format" %}}
#### Deprecated event content schemas
{{% rver-fragment name="v1-deprecated-formatting-off-spec" %}}
{{% rver-fragment name="v1-stringy-power-levels" %}}
### Authorization rules ### Authorization rules
{{% rver-fragment name="v8-auth-rules" %}} {{% rver-fragment name="v8-auth-rules" %}}

View file

@ -432,6 +432,16 @@ unspecified.
For an `m.room.member` state event, the user given by the `state_key` of For an `m.room.member` state event, the user given by the `state_key` of
the event. the event.
{{% boxes/warning %}}
Some [room versions](/rooms) accept power level values to be represented as
strings rather than integers. This is strictly for backwards compatibility.
A homeserver should take reasonable precautions to prevent users from sending
new power level events with string values (eg: by rejecting the API request),
and must never populate the default power levels in a room as string values.
See the [room version specification](/rooms) for more information.
{{% /boxes/warning %}}
#### Authorization rules #### Authorization rules
The rules governing whether an event is authorized depends on a set of The rules governing whether an event is authorized depends on a set of

View file

@ -28,7 +28,6 @@ properties:
type: string type: string
additionalProperties: additionalProperties:
description: Keys dependent on the login type description: Keys dependent on the login type
type: object
example: example:
type: "example.type.foo" type: "example.type.foo"
session: "xxxxx" session: "xxxxx"

View file

@ -38,6 +38,10 @@ properties:
Present if, and only if, this event is a *state* event. The key making Present if, and only if, this event is a *state* event. The key making
this piece of state unique in the room. Note that it is often an empty this piece of state unique in the room. Note that it is often an empty
string. string.
State keys starting with an `@` are reserved for referencing user IDs, such
as room members. With the exception of a few events, state events set with a
given user's ID as the state key MUST only be set by that user.
type: string type: string
example: '@user:example.org' example: '@user:example.org'
sender: sender:

View file

@ -0,0 +1,43 @@
# Copyright 2022 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
type: object
title: m.relates_to
description: |-
Describes the relationship of an event to its parent. This is contained
within the event's `content` alongside other fields for the relevant event type.
example: {
# We deliberately "break" the example by including the top-level field so it renders
# sensibly for readers of the spec.
"m.relates_to": {
"rel_type": "org.example.relationship",
"event_id": "$an_event"
}
}
properties:
rel_type:
type: string
description: |-
The namespaced relationship type. Values must use the
[Common Namespaced Identifier Grammar](/appendices/#common-namespaced-identifier-grammar).
The relationship type determines how clients should perceive the event, and in what
context. Some relationship types are processed server-side for "bundling", though not
all relationships require such behaviour. For example, an `m.thread` relationship type
might denote that the event is part of a "thread" of messages and should be rendered as
such.
event_id:
type: string
description: The event ID of the event that this event relates to.
required: ['rel_type', 'event_id']

View file

@ -1,5 +1,6 @@
# Copyright 2016 OpenMarket Ltd # Copyright 2016 OpenMarket Ltd
# Copyright 2018 New Vector Ltd # Copyright 2018 New Vector Ltd
# Copyright 2022 The Matrix.org Foundation C.I.C.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -133,6 +134,11 @@ paths:
description: |- description: |-
A display name to assign to the newly-created device. Ignored A display name to assign to the newly-created device. Ignored
if `device_id` corresponds to a known device. if `device_id` corresponds to a known device.
refresh_token:
type: boolean
description: |-
If true, the client supports refresh tokens.
x-addedInMatrixVersion: "1.3"
required: ["type"] required: ["type"]
responses: responses:
@ -142,6 +148,8 @@ paths:
application/json: { application/json: {
"user_id": "@cheeky_monkey:matrix.org", "user_id": "@cheeky_monkey:matrix.org",
"access_token": "abc123", "access_token": "abc123",
"refresh_token": "def456",
"expires_in_ms": 60000,
"device_id": "GHTYAJCE", "device_id": "GHTYAJCE",
"well_known": { "well_known": {
"m.homeserver": { "m.homeserver": {
@ -163,6 +171,23 @@ paths:
description: |- description: |-
An access token for the account. An access token for the account.
This access token can then be used to authorize other requests. This access token can then be used to authorize other requests.
refresh_token:
type: string
description: |-
A refresh token for the account. This token can be used to
obtain a new access token when it expires by calling the
`/refresh` endpoint.
x-addedInMatrixVersion: "1.3"
expires_in_ms:
type: integer
description: |-
The lifetime of the access token, in milliseconds. Once
the access token has expired a new access token can be
obtained by using the provided refresh token. If no
refresh token is provided, the client will need to re-log in
to obtain a new access token. If not given, the client can
assume that the access token will not expire.
x-addedInMatrixVersion: "1.3"
home_server: home_server:
type: string type: string
description: |- description: |-

View file

@ -0,0 +1,108 @@
# Copyright 2022 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
swagger: '2.0'
info:
title: "Matrix Client-Server Registration and Login API"
version: "1.0.0"
host: localhost:8008
schemes:
- https
- http
basePath: /_matrix/client/v3
consumes:
- application/json
produces:
- application/json
paths:
"/refresh":
post:
x-addedInMatrixVersion: "1.3"
summary: Refresh an access token
description: |-
Refresh an access token. Clients should use the returned access token
when making subsequent API calls, and store the returned refresh token
(if given) in order to refresh the new access token when necessary.
After an access token has been refreshed, a server can choose to
invalidate the old access token immediately, or can choose not to, for
example if the access token would expire soon anyways. Clients should
not make any assumptions about the old access token still being valid,
and should use the newly provided access token instead.
The old refresh token remains valid until the new access token or refresh token
is used, at which point the old refresh token is revoked.
Note that this endpoint does not require authentication via an
access token. Authentication is provided via the refresh token.
Application Service identity assertion is disabled for this endpoint.
operationId: refresh
parameters:
- in: body
name: body
required: true
schema:
type: object
example: {
"refresh_token": "some_token"
}
properties:
refresh_token:
type: string
description: The refresh token
responses:
200:
description: A new access token and refresh token were generated.
examples:
application/json: {
"access_token": "a_new_token",
"expires_in_ms": 60000,
"refresh_token": "another_new_token"
}
schema:
type: object
properties:
access_token:
type: string
description: |-
The new access token to use.
refresh_token:
type: string
description: |-
The new refresh token to use when the access token needs to
be refreshed again. If not given, the old refresh token can
be re-used.
expires_in_ms:
type: integer
description: |-
The lifetime of the access token, in milliseconds. If not
given, the client can assume that the access token will not
expire.
required:
- access_token
401:
description: |-
The provided token was unknown, or has already been used.
examples:
application/json: {
"errcode": "M_UNKNOWN_TOKEN",
"error": "Soft logged out",
"soft_logout": true
}
schema:
"$ref": "definitions/errors/error.yaml"
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/errors/rate_limited.yaml"

View file

@ -1,4 +1,5 @@
# Copyright 2016 OpenMarket Ltd # Copyright 2016 OpenMarket Ltd
# Copyright 2022 The Matrix.org Foundation C.I.C.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -127,6 +128,11 @@ paths:
returned from this call, therefore preventing an automatic returned from this call, therefore preventing an automatic
login. Defaults to false. login. Defaults to false.
example: false example: false
refresh_token:
type: boolean
description: |-
If true, the client supports refresh tokens.
x-addedInMatrixVersion: "1.3"
responses: responses:
200: 200:
description: The account has been registered. description: The account has been registered.
@ -152,6 +158,27 @@ paths:
An access token for the account. An access token for the account.
This access token can then be used to authorize other requests. This access token can then be used to authorize other requests.
Required if the `inhibit_login` option is false. Required if the `inhibit_login` option is false.
refresh_token:
type: string
description: |-
A refresh token for the account. This token can be used to
obtain a new access token when it expires by calling the
`/refresh` endpoint.
Omitted if the `inhibit_login` option is true.
x-addedInMatrixVersion: "1.3"
expires_in_ms:
type: integer
description: |-
The lifetime of the access token, in milliseconds. Once
the access token has expired a new access token can be
obtained by using the provided refresh token. If no
refresh token is provided, the client will need to re-log in
to obtain a new access token. If not given, the client can
assume that the access token will not expire.
Omitted if the `inhibit_login` option is true.
x-addedInMatrixVersion: "1.3"
home_server: home_server:
type: string type: string
description: |- description: |-

View file

@ -0,0 +1,425 @@
# Copyright 2022 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
swagger: '2.0'
info:
title: "Matrix Client-Server Relations API"
version: "1.0.0"
host: localhost:8008
schemes:
- https
- http
basePath: /_matrix/client/v1
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/rooms/{roomId}/relations/{eventId}":
get:
summary: Get the child events for a given parent event.
description: |-
Retrieve all of the child events for a given parent event.
Note that when paginating the `from` token should be "after" the `to` token in
terms of topological ordering, because it is only possible to paginate "backwards"
through events, starting at `from`.
For example, passing a `from` token from page 2 of the results, and a `to` token
from page 1, would return the empty set. The caller can use a `from` token from
page 1 and a `to` token from page 2 to paginate over the same range, however.
operationId: getRelatingEvents
security:
- accessToken: []
parameters:
- in: path
type: string
name: roomId
description: The ID of the room containing the parent event.
required: true
x-example: "!636q39766251:matrix.org"
- in: path
type: string
name: eventId
description: The ID of the parent event whose child events are to be returned.
required: true
x-example: "$asfDuShaf7Gafaw"
- in: query
type: string
name: from
description: |-
The pagination token to start returning results from. If not supplied, results
start at the most recent topological event known to the server.
Can be a `next_batch` token from a previous call, or a returned
`start` token from [`/messages`](/client-server-api/#get_matrixclientv3roomsroomidmessages),
or a `next_batch` token from [`/sync`](/client-server-api/#get_matrixclientv3sync).
required: false
x-example: "page2_token"
- in: query
type: string
name: to
description: |-
The pagination token to stop returning results at. If not supplied, results
continue up to `limit` or until there are no more events.
Like `from`, this can be a previous token from a prior call to this endpoint
or from `/messages` or `/sync`.
required: false
x-example: "page3_token"
- in: query
type: integer
name: limit
description: |-
The maximum number of results to return in a single `chunk`. The server can
and should apply a maximum value to this parameter to avoid large responses.
Similarly, the server should apply a default value when not supplied.
required: false
x-example: 20
responses:
# note: this endpoint deliberately does not support rate limiting, therefore a
# 429 error response is not included.
200:
description: |-
The paginated child events which point to the parent. If no events are
pointing to the parent or the pagination yields no results, an empty `chunk`
is returned.
examples:
application/json: {
"chunk": [{
"room_id": "!636q39766251:matrix.org",
"$ref": "../../event-schemas/examples/m.room.message$m.text.yaml",
"content": {
"m.relates_to": {
"rel_type": "org.example.my_relation",
"event_id": "$asfDuShaf7Gafaw"
}
}
}],
"next_batch": "page2_token",
"prev_batch": "page1_token"
}
schema:
type: object
properties:
chunk:
title: "ChildEventsChunk"
type: array
description: |-
The child events of the requested event, ordered topologically most-recent first.
items:
allOf:
- "$ref": "definitions/client_event.yaml"
next_batch:
type: string
description: |-
An opaque string representing a pagination token. The absence of this token
means there are no more results to fetch and the client should stop paginating.
prev_batch:
type: string
description: |-
An opaque string representing a pagination token. The absence of this token
means this is the start of the result set, i.e. this is the first batch/page.
required: ['chunk']
404:
description: |-
The parent event was not found or the user does not have permission to read
this event (it might be contained in history that is not accessible to the user).
examples:
application/json: {
"errcode": "M_NOT_FOUND",
"error": "Event not found."
}
schema:
"$ref": "definitions/errors/error.yaml"
tags:
- Event relationships
# The same as above, with added `/{relType}`
"/rooms/{roomId}/relations/{eventId}/{relType}":
get:
summary: Get the child events for a given parent event, with a given `relType`.
description: |-
Retrieve all of the child events for a given parent event which relate to the parent
using the given `relType`.
Note that when paginating the `from` token should be "after" the `to` token in
terms of topological ordering, because it is only possible to paginate "backwards"
through events, starting at `from`.
For example, passing a `from` token from page 2 of the results, and a `to` token
from page 1, would return the empty set. The caller can use a `from` token from
page 1 and a `to` token from page 2 to paginate over the same range, however.
operationId: getRelatingEventsWithRelType
security:
- accessToken: []
parameters:
- in: path
type: string
name: roomId
description: The ID of the room containing the parent event.
required: true
x-example: "!636q39766251:matrix.org"
- in: path
type: string
name: eventId
description: The ID of the parent event whose child events are to be returned.
required: true
x-example: "$asfDuShaf7Gafaw"
- in: path
type: string
name: relType
description: |-
The [relationship type](/client-server-api/#relationship-types) to search for.
required: true
x-example: "org.example.my_relation"
- in: query
type: string
name: from
description: |-
The pagination token to start returning results from. If not supplied, results
start at the most recent topological event known to the server.
Can be a `next_batch` token from a previous call, or a returned
`start` token from [`/messages`](/client-server-api/#get_matrixclientv3roomsroomidmessages),
or a `next_batch` token from [`/sync`](/client-server-api/#get_matrixclientv3sync).
required: false
x-example: "page2_token"
- in: query
type: string
name: to
description: |-
The pagination token to stop returning results at. If not supplied, results
continue up to `limit` or until there are no more events.
Like `from`, this can be a previous token from a prior call to this endpoint
or from `/messages` or `/sync`.
required: false
x-example: "page3_token"
- in: query
type: integer
name: limit
description: |-
The maximum number of results to return in a single `chunk`. The server can
and should apply a maximum value to this parameter to avoid large responses.
Similarly, the server should apply a default value when not supplied.
required: false
x-example: 20
responses:
# note: this endpoint deliberately does not support rate limiting, therefore a
# 429 error response is not included.
200:
description: |-
The paginated child events which point to the parent. If no events are
pointing to the parent or the pagination yields no results, an empty `chunk`
is returned.
examples:
application/json: {
"chunk": [{
"room_id": "!636q39766251:matrix.org",
"$ref": "../../event-schemas/examples/m.room.message$m.text.yaml",
"content": {
"m.relates_to": {
"rel_type": "org.example.my_relation",
"event_id": "$asfDuShaf7Gafaw"
}
}
}],
"next_batch": "page2_token",
"prev_batch": "page1_token"
}
schema:
type: object
properties:
chunk:
title: "ChildEventsChunk"
type: array
description: |-
The child events of the requested event, ordered topologically
most-recent first. The events returned will match the `relType`
supplied in the URL.
items:
allOf:
- "$ref": "definitions/client_event.yaml"
next_batch:
type: string
description: |-
An opaque string representing a pagination token. The absence of this token
means there are no more results to fetch and the client should stop paginating.
prev_batch:
type: string
description: |-
An opaque string representing a pagination token. The absence of this token
means this is the start of the result set, i.e. this is the first batch/page.
required: ['chunk']
404:
description: |-
The parent event was not found or the user does not have permission to read
this event (it might be contained in history that is not accessible to the user).
examples:
application/json: {
"errcode": "M_NOT_FOUND",
"error": "Event not found."
}
schema:
"$ref": "definitions/errors/error.yaml"
tags:
- Event relationships
# The same as above, with added `/{eventType}`
"/rooms/{roomId}/relations/{eventId}/{relType}/{eventType}":
get:
summary: Get the child events for a given parent event, with a given `relType` and `eventType`.
description: |-
Retrieve all of the child events for a given parent event which relate to the parent
using the given `relType` and have the given `eventType`.
Note that when paginating the `from` token should be "after" the `to` token in
terms of topological ordering, because it is only possible to paginate "backwards"
through events, starting at `from`.
For example, passing a `from` token from page 2 of the results, and a `to` token
from page 1, would return the empty set. The caller can use a `from` token from
page 1 and a `to` token from page 2 to paginate over the same range, however.
operationId: getRelatingEventsWithRelTypeAndEventType
security:
- accessToken: []
parameters:
- in: path
type: string
name: roomId
description: The ID of the room containing the parent event.
required: true
x-example: "!636q39766251:matrix.org"
- in: path
type: string
name: eventId
description: The ID of the parent event whose child events are to be returned.
required: true
x-example: "$asfDuShaf7Gafaw"
- in: path
type: string
name: relType
description: |-
The [relationship type](/client-server-api/#relationship-types) to search for.
required: true
x-example: "org.example.my_relation"
- in: path
type: string
name: eventType
description: |-
The event type of child events to search for.
Note that in encrypted rooms this will typically always be `m.room.encrypted`
regardless of the event type contained within the encrypted payload.
required: true
x-example: "m.room.message"
- in: query
type: string
name: from
description: |-
The pagination token to start returning results from. If not supplied, results
start at the most recent topological event known to the server.
Can be a `next_batch` token from a previous call, or a returned
`start` token from [`/messages`](/client-server-api/#get_matrixclientv3roomsroomidmessages),
or a `next_batch` token from [`/sync`](/client-server-api/#get_matrixclientv3sync).
required: false
x-example: "page2_token"
- in: query
type: string
name: to
description: |-
The pagination token to stop returning results at. If not supplied, results
continue up to `limit` or until there are no more events.
Like `from`, this can be a previous token from a prior call to this endpoint
or from `/messages` or `/sync`.
required: false
x-example: "page3_token"
- in: query
type: integer
name: limit
description: |-
The maximum number of results to return in a single `chunk`. The server can
and should apply a maximum value to this parameter to avoid large responses.
Similarly, the server should apply a default value when not supplied.
required: false
x-example: 20
responses:
# note: this endpoint deliberately does not support rate limiting, therefore a
# 429 error response is not included.
200:
description: |-
The paginated child events which point to the parent. If no events are
pointing to the parent or the pagination yields no results, an empty `chunk`
is returned.
examples:
application/json: {
"chunk": [{
"room_id": "!636q39766251:matrix.org",
"$ref": "../../event-schemas/examples/m.room.message$m.text.yaml",
"content": {
"m.relates_to": {
"rel_type": "org.example.my_relation",
"event_id": "$asfDuShaf7Gafaw"
}
}
}],
"next_batch": "page2_token",
"prev_batch": "page1_token"
}
schema:
type: object
properties:
chunk:
title: "ChildEventsChunk"
type: array
description: |-
The child events of the requested event, ordered topologically most-recent
first. The events returned will match the `relType` and `eventType` supplied
in the URL.
items:
allOf:
- "$ref": "definitions/client_event.yaml"
next_batch:
type: string
description: |-
An opaque string representing a pagination token. The absence of this token
means there are no more results to fetch and the client should stop paginating.
prev_batch:
type: string
description: |-
An opaque string representing a pagination token. The absence of this token
means this is the start of the result set, i.e. this is the first batch/page.
required: ['chunk']
404:
description: |-
The parent event was not found or the user does not have permission to read
this event (it might be contained in history that is not accessible to the user).
examples:
application/json: {
"errcode": "M_NOT_FOUND",
"error": "Event not found."
}
schema:
"$ref": "definitions/errors/error.yaml"
tags:
- Event relationships

View file

@ -58,7 +58,7 @@ paths:
contents. contents.
x-example: true x-example: true
- in: query - in: query
type: number type: integer
name: limit name: limit
description: |- description: |-
Optional limit for the maximum number of rooms to include per response. Must be an integer Optional limit for the maximum number of rooms to include per response. Must be an integer
@ -67,7 +67,7 @@ paths:
Servers should apply a default value, and impose a maximum value to avoid resource exhaustion. Servers should apply a default value, and impose a maximum value to avoid resource exhaustion.
x-example: 20 x-example: 20
- in: query - in: query
type: number type: integer
name: max_depth name: max_depth
description: |- description: |-
Optional limit for how far to go into the space. Must be a non-negative integer. Optional limit for how far to go into the space. Must be a non-negative integer.
@ -149,7 +149,7 @@ paths:
format: int64 format: int64
description: The `origin_server_ts` for the event. description: The `origin_server_ts` for the event.
required: [origin_server_ts] required: [origin_server_ts]
required: [room_type, children_state] required: [children_state]
next_batch: next_batch:
type: string type: string
description: |- description: |-

View file

@ -158,7 +158,7 @@ paths:
format: int64 format: int64
description: The `origin_server_ts` for the event. description: The `origin_server_ts` for the event.
required: [origin_server_ts] required: [origin_server_ts]
required: [room_type, allowed_room_ids, children_state] required: [children_state]
children: children:
type: array type: array
description: |- description: |-

View file

@ -40,10 +40,35 @@ properties:
Olm event. For more details, see [Messaging Algorithms](/client-server-api/#messaging-algorithms). Olm event. For more details, see [Messaging Algorithms](/client-server-api/#messaging-algorithms).
sender_key: sender_key:
type: string type: string
description: The Curve25519 key of the sender. x-changedInMatrixVersion:
1.3: |-
Previously this field was required, however given it offers no additional
security or privacy benefit it has been deprecated for Megolm messages.
See [`m.megolm.v1.aes-sha2`](#mmegolmv1aes-sha2) for more information.
description: |-
The Curve25519 key of the sender. Required (not deprecated) if not using Megolm.
**Deprecated**: This field provides no additional security or privacy benefit
for Megolm messages and must not be read from if the encrypted event is using
Megolm. It should still be included on outgoing messages, however must not be
used to find the corresponding session. See [`m.megolm.v1.aes-sha2`](#mmegolmv1aes-sha2)
for more information.
device_id: device_id:
type: string type: string
description: The ID of the sending device. Required with Megolm. x-changedInMatrixVersion:
1.3: |-
Previously this field was required for Megolm messages, however given it
offers no additional security or privacy benefit it has been deprecated
for Megolm messages. See [`m.megolm.v1.aes-sha2`](#mmegolmv1aes-sha2) for
more information.
description: |-
The ID of the sending device.
**Deprecated**: This field provides no additional security or privacy benefit
for Megolm messages and must not be read from if the encrypted event is using
Megolm. It should still be included on outgoing messages, however must not be
used to find the corresponding session. See [`m.megolm.v1.aes-sha2`](#mmegolmv1aes-sha2)
for more information.
session_id: session_id:
type: string type: string
description: |- description: |-
@ -51,7 +76,6 @@ properties:
Megolm. Megolm.
required: required:
- algorithm - algorithm
- sender_key
- ciphertext - ciphertext
type: object type: object
type: type:

View file

@ -12,6 +12,10 @@ description: |
* `restricted` - anyone able to satisfy at least one of the allow conditions is * `restricted` - anyone able to satisfy at least one of the allow conditions is
able to join the room without prior action. Otherwise, an invite is required. able to join the room without prior action. Otherwise, an invite is required.
Only available in rooms [which support the join rule](/rooms/#feature-matrix). Only available in rooms [which support the join rule](/rooms/#feature-matrix).
* `knock_restricted` - a user can request an invite using the same functions offered
by the `knock` join rule, or can attempt to join having satisfied an allow condition
per the `restricted` join rule. Only available in rooms
[which support the join rule](/rooms/#feature-matrix).
* `private` - reserved without implementation. No significant meaning. * `private` - reserved without implementation. No significant meaning.
properties: properties:
content: content:

View file

@ -23,8 +23,19 @@ properties:
description: The room where the key is used. description: The room where the key is used.
sender_key: sender_key:
type: string type: string
x-changedInMatrixVersion:
1.3: |-
Previously this field was required, however given it offers no additional
security or privacy benefit it has been deprecated. See [`m.megolm.v1.aes-sha2`](#mmegolmv1aes-sha2)
for more information.
description: |- description: |-
The Curve25519 key of the device which initiated the session originally. The Curve25519 key of the device which initiated the session originally.
**Deprecated**: This field provides no additional security or privacy benefit
and must not be read from. It should still be included on outgoing messages
(if the event for which keys are being requested for *also* has a `sender_key`),
however must not be used to find the corresponding session. See [`m.megolm.v1.aes-sha2`](#mmegolmv1aes-sha2)
for more information.
session_id: session_id:
type: string type: string
description: The ID of the session that the key is for. description: The ID of the session that the key is for.
@ -32,7 +43,6 @@ properties:
- algorithm - algorithm
- room_id - room_id
- session_id - session_id
- sender_key
type: object type: object
title: RequestedKeyInfo title: RequestedKeyInfo
action: action: