-
Notifications
You must be signed in to change notification settings - Fork 389
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MSC4115: membership information on events #4115
Changes from 1 commit
2545ccf
191e182
b63d565
6b0776c
3ab18b5
bbcedf8
7142bc3
a282730
283a7e9
638d299
6ef6feb
6db3b97
b297b8b
8b880df
ed20d83
9323f48
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
# MSC4115: membership metadata on events | ||
|
||
## Background | ||
|
||
Consider the following Event DAG: | ||
|
||
```mermaid | ||
graph BT; | ||
B[Bob joins]; | ||
B-->A; | ||
C-->A; | ||
D-->B; | ||
D-->C; | ||
``` | ||
|
||
Bob has joined a room, but at the same time, another user has sent a message | ||
`C`. | ||
|
||
Depending on the configuration of the room, Bob's server may serve the event | ||
`C` to Bob's client. However, if the room is encrypted, Bob will not be on the | ||
recipient list for `C` and the sender will not share the message key with Bob, | ||
even though, in an absolute time reference, `C` may have been sent at a later | ||
timestamp than Bob's join. | ||
richvdh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Unfortunately, there is no way for Bob's client to reliably distinguish events | ||
such as `A` and `C` that were sent "before" he joined (and he should therefore | ||
not expect to decrypt) from those such as `D` that were sent later. | ||
andybalaam marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
This issue is discussed in more detail at | ||
https://github.com/element-hq/element-meta/issues/2268. | ||
|
||
As a partial solution to this problem, we propose a mechanism for servers to | ||
inform clients of room membership at each event. | ||
richvdh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Proposal | ||
|
||
The `unsigned` structure contains data added to an event by a homeserver when | ||
serving an event over the client-server API. (See | ||
[specification](https://spec.matrix.org/v1.9/client-server-api/#definition-clientevent)). | ||
|
||
We propose adding a new property, `membership`, which should contain the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thoroughly unconvinced that Suggestions? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's clear enough. The sender must be in the room at the time they sent the event, so it wouldn't make sense to send the sender's membership. |
||
membership of the user making the request, according to the state of the room | ||
at the time of the event being returned. If the user had no membership at that | ||
point (ie, they had yet to join or be invited), `membership` is set to `leave`. | ||
Any changes caused by the event itself (ie, if the event itself is a | ||
`m.room.member` event for the requesting user) are *excluded*. | ||
|
||
In other words: servers should follow the following algorithm when serving an | ||
event E to a user Alice: | ||
|
||
1. Consider the room state just *before* event E landed (accounting for state | ||
resolution accross E's `prev_events`, but not E itself). | ||
2. Within the state, find the event M with type `m.room.member` and `state_key` | ||
set to Alice's user ID. | ||
3. * If no such event exists, set `membership` to `leave`. | ||
* Otherwise, set `membership` to the value of the `membership` property of | ||
the content of M. | ||
|
||
The new property should be *required* for all servers implementing a version of | ||
the spec that includes this MSC. However, clients needing to maintain | ||
compatibility with earlier versions of the spec will need to consider it as | ||
optional. | ||
|
||
For the avoidance of doubt, the new `membership` property is added to all | ||
Client-Server API endpoints that return events, including | ||
[`/sync`](https://spec.matrix.org/v1.9/client-server-api/#get_matrixclientv3sync), | ||
[`/messages`](https://spec.matrix.org/v1.9/client-server-api/#get_matrixclientv3roomsroomidmessages), | ||
[`/state`](https://spec.matrix.org/v1.9/client-server-api/#get_matrixclientv3roomsroomidstate), | ||
and deprecated endpoints such as | ||
[`/events`](https://spec.matrix.org/v1.9/client-server-api/#get_matrixclientv3events) | ||
and | ||
[`/initialSync`](https://spec.matrix.org/v1.9/client-server-api/#get_matrixclientv3events). | ||
richvdh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
Example event including the new property: | ||
|
||
```json | ||
{ | ||
"content": { | ||
"membership": "join" | ||
}, | ||
"event_id": "$26RqwJMLw-yds1GAH_QxjHRC1Da9oasK0e5VLnck_45", | ||
"origin_server_ts": 1632489532305, | ||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org", | ||
"sender": "@example:example.org", | ||
"state_key": "@user:example.org", | ||
"type": "m.room.member", | ||
"unsigned": { | ||
"age": 1567437, | ||
"membership": "leave", | ||
KitsuneRal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"redacted_because": { | ||
"content": { | ||
"reason": "spam" | ||
}, | ||
"event_id": "$Nhl3rsgHMjk-DjMJANawr9HHAhLg4GcoTYrSiYYGqEE", | ||
"origin_server_ts": 1632491098485, | ||
"redacts": "$26RqwJMLw-yds1GAH_QxjHRC1Da9oasK0e5VLnck_45", | ||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org", | ||
"sender": "@moderator:example.org", | ||
"type": "m.room.redaction", | ||
"unsigned": { | ||
"membership": "leave", | ||
"age": 1257 | ||
} | ||
} | ||
} | ||
} | ||
richvdh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
|
||
## Potential issues | ||
|
||
* Depending on server implementation, it may be expensive or difficult to | ||
implement? Feedback welcome from HS authors on this point. | ||
richvdh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Alternatives | ||
|
||
https://github.com/element-hq/element-meta/issues/2268#issuecomment-1904069895 | ||
proposes use of a Bloom filter — or possibly several Bloom filters — to | ||
mitigate this problem in a more general way. It is the opinion of the author of | ||
this MSC that there is room for both approaches. | ||
|
||
## Security considerations | ||
|
||
None foreseen. | ||
|
||
## Unstable prefix | ||
|
||
|
||
## Dependencies | ||
|
||
None. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementation requirements: