From 25dda1eadb14bc9915130d4c40e4109275af6413 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 27 Sep 2022 13:51:20 -0600 Subject: [PATCH 01/16] Threads: The base (#1254) * Spec MSC3440: Threading (just the base) Other threading MSCs to follow * Spec MSC3856: Threads list API * Spec MSC3715: Add`dir` to `/relations` * changelog * Apply suggestions from code review Co-authored-by: Patrick Cloke * Update changelogs/client_server/newsfragments/1254.feature Co-authored-by: Patrick Cloke Co-authored-by: Patrick Cloke --- .../client_server/newsfragments/1254.feature | 1 + content/client-server-api/_index.md | 5 +- .../client-server-api/modules/threading.md | 201 ++++++++++++++++++ .../definitions/m.relates_to.yaml | 4 +- data/api/client-server/relations.yaml | 36 +++- data/api/client-server/threads_list.yaml | 135 ++++++++++++ 6 files changed, 376 insertions(+), 6 deletions(-) create mode 100644 changelogs/client_server/newsfragments/1254.feature create mode 100644 content/client-server-api/modules/threading.md create mode 100644 data/api/client-server/threads_list.yaml diff --git a/changelogs/client_server/newsfragments/1254.feature b/changelogs/client_server/newsfragments/1254.feature new file mode 100644 index 00000000..84ed083d --- /dev/null +++ b/changelogs/client_server/newsfragments/1254.feature @@ -0,0 +1 @@ +Add threading via `m.thread` relations, as per [MSC3440](https://github.com/matrix-org/matrix-spec-proposals/pull/3440), [MSC3816](https://github.com/matrix-org/matrix-spec-proposals/pull/3816), [MSC3856](https://github.com/matrix-org/matrix-spec-proposals/pull/3856), and [MSC3715](https://github.com/matrix-org/matrix-spec-proposals/pull/3715). \ No newline at end of file diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index b29aeb32..44bd4151 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -1972,6 +1972,7 @@ This specification describes the following relationship types: * [Rich replies](#rich-replies) (**Note**: does not use `rel_type`). * [Event replacements](#event-replacements). +* [Threads](#threading). #### Aggregations @@ -2056,6 +2057,7 @@ The endpoints where the server *should* include bundled aggregations are: * [`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`. +* {{< added-in v="1.4" >}} [`GET /rooms/{roomId}/threads`](#get_matrixclientv1roomsroomidthreads) {{% boxes/note %}} The server is **not** required to return bundled aggregations on deprecated endpoints @@ -2641,4 +2643,5 @@ systems. {{< cs-module name="server_notices" >}} {{< cs-module name="moderation_policies" >}} {{< cs-module name="spaces" >}} -{{< cs-module name="event_replacements" >}} \ No newline at end of file +{{< cs-module name="event_replacements" >}} +{{< cs-module name="threading" >}} \ No newline at end of file diff --git a/content/client-server-api/modules/threading.md b/content/client-server-api/modules/threading.md new file mode 100644 index 00000000..103cfff4 --- /dev/null +++ b/content/client-server-api/modules/threading.md @@ -0,0 +1,201 @@ +--- +type: module +--- + +### Threading + +{{% added-in v="1.4" %}} + +Threads allow users to visually branch their conversations in a room. Typically mostly used +when a room is discussing multiple topics, threads provide more organisation of communication +that traditional [rich replies](#rich-replies) can't always offer. + +Clients SHOULD render threads differently to regular messages or replies in the timeline, such +as by providing some context to what is going on in the thread but keeping the full conversation +history behind a disclosure. + +Threads are established using a `rel_type` of `m.thread` and reference the *thread root* (the +first event in a thread). It is not possible to create a thread from an event with a `rel_type`, +which includes not being able to nest threads. All conversation in a thread reference the thread +root instead of the most recent message, unlike rich reply chains. + +As a worked example, the following represents a thread and how it'd be formed: + +```json +{ + // irrelevant fields excluded + "type": "m.room.message", + "event_id": "$alice_hello", + "sender": "@alice:example.org", + "content": { + "msgtype": "m.text", + "body": "Hello world! How are you?" + } +} +``` + +```json +{ + // irrelevant fields excluded + "type": "m.room.message", + "event_id": "$bob_hello", + "sender": "@bob:example.org", + "content": { + "m.relates_to": { + "rel_type": "m.thread", + "event_id": "$alice_hello" + }, + "msgtype": "m.text", + "body": "I'm doing okay, thank you! How about yourself?" + } +} +``` + +```json +{ + // irrelevant fields excluded + "type": "m.room.message", + "event_id": "$alice_reply", + "sender": "@alice:example.org", + "content": { + "m.relates_to": { + "rel_type": "m.thread", + "event_id": "$alice_hello" // note: always references the *thread root* + }, + "msgtype": "m.text", + "body": "I'm doing great! Thanks for asking." + } +} +``` + +As shown, any event without a `rel_type` can become a thread root by simply referencing it +using an `m.thread` relationship. + +#### Fallback for unthreaded clients + +Clients which understand how to work with threads should simply do so, however clients which +might not be aware of threads (due to age or scope) might not be able to helpfully represent +the conversation history to its users. + +To work around this, events sent by clients which understand threads include [rich reply](#rich-replies) +metadata to attempt to form a reply chain representation of the conversation. This representation +is not ideal for heavily threaded rooms, but allows for users to have context as to what is +being discussed with respect to other messages in the room. + +This representation is achieved by merging the two relationships and setting a new `is_falling_back` +flag to `true`. + +```json +// within an event's content... +"m.relates_to": { + // The m.thread relationship structure + "rel_type": "m.thread", + "event_id": "$root", + + // The rich reply structure + "m.in_reply_to": { + // The most recent message known to the client in the thread. + // This should be something with a high chance of being rendered by the other client, + // such as an `m.room.message` event. + "event_id": "$target" + }, + + // A flag to denote that this is a thread with reply fallback + "is_falling_back": true +} +``` + +For `m.room.message` events represented this way, no [reply fallback](#fallbacks-for-rich-replies) +is specified. This allows thread-aware clients to discard the `m.in_reply_to` object entirely +when `is_falling_back` is `true`. + +{{% boxes/note %}} +Clients which are acutely aware of threads (they do not render threads, but are otherwise +aware of the feature existing in the spec) can treat rich replies to an event with a `rel_type` +of `m.thread` as a threaded reply, for conversation continuity on the threaded client's side. + +To do this, copy the `event_id` (thread root) from the event being replied to, add the +`m.in_reply_to` metadata, and add `is_falling_back: true` to `m.relates_to`. +{{% /boxes/note %}} + +#### Replies within threads + +In the [fallback for unthreaded clients](#fallback-for-unthreaded-clients) section, a new +`is_falling_back` flag is added to `m.relates_to`. This flag defaults to `false` when not +provided, which also allows a threaded message to contain a reply itself. + +Aside from `is_falling_back` being `false` (or not specified), the fallback for unthreaded +clients is used to create a reply within a thread: clients should render the event accordingly. + +#### Server behaviour + +##### Validation of `m.thread` relationships + +Servers SHOULD reject client requests which attempt to start a thread off an event with a +`rel_type`. If the client attempts to target an event which already has an `m.thread`, +`m.reference`, or any other `rel_type` then it should receive a HTTP 400 error response +with appropriate error message, as per the [standard error response](#standard-error-response) +structure. + +{{% boxes/note %}} +A specific error code is not currently available for this case: servers should use `M_UNKNOWN` +alongside the HTTP 400 status code. +{{% /boxes/note %}} + +##### Server-side aggregation of `m.thread` relationships + +Given threads always reference the thread root, an event can have multiple "child" events which +then form the thread itself. These events should be [aggregated](#aggregations) by the server. + +The aggregation for threads includes some information about the user's participation in the thread, +the approximate number of events in the thread (as known to the server), and the most recent event +in the thread (topologically). This is then bundled into the event as `m.thread`: + +```json +{ + "event_id": "$root_event", + // irrelevant fields not shown + "unsigned": { + "m.relations": { + "m.thread": { + "latest_event": { + // A serialized copy of the latest event in the thread. + // Some fields are not shown here for brevity. + "event_id": "$message", + "sender": "@alice:example.org", + "room_id": "!room:example.org", + "type": "m.room.message", + "content": { + "msgtype": "m.text", + "body": "Woo! Threads!" + } + }, + "count": 7, + "current_user_participated": true + } + } + } +} +``` + +`latest_event` is the most recent event (topologically to the server) in the thread sent by an +un-[ignored user](#ignoring-users). + +Note that any bundled aggregations on `latest_event` should also be present. The server should be +careful to avoid loops, though loops are not currently possible due to `m.thread` not being possible +to target an event with a `rel_type` already. + +`count` is simply the number of events using `m.thread` as a `rel_type` pointing to the target event. +It does not include events sent by [ignored users](#ignoring-users). + +`current_user_participated` is `true` when the authenticated user is either: +1. The `sender` of the event receiving the bundle (they sent the thread root). +2. The `sender` of an event which references the thread root with a `rel_type` of `m.thread`. + +#### Querying threads in a room + +Clients looking to get all the events in a thread can use +[`GET /relations/{threadRootId}/m.thread`](#get_matrixclientv1roomsroomidrelationseventidreltype), +however getting all threads in a room is done through a dedicated API: + +{{% http-api spec="client-server" api="threads_list" %}} diff --git a/data/api/client-server/definitions/m.relates_to.yaml b/data/api/client-server/definitions/m.relates_to.yaml index 591281c3..401c8bb9 100644 --- a/data/api/client-server/definitions/m.relates_to.yaml +++ b/data/api/client-server/definitions/m.relates_to.yaml @@ -34,8 +34,8 @@ properties: 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 + all relationships require such behaviour. For example, an [`m.thread` relationship type](/client-server-api/#threading) + denotes that the event is part of a "thread" of messages and should be rendered as such. event_id: type: string diff --git a/data/api/client-server/relations.yaml b/data/api/client-server/relations.yaml index dc0d8761..a0abae1b 100644 --- a/data/api/client-server/relations.yaml +++ b/data/api/client-server/relations.yaml @@ -63,7 +63,7 @@ paths: 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 + Can be a `next_batch` or `prev_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 @@ -89,6 +89,16 @@ paths: Similarly, the server should apply a default value when not supplied. required: false x-example: 20 + - in: query + type: string + enum: ["b", "f"] + name: dir + x-addedInMatrixVersion: "1.4" + description: |- + Optional (default `b`) direction to return events from. If this is set to `f`, events + will be returned in chronological order starting at `from`. If it + is set to `b`, events will be returned in *reverse* chronological + order, again starting at `from`. responses: # note: this endpoint deliberately does not support rate limiting, therefore a # 429 error response is not included. @@ -193,7 +203,7 @@ paths: 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 + Can be a `next_batch` or `prev_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 @@ -219,6 +229,16 @@ paths: Similarly, the server should apply a default value when not supplied. required: false x-example: 20 + - in: query + type: string + enum: ["b", "f"] + name: dir + x-addedInMatrixVersion: "1.4" + description: |- + Optional (default `b`) direction to return events from. If this is set to `f`, events + will be returned in chronological order starting at `from`. If it + is set to `b`, events will be returned in *reverse* chronological + order, again starting at `from`. responses: # note: this endpoint deliberately does not support rate limiting, therefore a # 429 error response is not included. @@ -335,7 +355,7 @@ paths: 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 + Can be a `next_batch` or `prev_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 @@ -361,6 +381,16 @@ paths: Similarly, the server should apply a default value when not supplied. required: false x-example: 20 + - in: query + type: string + enum: ["b", "f"] + name: dir + x-addedInMatrixVersion: "1.4" + description: |- + Optional (default `b`) direction to return events from. If this is set to `f`, events + will be returned in chronological order starting at `from`. If it + is set to `b`, events will be returned in *reverse* chronological + order, again starting at `from`. responses: # note: this endpoint deliberately does not support rate limiting, therefore a # 429 error response is not included. diff --git a/data/api/client-server/threads_list.yaml b/data/api/client-server/threads_list.yaml new file mode 100644 index 00000000..c0c9cbd0 --- /dev/null +++ b/data/api/client-server/threads_list.yaml @@ -0,0 +1,135 @@ +# 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 Threads List 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}/threads": + get: + x-addedInMatrixVersion: "1.4" + summary: Retrieve a list of threads in a room, with optional filters. + description: |- + Paginates over the thread roots in a room, ordered by the `latest_event` of each thread root + in its bundle. + operationId: getThreadRoots + security: + - accessToken: [] + parameters: + - in: path + type: string + name: roomId + description: The room ID where the thread roots are located. + required: true + x-example: "!room:example.org" + - in: query + type: string + name: include + enum: [all, participated] + description: |- + Optional (default `all`) flag to denote which thread roots are of interest to the caller. + When `all`, all thread roots found in the room are returned. When `participated`, only + thread roots for threads the user has [participated in](/client-server-api/#server-side-aggreagtion-of-mthread-relationships) + will be returned. + x-example: "all" + - in: query + type: integer + name: limit + description: |- + Optional limit for the maximum number of thread roots to include per response. Must be an integer + greater than zero. + + Servers should apply a default value, and impose a maximum value to avoid resource exhaustion. + x-example: 20 + - in: query + type: string + name: from + description: |- + A pagination token from a previous result. When not provided, the server starts paginating from + the most recent event visible to the user (as per history visibility rules; topologically). + x-example: "next_batch_token" + responses: + 200: + description: |- + A portion of the available thread roots in the room, based on the filter criteria. + examples: + application/json: { + "chunk": [{ "$ref": "../../event-schemas/examples/m.room.message$m.text.yaml" }], + "next_batch": "next_batch_token" + } + schema: + type: object + properties: + chunk: + type: array + description: |- + The thread roots, ordered by the `latest_event` in each event's aggregation bundle. All events + returned include bundled [aggregations](/client-server-api/#aggregations). + + If the thread root event was sent by an [ignored user](/client-server-api/#ignoring-users), the + event is returned redacted to the caller. This is to simulate the same behaviour of a client doing + aggregation locally on the thread. + items: + $ref: "definitions/client_event.yaml" + next_batch: + type: string + description: |- + A token to supply to `from` to keep paginating the responses. Not present when there are + no further results. + required: [chunk] + 403: + description: |- + The user cannot view or peek on the room. A meaningful `errcode` + and description error text will be returned. Example reasons for rejection are: + + - The room is not set up for peeking. + - The user has been banned from the room. + - The room does not exist. + examples: + application/json: { + "errcode": "M_FORBIDDEN", + "error": "You are not allowed to view this room." + } + schema: + "$ref": "definitions/errors/error.yaml" + 400: + description: |- + The request was invalid in some way. A meaningful `errcode` + and description error text will be returned. Example reasons for rejection are: + + - The `from` token is unknown to the server. + examples: + application/json: { + "errcode": "M_INVALID_PARAM", + "error": "Unknown pagination token" + } + schema: + "$ref": "definitions/errors/error.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" + tags: + - Threads From 227757d49933b67a1f328ba30e0760c345cdbdf1 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Sep 2022 14:49:25 -0600 Subject: [PATCH 02/16] Threads: Read receipts & notifications (#1255) * Spec MSC3771: Threaded read receipts Note: this builds on a (as of writing) non-existent "threading" section, which is part of a different commit. * Spec MSC3773: Threaded notifications * changelog * Various clarifications per review --- .../client_server/newsfragments/1255.feature | 1 + .../server_server/newsfragments/1255.feature | 1 + content/client-server-api/modules/push.md | 17 ++- content/client-server-api/modules/receipts.md | 136 +++++++++++++++++- .../definitions/room_event_filter.yaml | 7 + data/api/client-server/sync.yaml | 47 +++++- .../definitions/event-schemas/m.receipt.yaml | 9 ++ data/event-schemas/schema/m.receipt.yaml | 8 ++ static/diagrams/threaded-dag-threads.drawio | 1 + static/diagrams/threaded-dag-threads.png | Bin 0 -> 18578 bytes static/diagrams/threaded-dag.drawio | 1 + static/diagrams/threaded-dag.png | Bin 0 -> 11621 bytes 12 files changed, 218 insertions(+), 10 deletions(-) create mode 100644 changelogs/client_server/newsfragments/1255.feature create mode 100644 changelogs/server_server/newsfragments/1255.feature create mode 100644 static/diagrams/threaded-dag-threads.drawio create mode 100644 static/diagrams/threaded-dag-threads.png create mode 100644 static/diagrams/threaded-dag.drawio create mode 100644 static/diagrams/threaded-dag.png diff --git a/changelogs/client_server/newsfragments/1255.feature b/changelogs/client_server/newsfragments/1255.feature new file mode 100644 index 00000000..a1d15d98 --- /dev/null +++ b/changelogs/client_server/newsfragments/1255.feature @@ -0,0 +1 @@ +Add per-thread notifications and read receipts, as per [MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) and [MSC3773](https://github.com/matrix-org/matrix-spec-proposals/pull/3773). \ No newline at end of file diff --git a/changelogs/server_server/newsfragments/1255.feature b/changelogs/server_server/newsfragments/1255.feature new file mode 100644 index 00000000..a1d15d98 --- /dev/null +++ b/changelogs/server_server/newsfragments/1255.feature @@ -0,0 +1 @@ +Add per-thread notifications and read receipts, as per [MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) and [MSC3773](https://github.com/matrix-org/matrix-spec-proposals/pull/3773). \ No newline at end of file diff --git a/content/client-server-api/modules/push.md b/content/client-server-api/modules/push.md index 5cce9449..9f9b30ac 100644 --- a/content/client-server-api/modules/push.md +++ b/content/client-server-api/modules/push.md @@ -107,8 +107,10 @@ determined by the push rules which apply to an event. When the user updates their read receipt (either by using the API or by sending an event), notifications prior to and including that event MUST -be marked as read. Note that users can send both an `m.read` and -`m.read.private` receipt, both of which are capable of clearing notifications. +be marked as read. Which specific events are affected can vary depending +on whether a [threaded read receipt](#threaded-read-receipts) was used. +Note that users can send both an `m.read` and `m.read.private` receipt, +both of which are capable of clearing notifications. If the user has both `m.read` and `m.read.private` set in the room then the receipt which is more recent/ahead must be used to determine where @@ -121,6 +123,17 @@ ahead), however if the `m.read.private` receipt were to be updated to event D then the user has read up to D (the `m.read` receipt is now behind the `m.read.private` receipt). +{{< added-in v="1.4" >}} When handling threaded read receipts, the server +is to partition the notification count to each thread (with the main timeline +being its own thread). To determine if an event is part of a thread the +server follows the [event relationship](#forming-relationships-between-events) +until it finds a thread root (as specified by the [threading module](#threading)), +however it is not recommended that the server traverse infinitely. Instead, +implementations are encouraged to do a maximum of 3 hops to find a thread +before deciding that the event does not belong to a thread. This is primarily +to ensure that future events, like `m.reaction`, are correctly considered +"part of" a given thread. + ##### Push Rules A push rule is a single rule that states under what *conditions* an diff --git a/content/client-server-api/modules/receipts.md b/content/client-server-api/modules/receipts.md index 9f80ff60..7fdde0d0 100644 --- a/content/client-server-api/modules/receipts.md +++ b/content/client-server-api/modules/receipts.md @@ -22,33 +22,68 @@ that the user had read all events *up to* the referenced event. See the [Receiving notifications](#receiving-notifications) section for more information on how read receipts affect notification counts. +{{< added-in v="1.4" >}} Read receipts exist in three major forms: +* Unthreaded: Denotes a read-up-to receipt regardless of threads. This is how + pre-threading read receipts worked. +* Threaded, main timeline: Denotes a read-up-to receipt for events not in a + particular thread. Identified by the thread ID `main`. +* Threaded, in a thread: Denotes a read-up-to receipt within a particular + thread. Identified by the event ID of the thread root. + +Threaded read receipts are discussed in further detail [below](#threaded-read-receipts). + #### Events -Each `user_id`, `receipt_type` pair must be associated with only a -single `event_id`. +{{< changed-in v="1.4" >}} Each `user_id`, `receipt_type`, and categorisation +(unthreaded, or `thread_id`) tuple must be associated with only a single +`event_id`. {{% event event="m.receipt" %}} #### Client behaviour +{{< changed-in v="1.4" >}} Altered to support threaded read receipts. + In `/sync`, receipts are listed under the `ephemeral` array of events for a given room. New receipts that come down the event streams are deltas which update existing mappings. Clients should replace older -receipt acknowledgements based on `user_id` and `receipt_type` pairs. +receipt acknowledgements based on `user_id`, `receipt_type`, and the +`thread_id` (if present). For example: Client receives m.receipt: user = @alice:example.com receipt_type = m.read event_id = $aaa:example.com + thread_id = undefined Client receives another m.receipt: user = @alice:example.com receipt_type = m.read event_id = $bbb:example.com + thread_id = main - The client should replace the older acknowledgement for $aaa:example.com with - this one for $bbb:example.com + The client does not replace any acknowledgements, yet. + + Client receives yet another m.receipt: + user = @alice:example.com + receipt_type = m.read + event_id = $ccc:example.com + thread_id = undefined + + The client replaces the older acknowledgement for $aaa:example.com + with this new one for $ccc:example.com, but does not replace the + acknowledgement for $bbb:example.com because it belongs to a thread. + + Client receives yet another m.receipt: + user = @alice:example.com + receipt_type = m.read + event_id = $ddd:example.com + thread_id = main + + Now the client replaces the older $bbb:example.com acknowledgement with + this new $ddd:example.com acknowledgement. The client does NOT replace the + older acknowledgement for $ccc:example.com as it is unthreaded. Clients should send read receipts when there is some certainty that the event in question has been **displayed** to the user. Simply receiving @@ -58,6 +93,12 @@ room that the event was sent to or dismissing a notification in order for the event to count as "read". Clients SHOULD NOT send read receipts for events sent by their own user. +Similar to the rules for sending receipts, threaded receipts should appear +in the context of the thread. If a thread is rendered behind a disclosure, +the client hasn't yet shown the event (or any applicable read receipts) +to the user. Once they expand the thread though, a threaded read receipt +would be sent and per-thread receipts from other users shown. + A client can update the markers for its user by interacting with the following HTTP APIs. @@ -87,6 +128,89 @@ not have their notification counts rewound to that point in time. While uncommon, it is considered valid to have an `m.read` (public) receipt lag several messages behind the `m.read.private` receipt, for example. +##### Threaded read receipts + +{{% added-in v="1.4" %}} + +If a client does not use [threading](#threading), then they will simply only +send "unthreaded" read receipts which affect the whole room regardless of threads. + +A threaded read receipt is simply one which has a `thread_id` on it, targeting +either a thread root's event ID or `main` for the main timeline. + +Threading introduces a concept of multiple conversations being held in the same +room and thus deserve their own read receipts and notification counts. An event is +considered to be "in a thread" if it meets any of the following criteria: +* It has a `rel_type` of `m.thread`. +* It has child events with a `rel_type` of `m.thread` (in which case it'd be the + thread root). +* Following the event relationships, it has a parent event which qualifies for + one of the above. Implementations should not recurse infinitely, though: a + maximum of 3 hops is recommended to cover indirect relationships. + +Events not in a thread but still in the room are considered to be part of the +"main timeline", or a special thread with an ID of `main`. + +The following is an example DAG for a room, with dotted lines showing event +relationships and solid lines showing topological ordering. + +![threaded-dag](/diagrams/threaded-dag.png) + +{{% boxes/note %}} +`m.reaction` relationships are not currently specified, but are shown here for +their conceptual place in a threaded DAG. They are currently proposed as +[MSC2677](https://github.com/matrix-org/matrix-spec-proposals/pull/2677). +{{% /boxes/note %}} + +This DAG can be represented as 3 threaded timelines, with `A` and `B` being thread +roots: + +![threaded-dag-threads](/diagrams/threaded-dag-threads.png) + +With this, we can demonstrate that: +* A threaded read receipt on `I` would mark `A`, `B`, and `I` as read. +* A threaded read receipt on `E` would mark `C` and `E` as read. +* An unthreaded read receipt on `D` would mark `A`, `B`, `C`, and `D` as read. + +Note that marking `A` as read with a threaded read receipt would not mean +that `C`, `E`, `G`, or `H` get marked as read: Thread A's timeline would need +its own threaded read receipt at `H` to accomplish that. + +The read receipts for the above 3 examples would be: + +```json +{ + "$I": { + "m.read": { + "@user:example.org": { + "ts": 1661384801651, + "thread_id": "main" // because `I` is not in a thread, but is a threaded receipt + } + } + }, + "$E": { + "m.read": { + "@user:example.org": { + "ts": 1661384801651, + "thread_id": "$A" // because `E` is in Thread `A` + } + } + }, + "$D": { + "m.read": { + "@user:example.org": { + "ts": 1661384801651 + // no `thread_id` because the receipt is *unthreaded* + } + } + } +} +``` + +Conditions on sending read receipts apply similarly to threaded and unthreaded read +receipts. For example, a client might send a private read receipt for a threaded +event when the user expands that thread. + #### Server behaviour For efficiency, receipts SHOULD be batched into one event per room @@ -99,7 +223,7 @@ format of the EDUs are: { : { : { - : { } + : { } }, ... }, diff --git a/data/api/client-server/definitions/room_event_filter.yaml b/data/api/client-server/definitions/room_event_filter.yaml index 8d96a165..ab8ef79e 100644 --- a/data/api/client-server/definitions/room_event_filter.yaml +++ b/data/api/client-server/definitions/room_event_filter.yaml @@ -1,4 +1,5 @@ # Copyright 2016 OpenMarket Ltd +# 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. @@ -16,6 +17,12 @@ allOf: - type: object title: RoomEventFilter properties: + unread_thread_notifications: + type: boolean + description: |- + If `true`, enables per-[thread](/client-server-api/#threading) notification + counts. Only applies to the `/sync` endpoint. Defaults to `false`. + x-addedInMatrixVersion: "1.4" lazy_load_members: type: boolean description: |- diff --git a/data/api/client-server/sync.yaml b/data/api/client-server/sync.yaml index f8127bf5..93265cae 100644 --- a/data/api/client-server/sync.yaml +++ b/data/api/client-server/sync.yaml @@ -239,17 +239,50 @@ paths: Counts of unread notifications for this room. See the [Receiving notifications](/client-server-api/#receiving-notifications) section for more information on how these are calculated. + + If `unread_thread_notifications` was specified as `true` on the `RoomEventFilter`, + these counts will only be for the main timeline rather than all events in the room. + See the [threading module](#threading) for more information. + x-changedInMatrixVersion: + 1.4: | + Updated to reflect behaviour of having `unread_thread_notifications` as `true` in + the `RoomEventFilter` for `/sync`. properties: highlight_count: title: Highlighted notification count type: integer description: The number of unread notifications - for this room with the highlight flag set + for this room with the highlight flag set. notification_count: title: Total notification count type: integer description: The total number of unread notifications - for this room + for this room. + unread_thread_notifications: + title: Unread Thread Notification Counts + type: object + description: |- + If `unread_thread_notifications` was specified as `true` on the `RoomEventFilter`, + the notification counts for each [thread](#threading) in this room. The object is + keyed by thread root ID, with values matching `unread_notifications`. + + If a thread does not have any notifications it can be omitted from this object. If + no threads have notification counts, this whole object can be omitted. + x-addedInMatrixVersion: "1.4" + additionalProperties: + title: ThreadNotificationCounts + type: object + properties: + highlight_count: + title: ThreadedHighlightNotificationCount + type: integer + description: |- + The number of unread notifications for this *thread* with the highlight flag set. + notification_count: + title: ThreadedTotalNotificationCount + type: integer + description: |- + The total number of unread notifications for this *thread*. invite: title: Invited Rooms type: object @@ -424,6 +457,16 @@ paths: } } ] + }, + "unread_notifications": { + "highlight_count": 1, + "notification_count": 5 + }, + "unread_thread_notifications": { + "$threadroot": { + "highlight_count": 3, + "notification_count": 6 + } } } }, diff --git a/data/api/server-server/definitions/event-schemas/m.receipt.yaml b/data/api/server-server/definitions/event-schemas/m.receipt.yaml index 335e7c27..bbc3ac67 100644 --- a/data/api/server-server/definitions/event-schemas/m.receipt.yaml +++ b/data/api/server-server/definitions/event-schemas/m.receipt.yaml @@ -65,6 +65,15 @@ allOf: A POSIX timestamp in milliseconds for when the user read the event specified in the read receipt. example: 1533358089009 + thread_id: + type: string + x-addedInMatrixVersion: "1.4" + description: |- + The root thread event's ID (or `main`) for which + thread this receipt is intended to be under. If + not specified, the read receipt is *unthreaded* + (default). + example: "$threadroot" required: ['ts'] required: ['event_ids', 'data'] required: ['m.read'] diff --git a/data/event-schemas/schema/m.receipt.yaml b/data/event-schemas/schema/m.receipt.yaml index b9ec7e4e..c501d022 100644 --- a/data/event-schemas/schema/m.receipt.yaml +++ b/data/event-schemas/schema/m.receipt.yaml @@ -38,6 +38,14 @@ properties: type: integer format: int64 description: The timestamp the receipt was sent at. + thread_id: + type: string + x-addedInMatrixVersion: "1.4" + description: |- + The root thread event's ID (or `main`) for which + thread this receipt is intended to be under. If + not specified, the read receipt is *unthreaded* + (default). "m.read.private": type: object title: Own User diff --git a/static/diagrams/threaded-dag-threads.drawio b/static/diagrams/threaded-dag-threads.drawio new file mode 100644 index 00000000..2f3121d7 --- /dev/null +++ b/static/diagrams/threaded-dag-threads.drawio @@ -0,0 +1 @@ +7ZpdU+IwFIZ/DZc6bdNWuJQCujPquOvOrl452TbQaNowIXztr9+EJv0goLCirYwyo81JGpL3PQ8nU2mBIFlcMDiOr2mESMuxokUL9FqO41i+I/7IyDKL2JbvZZERw5GKFYE7/BfpgSo6xRGaVAZySgnH42owpGmKQl6JQcbovDpsSEn1XcdwhIzAXQiJGf2NIx5n0bZzVsQvER7F+p1tv5P1JFAPVjuZxDCi81II9FsgYJTy7CpZBIhI9bQu2X2DLb35whhK+S43/PIf6YMfPSfXNzfx1WP3ez/2ToDaxwySqdrxz5ghGInYudQaJ4jgFKkt8KXWhdFpGiE5td0C3XmMObobw1D2zkUqiFjME6K6hzTlA5hgIrPgEpEZ4jiEsgMTElBC2WpS0O/Jl4jPEJMjyDnBo1T0cTpW09ypJajty4FosVURO9dZZCiiCeJsKYbo9NTWqOT0dHteOO2c+acqY+Oyz201FKr8GuWzFxaIC+XCPo742x3pHrsjAFQdcS3TEdu3Nvhhv5sfruHHNcTpsTuRq7zUHJhO5G59jBO2YcS5If0rYsPJOCsSQ7yQBq2LHAR9byDW2D2Egp2qgsDeoOAGAcG76dc25EKRKHaqSRmP6YimkPSLaLeay8WYKyrTbhV8QpwvVeWGU06rkqMF5vfi2lLXD/JafKRmrd6i1NVb6kYq9nuvJ5CN0l2yWdy2aun7Kiz9FHhOxHZv0Fz8/kETmObGyn2/bKuQiU5ZiF7QUx1tOGQjxF/LWzNNGCKQ41l1HQc33TGg6TYZGsdvGDQueDM0T9NkrMenNEU1cFRC56GM1RaOCPyDSBeGz6PVTkpeDwL5eqlsHRAw8BkAAwZgwZsBOwRIbn5u1afbjlczSs4XSnWh5O6IklMnSuZJu9cElMBaTXLdumuSewwg7Xm2awhI3o4ggTpB8gyQ+o0AyW5eTbINYb5Q+iCU/B1RcutEyXwaN2gCSu76g7K6axLoGEIlpwzBkGOaHgNje577IjiJ8+XLxi3kHLF0FXEstzkYnr2toqmEPLFObfFTSUpbfbjvTKqa/ZZisYliCB0OJ2Jp6ymaL+L/s9b878dFE+g2C6Xv1lwoQXsD3yjC/BjY3rN+fh62Ozuy7dVZYs3KcdkECF3QvNOqZQhz/LQ1BCX9ILrZj1D0KkswfWsETO6HPdcXzeJLFdlBofhuCuj/Aw== \ No newline at end of file diff --git a/static/diagrams/threaded-dag-threads.png b/static/diagrams/threaded-dag-threads.png new file mode 100644 index 0000000000000000000000000000000000000000..4cf865edd5d3eeccf8a5cb3850a739f3847e84e8 GIT binary patch literal 18578 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 literal 0 HcmV?d00001 diff --git a/static/diagrams/threaded-dag.drawio b/static/diagrams/threaded-dag.drawio new file mode 100644 index 00000000..e481b875 --- /dev/null +++ b/static/diagrams/threaded-dag.drawio @@ -0,0 +1 @@ +7VpbU+IwFP41PMqkTS/wKDfdGXXcdWdXn5wsDTTaNkwIAvvrN6UJbYlCF1gbXcYZTU5P0ub0u6S1DdiNFxcMTcJrGuCoYYNg0YC9hm3bwLPFnzSyzCIW8NwsMmYkkLE8cEd+Y5UoozMS4GkpkVMacTIpB4c0SfCQl2KIMTovp41oVD7rBI2xFrgbokiP/iQBD7Noy/bz+CUm41Cd2fLa2ZEYqWS5kmmIAjovhGC/AbuMUp614kUXR2n1VF2ycYM3jq4vjOGEVxnww3ukD17wHF/f3IRXj52v/dA9k7O8oGgmF3wur5YvVQnmIeH4boKGaX8u7nMDdkIeR6JniSaaTrLCj8gCi3N15JSYcbx481qtdQUEdjCNMWdLkaIGQFk0BRtH9uf5PVApYaH8KobkXR+vZ84LIxqyNn9Tp5ZWFhwIoMguZTykY5qgqJ9HO4zOkiAtyapOec4VpRMZfMKcLyXq0YzTcmnxgvB70Qay/ZC2m67s9RaFQ72l6iRivfdqgrRTGJV282Grnho3ogkfoJhEaeA7iQXpbHCD5+L3NxqjZH1j03Vvv62iTHTGhnhLPaUscMTGmO/Cpw4ThiPEyUv5Oo5+022NHB0TyGED08jhn8hxTHLAiuSwayWHr7EjbvKQYRQcjIanWTxR+QlN8IEAadpuASNWNYSApu8WQWLtgEiApuF6AWnnFnGOWbKK2MAR0Qj9wlEHDZ/Hq+V2aUTZqkBw0E1/NoF2iaMXzMkQ1QOvWrUXaujqGqG9vmna2z5p7zHJ4VQkB6xVe52Po71F6QXVALIpvWAHQj6O9FZFV63OroOrZ4L0Qsc06XVP0ntMcrgVyeHUKr3ux5He/ba99ifd9laF13YVOgNNB/pSIitDbjXdOWNoWUiYUJLwaeFst2kgP5WjZpSCp577B2/kW7C1LV80sivYGK0uh45GU1GYTYKsS7A/Z3TK9E0wFMeCTdcwS3FOlnJMznsVOe/Wain6e0ZjLWWv3bz9SXfzVdF16G5+L/dwwYa27XAPG7S25Zfd41jO4GnIHxjhDG3THjXgyReOyVy/InO9Wn1BZ0fcFK4w5IQmRjvDf/+KvSq+Dn2LuJ8ztMrOoH04sOkMbbgt/984g/7fpQsTnME17v2/fZASgJMzlOvZrshcv1ZnAK84Aw4If7ddwrvq/puKXcEQpkIeSDL+vloMyAOi54LXbbCA8wp2UgP2an1abWvQuzRBmD3XNGG2tLKchPkAcqgPQneyo10nOyxdmb+YQA///T6oFN38o9ZsO5h/Gwz7fwA= \ No newline at end of file diff --git a/static/diagrams/threaded-dag.png b/static/diagrams/threaded-dag.png new file mode 100644 index 0000000000000000000000000000000000000000..085d0f0915a41eb5279332cb6d7f83852d22e8b0 GIT binary patch literal 11621 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 R!F$t82D+v?xmxEh{tuJ*8)^Um literal 0 HcmV?d00001 From c8a1046e841d733cd2c2c6f8bb148a0751ff7e93 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 29 Sep 2022 06:59:08 -0600 Subject: [PATCH 03/16] v1.4 --- config.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config.toml b/config.toml index 26cf1670..186c330f 100644 --- a/config.toml +++ b/config.toml @@ -44,14 +44,14 @@ privacy_policy = "https://matrix.org/legal/privacy-notice" [params.version] # must be one of "unstable", "current", "historical" # this is used to decide whether to show a banner pointing to the current release -status = "unstable" +status = "stable" # A URL pointing to the latest, stable release of the spec. To be shown in the unstable version warning banner. current_version_url = "https://spec.matrix.org/latest" # The following is used when status = "stable", and is displayed in various UI elements on a released version # of the spec. CI will set these values here automatically when a release git tag (i.e `v1.5`) is created. -#major = "1" -#minor = "3" -#release_date = "June 16, 2022" +major = "1" +minor = "4" +release_date = "September 29, 2022" # User interface configuration [params.ui] From 7a591366c119f53b1ffa549c2179054e0e800b93 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 29 Sep 2022 07:03:48 -0600 Subject: [PATCH 04/16] v1.4 changelog --- .../newsfragments/1174.clarification | 1 - .../newsfragments/1200.breaking | 1 - .../newsfragments/1084.clarification | 1 - .../newsfragments/1135.clarification | 1 - .../newsfragments/1155.clarification | 1 - .../newsfragments/1161.clarification | 1 - .../newsfragments/1164.clarification | 1 - .../newsfragments/1165.clarification | 1 - .../newsfragments/1166.clarification | 1 - .../newsfragments/1170.clarification | 1 - .../newsfragments/1174.clarification | 1 - .../newsfragments/1179.clarification | 1 - .../newsfragments/1180.clarification | 1 - .../newsfragments/1185.clarification | 1 - .../client_server/newsfragments/1190.feature | 1 - .../client_server/newsfragments/1196.removal | 1 - .../client_server/newsfragments/1197.feature | 1 - .../client_server/newsfragments/1198.feature | 1 - .../client_server/newsfragments/1199.feature | 1 - .../client_server/newsfragments/1201.feature | 1 - .../newsfragments/1210.clarification | 1 - .../client_server/newsfragments/1211.feature | 1 - .../newsfragments/1215.clarification | 1 - .../newsfragments/1216.feature.1 | 1 - .../newsfragments/1216.feature.2 | 1 - .../newsfragments/1216.feature.3 | 1 - .../newsfragments/1236.clarification | 1 - .../newsfragments/1238.clarification | 1 - .../newsfragments/1240.clarification | 1 - .../newsfragments/1243.clarification | 1 - .../client_server/newsfragments/1254.feature | 1 - .../client_server/newsfragments/1255.feature | 1 - .../newsfragments/1174.clarification | 1 - .../newsfragments/1185.clarification | 1 - .../internal/newsfragments/1191.clarification | 1 - .../internal/newsfragments/1194.feature | 1 - .../internal/newsfragments/1195.clarification | 1 - .../internal/newsfragments/1205.clarification | 1 - .../internal/newsfragments/1230.clarification | 1 - .../newsfragments/1174.clarification | 1 - .../newsfragments/1137.clarification | 1 - .../newsfragments/1158.clarification | 1 - .../newsfragments/1175.clarification | 1 - .../newsfragments/1174.clarification | 1 - .../newsfragments/1179.clarification | 1 - .../newsfragments/1185.clarification | 1 - .../server_server/newsfragments/1255.feature | 1 - content/changelog.md | 1 + layouts/partials/changelogs/v1.4.md | 140 ++++++++++++++++++ 49 files changed, 141 insertions(+), 47 deletions(-) delete mode 100644 changelogs/application_service/newsfragments/1174.clarification delete mode 100644 changelogs/application_service/newsfragments/1200.breaking delete mode 100644 changelogs/client_server/newsfragments/1084.clarification delete mode 100644 changelogs/client_server/newsfragments/1135.clarification delete mode 100644 changelogs/client_server/newsfragments/1155.clarification delete mode 100644 changelogs/client_server/newsfragments/1161.clarification delete mode 100644 changelogs/client_server/newsfragments/1164.clarification delete mode 100644 changelogs/client_server/newsfragments/1165.clarification delete mode 100644 changelogs/client_server/newsfragments/1166.clarification delete mode 100644 changelogs/client_server/newsfragments/1170.clarification delete mode 100644 changelogs/client_server/newsfragments/1174.clarification delete mode 100644 changelogs/client_server/newsfragments/1179.clarification delete mode 100644 changelogs/client_server/newsfragments/1180.clarification delete mode 100644 changelogs/client_server/newsfragments/1185.clarification delete mode 100644 changelogs/client_server/newsfragments/1190.feature delete mode 100644 changelogs/client_server/newsfragments/1196.removal delete mode 100644 changelogs/client_server/newsfragments/1197.feature delete mode 100644 changelogs/client_server/newsfragments/1198.feature delete mode 100644 changelogs/client_server/newsfragments/1199.feature delete mode 100644 changelogs/client_server/newsfragments/1201.feature delete mode 100644 changelogs/client_server/newsfragments/1210.clarification delete mode 100644 changelogs/client_server/newsfragments/1211.feature delete mode 100644 changelogs/client_server/newsfragments/1215.clarification delete mode 100644 changelogs/client_server/newsfragments/1216.feature.1 delete mode 100644 changelogs/client_server/newsfragments/1216.feature.2 delete mode 100644 changelogs/client_server/newsfragments/1216.feature.3 delete mode 100644 changelogs/client_server/newsfragments/1236.clarification delete mode 100644 changelogs/client_server/newsfragments/1238.clarification delete mode 100644 changelogs/client_server/newsfragments/1240.clarification delete mode 100644 changelogs/client_server/newsfragments/1243.clarification delete mode 100644 changelogs/client_server/newsfragments/1254.feature delete mode 100644 changelogs/client_server/newsfragments/1255.feature delete mode 100644 changelogs/identity_service/newsfragments/1174.clarification delete mode 100644 changelogs/identity_service/newsfragments/1185.clarification delete mode 100644 changelogs/internal/newsfragments/1191.clarification delete mode 100644 changelogs/internal/newsfragments/1194.feature delete mode 100644 changelogs/internal/newsfragments/1195.clarification delete mode 100644 changelogs/internal/newsfragments/1205.clarification delete mode 100644 changelogs/internal/newsfragments/1230.clarification delete mode 100644 changelogs/push_gateway/newsfragments/1174.clarification delete mode 100644 changelogs/room_versions/newsfragments/1137.clarification delete mode 100644 changelogs/room_versions/newsfragments/1158.clarification delete mode 100644 changelogs/room_versions/newsfragments/1175.clarification delete mode 100644 changelogs/server_server/newsfragments/1174.clarification delete mode 100644 changelogs/server_server/newsfragments/1179.clarification delete mode 100644 changelogs/server_server/newsfragments/1185.clarification delete mode 100644 changelogs/server_server/newsfragments/1255.feature create mode 100644 layouts/partials/changelogs/v1.4.md diff --git a/changelogs/application_service/newsfragments/1174.clarification b/changelogs/application_service/newsfragments/1174.clarification deleted file mode 100644 index 9eef7945..00000000 --- a/changelogs/application_service/newsfragments/1174.clarification +++ /dev/null @@ -1 +0,0 @@ -Add HTML anchors for object definitions in the formatted specification. diff --git a/changelogs/application_service/newsfragments/1200.breaking b/changelogs/application_service/newsfragments/1200.breaking deleted file mode 100644 index 8b362072..00000000 --- a/changelogs/application_service/newsfragments/1200.breaking +++ /dev/null @@ -1 +0,0 @@ -Replace homeserver authorization approach with an `Authorization` header instead of `access_token` when talking to the application service, as per [MSC2832](https://github.com/matrix-org/matrix-spec-proposals/pull/2832). \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1084.clarification b/changelogs/client_server/newsfragments/1084.clarification deleted file mode 100644 index c0d6e0f3..00000000 --- a/changelogs/client_server/newsfragments/1084.clarification +++ /dev/null @@ -1 +0,0 @@ -Mention that the `/rooms/{roomId}/invite` endpoint will return a 200 response if the user is already invited to the room. diff --git a/changelogs/client_server/newsfragments/1135.clarification b/changelogs/client_server/newsfragments/1135.clarification deleted file mode 100644 index 3ccb2333..00000000 --- a/changelogs/client_server/newsfragments/1135.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various typos throughout the specification. diff --git a/changelogs/client_server/newsfragments/1155.clarification b/changelogs/client_server/newsfragments/1155.clarification deleted file mode 100644 index 08e9dd2f..00000000 --- a/changelogs/client_server/newsfragments/1155.clarification +++ /dev/null @@ -1 +0,0 @@ -Describe return codes for account data endpoints, and clarify that per-room data does not inherit from the global data. diff --git a/changelogs/client_server/newsfragments/1161.clarification b/changelogs/client_server/newsfragments/1161.clarification deleted file mode 100644 index 3ccb2333..00000000 --- a/changelogs/client_server/newsfragments/1161.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various typos throughout the specification. diff --git a/changelogs/client_server/newsfragments/1164.clarification b/changelogs/client_server/newsfragments/1164.clarification deleted file mode 100644 index 3ccb2333..00000000 --- a/changelogs/client_server/newsfragments/1164.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various typos throughout the specification. diff --git a/changelogs/client_server/newsfragments/1165.clarification b/changelogs/client_server/newsfragments/1165.clarification deleted file mode 100644 index 0cf092bb..00000000 --- a/changelogs/client_server/newsfragments/1165.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that policy rule globs work like ACL globs. Contributed by Nico. diff --git a/changelogs/client_server/newsfragments/1166.clarification b/changelogs/client_server/newsfragments/1166.clarification deleted file mode 100644 index 9db3e7c3..00000000 --- a/changelogs/client_server/newsfragments/1166.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify the format of some structures in the End-to-end encryption module. diff --git a/changelogs/client_server/newsfragments/1170.clarification b/changelogs/client_server/newsfragments/1170.clarification deleted file mode 100644 index 3ccb2333..00000000 --- a/changelogs/client_server/newsfragments/1170.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various typos throughout the specification. diff --git a/changelogs/client_server/newsfragments/1174.clarification b/changelogs/client_server/newsfragments/1174.clarification deleted file mode 100644 index 9eef7945..00000000 --- a/changelogs/client_server/newsfragments/1174.clarification +++ /dev/null @@ -1 +0,0 @@ -Add HTML anchors for object definitions in the formatted specification. diff --git a/changelogs/client_server/newsfragments/1179.clarification b/changelogs/client_server/newsfragments/1179.clarification deleted file mode 100644 index 8bb04d09..00000000 --- a/changelogs/client_server/newsfragments/1179.clarification +++ /dev/null @@ -1 +0,0 @@ -Tweak the styling of `` snippets in tables rendered from OpenAPI definitions. diff --git a/changelogs/client_server/newsfragments/1180.clarification b/changelogs/client_server/newsfragments/1180.clarification deleted file mode 100644 index 3ccb2333..00000000 --- a/changelogs/client_server/newsfragments/1180.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various typos throughout the specification. diff --git a/changelogs/client_server/newsfragments/1185.clarification b/changelogs/client_server/newsfragments/1185.clarification deleted file mode 100644 index 0865507a..00000000 --- a/changelogs/client_server/newsfragments/1185.clarification +++ /dev/null @@ -1 +0,0 @@ -Update "API Standards" section to clarify how JSON is used. diff --git a/changelogs/client_server/newsfragments/1190.feature b/changelogs/client_server/newsfragments/1190.feature deleted file mode 100644 index ca206eb2..00000000 --- a/changelogs/client_server/newsfragments/1190.feature +++ /dev/null @@ -1 +0,0 @@ -Add a `.m.rule.room.server_acl` push rule to match `m.room.server_acl` events, as per [MSC3786](https://github.com/matrix-org/matrix-spec-proposals/pull/3786). diff --git a/changelogs/client_server/newsfragments/1196.removal b/changelogs/client_server/newsfragments/1196.removal deleted file mode 100644 index c09a4b0d..00000000 --- a/changelogs/client_server/newsfragments/1196.removal +++ /dev/null @@ -1 +0,0 @@ -Remove unused policy room sharing mechanism, as per [MSC3844](https://github.com/matrix-org/matrix-spec-proposals/pull/3844). \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1197.feature b/changelogs/client_server/newsfragments/1197.feature deleted file mode 100644 index d4ea9b42..00000000 --- a/changelogs/client_server/newsfragments/1197.feature +++ /dev/null @@ -1 +0,0 @@ -Add `Cross-Origin-Resource-Policy` (CORP) headers to media repository, as per [MSC3828](https://github.com/matrix-org/matrix-spec-proposals/pull/3828). \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1198.feature b/changelogs/client_server/newsfragments/1198.feature deleted file mode 100644 index 4e41e587..00000000 --- a/changelogs/client_server/newsfragments/1198.feature +++ /dev/null @@ -1 +0,0 @@ -Copy a room's `type` when upgrading it, as per [MSC3818](https://github.com/matrix-org/matrix-spec-proposals/pull/3818). \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1199.feature b/changelogs/client_server/newsfragments/1199.feature deleted file mode 100644 index ca32e966..00000000 --- a/changelogs/client_server/newsfragments/1199.feature +++ /dev/null @@ -1 +0,0 @@ -Add `room_types` filter and `room_type` response to `/publicRooms`, as per [MSC3827](https://github.com/matrix-org/matrix-spec-proposals/pull/3827). \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1201.feature b/changelogs/client_server/newsfragments/1201.feature deleted file mode 100644 index 4c9a5ea1..00000000 --- a/changelogs/client_server/newsfragments/1201.feature +++ /dev/null @@ -1 +0,0 @@ -Add a `.m.rule.room.server_acl` push rule to match `m.room.server_acl` events, as per [MSC3786](https://github.com/matrix-org/matrix-spec-proposals/pull/3786). \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1210.clarification b/changelogs/client_server/newsfragments/1210.clarification deleted file mode 100644 index 6a024852..00000000 --- a/changelogs/client_server/newsfragments/1210.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that the "device_id", "user_id" and "access_token" fields are required in the response body of `POST /_matrix/client/v3/login`. \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1211.feature b/changelogs/client_server/newsfragments/1211.feature deleted file mode 100644 index 92f1bf1b..00000000 --- a/changelogs/client_server/newsfragments/1211.feature +++ /dev/null @@ -1 +0,0 @@ -Add `m.replace` relations (event edits), as per [MSC2676](https://github.com/matrix-org/matrix-spec-proposals/pull/2676). diff --git a/changelogs/client_server/newsfragments/1215.clarification b/changelogs/client_server/newsfragments/1215.clarification deleted file mode 100644 index 3ccb2333..00000000 --- a/changelogs/client_server/newsfragments/1215.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various typos throughout the specification. diff --git a/changelogs/client_server/newsfragments/1216.feature.1 b/changelogs/client_server/newsfragments/1216.feature.1 deleted file mode 100644 index fb130e2c..00000000 --- a/changelogs/client_server/newsfragments/1216.feature.1 +++ /dev/null @@ -1 +0,0 @@ -Add `m.read.private` receipts, as per [MSC2285](https://github.com/matrix-org/matrix-spec-proposals/pull/2285). \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1216.feature.2 b/changelogs/client_server/newsfragments/1216.feature.2 deleted file mode 100644 index 27760b75..00000000 --- a/changelogs/client_server/newsfragments/1216.feature.2 +++ /dev/null @@ -1 +0,0 @@ -Make `m.fully_read` optional on `/read_markers`, as per [MSC2285](https://github.com/matrix-org/matrix-spec-proposals/pull/2285). \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1216.feature.3 b/changelogs/client_server/newsfragments/1216.feature.3 deleted file mode 100644 index 0f6eeb07..00000000 --- a/changelogs/client_server/newsfragments/1216.feature.3 +++ /dev/null @@ -1 +0,0 @@ -Allow `m.fully_read` markers to be set from `/receipts`, as per [MSC2285](https://github.com/matrix-org/matrix-spec-proposals/pull/2285). \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1236.clarification b/changelogs/client_server/newsfragments/1236.clarification deleted file mode 100644 index 36052275..00000000 --- a/changelogs/client_server/newsfragments/1236.clarification +++ /dev/null @@ -1 +0,0 @@ -Reinforce the relationship of refreshed access tokens to transaction IDs. \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1238.clarification b/changelogs/client_server/newsfragments/1238.clarification deleted file mode 100644 index 3ccb2333..00000000 --- a/changelogs/client_server/newsfragments/1238.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various typos throughout the specification. diff --git a/changelogs/client_server/newsfragments/1240.clarification b/changelogs/client_server/newsfragments/1240.clarification deleted file mode 100644 index d88de5eb..00000000 --- a/changelogs/client_server/newsfragments/1240.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify enum values by separating possible values with commas. diff --git a/changelogs/client_server/newsfragments/1243.clarification b/changelogs/client_server/newsfragments/1243.clarification deleted file mode 100644 index ca5f3aea..00000000 --- a/changelogs/client_server/newsfragments/1243.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various typos throughout the specification. \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1254.feature b/changelogs/client_server/newsfragments/1254.feature deleted file mode 100644 index 84ed083d..00000000 --- a/changelogs/client_server/newsfragments/1254.feature +++ /dev/null @@ -1 +0,0 @@ -Add threading via `m.thread` relations, as per [MSC3440](https://github.com/matrix-org/matrix-spec-proposals/pull/3440), [MSC3816](https://github.com/matrix-org/matrix-spec-proposals/pull/3816), [MSC3856](https://github.com/matrix-org/matrix-spec-proposals/pull/3856), and [MSC3715](https://github.com/matrix-org/matrix-spec-proposals/pull/3715). \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1255.feature b/changelogs/client_server/newsfragments/1255.feature deleted file mode 100644 index a1d15d98..00000000 --- a/changelogs/client_server/newsfragments/1255.feature +++ /dev/null @@ -1 +0,0 @@ -Add per-thread notifications and read receipts, as per [MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) and [MSC3773](https://github.com/matrix-org/matrix-spec-proposals/pull/3773). \ No newline at end of file diff --git a/changelogs/identity_service/newsfragments/1174.clarification b/changelogs/identity_service/newsfragments/1174.clarification deleted file mode 100644 index 9eef7945..00000000 --- a/changelogs/identity_service/newsfragments/1174.clarification +++ /dev/null @@ -1 +0,0 @@ -Add HTML anchors for object definitions in the formatted specification. diff --git a/changelogs/identity_service/newsfragments/1185.clarification b/changelogs/identity_service/newsfragments/1185.clarification deleted file mode 100644 index 0865507a..00000000 --- a/changelogs/identity_service/newsfragments/1185.clarification +++ /dev/null @@ -1 +0,0 @@ -Update "API Standards" section to clarify how JSON is used. diff --git a/changelogs/internal/newsfragments/1191.clarification b/changelogs/internal/newsfragments/1191.clarification deleted file mode 100644 index 3c4ca5f6..00000000 --- a/changelogs/internal/newsfragments/1191.clarification +++ /dev/null @@ -1 +0,0 @@ -Render HTML anchors for object definition tables. diff --git a/changelogs/internal/newsfragments/1194.feature b/changelogs/internal/newsfragments/1194.feature deleted file mode 100644 index 23f23618..00000000 --- a/changelogs/internal/newsfragments/1194.feature +++ /dev/null @@ -1 +0,0 @@ -Add internal changes changelog section. \ No newline at end of file diff --git a/changelogs/internal/newsfragments/1195.clarification b/changelogs/internal/newsfragments/1195.clarification deleted file mode 100644 index da9ce6fe..00000000 --- a/changelogs/internal/newsfragments/1195.clarification +++ /dev/null @@ -1 +0,0 @@ -Give rendered-data sections a background and some padding. diff --git a/changelogs/internal/newsfragments/1205.clarification b/changelogs/internal/newsfragments/1205.clarification deleted file mode 100644 index 6fb72a7a..00000000 --- a/changelogs/internal/newsfragments/1205.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix rendering of shortcodes within the client-server API. diff --git a/changelogs/internal/newsfragments/1230.clarification b/changelogs/internal/newsfragments/1230.clarification deleted file mode 100644 index 736fbd12..00000000 --- a/changelogs/internal/newsfragments/1230.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix the spacing of mapping types generated from the OpenAPI spec. diff --git a/changelogs/push_gateway/newsfragments/1174.clarification b/changelogs/push_gateway/newsfragments/1174.clarification deleted file mode 100644 index 9eef7945..00000000 --- a/changelogs/push_gateway/newsfragments/1174.clarification +++ /dev/null @@ -1 +0,0 @@ -Add HTML anchors for object definitions in the formatted specification. diff --git a/changelogs/room_versions/newsfragments/1137.clarification b/changelogs/room_versions/newsfragments/1137.clarification deleted file mode 100644 index b7c04045..00000000 --- a/changelogs/room_versions/newsfragments/1137.clarification +++ /dev/null @@ -1 +0,0 @@ -For room versions 1 through 10, clarify that events with rejected `auth_events` must be rejected. diff --git a/changelogs/room_versions/newsfragments/1158.clarification b/changelogs/room_versions/newsfragments/1158.clarification deleted file mode 100644 index d4081aa2..00000000 --- a/changelogs/room_versions/newsfragments/1158.clarification +++ /dev/null @@ -1 +0,0 @@ -For room versions 2–10: correct a mistaken clarification to the state resolution algorithm. diff --git a/changelogs/room_versions/newsfragments/1175.clarification b/changelogs/room_versions/newsfragments/1175.clarification deleted file mode 100644 index b7cda453..00000000 --- a/changelogs/room_versions/newsfragments/1175.clarification +++ /dev/null @@ -1 +0,0 @@ -For room versions 7 through 10: Clarify that `invite->knock` is actually a legal transition. \ No newline at end of file diff --git a/changelogs/server_server/newsfragments/1174.clarification b/changelogs/server_server/newsfragments/1174.clarification deleted file mode 100644 index 9eef7945..00000000 --- a/changelogs/server_server/newsfragments/1174.clarification +++ /dev/null @@ -1 +0,0 @@ -Add HTML anchors for object definitions in the formatted specification. diff --git a/changelogs/server_server/newsfragments/1179.clarification b/changelogs/server_server/newsfragments/1179.clarification deleted file mode 100644 index 8bb04d09..00000000 --- a/changelogs/server_server/newsfragments/1179.clarification +++ /dev/null @@ -1 +0,0 @@ -Tweak the styling of `` snippets in tables rendered from OpenAPI definitions. diff --git a/changelogs/server_server/newsfragments/1185.clarification b/changelogs/server_server/newsfragments/1185.clarification deleted file mode 100644 index 0865507a..00000000 --- a/changelogs/server_server/newsfragments/1185.clarification +++ /dev/null @@ -1 +0,0 @@ -Update "API Standards" section to clarify how JSON is used. diff --git a/changelogs/server_server/newsfragments/1255.feature b/changelogs/server_server/newsfragments/1255.feature deleted file mode 100644 index a1d15d98..00000000 --- a/changelogs/server_server/newsfragments/1255.feature +++ /dev/null @@ -1 +0,0 @@ -Add per-thread notifications and read receipts, as per [MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) and [MSC3773](https://github.com/matrix-org/matrix-spec-proposals/pull/3773). \ No newline at end of file diff --git a/content/changelog.md b/content/changelog.md index 2a623f9c..a84514b6 100644 --- a/content/changelog.md +++ b/content/changelog.md @@ -9,6 +9,7 @@ weight: 1000 {{% changelog/changelog-changes %}} +{{% changelog/changelog-rendered p="changelogs/v1.4.md" %}} {{% changelog/changelog-rendered p="changelogs/v1.3.md" %}} {{% changelog/changelog-rendered p="changelogs/v1.2.md" %}} {{% changelog/changelog-rendered p="changelogs/v1.1.md" %}} diff --git a/layouts/partials/changelogs/v1.4.md b/layouts/partials/changelogs/v1.4.md new file mode 100644 index 00000000..e383ae6e --- /dev/null +++ b/layouts/partials/changelogs/v1.4.md @@ -0,0 +1,140 @@ + + +## v1.4 + + + + +
Git commithttps://github.com/matrix-org/matrix-spec/tree/v1.4
Release dateSeptember 29, 2022
+ + +### Client-Server API + + +Removed Endpoints + + +- Remove unused policy room sharing mechanism, as per [MSC3844](https://github.com/matrix-org/matrix-spec-proposals/pull/3844). ([#1196](https://github.com/matrix-org/matrix-spec/issues/1196)) + + +Backwards Compatible Changes + + +- Add a `.m.rule.room.server_acl` push rule to match `m.room.server_acl` events, as per [MSC3786](https://github.com/matrix-org/matrix-spec-proposals/pull/3786). ([#1190](https://github.com/matrix-org/matrix-spec/issues/1190), [#1201](https://github.com/matrix-org/matrix-spec/issues/1201)) +- Add `Cross-Origin-Resource-Policy` (CORP) headers to media repository, as per [MSC3828](https://github.com/matrix-org/matrix-spec-proposals/pull/3828). ([#1197](https://github.com/matrix-org/matrix-spec/issues/1197)) +- Copy a room's `type` when upgrading it, as per [MSC3818](https://github.com/matrix-org/matrix-spec-proposals/pull/3818). ([#1198](https://github.com/matrix-org/matrix-spec/issues/1198)) +- Add `room_types` filter and `room_type` response to `/publicRooms`, as per [MSC3827](https://github.com/matrix-org/matrix-spec-proposals/pull/3827). ([#1199](https://github.com/matrix-org/matrix-spec/issues/1199)) +- Add `m.replace` relations (event edits), as per [MSC2676](https://github.com/matrix-org/matrix-spec-proposals/pull/2676). ([#1211](https://github.com/matrix-org/matrix-spec/issues/1211)) +- Add `m.read.private` receipts, as per [MSC2285](https://github.com/matrix-org/matrix-spec-proposals/pull/2285). ([#1216](https://github.com/matrix-org/matrix-spec/issues/1216)) +- Make `m.fully_read` optional on `/read_markers`, as per [MSC2285](https://github.com/matrix-org/matrix-spec-proposals/pull/2285). ([#1216](https://github.com/matrix-org/matrix-spec/issues/1216)) +- Allow `m.fully_read` markers to be set from `/receipts`, as per [MSC2285](https://github.com/matrix-org/matrix-spec-proposals/pull/2285). ([#1216](https://github.com/matrix-org/matrix-spec/issues/1216)) +- Add threading via `m.thread` relations, as per [MSC3440](https://github.com/matrix-org/matrix-spec-proposals/pull/3440), [MSC3816](https://github.com/matrix-org/matrix-spec-proposals/pull/3816), [MSC3856](https://github.com/matrix-org/matrix-spec-proposals/pull/3856), and [MSC3715](https://github.com/matrix-org/matrix-spec-proposals/pull/3715). ([#1254](https://github.com/matrix-org/matrix-spec/issues/1254)) +- Add per-thread notifications and read receipts, as per [MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) and [MSC3773](https://github.com/matrix-org/matrix-spec-proposals/pull/3773). ([#1255](https://github.com/matrix-org/matrix-spec/issues/1255)) + + +Spec Clarifications + + +- Mention that the `/rooms/{roomId}/invite` endpoint will return a 200 response if the user is already invited to the room. ([#1084](https://github.com/matrix-org/matrix-spec/issues/1084)) +- Fix various typos throughout the specification. ([#1135](https://github.com/matrix-org/matrix-spec/issues/1135), [#1161](https://github.com/matrix-org/matrix-spec/issues/1161), [#1164](https://github.com/matrix-org/matrix-spec/issues/1164), [#1170](https://github.com/matrix-org/matrix-spec/issues/1170), [#1180](https://github.com/matrix-org/matrix-spec/issues/1180), [#1215](https://github.com/matrix-org/matrix-spec/issues/1215), [#1238](https://github.com/matrix-org/matrix-spec/issues/1238), [#1243](https://github.com/matrix-org/matrix-spec/issues/1243)) +- Describe return codes for account data endpoints, and clarify that per-room data does not inherit from the global data. ([#1155](https://github.com/matrix-org/matrix-spec/issues/1155)) +- Clarify that policy rule globs work like ACL globs. Contributed by Nico. ([#1165](https://github.com/matrix-org/matrix-spec/issues/1165)) +- Clarify the format of some structures in the End-to-end encryption module. ([#1166](https://github.com/matrix-org/matrix-spec/issues/1166)) +- Add HTML anchors for object definitions in the formatted specification. ([#1174](https://github.com/matrix-org/matrix-spec/issues/1174)) +- Tweak the styling of `` snippets in tables rendered from OpenAPI definitions. ([#1179](https://github.com/matrix-org/matrix-spec/issues/1179)) +- Update "API Standards" section to clarify how JSON is used. ([#1185](https://github.com/matrix-org/matrix-spec/issues/1185)) +- Clarify that the "device_id", "user_id" and "access_token" fields are required in the response body of `POST /_matrix/client/v3/login`. ([#1210](https://github.com/matrix-org/matrix-spec/issues/1210)) +- Reinforce the relationship of refreshed access tokens to transaction IDs. ([#1236](https://github.com/matrix-org/matrix-spec/issues/1236)) +- Clarify enum values by separating possible values with commas. ([#1240](https://github.com/matrix-org/matrix-spec/issues/1240)) + + +### Server-Server API + + +Backwards Compatible Changes + + +- Add per-thread notifications and read receipts, as per [MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) and [MSC3773](https://github.com/matrix-org/matrix-spec-proposals/pull/3773). ([#1255](https://github.com/matrix-org/matrix-spec/issues/1255)) + + +Spec Clarifications + + +- Add HTML anchors for object definitions in the formatted specification. ([#1174](https://github.com/matrix-org/matrix-spec/issues/1174)) +- Tweak the styling of `` snippets in tables rendered from OpenAPI definitions. ([#1179](https://github.com/matrix-org/matrix-spec/issues/1179)) +- Update "API Standards" section to clarify how JSON is used. ([#1185](https://github.com/matrix-org/matrix-spec/issues/1185)) + + +### Application Service API + + +Breaking Changes + + +- Replace homeserver authorization approach with an `Authorization` header instead of `access_token` when talking to the application service, as per [MSC2832](https://github.com/matrix-org/matrix-spec-proposals/pull/2832). ([#1200](https://github.com/matrix-org/matrix-spec/issues/1200)) + + +Spec Clarifications + + +- Add HTML anchors for object definitions in the formatted specification. ([#1174](https://github.com/matrix-org/matrix-spec/issues/1174)) + + +### Identity Service API + + +Spec Clarifications + + +- Add HTML anchors for object definitions in the formatted specification. ([#1174](https://github.com/matrix-org/matrix-spec/issues/1174)) +- Update "API Standards" section to clarify how JSON is used. ([#1185](https://github.com/matrix-org/matrix-spec/issues/1185)) + + +### Push Gateway API + + +Spec Clarifications + + +- Add HTML anchors for object definitions in the formatted specification. ([#1174](https://github.com/matrix-org/matrix-spec/issues/1174)) + + +### Room Versions + + +Spec Clarifications + + +- For room versions 1 through 10, clarify that events with rejected `auth_events` must be rejected. ([#1137](https://github.com/matrix-org/matrix-spec/issues/1137)) +- For room versions 2–10: correct a mistaken clarification to the state resolution algorithm. ([#1158](https://github.com/matrix-org/matrix-spec/issues/1158)) +- For room versions 7 through 10: Clarify that `invite->knock` is actually a legal transition. ([#1175](https://github.com/matrix-org/matrix-spec/issues/1175)) + + +### Appendices + + +No significant changes. + + +### Internal Changes/Tooling + + +Backwards Compatible Changes + + +- Add internal changes changelog section. ([#1194](https://github.com/matrix-org/matrix-spec/issues/1194)) + + +Spec Clarifications + + +- Render HTML anchors for object definition tables. ([#1191](https://github.com/matrix-org/matrix-spec/issues/1191)) +- Give rendered-data sections a background and some padding. ([#1195](https://github.com/matrix-org/matrix-spec/issues/1195)) +- Fix rendering of shortcodes within the client-server API. ([#1205](https://github.com/matrix-org/matrix-spec/issues/1205)) +- Fix the spacing of mapping types generated from the OpenAPI spec. ([#1230](https://github.com/matrix-org/matrix-spec/issues/1230)) From 434f1b0672d76b04432622b55a9971618d120247 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 29 Sep 2022 07:04:16 -0600 Subject: [PATCH 05/16] Go back to unstable --- config.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config.toml b/config.toml index 186c330f..525e968b 100644 --- a/config.toml +++ b/config.toml @@ -44,14 +44,14 @@ privacy_policy = "https://matrix.org/legal/privacy-notice" [params.version] # must be one of "unstable", "current", "historical" # this is used to decide whether to show a banner pointing to the current release -status = "stable" +status = "unstable" # A URL pointing to the latest, stable release of the spec. To be shown in the unstable version warning banner. current_version_url = "https://spec.matrix.org/latest" # The following is used when status = "stable", and is displayed in various UI elements on a released version # of the spec. CI will set these values here automatically when a release git tag (i.e `v1.5`) is created. -major = "1" -minor = "4" -release_date = "September 29, 2022" +# major = "1" +# minor = "4" +# release_date = "September 29, 2022" # User interface configuration [params.ui] From 3c796e9876de447f45b06f5f537fbd88954c9549 Mon Sep 17 00:00:00 2001 From: Val Lorentz Date: Tue, 4 Oct 2022 05:26:31 +0200 Subject: [PATCH 06/16] Aggregations: remove not about "future extensions" (#1263) * Aggregations: remove not about "future extensions" It is now used by threading. * Create 1263.clarification --- changelogs/client_server/newsfragments/1263.clarification | 1 + content/client-server-api/_index.md | 7 +------ 2 files changed, 2 insertions(+), 6 deletions(-) create mode 100644 changelogs/client_server/newsfragments/1263.clarification diff --git a/changelogs/client_server/newsfragments/1263.clarification b/changelogs/client_server/newsfragments/1263.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/client_server/newsfragments/1263.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index 44bd4151..dd50f225 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -1988,11 +1988,6 @@ 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". @@ -2644,4 +2639,4 @@ systems. {{< cs-module name="moderation_policies" >}} {{< cs-module name="spaces" >}} {{< cs-module name="event_replacements" >}} -{{< cs-module name="threading" >}} \ No newline at end of file +{{< cs-module name="threading" >}} From 460bea4024dba391621968647b839b7bf68211e5 Mon Sep 17 00:00:00 2001 From: Val Lorentz Date: Tue, 4 Oct 2022 05:31:10 +0200 Subject: [PATCH 07/16] Fix definition of `data-mx-color` values (#1260) * Fix definition of `data-mx-color` values * Create 1260.clarification * Update changelogs/client_server/newsfragments/1260.clarification Co-authored-by: Travis Ralston Co-authored-by: Travis Ralston --- changelogs/client_server/newsfragments/1260.clarification | 1 + content/client-server-api/modules/instant_messaging.md | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/1260.clarification diff --git a/changelogs/client_server/newsfragments/1260.clarification b/changelogs/client_server/newsfragments/1260.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/client_server/newsfragments/1260.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. diff --git a/content/client-server-api/modules/instant_messaging.md b/content/client-server-api/modules/instant_messaging.md index 7f9b3ca1..47440cd3 100644 --- a/content/client-server-api/modules/instant_messaging.md +++ b/content/client-server-api/modules/instant_messaging.md @@ -47,8 +47,9 @@ Not all attributes on those tags should be permitted as they may be avenues for other disruption attempts, such as adding `onclick` handlers or excessively large text. Clients should only permit the attributes listed for the tags below. Where `data-mx-bg-color` and `data-mx-color` -are listed, clients should translate the value (a 6-character hex color -code) to the appropriate CSS/attributes for the tag. +are listed, clients should translate the value (a `#` character followed +by a 6-character hex color code) to the appropriate CSS/attributes for +the tag. `font` `data-mx-bg-color`, `data-mx-color`, `color` From 098aabd22a25fbcb8d18a0a2d6b26921e1574102 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 4 Oct 2022 09:47:33 +0100 Subject: [PATCH 08/16] Add a missing 'the' --- content/application-service-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/application-service-api.md b/content/application-service-api.md index 029e0350..255f5cbc 100644 --- a/content/application-service-api.md +++ b/content/application-service-api.md @@ -14,7 +14,7 @@ underlying homeserver implementation. ## Application Services -Application services are passive and can only observe events from +Application services are passive and can only observe events from the homeserver. They can inject events into rooms they are participating in. They cannot prevent events from being sent, nor can they modify the content of the event being sent. In order to observe events from a From d3d4afdbfde3f2763ed832227469dbcb6b4371f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= <76261501+zecakeh@users.noreply.github.com> Date: Tue, 4 Oct 2022 16:09:23 +0200 Subject: [PATCH 09/16] Receipts: Add `thread_id` to the `/receipt` endpoint (#1261) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Receipts: Add thread_id to the /receipt endpoint It seems to have been omitted in #1255 Signed-off-by: Kévin Commaille * changelog Signed-off-by: Kévin Commaille * Fix missing backtick * Apply suggestion for error description Co-authored-by: Travis Ralston Signed-off-by: Kévin Commaille Co-authored-by: Travis Ralston --- .../newsfragments/1261.clarification | 1 + data/api/client-server/receipts.yaml | 26 ++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/1261.clarification diff --git a/changelogs/client_server/newsfragments/1261.clarification b/changelogs/client_server/newsfragments/1261.clarification new file mode 100644 index 00000000..a973a159 --- /dev/null +++ b/changelogs/client_server/newsfragments/1261.clarification @@ -0,0 +1 @@ +Add `thread_id` to the `/receipt` endpoint, as per [MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) \ No newline at end of file diff --git a/data/api/client-server/receipts.yaml b/data/api/client-server/receipts.yaml index a4dabdd2..7a8dc279 100644 --- a/data/api/client-server/receipts.yaml +++ b/data/api/client-server/receipts.yaml @@ -74,8 +74,18 @@ paths: required: true schema: type: object + properties: + thread_id: + type: string + x-addedInMatrixVersion: "1.4" + description: |- + The root thread event's ID (or `main`) for which + thread this receipt is intended to be under. If + not specified, the read receipt is *unthreaded* + (default). example: { - } + "thread_id": "main" + } responses: 200: description: The receipt was sent. @@ -88,5 +98,19 @@ paths: description: This request was rate-limited. schema: "$ref": "definitions/errors/rate_limited.yaml" + 400: + description: |- + The `thread_id` is invalid in some way. For example: + * It is not a string. + * It is empty. + * It is provided for an incompatible receipt type. + * The `event_id` is not related to the `thread_id`. + schema: + $ref: "definitions/errors/error.yaml" + examples: + application/json: { + "errcode": "M_INVALID_PARAM", + "error": "thread_id field must be a non-empty string" + } tags: - Room participation From dc0882012bce56dba5f4a0e35ae2dc400d1dcbce Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 4 Oct 2022 16:00:27 +0100 Subject: [PATCH 10/16] Fix naming of `device_one_time_keys_count` in /sync Fixes #671 --- content/client-server-api/modules/end_to_end_encryption.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index 10f21e86..3deae943 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -1622,7 +1622,7 @@ specified). The client is expected to use [`/keys/query`](/client-server-api/#po sync, as documented in [Tracking the device list for a user](#tracking-the-device-list-for-a-user). -It also adds a `one_time_keys_count` property. Note the spelling +It also adds a `device_one_time_keys_count` property. Note the spelling difference with the `one_time_key_counts` property in the [`/keys/upload`](/client-server-api/#post_matrixclientv3keysupload) response. From b8e7c4e1333062ab7effd42f31d47afc4eff48c5 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 4 Oct 2022 16:01:55 +0100 Subject: [PATCH 11/16] Newsfile --- changelogs/client_server/newsfragments/1266.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/1266.clarification diff --git a/changelogs/client_server/newsfragments/1266.clarification b/changelogs/client_server/newsfragments/1266.clarification new file mode 100644 index 00000000..ad9a0d27 --- /dev/null +++ b/changelogs/client_server/newsfragments/1266.clarification @@ -0,0 +1 @@ +Fix naming of `device_one_time_keys_count` in `/sync`. From 1cdfbd3cd8e01d04b3875f297bc0ab27822f7ea2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 4 Oct 2022 12:00:16 -0400 Subject: [PATCH 12/16] v1.4 patch release cleanup (#1268) * Add missing steps to patch release guidelines * Update from v1.4 patch --- changelogs/client_server/newsfragments/1261.clarification | 1 - changelogs/client_server/newsfragments/1263.clarification | 1 - layouts/partials/changelogs/v1.4.md | 3 ++- meta/releasing.md | 2 ++ 4 files changed, 4 insertions(+), 3 deletions(-) delete mode 100644 changelogs/client_server/newsfragments/1261.clarification delete mode 100644 changelogs/client_server/newsfragments/1263.clarification diff --git a/changelogs/client_server/newsfragments/1261.clarification b/changelogs/client_server/newsfragments/1261.clarification deleted file mode 100644 index a973a159..00000000 --- a/changelogs/client_server/newsfragments/1261.clarification +++ /dev/null @@ -1 +0,0 @@ -Add `thread_id` to the `/receipt` endpoint, as per [MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1263.clarification b/changelogs/client_server/newsfragments/1263.clarification deleted file mode 100644 index 3ccb2333..00000000 --- a/changelogs/client_server/newsfragments/1263.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various typos throughout the specification. diff --git a/layouts/partials/changelogs/v1.4.md b/layouts/partials/changelogs/v1.4.md index e383ae6e..2e741e06 100644 --- a/layouts/partials/changelogs/v1.4.md +++ b/layouts/partials/changelogs/v1.4.md @@ -36,13 +36,14 @@ Variables: - Allow `m.fully_read` markers to be set from `/receipts`, as per [MSC2285](https://github.com/matrix-org/matrix-spec-proposals/pull/2285). ([#1216](https://github.com/matrix-org/matrix-spec/issues/1216)) - Add threading via `m.thread` relations, as per [MSC3440](https://github.com/matrix-org/matrix-spec-proposals/pull/3440), [MSC3816](https://github.com/matrix-org/matrix-spec-proposals/pull/3816), [MSC3856](https://github.com/matrix-org/matrix-spec-proposals/pull/3856), and [MSC3715](https://github.com/matrix-org/matrix-spec-proposals/pull/3715). ([#1254](https://github.com/matrix-org/matrix-spec/issues/1254)) - Add per-thread notifications and read receipts, as per [MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) and [MSC3773](https://github.com/matrix-org/matrix-spec-proposals/pull/3773). ([#1255](https://github.com/matrix-org/matrix-spec/issues/1255)) +- Add `thread_id` to the `/receipt` endpoint, as per [MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771). ([#1261](https://github.com/matrix-org/matrix-spec/issues/1261)) Spec Clarifications - Mention that the `/rooms/{roomId}/invite` endpoint will return a 200 response if the user is already invited to the room. ([#1084](https://github.com/matrix-org/matrix-spec/issues/1084)) -- Fix various typos throughout the specification. ([#1135](https://github.com/matrix-org/matrix-spec/issues/1135), [#1161](https://github.com/matrix-org/matrix-spec/issues/1161), [#1164](https://github.com/matrix-org/matrix-spec/issues/1164), [#1170](https://github.com/matrix-org/matrix-spec/issues/1170), [#1180](https://github.com/matrix-org/matrix-spec/issues/1180), [#1215](https://github.com/matrix-org/matrix-spec/issues/1215), [#1238](https://github.com/matrix-org/matrix-spec/issues/1238), [#1243](https://github.com/matrix-org/matrix-spec/issues/1243)) +- Fix various typos throughout the specification. ([#1135](https://github.com/matrix-org/matrix-spec/issues/1135), [#1161](https://github.com/matrix-org/matrix-spec/issues/1161), [#1164](https://github.com/matrix-org/matrix-spec/issues/1164), [#1170](https://github.com/matrix-org/matrix-spec/issues/1170), [#1180](https://github.com/matrix-org/matrix-spec/issues/1180), [#1215](https://github.com/matrix-org/matrix-spec/issues/1215), [#1238](https://github.com/matrix-org/matrix-spec/issues/1238), [#1243](https://github.com/matrix-org/matrix-spec/issues/1243), [#1263](https://github.com/matrix-org/matrix-spec/issues/1263)) - Describe return codes for account data endpoints, and clarify that per-room data does not inherit from the global data. ([#1155](https://github.com/matrix-org/matrix-spec/issues/1155)) - Clarify that policy rule globs work like ACL globs. Contributed by Nico. ([#1165](https://github.com/matrix-org/matrix-spec/issues/1165)) - Clarify the format of some structures in the End-to-end encryption module. ([#1166](https://github.com/matrix-org/matrix-spec/issues/1166)) diff --git a/meta/releasing.md b/meta/releasing.md index 64a01a95..3e01dc86 100644 --- a/meta/releasing.md +++ b/meta/releasing.md @@ -83,3 +83,5 @@ is typically best reserved for the next release cycle. 4. Wait for the GitHub Actions build to complete on the tag. 5. Update the assets on the GitHub release to those generated by the latest Actions build. 6. Deploy the release on the webserver. See internal wiki. +7. Remove the changelog entries from `main`, if the changes landed on `main`. +8. Update the github release changelog and changelog on `main`, likely by hand. From 43a48314acf3a9c66124cb499fbc540ff5906d34 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Wed, 5 Oct 2022 10:54:58 +0100 Subject: [PATCH 13/16] Remove reference to a `room_id` key for typing events (#1265) --- changelogs/client_server/newsfragments/1265.clarification | 1 + content/client-server-api/modules/typing_notifications.md | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/1265.clarification diff --git a/changelogs/client_server/newsfragments/1265.clarification b/changelogs/client_server/newsfragments/1265.clarification new file mode 100644 index 00000000..ca5f3aea --- /dev/null +++ b/changelogs/client_server/newsfragments/1265.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. \ No newline at end of file diff --git a/content/client-server-api/modules/typing_notifications.md b/content/client-server-api/modules/typing_notifications.md index 722c011f..b3ce2372 100644 --- a/content/client-server-api/modules/typing_notifications.md +++ b/content/client-server-api/modules/typing_notifications.md @@ -6,8 +6,9 @@ type: module Users may wish to be informed when another user is typing in a room. This can be achieved using typing notifications. These are ephemeral -events scoped to a `room_id`. This means they do not form part of the -[Event Graph](index.html#event-graphs) but still have a `room_id` key. +events, so they do not form part of the +[Event Graph](index.html#event-graphs). Typing notifications are scoped +to a room. #### Events From c4505665e0d437ac8cffa9eace8f553a7edad6df Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Wed, 5 Oct 2022 17:54:34 +0100 Subject: [PATCH 14/16] Various clarifications to auth rules text (#1270) --- .../newsfragments/1270.clarification | 1 + content/rooms/fragments/v1-auth-rules.md | 17 ++++++----- content/rooms/fragments/v3-auth-rules.md | 21 ++++++------- content/rooms/fragments/v8-auth-rules.md | 26 ++++++++-------- content/rooms/v10.md | 19 ++++++------ content/rooms/v3.md | 4 +-- content/rooms/v6.md | 19 ++++++------ content/rooms/v7.md | 30 +++++++++++-------- content/rooms/v8.md | 4 +-- content/rooms/v9.md | 2 +- layouts/shortcodes/rver-fragment.html | 1 + 11 files changed, 78 insertions(+), 66 deletions(-) create mode 100644 changelogs/room_versions/newsfragments/1270.clarification diff --git a/changelogs/room_versions/newsfragments/1270.clarification b/changelogs/room_versions/newsfragments/1270.clarification new file mode 100644 index 00000000..638ef04b --- /dev/null +++ b/changelogs/room_versions/newsfragments/1270.clarification @@ -0,0 +1 @@ +Various clarifications to the text on event authorisation rules. diff --git a/content/rooms/fragments/v1-auth-rules.md b/content/rooms/fragments/v1-auth-rules.md index 242c7620..289e40e5 100644 --- a/content/rooms/fragments/v1-auth-rules.md +++ b/content/rooms/fragments/v1-auth-rules.md @@ -19,12 +19,12 @@ the default power level for users in the room. The rules are as follows: 1. If type is `m.room.create`: - 1. If it has any previous events, reject. + 1. If it has any `prev_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. + 4. If `content` has no `creator` property, reject. 5. Otherwise, allow. 2. Considering the event's `auth_events`: 1. If there are duplicate entries for a given `type` and `state_key` pair, @@ -45,7 +45,8 @@ The rules are as follows: 2. If sender's domain doesn't matches `state_key`, reject. 3. Otherwise, allow. 5. If type is `m.room.member`: - 1. If no `state_key` key or `membership` key in `content`, reject. + 1. If there is no `state_key` property, or no `membership` property in + `content`, reject. 2. If `membership` is `join`: 1. If the only previous event is an `m.room.create` and the `state_key` is the creator, allow. @@ -56,11 +57,11 @@ The rules are as follows: 5. If the `join_rule` is `public`, allow. 6. Otherwise, reject. 3. If `membership` is `invite`: - 1. If `content` has `third_party_invite` key: + 1. If `content` has a `third_party_invite` property: 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, + property, reject. + 3. If `signed` does not have `mxid` and `token` properties, reject. 4. If `mxid` does not match `state_key`, reject. 5. If there is no `m.room.third_party_invite` event in the @@ -71,8 +72,8 @@ The rules are as follows: 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. + 1. A single public key in the `public_key` property. + 2. A list of public keys in the `public_keys` property. 8. Otherwise, reject. 2. If the `sender`'s current membership state is not `join`, reject. diff --git a/content/rooms/fragments/v3-auth-rules.md b/content/rooms/fragments/v3-auth-rules.md index d5da48c5..47aceea3 100644 --- a/content/rooms/fragments/v3-auth-rules.md +++ b/content/rooms/fragments/v3-auth-rules.md @@ -2,11 +2,11 @@ toc_hide: true --- -{{% added-in this=true %}} In room versions 1 and 2, events need a +{{< added-in this=true >}} In room versions 1 and 2, events need a signature from the domain of the `event_id` in order to be considered valid. This room version does not include an `event_id` over federation in the same respect, so does not need a signature from that server. -The event must still be signed by the server denoted by the `sender`, +The event must still be signed by the server denoted by the `sender` property, however. The types of state events that affect authorization are: @@ -26,12 +26,12 @@ the default power level for users in the room. The complete list of rules, as of room version 3, is as follows: 1. If type is `m.room.create`: - 1. If it has any previous events, reject. + 1. If it has any `prev_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. + 4. If `content` has no `creator` property, reject. 5. Otherwise, allow. 2. Considering the event's `auth_events`: 1. If there are duplicate entries for a given `type` and `state_key` pair, @@ -52,7 +52,8 @@ The complete list of rules, as of room version 3, is as follows: 2. If sender's domain doesn't matches `state_key`, reject. 3. Otherwise, allow. 5. If type is `m.room.member`: - 1. If no `state_key` key or `membership` key in `content`, reject. + 1. If there is no `state_key` property, or no `membership` property in + `content`, reject. 2. If `membership` is `join`: 1. If the only previous event is an `m.room.create` and the `state_key` is the creator, allow. @@ -63,11 +64,11 @@ The complete list of rules, as of room version 3, is as follows: 5. If the `join_rule` is `public`, allow. 6. Otherwise, reject. 3. If `membership` is `invite`: - 1. If `content` has `third_party_invite` key: + 1. If `content` has a `third_party_invite` property: 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, + property, reject. + 3. If `signed` does not have `mxid` and `token` properties, reject. 4. If `mxid` does not match `state_key`, reject. 5. If there is no `m.room.third_party_invite` event in the @@ -78,8 +79,8 @@ The complete list of rules, as of room version 3, is as follows: 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. + 1. A single public key in the `public_key` property. + 2. A list of public keys in the `public_keys` property. 8. Otherwise, reject. 2. If the `sender`'s current membership state is not `join`, reject. diff --git a/content/rooms/fragments/v8-auth-rules.md b/content/rooms/fragments/v8-auth-rules.md index f1e0532e..86c3c697 100644 --- a/content/rooms/fragments/v8-auth-rules.md +++ b/content/rooms/fragments/v8-auth-rules.md @@ -2,7 +2,7 @@ toc_hide: true --- -Events must be signed by the server denoted by the `sender` key. +Events must be signed by the server denoted by the `sender` property. `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 @@ -27,12 +27,12 @@ the default power level for users in the room. The rules are as follows: 1. If type is `m.room.create`: - 1. If it has any previous events, reject. + 1. If it has any `prev_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. + 4. If `content` has no `creator` property, reject. 5. Otherwise, allow. 2. Considering the event's `auth_events`: 1. If there are duplicate entries for a given `type` and `state_key` pair, @@ -49,9 +49,10 @@ The rules are as follows: property `m.federate` set to `false`, and the `sender` domain of the event does not match the `sender` domain of the create event, 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 there is no `state_key` property, or no `membership` property in + `content`, reject. + 2. {{< added-in this=true >}} + If `content` has a `join_authorised_via_users_server` property: 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`: @@ -61,7 +62,8 @@ The rules are as follows: 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. If the `join_rule` is `restricted`: + 5. {{< added-in this=true >}} + If the `join_rule` is `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 @@ -70,11 +72,11 @@ The rules are as follows: 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 `content` has a `third_party_invite` property: 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, + property, reject. + 3. If `signed` does not have `mxid` and `token` properties, reject. 4. If `mxid` does not match `state_key`, reject. 5. If there is no `m.room.third_party_invite` event in the @@ -85,8 +87,8 @@ The rules are as follows: 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. + 1. A single public key in the `public_key` property. + 2. A list of public keys in the `public_keys` property. 8. Otherwise, reject. 2. If the `sender`'s current membership state is not `join`, reject. diff --git a/content/rooms/v10.md b/content/rooms/v10.md index d5d294e9..24e45723 100644 --- a/content/rooms/v10.md +++ b/content/rooms/v10.md @@ -74,7 +74,7 @@ correctly structured are rejected under the authorization rules below. ### Authorization rules -Events must be signed by the server denoted by the `sender` key. +Events must be signed by the server denoted by the `sender` property. `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 @@ -99,12 +99,12 @@ the default power level for users in the room. The rules are as follows: 1. If type is `m.room.create`: - 1. If it has any previous events, reject. + 1. If it has any `prev_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. + 4. If `content` has no `creator` property, reject. 5. Otherwise, allow. 2. Considering the event's `auth_events`: 1. If there are duplicate entries for a given `type` and `state_key` pair, @@ -121,7 +121,8 @@ The rules are as follows: property `m.federate` set to `false`, and the `sender` domain of the event does not match the `sender` domain of the create event, reject. 4. If type is `m.room.member`: - 1. If no `state_key` key or `membership` key in `content`, reject. + 1. If there is no `state_key` property, or no `membership` property 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 @@ -143,11 +144,11 @@ The rules are as follows: 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 `content` has a `third_party_invite` property: 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, + property, reject. + 3. If `signed` does not have `mxid` and `token` properties, reject. 4. If `mxid` does not match `state_key`, reject. 5. If there is no `m.room.third_party_invite` event in the @@ -158,8 +159,8 @@ The rules are as follows: 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. + 1. A single public key in the `public_key` property. + 2. A list of public keys in the `public_keys` property. 8. Otherwise, reject. 2. If the `sender`'s current membership state is not `join`, reject. diff --git a/content/rooms/v3.md b/content/rooms/v3.md index 8dd261e8..dd2fd144 100644 --- a/content/rooms/v3.md +++ b/content/rooms/v3.md @@ -89,7 +89,7 @@ The complete structure of a event in a v3 room is shown below. ### Authorization rules -{{% added-in this=true %}} `m.room.redaction` events are no longer +{{< added-in this=true >}} `m.room.redaction` events are no longer explicitly part of the auth rules. They are still subject to the minimum power level rules, but should always fall into "11. Otherwise, allow". Instead of being authorized at the time of receipt, they are @@ -97,7 +97,7 @@ authorized at a later stage: see the [Handling Redactions](#handling-redactions) section below for more information. -{{% rver-fragment name="v3-auth-rules" withVersioning=true %}} +{{< rver-fragment name="v3-auth-rules" withVersioning=true >}} ## Unchanged from v2 diff --git a/content/rooms/v6.md b/content/rooms/v6.md index 0e2e70dc..a76ee98b 100644 --- a/content/rooms/v6.md +++ b/content/rooms/v6.md @@ -55,7 +55,7 @@ of type `m.room.power_levels` now include the content key `notifications`. This new rule takes the place of rule 10.4, which checked the `events` and `users` keys. -Events must be signed by the server denoted by the `sender` key. +Events must be signed by the server denoted by the `sender` property. The types of state events that affect authorization are: @@ -74,12 +74,12 @@ the default power level for users in the room. The rules are as follows: 1. If type is `m.room.create`: - 1. If it has any previous events, reject. + 1. If it has any `prev_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. + 4. If `content` has no `creator` property, reject. 5. Otherwise, allow. 2. Reject if event has `auth_events` that: 1. have duplicate entries for a given `type` and `state_key` pair @@ -90,7 +90,8 @@ The rules are as follows: 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. + 1. If there is no `state_key` property, or no `membership` property in + `content`, reject. 2. If `membership` is `join`: 1. If the only previous event is an `m.room.create` and the `state_key` is the creator, allow. @@ -101,11 +102,11 @@ The rules are as follows: 5. If the `join_rule` is `public`, allow. 6. Otherwise, reject. 3. If `membership` is `invite`: - 1. If `content` has `third_party_invite` key: + 1. If `content` has a `third_party_invite` property: 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, + property, reject. + 3. If `signed` does not have `mxid` and `token` properties, reject. 4. If `mxid` does not match `state_key`, reject. 5. If there is no `m.room.third_party_invite` event in the @@ -116,8 +117,8 @@ The rules are as follows: 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. + 1. A single public key in the `public_key` property. + 2. A list of public keys in the `public_keys` property. 8. Otherwise, reject. 2. If the `sender`'s current membership state is not `join`, reject. diff --git a/content/rooms/v7.md b/content/rooms/v7.md index 8bb4dad2..7bec7755 100644 --- a/content/rooms/v7.md +++ b/content/rooms/v7.md @@ -32,10 +32,10 @@ as do the versions v6 is based upon. ### Authorization rules -{{% added-in this=true %}} For checks performed upon `m.room.member` events, a +{{< added-in this=true >}} For checks performed upon `m.room.member` events, a new point for `membership=knock` is added. -Events must be signed by the server denoted by the `sender` key. +Events must be signed by the server denoted by the `sender` property. `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 @@ -60,12 +60,12 @@ the default power level for users in the room. The rules are as follows: 1. If type is `m.room.create`: - 1. If it has any previous events, reject. + 1. If it has any `prev_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. + 4. If `content` has no `creator` property, reject. 5. Otherwise, allow. 2. Reject if event has `auth_events` that: 1. have duplicate entries for a given `type` and `state_key` pair @@ -76,22 +76,24 @@ The rules are as follows: 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. + 1. If there is no `state_key` property, or no `membership` property in + `content`, reject. 2. 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 + 4. {{< changed-in this=true >}} + If the `join_rule` is `invite` or `knock` then allow if membership state is `invite` or `join`. 5. If the `join_rule` is `public`, allow. 6. Otherwise, reject. 3. If `membership` is `invite`: - 1. If `content` has `third_party_invite` key: + 1. If `content` has `third_party_invite` property: 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, + property, reject. + 3. If `signed` does not have `mxid` and `token` properties, reject. 4. If `mxid` does not match `state_key`, reject. 5. If there is no `m.room.third_party_invite` event in the @@ -102,8 +104,8 @@ The rules are as follows: 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. + 1. A single public key in the `public_key` property. + 2. A list of public keys in the `public_keys` property. 8. Otherwise, reject. 2. If the `sender`'s current membership state is not `join`, reject. @@ -113,7 +115,8 @@ The rules are as follows: the *invite level*, allow. 5. Otherwise, reject. 4. If `membership` is `leave`: - 1. If the `sender` matches `state_key`, allow if and only if + 1. {{< changed-in this=true >}} + 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`, @@ -132,7 +135,8 @@ The rules are as follows: the *ban level*, and the *target user*'s power level is less than the `sender`'s power level, allow. 3. Otherwise, reject. - 6. If `membership` is `knock`: + 6. {{< added-in this=true >}} + If `membership` is `knock`: 1. If the `join_rule` is anything other than `knock`, reject. 2. If `sender` does not match `state_key`, reject. 3. If the `sender`'s current membership is not `ban` or `join`, allow. diff --git a/content/rooms/v8.md b/content/rooms/v8.md index 2a8cf125..ab4cd970 100644 --- a/content/rooms/v8.md +++ b/content/rooms/v8.md @@ -83,11 +83,11 @@ room without invite. Otherwise, the room version inherits all properties of ### Authorization rules -{{% added-in this=true %}} For checks performed upon `m.room.member` events, new +{{< added-in this=true >}} For checks performed upon `m.room.member` events, new points for handling `content.join_authorised_via_users_server` are added (Rule 4.2 and 4.3.5). -{{% rver-fragment name="v8-auth-rules" %}} +{{< rver-fragment name="v8-auth-rules" withVersioning=true >}} ### Redactions diff --git a/content/rooms/v9.md b/content/rooms/v9.md index d4da72de..f6735415 100644 --- a/content/rooms/v9.md +++ b/content/rooms/v9.md @@ -62,7 +62,7 @@ completeness. ### Authorization rules -{{% rver-fragment name="v8-auth-rules" %}} +{{< rver-fragment name="v8-auth-rules" >}} ### State resolution diff --git a/layouts/shortcodes/rver-fragment.html b/layouts/shortcodes/rver-fragment.html index 14a8a027..62434586 100644 --- a/layouts/shortcodes/rver-fragment.html +++ b/layouts/shortcodes/rver-fragment.html @@ -21,5 +21,6 @@ {{ $content := $page.Content }} {{ if not $withVersioning }} {{ $content = (replace $content "[New in this version]" "") }} + {{ $content = (replace $content "[Changed in this version]" "") }} {{ end }} {{ $content | safeHTML }} From 3808a679c148e67c1492d1eee4852c9e94d46144 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Fri, 7 Oct 2022 13:46:37 +0100 Subject: [PATCH 15/16] Fix up description of `knock_room_state` field, which implied the required field was optional (#1276) --- changelogs/client_server/newsfragments/1276.clarification | 1 + data/api/server-server/knocks.yaml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/1276.clarification diff --git a/changelogs/client_server/newsfragments/1276.clarification b/changelogs/client_server/newsfragments/1276.clarification new file mode 100644 index 00000000..ca5f3aea --- /dev/null +++ b/changelogs/client_server/newsfragments/1276.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. \ No newline at end of file diff --git a/data/api/server-server/knocks.yaml b/data/api/server-server/knocks.yaml index 2ef5ceaa..aa388bda 100644 --- a/data/api/server-server/knocks.yaml +++ b/data/api/server-server/knocks.yaml @@ -287,7 +287,7 @@ paths: items: $ref: "../../event-schemas/schema/core-event-schema/stripped_state.yaml" description: |- - An optional list of [stripped state events](/client-server-api/#stripped-state) + A list of [stripped state events](/client-server-api/#stripped-state) to help the initiator of the knock identify the room. example: $ref: "../../event-schemas/examples/knock_room_state.json" From 11cef5417a458c0f6def375c50773304681badae Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Wed, 12 Oct 2022 13:36:02 +0100 Subject: [PATCH 16/16] Clarify auth rules for `m.room.power_levels` events (#1269) --- .../newsfragments/1269.clarification | 1 + content/rooms/fragments/v1-auth-rules.md | 29 +++++++------- content/rooms/fragments/v3-auth-rules.md | 29 +++++++------- content/rooms/fragments/v8-auth-rules.md | 27 +++++++------ content/rooms/v10.md | 35 ++++++++++------- content/rooms/v6.md | 39 +++++++++++-------- content/rooms/v7.md | 27 +++++++------ 7 files changed, 108 insertions(+), 79 deletions(-) create mode 100644 changelogs/room_versions/newsfragments/1269.clarification diff --git a/changelogs/room_versions/newsfragments/1269.clarification b/changelogs/room_versions/newsfragments/1269.clarification new file mode 100644 index 00000000..aa8aa338 --- /dev/null +++ b/changelogs/room_versions/newsfragments/1269.clarification @@ -0,0 +1 @@ +Reword the event auth rules to clarify that users cannot demote other users with the same power level. diff --git a/content/rooms/fragments/v1-auth-rules.md b/content/rooms/fragments/v1-auth-rules.md index 289e40e5..d91aaf23 100644 --- a/content/rooms/fragments/v1-auth-rules.md +++ b/content/rooms/fragments/v1-auth-rules.md @@ -111,29 +111,32 @@ The rules are as follows: 9. If the event has a `state_key` that starts with an `@` and does not match the `sender`, reject. 10. If type is `m.room.power_levels`: - 1. If `users` key in `content` is not a dictionary with keys that + 1. If the `users` property in `content` is not an object with keys that are valid user IDs with values that are integers (or a string that is an integer), 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`, + 3. For the properties `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 + 1. If the current value is greater than the `sender`'s current power level, reject. - 2. If the new value is higher than the `sender`'s current power + 2. If the new value is greater than the `sender`'s current power level, reject. - 4. For each entry being added, changed or removed in both the - `events` and `users` keys: - 1. If the current value is higher than the `sender`'s current + 4. For each entry being changed in, or removed from, the `events` property: + 1. If the current value is greater than the `sender`'s current power level, reject. - 2. If the new value is higher than the `sender`'s current power + 5. For each entry being added to, or changed in, the `events` property: + 1. If the new value is greater 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. + 6. For each entry being changed in, or removed from, the `users` property, + other than the `sender`'s own entry: + 1. If the current value is greater than or equal to the `sender`'s + current power level, reject. + 7. For each entry being added to, or changed in, the `users` property: + 1. If the new value is greater than the `sender`'s current power + level, reject. + 8. Otherwise, allow. 11. If type is `m.room.redaction`: 1. If the `sender`'s power level is greater than or equal to the *redact level*, allow. diff --git a/content/rooms/fragments/v3-auth-rules.md b/content/rooms/fragments/v3-auth-rules.md index 47aceea3..ea1ffc2f 100644 --- a/content/rooms/fragments/v3-auth-rules.md +++ b/content/rooms/fragments/v3-auth-rules.md @@ -118,29 +118,32 @@ The complete list of rules, as of room version 3, is as follows: 9. If the event has a `state_key` that starts with an `@` and does not match the `sender`, reject. 10. If type is `m.room.power_levels`: - 1. If `users` key in `content` is not a dictionary with keys that + 1. If `users` property in `content` is not an object with keys that are valid user IDs with values that are integers (or a string that is an integer), 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`, + 3. For the properties `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 + 1. If the current value is greater than the `sender`'s current power level, reject. - 2. If the new value is higher than the `sender`'s current power + 2. If the new value is greater than the `sender`'s current power level, reject. - 4. For each entry being added, changed or removed in both the - `events` and `users` keys: - 1. If the current value is higher than the `sender`'s current + 4. For each entry being changed in, or removed from, the `events` property: + 1. If the current value is greater than the `sender`'s current power level, reject. - 2. If the new value is higher than the `sender`'s current power + 5. For each entry being added to, or changed in, the `events` property: + 1. If the new value is greater 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. + 6. For each entry being changed in, or removed from, the `users` property, + other than the `sender`'s own entry: + 1. If the current value is greater than or equal to the `sender`'s + current power level, reject. + 7. For each entry being added to, or changed in, the `users` property: + 1. If the new value is greater than the `sender`'s current power + level, reject. + 8. Otherwise, allow. 11. Otherwise, allow. {{% boxes/note %}} diff --git a/content/rooms/fragments/v8-auth-rules.md b/content/rooms/fragments/v8-auth-rules.md index 86c3c697..bb7aabd8 100644 --- a/content/rooms/fragments/v8-auth-rules.md +++ b/content/rooms/fragments/v8-auth-rules.md @@ -132,29 +132,34 @@ The rules are as follows: 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. If `users` key in `content` is not a dictionary with keys that + 1. If the `users` property in `content` is not an object with keys that are valid user IDs with values that are integers (or a string that is an integer), 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`, + 3. For the properties `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 + 4. For each entry being changed in, or removed from, the `events` or + `notifications` properties: + 1. If the current value is greater than the `sender`'s current power level, reject. - 2. If the new value is higher than the `sender`'s current power + 5. For each entry being added to, or changed in the `events` or + `notifications` properties: + 1. If the new value is greater 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. + 6. For each entry being changed in, or removed from, the `users` property, + other than the `sender`'s own entry: + 1. If the current value is greater than or equal to the `sender`'s + current power level, reject. + 7. For each entry being added to, or changed in, the `users` property: + 1. If the new value is greater than the `sender`'s current power + level, reject. + 8. Otherwise, allow. 10. Otherwise, allow. {{% boxes/note %}} diff --git a/content/rooms/v10.md b/content/rooms/v10.md index 24e45723..628f14e1 100644 --- a/content/rooms/v10.md +++ b/content/rooms/v10.md @@ -207,35 +207,40 @@ The rules are as follows: 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`, + If any of the properties `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, + If either of the properties `events` or `notifications` in `content` + are present and not an object with values that are integers, reject. - 3. If `users` key in `content` is not a dictionary with keys that + 3. If the `users` property in `content` is not an obiect 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, + 4. If there is no previous `m.room.power_levels` event in the room, allow. - 3. For the keys `users_default`, `events_default`, `state_default`, + 5. For the properties `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 + 6. For each entry being changed in, or removed from, the `events` or + `notifications` properties: + 1. If the current value is greater than the `sender`'s current power level, reject. - 2. If the new value is higher than the `sender`'s current power + 7. For each entry being added to, or changed in, the `events` or + `notifications` properties: + 1. If the new value is greater 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. + 8. For each entry being changed in, or removed from, the `users` property, + other than the `sender`'s own entry: + 1. If the current value is greater than or equal to the `sender`'s + current power level, reject. + 9. For each entry being added to, or changed in, the `users` property: + 1. If the new value is greater than the `sender`'s current power + level, reject. + 10. Otherwise, allow. 10. Otherwise, allow. {{% boxes/note %}} diff --git a/content/rooms/v6.md b/content/rooms/v6.md index a76ee98b..bcacfef8 100644 --- a/content/rooms/v6.md +++ b/content/rooms/v6.md @@ -46,14 +46,14 @@ fall into "10. Otherwise, allow". Instead of being authorized at the time of receipt, they are authorized at a later stage: see the [Handling Redactions](#handling-redactions) section below for more information. -{{% added-in this=true %}} Rule 4, which related specifically to events +{{< added-in this=true >}} Rule 4, which related specifically to events of type `m.room.aliases`, is removed. `m.room.aliases` events must still pass authorization checks relating to state events. -{{% added-in this=true %}} Additionally, the authorization rules for events -of type `m.room.power_levels` now include the content key `notifications`. -This new rule takes the place of rule 10.4, which checked the `events` and -`users` keys. +{{< added-in this=true >}} Additionally, the authorization rules for events of +type `m.room.power_levels` now include a `notifications` property under +`content`. This updates rules 10.4 and 10.5 (now 9.4 and 9.5), which checked +the `events` property. Events must be signed by the server denoted by the `sender` property. @@ -156,29 +156,36 @@ The rules are as follows: 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. If `users` key in `content` is not a dictionary with keys that + 1. If the `users` property in `content` is not an object with keys that are valid user IDs with values that are integers (or a string that is an integer), 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`, + 3. For the properties `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 + 4. {{< changed-in this="true" >}} + For each entry being changed in, or removed from, the `events` or + `notifications` properties: + 1. If the current value is greater than the `sender`'s current power level, reject. - 2. If the new value is higher than the `sender`'s current power + 5. {{< changed-in this="true" >}} + For each entry being added to, or changed in, the `events` or + `notifications` properties: + 1. If the new value is greater 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. + 6. For each entry being changed in, or removed from, the `users` property, + other than the `sender`'s own entry: + 1. If the current value is greater than or equal to the `sender`'s + current power level, reject. + 7. For each entry being added to, or changed in, the `users` property: + 1. If the new value is greater than the `sender`'s current power + level, reject. + 8. Otherwise, allow. 10. Otherwise, allow. {{% boxes/note %}} diff --git a/content/rooms/v7.md b/content/rooms/v7.md index 7bec7755..3cc77bb3 100644 --- a/content/rooms/v7.md +++ b/content/rooms/v7.md @@ -151,29 +151,34 @@ The rules are as follows: 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. If `users` key in `content` is not a dictionary with keys that + 1. If the `users` property in `content` is not an object with keys that are valid user IDs with values that are integers (or a string that is an integer), 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`, + 3. For the properties `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 + 4. For each entry being changed in, or removed from, the `events` or + `notifications` properties: + 1. If the current value is greater than the `sender`'s current power level, reject. - 2. If the new value is higher than the `sender`'s current power + 5. For each entry being added to, or changed in, the `events` or + `notifications` properties: + 1. If the new value is greater 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. + 6. For each entry being changed in, or removed from, the `users` property, + other than the `sender`'s own entry: + 1. If the current value is greater than or equal to the `sender`'s + current power level, reject. + 7. For each entry being added to, or changed in, the `users` property: + 1. If the new value is greater than the `sender`'s current power + level, reject. + 8. Otherwise, allow.. 10. Otherwise, allow. {{% boxes/note %}}