From 091d1f032c02f6d00cb8fb93179f41582ec3fd0e Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 23 Aug 2022 15:27:28 +0100 Subject: [PATCH] Apply suggestions from code review Co-authored-by: Travis Ralston --- .../modules/event_replacements.md | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/content/client-server-api/modules/event_replacements.md b/content/client-server-api/modules/event_replacements.md index 2547e5d7..9eb267f5 100644 --- a/content/client-server-api/modules/event_replacements.md +++ b/content/client-server-api/modules/event_replacements.md @@ -7,7 +7,7 @@ type: module {{% added-in v="1.4" %}} Event replacements, or "message edit events", are events that use an [event -relationship](http://localhost:1313/client-server-api/#forming-relationships-between-events) +relationship](#forming-relationships-between-events) with a `rel_type` of `m.replace`, which indicates that the original event is intended to be replaced. @@ -46,17 +46,17 @@ an event's content property, such as `formatted_body` (see [`m.room.message` There are a number of requirements on message edit events, which must be satisfied for the replacement to be considered valid: * As with all event relationships, the original event and replacement event - must have the same `room_id` (i.e. it is not possible to send an event in + must have the same `room_id` (i.e. you cannot send an event in one room and then an edited version in a different room). * The original event and replacement event must have the same `sender` (i.e. you cannot edit someone else's messages). - * The replacement and original events must have the same `type` (i.e. editing - an event cannot change its type). + * The replacement and original events must have the same `type` (i.e. you + cannot change the original event's type). - * Neither the replacement nor original events may have a `state_key` property - (i.e. it is not possible to edit a state event). + * The replacement and original events must not have a `state_key` property + (i.e. you cannot edit state events at all). * The original event must not, itself, have a `rel_type` of `m.replace` (i.e. you cannot edit an edit — though you can send multiple edits for a @@ -70,7 +70,7 @@ replacement event (the content of the original should not be replaced, and the edit should not be included in the server-side aggregation). Note that the [`msgtype`](#mroommessage-msgtypes) property of replacement -`m.room.message` events need *not* be the same as in the original event. For +`m.room.message` events does *not* need to be the same as in the original event. For example, it is legitimate to replace an `m.text` event with an `m.emote`. #### Editing encrypted events @@ -82,8 +82,6 @@ must be sent in the unencrypted (cleartext) part of the event. For example, a replacement for an encrypted event might look like this: -For example, an encrypted replacement event might look like this: - ```json { "type": "m.room.encrypted", @@ -98,7 +96,7 @@ For example, an encrypted replacement event might look like this: "session_id": "", "ciphertext": "" } - // ... + // irrelevant fields not shown } ``` @@ -121,10 +119,14 @@ For example, an encrypted replacement event might look like this: Note that: - * There is no `m.relates_to` property in the encrypted payload. (Any such property would be ignored.) - * There is no `m.new_content` property in the cleartext content of the `m.room.encrypted` event. (Again, any such property would be ignored.) + * There is no `m.relates_to` property in the encrypted payload. If there was, it would be ignored. + * There is no `m.new_content` property in the cleartext content of the `m.room.encrypted` event. As above, if there was then it would be ignored. -The payload of an encrypted replacement event must be encrypted as normal, including ratcheting any [Megolm](#mmegolmv1aes-sha2) session as normal. The original Megolm ratchet entry should **not** be re-used. +{{% boxes/note %}} +The payload of an encrypted replacement event must be encrypted as normal, including +ratcheting any [Megolm](#mmegolmv1aes-sha2) session as normal. The original Megolm +ratchet entry should **not** be re-used. +{{% /boxes/note %}} #### Applying `m.new_content` @@ -199,13 +201,13 @@ most recent event is determined by comparing `origin_server_ts`; if two or more replacement events have identical `origin_server_ts`, the event with the lexicographically largest `event_id` is treated as more recent. -This aggregation is bundled into the `unsigned/m.relations` property of any +This aggregation is bundled under the `unsigned` property as `m.relations` for any event that is the target of an `m.replace` relationship. For example: ```json { "event_id": "$original_event_id", - // ... + // irrelevant fields not shown "unsigned": { "m.relations": { "m.replace": { @@ -219,13 +221,13 @@ event that is the target of an `m.replace` relationship. For example: ``` If the original event is -[redacted](http://localhost:1313/client-server-api/#redactions), any +[redacted](#redactions), any `m.replace` relationship should **not** be bundled with it (whether or not any subsequent replacements are themselves redacted). Note that this behaviour is specific to the `m.replace` relationship. See also [redactions of edited events](#redactions-of-edited-events) below. -#### Server-side replacement of content +##### Server-side replacement of content Whenever an `m.replace` is to be bundled with an event as above, the server should also modify the content of the original event according to the @@ -237,9 +239,9 @@ be bundled, as described above). #### Client behaviour -Clients can often ignore `m.replace` events, since any events the server -returns via the C-S API will be updated by the server to account for subsequent -edits. +Clients can often ignore `m.replace` events, because any events returned +by the server to the client will be updated by the server to account for +subsequent edits. However, clients should apply the replacement themselves when the server is unable to do so. This happens in the following situations: @@ -251,7 +253,7 @@ unable to do so. This happens in the following situations: Client authors are reminded to take note of the requirements for [Validity of message edit events](#validity-of-message-edit-events), and to ignore any -invalid edit events that may be received. +invalid edit events that are received. ##### Permalinks @@ -274,7 +276,8 @@ subsequent edits, from the visible timeline. In this situation, homeservers will return an empty `content` for the original event as with any other redacted event, and as [above](#server-side-aggregation-of-mreplace-relationships) the replacement -events will not be bundled with the original event. +events will not be bundled with the original event. Note that the subsequent edits are +not actually redacted themselves: they simply serve no purpose within the visible timeline. #### Edits of replies @@ -283,13 +286,13 @@ Some particular constraints apply to events which replace a * In contrast to the original reply, there should be no `m.in_reply_to` property in the the `m.relates_to` object, since it would be redundant (see - [Applying `m.new_content`](/#applying-mnew_content) above, which notes that + [Applying `m.new_content`](#applying-mnew_content) above, which notes that the original event's `m.relates_to` is preserved), as well as being contrary to the spirit of the event relationships mechanism which expects only one "parent" per event. * `m.new_content` should **not** contain any [reply - fallback](https://spec.matrix.org/v1.3/client-server-api/#fallbacks-for-rich-replies), + fallback](#fallbacks-for-rich-replies), since it is assumed that any client which can handle edits can also display replies natively. However, the `content` of the replacement event should provide fallback content for clients which support neither rich replies nor edits. @@ -299,6 +302,7 @@ An example of an edit to a reply is as follows: ```json { "type": "m.room.message", + // irrelevant fields not shown "content": { "body": "> <@alice:example.org> question\n\n* reply", "msgtype": "m.text",