mirror of
https://github.com/matrix-org/matrix-spec
synced 2026-03-26 04:54:10 +01:00
Merge branch 'main' into neilalexander/mfederate
This commit is contained in:
commit
5a58eafd7e
|
|
@ -0,0 +1 @@
|
||||||
|
Add timestamp massaging as per [MSC3316](https://github.com/matrix-org/matrix-spec-proposals/pull/3316).
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
1
changelogs/client_server/newsfragments/1056.feature
Normal file
1
changelogs/client_server/newsfragments/1056.feature
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Add refresh tokens, per [MSC2918](https://github.com/matrix-org/matrix-spec-proposals/pull/2918).
|
||||||
|
|
@ -1 +1 @@
|
||||||
Fix room state 400 code error examples to match known error codes.
|
Fix various typos throughout the specification.
|
||||||
1
changelogs/client_server/newsfragments/1062.feature.1
Normal file
1
changelogs/client_server/newsfragments/1062.feature.1
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Relax the restrictions on Rich Replies, as per [MSC3676](https://github.com/matrix-org/matrix-spec-proposals/pull/3676).
|
||||||
1
changelogs/client_server/newsfragments/1062.feature.2
Normal file
1
changelogs/client_server/newsfragments/1062.feature.2
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Describe a structured system for event relationships, as per [MSC2674](https://github.com/matrix-org/matrix-spec-proposals/pull/2674).
|
||||||
1
changelogs/client_server/newsfragments/1062.feature.3
Normal file
1
changelogs/client_server/newsfragments/1062.feature.3
Normal 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).
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Fix various typos throughout the specification.
|
||||||
1
changelogs/client_server/newsfragments/1099.feature
Normal file
1
changelogs/client_server/newsfragments/1099.feature
Normal 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).
|
||||||
|
|
@ -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).
|
||||||
1
changelogs/client_server/newsfragments/1101.deprecation
Normal file
1
changelogs/client_server/newsfragments/1101.deprecation
Normal 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).
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Fix various typos throughout the specification.
|
||||||
1
changelogs/client_server/newsfragments/1113.feature
Normal file
1
changelogs/client_server/newsfragments/1113.feature
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Add refresh tokens, per [MSC2918](https://github.com/matrix-org/matrix-spec-proposals/pull/2918).
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Fix various typos throughout the specification.
|
||||||
|
|
@ -1 +1 @@
|
||||||
Fix broken syntax in Server Access Control Lists definition.
|
Fix various typos throughout the specification.
|
||||||
|
|
@ -1,2 +1 @@
|
||||||
Improve readability of definitions in the state resolution v2 algorithm.
|
Improve readability and understanding of the state resolution algorithms.
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Improve readability and understanding of the state resolution algorithms.
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -1 +1 @@
|
||||||
Add cross-references to PDU content definitions from the authorisation rules.
|
Improve readability of the authorization rules.
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -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).
|
||||||
1
changelogs/room_versions/newsfragments/1099.feature.1
Normal file
1
changelogs/room_versions/newsfragments/1099.feature.1
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Add room version 10 as per [MSC3604](https://github.com/matrix-org/matrix-spec-proposals/pull/3604).
|
||||||
1
changelogs/room_versions/newsfragments/1099.feature.2
Normal file
1
changelogs/room_versions/newsfragments/1099.feature.2
Normal 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).
|
||||||
1
changelogs/room_versions/newsfragments/1099.feature.3
Normal file
1
changelogs/room_versions/newsfragments/1099.feature.3
Normal 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).
|
||||||
|
|
@ -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`.
|
||||||
|
|
|
||||||
|
|
@ -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).
|
||||||
|
|
@ -1 +1 @@
|
||||||
Fix origin server name in S2S Request Authentication example.
|
Clarify the format for the Authorization header.
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Clarify the meaning of "unconflicted state map" and "auth chain" in state res v2.
|
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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).
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Clarify the historical handling of non-integer power levels.
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Fix various typos throughout the specification.
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
||||||

|

|
||||||
|
|
@ -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" %}}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 ("> ", 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" %}}
|
||||||
|
|
|
||||||
182
content/client-server-api/modules/rich_replies.md
Normal file
182
content/client-server-api/modules/rich_replies.md
Normal 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 ("> ", 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"`.
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
13
content/rooms/fragments/v1-deprecated-formatting-off-spec.md
Normal file
13
content/rooms/fragments/v1-deprecated-formatting-off-spec.md
Normal 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 %}}
|
||||||
43
content/rooms/fragments/v1-stringy-power-levels.md
Normal file
43
content/rooms/fragments/v1-stringy-power-levels.md
Normal 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 "`);
|
||||||
51
content/rooms/fragments/v9-redactions.md
Normal file
51
content/rooms/fragments/v9-redactions.md
Normal 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`.
|
||||||
|
|
@ -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
277
content/rooms/v10.md
Normal 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" %}}
|
||||||
|
|
@ -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" %}}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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" %}}
|
||||||
|
|
|
||||||
|
|
@ -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" %}}
|
||||||
|
|
|
||||||
|
|
@ -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" %}}
|
||||||
|
|
|
||||||
|
|
@ -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" %}}
|
||||||
|
|
|
||||||
|
|
@ -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" %}}
|
||||||
|
|
|
||||||
|
|
@ -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" %}}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
43
data/api/client-server/definitions/m.relates_to.yaml
Normal file
43
data/api/client-server/definitions/m.relates_to.yaml
Normal 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']
|
||||||
|
|
@ -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: |-
|
||||||
|
|
|
||||||
108
data/api/client-server/refresh.yaml
Normal file
108
data/api/client-server/refresh.yaml
Normal 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"
|
||||||
|
|
@ -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: |-
|
||||||
|
|
|
||||||
425
data/api/client-server/relations.yaml
Normal file
425
data/api/client-server/relations.yaml
Normal 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
|
||||||
|
|
||||||
|
|
@ -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: |-
|
||||||
|
|
|
||||||
|
|
@ -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: |-
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue