MSC3925: m.replace aggregation with full event (#3925)
* init m.replace aggregation with full event Signed-off-by: benkuly <kontakt@folivo.net> * Rename tmp.md to 3925-replace-aggregation-with-full-event.md Signed-off-by: benkuly <kontakt@folivo.net> * Update 3925-replace-aggregation-with-full-event.md typos Signed-off-by: benkuly <kontakt@folivo.net> * Update 3925-replace-aggregation-with-full-event.md added MSC number Signed-off-by: benkuly <kontakt@folivo.net> * Update proposals/3925-replace-aggregation-with-full-event.md Co-authored-by: Jonas Platte <jplatte+git@posteo.de> Signed-off-by: benkuly <kontakt@folivo.net> * Update proposals/3925-replace-aggregation-with-full-event.md Co-authored-by: Jonas Platte <jplatte+git@posteo.de> Signed-off-by: benkuly <kontakt@folivo.net> * Update proposals/3925-replace-aggregation-with-full-event.md Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * redact instead of delete * Update proposals/3925-replace-aggregation-with-full-event.md Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Update proposals/3925-replace-aggregation-with-full-event.md Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * word wrap 80 * remove immutable argument * add alternative from https://github.com/matrix-org/matrix-spec/issues/1299#issuecomment-1290332433 * add json example * shorter version of the actual proposal Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * describe the actual reason, why encrypted events cannot be replaced Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * mention discussion * typo * Update proposals/3925-replace-aggregation-with-full-event.md Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Update proposals/3925-replace-aggregation-with-full-event.md Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Update proposals/3925-replace-aggregation-with-full-event.md Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Update proposals/3925-replace-aggregation-with-full-event.md Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Update proposals/3925-replace-aggregation-with-full-event.md Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Update proposals/3925-replace-aggregation-with-full-event.md Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Update proposals/3925-replace-aggregation-with-full-event.md Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * clarify inconsistent behavior with replaced contents * Update proposals/3925-replace-aggregation-with-full-event.md Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Update proposals/3925-replace-aggregation-with-full-event.md Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Update proposals/3925-replace-aggregation-with-full-event.md Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * Update proposals/3925-replace-aggregation-with-full-event.md Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * clarify inconsistent behavior and put it into introduction * remove superfluous event content field * add some details to potential issues suggested by @richvdh --------- Signed-off-by: benkuly <kontakt@folivo.net> Co-authored-by: Jonas Platte <jplatte+git@posteo.de> Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>pull/3972/head
parent
26f5effe45
commit
13935ec33b
@ -0,0 +1,140 @@
|
|||||||
|
# MSC3925: m.replace aggregation with full event
|
||||||
|
|
||||||
|
As [currently specified](https://spec.matrix.org/v1.4/client-server-api/#server-side-replacement-of-content),
|
||||||
|
servers should replace the content of events that have been replaced via an `m.replace`
|
||||||
|
relation.
|
||||||
|
|
||||||
|
There are some issues with this requirement:
|
||||||
|
|
||||||
|
* Changing the fundamental concept of mostly immutable events is confusing. The server
|
||||||
|
can respond with different event contents for the same `event_id`.
|
||||||
|
* If an event with `m.replace` relation is redacted, clients need to
|
||||||
|
detect if the original content was replaced, and possibly need to fetch the
|
||||||
|
original content.
|
||||||
|
* Servers cannot replace the original event content for encrypted events (because the
|
||||||
|
replacement content is inside the encrypted body).
|
||||||
|
See [matrix-spec#1299](https://github.com/matrix-org/matrix-spec/issues/1299).
|
||||||
|
* Replacing the content can lead to inconsistent behavior on clients which don't
|
||||||
|
support replacing events.
|
||||||
|
Assume that we have this timeline on the server:
|
||||||
|
- `{"event_id": "E1", "content": {"body": "1"}}`
|
||||||
|
- `{"event_id": "E2", "content": {"body": "* 2", "m.new_content": {"body": "2"}}` // replaces `E1`
|
||||||
|
|
||||||
|
A `/sync` is done after `E2`. We will have this timeline on a client:
|
||||||
|
- `{"event_id": "E1", "content": {"body": "2"}}`
|
||||||
|
- `{"event_id": "E2", "content": {"body": "* 2"}`
|
||||||
|
|
||||||
|
Although `2` is a replaced body it does not have a `*`. This looks to the
|
||||||
|
user as if it is the original content of the event.
|
||||||
|
|
||||||
|
|
||||||
|
## Proposal
|
||||||
|
|
||||||
|
The following two changes are proposed:
|
||||||
|
1. The [server-side aggregation of `m.replace` relationships](https://spec.matrix.org/v1.4/client-server-api/#server-side-aggregation-of-mreplace-relationships)
|
||||||
|
is extended to be the entire content of the most recent replacement event, formatted
|
||||||
|
as described in [Room Event Format](https://spec.matrix.org/v1.4/client-server-api/#room-event-format).
|
||||||
|
This ensures that the client will always have the most recent edit without having to
|
||||||
|
fetch it from the server.
|
||||||
|
2. Servers should no longer replace the original content of an event as described
|
||||||
|
at https://spec.matrix.org/v1.4/client-server-api/#server-side-replacement-of-content.
|
||||||
|
|
||||||
|
For an original event:
|
||||||
|
|
||||||
|
```json5
|
||||||
|
{
|
||||||
|
"event_id": "$original_event",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"content": {
|
||||||
|
"body": "I really like cake",
|
||||||
|
"msgtype": "m.text",
|
||||||
|
"formatted_body": "I really like cake"
|
||||||
|
}
|
||||||
|
// irrelevant fields not shown
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
With a replacing event:
|
||||||
|
|
||||||
|
```json5
|
||||||
|
{
|
||||||
|
"event_id": "$edit_event",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"content": {
|
||||||
|
"body": "* I really like *chocolate* cake",
|
||||||
|
"msgtype": "m.text",
|
||||||
|
"m.new_content": {
|
||||||
|
"body": "I really like *chocolate* cake",
|
||||||
|
"msgtype": "m.text"
|
||||||
|
},
|
||||||
|
"m.relates_to": {
|
||||||
|
"rel_type": "m.replace",
|
||||||
|
"event_id": "$original_event_id"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// irrelevant fields not shown
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
This is how the original event would look like after the replacement:
|
||||||
|
|
||||||
|
```json5
|
||||||
|
{
|
||||||
|
"event_id": "$original_event",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"content": {
|
||||||
|
"body": "I really like cake",
|
||||||
|
"msgtype": "m.text",
|
||||||
|
"formatted_body": "I really like cake"
|
||||||
|
},
|
||||||
|
"unsigned": {
|
||||||
|
"m.relations": {
|
||||||
|
"m.replace": {
|
||||||
|
"event_id": "$edit_event",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"content": {
|
||||||
|
"body": "* I really like *chocolate* cake",
|
||||||
|
"msgtype": "m.text",
|
||||||
|
"m.new_content": {
|
||||||
|
"body": "I really like *chocolate* cake",
|
||||||
|
"msgtype": "m.text"
|
||||||
|
},
|
||||||
|
"m.relates_to": {
|
||||||
|
"rel_type": "m.replace",
|
||||||
|
"event_id": "$original_event_id"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// irrelevant fields not shown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// irrelevant fields not shown
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Potential issues
|
||||||
|
|
||||||
|
* There could be clients which rely on the current behavior:
|
||||||
|
* element-web relied on it until [matrix-org/matrix-js-sdk#3045](https://github.com/matrix-org/matrix-js-sdk/pull/3045)
|
||||||
|
* The failure mode is: suppose we have an event E, which was subsequently replaced by an event E'. Now, if jumped back to a bit of timeline that contains E but not E', then clients unaware of this change will show the original event E rather than the edited content E'. But: That is an edge-case and it already happens for events other than `m.room.message` (including encrypted events) due to [matrix-org/synapse#12503](https://github.com/matrix-org/synapse/issues/12503).
|
||||||
|
* It will be harder for clients which do not support replacing events to get
|
||||||
|
the current content of an event: currently they can just look at `content.body`.
|
||||||
|
However, there is an inconsistent behavior for clients that do not support
|
||||||
|
replacing events (see above).
|
||||||
|
|
||||||
|
## Alternatives
|
||||||
|
|
||||||
|
One [suggestion](https://github.com/matrix-org/matrix-spec/issues/1299#issuecomment-1290332433) is
|
||||||
|
to have the server return the complete replacement event instead of the original event. However, that would
|
||||||
|
break compatibility with existing clients and is a more invasive change.
|
||||||
|
|
||||||
|
## Security considerations
|
||||||
|
|
||||||
|
None currently foreseen.
|
||||||
|
|
||||||
|
## Unstable prefix
|
||||||
|
|
||||||
|
No unstable prefix is currently proposed.
|
Loading…
Reference in New Issue