From 642f4e14f9dfb8fe604c9d8d03698330a3a78dc2 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sun, 4 Jul 2021 21:25:06 +0200 Subject: [PATCH 01/27] Room summary proposal Signed-off-by: Nicolas Werner --- proposals/3266-room-summary.md | 161 +++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 proposals/3266-room-summary.md diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md new file mode 100644 index 00000000000..58e3cbf1386 --- /dev/null +++ b/proposals/3266-room-summary.md @@ -0,0 +1,161 @@ +# MSC3266: Room Summary API + +Quite a few clients and tools have a need preview a room: + +- A client may want to show the room in the roomlist, when showing a space. +- matrix.to may want to show avatar and name of a room. +- Nextcloud may want to list the names and avatars of your `/joined_rooms` when + asking where to share the media. +- A client may want to preview a room, when hovering a room alias, id or after + clicking on it. +- A client may want to preview a room, when the user is trying to knock on it or + to show pending knocks. +- A traveller bot may use that to show a room summary on demand without actually + keeping the whole room state around and having to subscribe to /sync (or + using the appservice API). + +There are a few ways to request a room summary, but they only support some of +the use cases. The spaces summary API +([MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946)) only provides +limited control over what rooms to summarize and only works for rooms in spaces. +`{roomid}/initialSync` and `{roomid}/state/{event_type}` don't work over +federation and are much heavier than necessary or need a lot of http calls for +each room. + +## Proposal + +A new client-server API, which allows you to fetch a summary of a room by id or +alias and a corresponding server-server API, to fetch a summary over federation. + +### Client-Server API + +The API returns the summary of the specified room, if the room could be found +and the client should be able to view its contents according to the join_rules, +history visibility, space membership and similar rules outlined in +[MSC3173](https://github.com/matrix-org/matrix-doc/pull/3173) as well as if the +user is already a member of that room. + +A request could look like this: + +``` +GET /_matrix/client/r0/rooms/{roomidOrAlias}/summary? + via=matrix.org& + via=neko.dev +``` + +- `roomidOrAlias` can be the roomid or an alias to a room. +- `via` are servers, that should be tried to request a summary from, if it can't + be generated locally. These can be from a matrix URI, matrix.to link or a + `m.space.child` event for example. + +A response includes the stripped state in the following format: + +```json5 +{ + room_id: "!ol19s:bleecker.street", + avatar_url: "mxc://bleecker.street/CHEDDARandBRIE", + guest_can_join: false, + name: "CHEESE", + num_joined_members: 37, + topic: "Tasty tasty cheese", + world_readable: true, + join_rules: "public", + room_type: "m.space", + is_direct: true, + membership: "invite", + is_encrypted: true, +} +``` + +These are the same fields as those returned by `/publicRooms`, with a few +additions: `room_type`, `is_direct`, `membership` and `is_encrypted`. + +All those fields are already accessible as the stripped state according to +[MSC3173](https://github.com/matrix-org/matrix-doc/pull/3173), with the +exception of `membership` and potentially `is_direct`. + +#### Rationale and description of reponse fields + +| fieldname | description | rationale | +| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| room_id | Id of the room | Useful, when the API is called with an alias or to disambiguate multiple responses clientside. | +| avatar_url | Avatar of the room | Copied from `publicRooms`. | +| guest_can_join | If guests can join the room. | Copied from `publicRooms`. | +| name | Name of the room | Copied from `publicRooms`. | +| num_joined_members | Member count of the room | Copied from `publicRooms`. | +| topic | Topic of the room | Copied from `publicRooms`. | +| world_readable | If the room history can be read without joining. | Copied from `publicRooms`. | +| join_rules | Join rules of the room | Copied from `publicRooms`. | +| room_type | Optional. Type of the room, if any, i.e. `m.space` | Used to distinguish rooms from spaces. | +| is_direct | Optional. If this is a direct chat. The server should use the usual rules to figure out, if this is a direct chat, not just look in the create event. | May be used in previews to distinguish normal rooms from DMs. | +| membership | The current membership of this user in the room. Usually `leave` if the room is fetched over federation. | Useful to distinguish invites and knocks from joined rooms. | +| is_encrypted | Optional. If the room is encrypted. This is already accessible as stripped state. Currently a bool, but maybe the algorithm makes more sense? | Some users may only want to join encrypted rooms or clients may want to filter out encrypted rooms, if they don't support encryption. | + +It should be possible to call this API without authentication, but servers may +rate limit how often they fetch information over federation more heavily, if the +user is unauthenticated. Also the fields `membership` and `is_direct` will be +missing. + +### Server-Server API + +The Server-Server API mirrors the Client-Server API, with a few exceptions. The +`membership` and `is_direct` fields are never present. No `via` field is +necessary on the request, since servers should not forward the request to other +servers. + +The server can't know, which user is requesting the summary. As such it should +apply visibility rules to check if any user on the requesting server would have +access to the summary. + +A request would be made as follows: + +``` +GET /_matrix/federation/v1/summary/{roomidOrAlias} +``` + +The requesting server should cache the response to this request. + +## Potential issues + +### Perfomance + +Clients may start calling this API very often instead of using the batched +summary API (MSC2946) for spaces or caching the state received via `/sync`. +Looking up all the state events required for this API may cause performance +issues in that case. + +To mitigate that, servers are recommended to cache the response for this API and +apply rate limiting if necessary. + +## Alternatives + +- The spaces summary API could be used, but it doesn't work for arbitrary rooms + and you always need to pass the parent space, without any control over the + rooms being returned. +- The `/state` API could be used, but the response is much bigger than needed, + can't be cached as easily and may need more requests. This also doesn't work + over federation (yet). +- Peeking could solve this too, but with additional overhead and + [MSC2753](https://github.com/matrix-org/matrix-doc/pull/2753) is much more + complex. + +## Security considerations + +This API may leak data, if implemented incorrectly or malicious servers could +return wrong results for a summary. + +Those are the same concerns as on [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946) +or [MSC3173](https://github.com/matrix-org/matrix-doc/pull/3173). + +This API could also used for denial of service type attacks. Appropriate +ratelimiting and caching should be able to mitigate that. + +## Unstable prefix + +This uses the `im.nheko.summary` unstable prefix instead of the `summary` key in +the request paths during the MSC phase. As a result: + +- the client API will be + `/_matrix/client/unstable/rooms/{roomidOrAlias}/im.nheko.summary` +- the federation API will be + `/_matrix/federation/unstable/im.nheko.summary/{roomidOrAlias}` From 188b6e59025f29019f1f028f82b657b252fbe43c Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 5 Jul 2021 21:11:33 +0200 Subject: [PATCH 02/27] Remove alias resolution step from the federation API --- proposals/3266-room-summary.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index 58e3cbf1386..fdb790233b8 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -110,11 +110,15 @@ access to the summary. A request would be made as follows: ``` -GET /_matrix/federation/v1/summary/{roomidOrAlias} +GET /_matrix/federation/v1/summary/{roomid} ``` The requesting server should cache the response to this request. +Note that the federation API only allows roomids and should use the usual +protocols to resolve the alias first, since it makes no sense to let anything +but the authoritive server for that alias resolve it. + ## Potential issues ### Perfomance @@ -158,4 +162,4 @@ the request paths during the MSC phase. As a result: - the client API will be `/_matrix/client/unstable/rooms/{roomidOrAlias}/im.nheko.summary` - the federation API will be - `/_matrix/federation/unstable/im.nheko.summary/{roomidOrAlias}` + `/_matrix/federation/unstable/im.nheko.summary/{roomid}` From dc5b372f6f381f217dc86940cb6692c496dc86c0 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 12 Jul 2021 16:51:04 +0200 Subject: [PATCH 03/27] Reference #688 in the alternatives section Signed-off-by: Nicolas Werner --- proposals/3266-room-summary.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index fdb790233b8..cef305be6a3 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -136,6 +136,21 @@ apply rate limiting if necessary. - The spaces summary API could be used, but it doesn't work for arbitrary rooms and you always need to pass the parent space, without any control over the rooms being returned. +- For joined rooms, the `/sync` API can be used to get a summary for all joined + rooms. Apart from not working for unjoined rooms, like knocks, invites and + space children, `/sync` is very heavy for the server and the client needs to + cobble together information from the `state`, `timeline` and + [`summary`](https://github.com/matrix-org/matrix-doc/issues/688) sections to + calculate the room name, topic and other fields provided in this MSC. + Furthermore, the membership counts in the summary field are only included, if + the client is using lazy loading. + This MSC provides similar information as calling `/sync`, but it uses the + stripped state, which is needed to allow this to work for unjoined rooms and + it excludes `m.heroes` as well as membership events, since those are not + included in the stripped state of a room. (A client can call + `/joined_members` to receive those if needed. It may still make sense to + include heroes, but solving the security implications with that may better + be left to a separate MSC.) - The `/state` API could be used, but the response is much bigger than needed, can't be cached as easily and may need more requests. This also doesn't work over federation (yet). @@ -151,7 +166,7 @@ return wrong results for a summary. Those are the same concerns as on [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946) or [MSC3173](https://github.com/matrix-org/matrix-doc/pull/3173). -This API could also used for denial of service type attacks. Appropriate +This API could also be used for denial of service type attacks. Appropriate ratelimiting and caching should be able to mitigate that. ## Unstable prefix From 975ece57dbe85a72e498c6852501a169c6347758 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 14 Jul 2021 20:09:07 +0200 Subject: [PATCH 04/27] Remove `is_direct` from response Signed-off-by: Nicolas Werner --- proposals/3266-room-summary.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index cef305be6a3..1c513ef280d 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -61,18 +61,17 @@ A response includes the stripped state in the following format: world_readable: true, join_rules: "public", room_type: "m.space", - is_direct: true, membership: "invite", is_encrypted: true, } ``` These are the same fields as those returned by `/publicRooms`, with a few -additions: `room_type`, `is_direct`, `membership` and `is_encrypted`. +additions: `room_type`, `membership` and `is_encrypted`. All those fields are already accessible as the stripped state according to [MSC3173](https://github.com/matrix-org/matrix-doc/pull/3173), with the -exception of `membership` and potentially `is_direct`. +exception of `membership`. #### Rationale and description of reponse fields @@ -87,21 +86,19 @@ exception of `membership` and potentially `is_direct`. | world_readable | If the room history can be read without joining. | Copied from `publicRooms`. | | join_rules | Join rules of the room | Copied from `publicRooms`. | | room_type | Optional. Type of the room, if any, i.e. `m.space` | Used to distinguish rooms from spaces. | -| is_direct | Optional. If this is a direct chat. The server should use the usual rules to figure out, if this is a direct chat, not just look in the create event. | May be used in previews to distinguish normal rooms from DMs. | | membership | The current membership of this user in the room. Usually `leave` if the room is fetched over federation. | Useful to distinguish invites and knocks from joined rooms. | | is_encrypted | Optional. If the room is encrypted. This is already accessible as stripped state. Currently a bool, but maybe the algorithm makes more sense? | Some users may only want to join encrypted rooms or clients may want to filter out encrypted rooms, if they don't support encryption. | It should be possible to call this API without authentication, but servers may rate limit how often they fetch information over federation more heavily, if the -user is unauthenticated. Also the fields `membership` and `is_direct` will be +user is unauthenticated. Also the fields `membership` will be missing. ### Server-Server API The Server-Server API mirrors the Client-Server API, with a few exceptions. The -`membership` and `is_direct` fields are never present. No `via` field is -necessary on the request, since servers should not forward the request to other -servers. +`membership` fields is never present. No `via` field is necessary on the +request, since servers should not forward the request to other servers. The server can't know, which user is requesting the summary. As such it should apply visibility rules to check if any user on the requesting server would have From d148acfdf063e43dd6a66f93066c164716d4eda3 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 14 Jul 2021 20:12:15 +0200 Subject: [PATCH 05/27] Fix unstable prefixes for implementations which keep the prefix and rest of the path separate Signed-off-by: Nicolas Werner --- proposals/3266-room-summary.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index 1c513ef280d..738388268e2 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -168,10 +168,10 @@ ratelimiting and caching should be able to mitigate that. ## Unstable prefix -This uses the `im.nheko.summary` unstable prefix instead of the `summary` key in -the request paths during the MSC phase. As a result: +This uses the `im.nheko.summary` unstable prefix. As such the paths are prefixed +with `unstable/im.nheko.summary`. - the client API will be - `/_matrix/client/unstable/rooms/{roomidOrAlias}/im.nheko.summary` + `/_matrix/client/unstable/im.nheko.summary/rooms/{roomidOrAlias}/summary` - the federation API will be - `/_matrix/federation/unstable/im.nheko.summary/{roomid}` + `/_matrix/federation/unstable/im.nheko.summary/summary/{roomid}` From 67768639252ba7101f146b3f5f32b363f2536355 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 14 Jul 2021 20:17:24 +0200 Subject: [PATCH 06/27] Add allowed_room_ids field That way the requesting server knows, if any user would have access to that room and it can forward the room to the user. Signed-off-by: Nicolas Werner --- proposals/3266-room-summary.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index 738388268e2..1a3f1247013 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -99,8 +99,14 @@ missing. The Server-Server API mirrors the Client-Server API, with a few exceptions. The `membership` fields is never present. No `via` field is necessary on the request, since servers should not forward the request to other servers. - -The server can't know, which user is requesting the summary. As such it should +The request also contains an additional field `allowed_room_ids`, which list of +room IDs which give access to this room per +[MSC3083](https://github.com/matrix-org/matrix-doc/pull/3083). This is needed so +that the requesting server knows if the user is allowed to see this room. If +the history is visible without space membership, this field can be ignored by +the requesting server and doesn't need to be present. + +The server can't know which user is requesting the summary. As such it should apply visibility rules to check if any user on the requesting server would have access to the summary. From df376a3cf29472c07e987149515ff99b1eaeaf6c Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 14 Jul 2021 20:47:21 +0200 Subject: [PATCH 07/27] Extend rationale for additional fields to reference MSC2946 Also explain that membership is already accessible information. Signed-off-by: Nicolas Werner --- proposals/3266-room-summary.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index 1a3f1247013..e42755f105d 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -71,7 +71,11 @@ additions: `room_type`, `membership` and `is_encrypted`. All those fields are already accessible as the stripped state according to [MSC3173](https://github.com/matrix-org/matrix-doc/pull/3173), with the -exception of `membership`. +exception of `membership`. These are the same fields as in +[MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946) apart from the +adition of the membership field. The membership can already be accessed by a +client anyway, this API just provides it as a convenience. + #### Rationale and description of reponse fields From 43eecf0d9de976c6b4ac29800dc1f210fd630d36 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 14 Jul 2021 20:55:48 +0200 Subject: [PATCH 08/27] Add bulk API as an alternative Signed-off-by: Nicolas Werner --- proposals/3266-room-summary.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index e42755f105d..244779ee5c8 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -140,9 +140,9 @@ apply rate limiting if necessary. ## Alternatives -- The spaces summary API could be used, but it doesn't work for arbitrary rooms - and you always need to pass the parent space, without any control over the - rooms being returned. +- The spaces summary API could be used, but it returns more data than necessary + by default (but it can be limited to just 1 room) such as all the + `m.space.child` events in a space. - For joined rooms, the `/sync` API can be used to get a summary for all joined rooms. Apart from not working for unjoined rooms, like knocks, invites and space children, `/sync` is very heavy for the server and the client needs to @@ -164,6 +164,12 @@ apply rate limiting if necessary. - Peeking could solve this too, but with additional overhead and [MSC2753](https://github.com/matrix-org/matrix-doc/pull/2753) is much more complex. +- This API could take a list of rooms with included `via`s for each room instead + of a single room (as a POST request). This may have performance benefits for + the federation API and a client could then easily request a summary of all + joined rooms. It could still request the summary of a single room by just + including only a single room in the POST or a convenience GET could be + provided by the server (that looks like this proposal). ## Security considerations From 66fee2305465c681327b7e5fba43e919029a7090 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 6 Oct 2021 18:42:14 +0200 Subject: [PATCH 09/27] Remove federation API and address feedback - Add some additional rationale to some things. - Federation API now reuses MSC 2946 - roomid -> roomId - Move it out of /rooms, because it allows using an alias Signed-off-by: Nicolas Werner --- proposals/3266-room-summary.md | 67 ++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index 244779ee5c8..f2dab90731b 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -38,12 +38,14 @@ user is already a member of that room. A request could look like this: ``` -GET /_matrix/client/r0/rooms/{roomidOrAlias}/summary? +GET /_matrix/client/r0/summary/{roomIdOrAlias}? via=matrix.org& via=neko.dev ``` -- `roomidOrAlias` can be the roomid or an alias to a room. +(This is not under `/rooms`, because it can be used with an alias. + +- `roomIdOrAlias` can be the roomid or an alias to a room. - `via` are servers, that should be tried to request a summary from, if it can't be generated locally. These can be from a matrix URI, matrix.to link or a `m.space.child` event for example. @@ -100,31 +102,27 @@ missing. ### Server-Server API -The Server-Server API mirrors the Client-Server API, with a few exceptions. The -`membership` fields is never present. No `via` field is necessary on the -request, since servers should not forward the request to other servers. -The request also contains an additional field `allowed_room_ids`, which list of -room IDs which give access to this room per -[MSC3083](https://github.com/matrix-org/matrix-doc/pull/3083). This is needed so -that the requesting server knows if the user is allowed to see this room. If -the history is visible without space membership, this field can be ignored by -the requesting server and doesn't need to be present. +For the federation API +[MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946) is reused. This +provides almost all the information needed in this MSC, but it also provides a +few additional fields and one level of children of this room. -The server can't know which user is requesting the summary. As such it should -apply visibility rules to check if any user on the requesting server would have -access to the summary. +One small modifications is needed to that endpoint, so that it can be reused +for this MSC: -A request would be made as follows: +- the `allowed_room_ids` field is added to the `room` object too. Originally + this was only added for child rooms, but this makes it impossible to + calculate the access rules for the top most room, as such this should be a + reasonable addition. -``` -GET /_matrix/federation/v1/summary/{roomid} -``` +In theory one could also add the `max_depth` parameter with allowed values of 0 +and 1, so that child rooms are excluded, but this performance optimization does +not seem necessary at this time and could be added at any later point while +degrading gracefully. -The requesting server should cache the response to this request. - -Note that the federation API only allows roomids and should use the usual -protocols to resolve the alias first, since it makes no sense to let anything -but the authoritive server for that alias resolve it. +(Originally there was a separate federation API for this, but it was decided +that lowering the duplication on the federation side is the way to go by the +author.) ## Potential issues @@ -142,7 +140,7 @@ apply rate limiting if necessary. - The spaces summary API could be used, but it returns more data than necessary by default (but it can be limited to just 1 room) such as all the - `m.space.child` events in a space. + `m.space.child` events in a space. (We do reuse the federation API now.) - For joined rooms, the `/sync` API can be used to get a summary for all joined rooms. Apart from not working for unjoined rooms, like knocks, invites and space children, `/sync` is very heavy for the server and the client needs to @@ -160,7 +158,10 @@ apply rate limiting if necessary. be left to a separate MSC.) - The `/state` API could be used, but the response is much bigger than needed, can't be cached as easily and may need more requests. This also doesn't work - over federation (yet). + over federation (yet). The variant of this API, which returns the full state + of a room, also does not return stripped events, which prevents it from + being used by non-members. The event for specific events DOES return + stripped events, but could not provide a member count for a room. - Peeking could solve this too, but with additional overhead and [MSC2753](https://github.com/matrix-org/matrix-doc/pull/2753) is much more complex. @@ -170,6 +171,14 @@ apply rate limiting if necessary. joined rooms. It could still request the summary of a single room by just including only a single room in the POST or a convenience GET could be provided by the server (that looks like this proposal). +- [MSC3429](https://github.com/matrix-org/matrix-doc/pull/3429) is an + alternative implementation, but it chooses a different layout. While this + layout might make sense in the future, it is inconsistent with the APIs + already in use, harder to use for clients (iterate array over directly + including the interesting fields) and can't reuse the federation API. In my + opinion an MSC in the future, that bases all summary APIs on a list of + stripped events seems like the more reasonable approach to me and would make + the APIs more extensible. ## Security considerations @@ -188,6 +197,8 @@ This uses the `im.nheko.summary` unstable prefix. As such the paths are prefixed with `unstable/im.nheko.summary`. - the client API will be - `/_matrix/client/unstable/im.nheko.summary/rooms/{roomidOrAlias}/summary` -- the federation API will be - `/_matrix/federation/unstable/im.nheko.summary/summary/{roomid}` + `/_matrix/client/unstable/im.nheko.summary/{roomIdOrAlias}`. + +Earlier versions of this MSC used + `/_matrix/client/unstable/im.nheko.summary/rooms/{roomIdOrAlias}/summary`, + but this was a mistake. Endpoints using aliases shouldn't be under /rooms. From 469b77b734cf513cda3561619a3651c2c036cb24 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 20 Oct 2021 13:42:31 +0200 Subject: [PATCH 10/27] fix prefixes again --- proposals/3266-room-summary.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index f2dab90731b..3de3dfddb18 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -197,8 +197,8 @@ This uses the `im.nheko.summary` unstable prefix. As such the paths are prefixed with `unstable/im.nheko.summary`. - the client API will be - `/_matrix/client/unstable/im.nheko.summary/{roomIdOrAlias}`. + `/_matrix/client/unstable/im.nheko.summary/summary/{roomIdOrAlias}`. -Earlier versions of this MSC used +Some implementations still use `/_matrix/client/unstable/im.nheko.summary/rooms/{roomIdOrAlias}/summary`, - but this was a mistake. Endpoints using aliases shouldn't be under /rooms. + but this was a mistake in this MSC. Endpoints using aliases shouldn't be under /rooms. From 04f807baf84bda104ea55ad3243dcd0dcfcac22a Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 20 Oct 2021 13:50:56 +0200 Subject: [PATCH 11/27] Remove extensions to federation API since that MSC is amended now Signed-off-by: Nicolas Werner --- proposals/3266-room-summary.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index 3de3dfddb18..458073da5d9 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -104,17 +104,9 @@ missing. For the federation API [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946) is reused. This -provides almost all the information needed in this MSC, but it also provides a +provides all the information needed in this MSC, but it also provides a few additional fields and one level of children of this room. -One small modifications is needed to that endpoint, so that it can be reused -for this MSC: - -- the `allowed_room_ids` field is added to the `room` object too. Originally - this was only added for child rooms, but this makes it impossible to - calculate the access rules for the top most room, as such this should be a - reasonable addition. - In theory one could also add the `max_depth` parameter with allowed values of 0 and 1, so that child rooms are excluded, but this performance optimization does not seem necessary at this time and could be added at any later point while From f1233c4881e9860898827dc62987460535b9380c Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 3 Dec 2021 23:23:19 +0100 Subject: [PATCH 12/27] Fix minor inaccuracy about the spaces sumary api --- proposals/3266-room-summary.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index 458073da5d9..d40f02d19cb 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -17,10 +17,10 @@ Quite a few clients and tools have a need preview a room: There are a few ways to request a room summary, but they only support some of the use cases. The spaces summary API ([MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946)) only provides -limited control over what rooms to summarize and only works for rooms in spaces. -`{roomid}/initialSync` and `{roomid}/state/{event_type}` don't work over -federation and are much heavier than necessary or need a lot of http calls for -each room. +limited control over what rooms to summarize and returns a lot more data than +necessary. `{roomid}/initialSync` and `{roomid}/state/{event_type}` don't work +over federation and are much heavier than necessary or need a lot of http calls +for each room. ## Proposal From 5fc2f5b4a5f9f61dfd77a75a99acda0e9489563d Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 2 May 2022 19:48:52 +0200 Subject: [PATCH 13/27] Add encryption field back --- proposals/3266-room-summary.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index d40f02d19cb..546ba7790c5 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -93,7 +93,7 @@ client anyway, this API just provides it as a convenience. | join_rules | Join rules of the room | Copied from `publicRooms`. | | room_type | Optional. Type of the room, if any, i.e. `m.space` | Used to distinguish rooms from spaces. | | membership | The current membership of this user in the room. Usually `leave` if the room is fetched over federation. | Useful to distinguish invites and knocks from joined rooms. | -| is_encrypted | Optional. If the room is encrypted. This is already accessible as stripped state. Currently a bool, but maybe the algorithm makes more sense? | Some users may only want to join encrypted rooms or clients may want to filter out encrypted rooms, if they don't support encryption. | +| encryption | Optional. If the room is encrypted this specified the algorithm used for this room. This is already accessible as stripped state. Currently a bool, but maybe the algorithm makes more sense? | Some users may only want to join encrypted rooms or clients may want to filter out encrypted rooms, if they don't support encryption. | It should be possible to call this API without authentication, but servers may rate limit how often they fetch information over federation more heavily, if the @@ -107,6 +107,8 @@ For the federation API provides all the information needed in this MSC, but it also provides a few additional fields and one level of children of this room. +Additionally the `encryption` field is added to the response for each room. + In theory one could also add the `max_depth` parameter with allowed values of 0 and 1, so that child rooms are excluded, but this performance optimization does not seem necessary at this time and could be added at any later point while @@ -194,3 +196,6 @@ with `unstable/im.nheko.summary`. Some implementations still use `/_matrix/client/unstable/im.nheko.summary/rooms/{roomIdOrAlias}/summary`, but this was a mistake in this MSC. Endpoints using aliases shouldn't be under /rooms. + +Additionally the field `encryption` in the summaries is prefixed with +`im.nheko.summary` as well since it is new. From 9e41b451cc6764dbd46fd290d2bb0268ed24ef75 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 2 May 2022 20:02:02 +0200 Subject: [PATCH 14/27] Add room version field Signed-off-by: Nicolas Werner --- proposals/3266-room-summary.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index 546ba7790c5..8d0d2c6aa05 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -64,12 +64,13 @@ A response includes the stripped state in the following format: join_rules: "public", room_type: "m.space", membership: "invite", - is_encrypted: true, + encryption: "m.megolm.v100", + version: 9001, } ``` These are the same fields as those returned by `/publicRooms`, with a few -additions: `room_type`, `membership` and `is_encrypted`. +additions: `room_type`, `membership`, `version` and `encryption`. All those fields are already accessible as the stripped state according to [MSC3173](https://github.com/matrix-org/matrix-doc/pull/3173), with the @@ -92,6 +93,7 @@ client anyway, this API just provides it as a convenience. | world_readable | If the room history can be read without joining. | Copied from `publicRooms`. | | join_rules | Join rules of the room | Copied from `publicRooms`. | | room_type | Optional. Type of the room, if any, i.e. `m.space` | Used to distinguish rooms from spaces. | +| version | Optional (for historical reasons). Version of the room. | Can be used by clients to show incompatibilities with a room early. | | membership | The current membership of this user in the room. Usually `leave` if the room is fetched over federation. | Useful to distinguish invites and knocks from joined rooms. | | encryption | Optional. If the room is encrypted this specified the algorithm used for this room. This is already accessible as stripped state. Currently a bool, but maybe the algorithm makes more sense? | Some users may only want to join encrypted rooms or clients may want to filter out encrypted rooms, if they don't support encryption. | @@ -100,6 +102,11 @@ rate limit how often they fetch information over federation more heavily, if the user is unauthenticated. Also the fields `membership` will be missing. +#### Modifications to `/_matrix/client/v1/rooms/{roomId}/hierarchy` + +For symmetry the `version` and `encryption` fields are also added to the +`/hierarchy` API. + ### Server-Server API For the federation API @@ -107,7 +114,8 @@ For the federation API provides all the information needed in this MSC, but it also provides a few additional fields and one level of children of this room. -Additionally the `encryption` field is added to the response for each room. +Additionally the `encryption` and `version` fields are added to the responses for +each room. In theory one could also add the `max_depth` parameter with allowed values of 0 and 1, so that child rooms are excluded, but this performance optimization does @@ -197,5 +205,5 @@ Some implementations still use `/_matrix/client/unstable/im.nheko.summary/rooms/{roomIdOrAlias}/summary`, but this was a mistake in this MSC. Endpoints using aliases shouldn't be under /rooms. -Additionally the field `encryption` in the summaries is prefixed with -`im.nheko.summary` as well since it is new. +Additionally the fields `encryption` and `version` in the summaries are prefixed +with `im.nheko.summary` as well since it is new. From cab37e58a9c70512c73d5b047991bf04ce3d99e3 Mon Sep 17 00:00:00 2001 From: "DeepBlueV7.X" Date: Mon, 2 May 2022 18:05:51 +0000 Subject: [PATCH 15/27] Apply suggestions from code review Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Co-authored-by: Alexey Rusakov --- proposals/3266-room-summary.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index 8d0d2c6aa05..2cc479aa0c6 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -80,7 +80,7 @@ adition of the membership field. The membership can already be accessed by a client anyway, this API just provides it as a convenience. -#### Rationale and description of reponse fields +#### Rationale and description of response fields | fieldname | description | rationale | | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | @@ -128,7 +128,7 @@ author.) ## Potential issues -### Perfomance +### Performance Clients may start calling this API very often instead of using the batched summary API (MSC2946) for spaces or caching the state received via `/sync`. @@ -156,8 +156,9 @@ apply rate limiting if necessary. it excludes `m.heroes` as well as membership events, since those are not included in the stripped state of a room. (A client can call `/joined_members` to receive those if needed. It may still make sense to - include heroes, but solving the security implications with that may better - be left to a separate MSC.) + include heroes so that clients could construct a human-friendly room display + name in case both the name and the canonical alias are absent; but solving + the security implications with that may better be left to a separate MSC. - The `/state` API could be used, but the response is much bigger than needed, can't be cached as easily and may need more requests. This also doesn't work over federation (yet). The variant of this API, which returns the full state From a93190f65e7567f06ba1ca22b04e35a697c97877 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 2 May 2022 20:33:35 +0200 Subject: [PATCH 16/27] Add a bit more reasoning --- proposals/3266-room-summary.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index 2cc479aa0c6..1d704bf3614 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -13,6 +13,8 @@ Quite a few clients and tools have a need preview a room: - A traveller bot may use that to show a room summary on demand without actually keeping the whole room state around and having to subscribe to /sync (or using the appservice API). +- A client can use this to knock on a room instead of joining it when the user + tries to join my room alias or link. There are a few ways to request a room summary, but they only support some of the use cases. The spaces summary API @@ -167,7 +169,10 @@ apply rate limiting if necessary. stripped events, but could not provide a member count for a room. - Peeking could solve this too, but with additional overhead and [MSC2753](https://github.com/matrix-org/matrix-doc/pull/2753) is much more - complex. + complex. You need to add a peek and remember to remove it. For many usecases + you just want to do one request to get info about a room, no history and no + updates. This MSC solves that by reusing the existing hierarchy APIs, + returns a lightweight response and provides a convenient API instead. - This API could take a list of rooms with included `via`s for each room instead of a single room (as a POST request). This may have performance benefits for the federation API and a client could then easily request a summary of all From 8186b72210bda4e20021aa19ade95f07770fa09d Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 4 May 2022 20:24:05 +0200 Subject: [PATCH 17/27] version -> room_version --- proposals/3266-room-summary.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index 1d704bf3614..41ecb2c7748 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -67,12 +67,12 @@ A response includes the stripped state in the following format: room_type: "m.space", membership: "invite", encryption: "m.megolm.v100", - version: 9001, + room_version: "9001", } ``` These are the same fields as those returned by `/publicRooms`, with a few -additions: `room_type`, `membership`, `version` and `encryption`. +additions: `room_type`, `membership`, `room_version` and `encryption`. All those fields are already accessible as the stripped state according to [MSC3173](https://github.com/matrix-org/matrix-doc/pull/3173), with the @@ -95,7 +95,7 @@ client anyway, this API just provides it as a convenience. | world_readable | If the room history can be read without joining. | Copied from `publicRooms`. | | join_rules | Join rules of the room | Copied from `publicRooms`. | | room_type | Optional. Type of the room, if any, i.e. `m.space` | Used to distinguish rooms from spaces. | -| version | Optional (for historical reasons). Version of the room. | Can be used by clients to show incompatibilities with a room early. | +| room_version | Optional (for historical reasons). Version of the room. | Can be used by clients to show incompatibilities with a room early. | | membership | The current membership of this user in the room. Usually `leave` if the room is fetched over federation. | Useful to distinguish invites and knocks from joined rooms. | | encryption | Optional. If the room is encrypted this specified the algorithm used for this room. This is already accessible as stripped state. Currently a bool, but maybe the algorithm makes more sense? | Some users may only want to join encrypted rooms or clients may want to filter out encrypted rooms, if they don't support encryption. | @@ -106,7 +106,7 @@ missing. #### Modifications to `/_matrix/client/v1/rooms/{roomId}/hierarchy` -For symmetry the `version` and `encryption` fields are also added to the +For symmetry the `room_version` and `encryption` fields are also added to the `/hierarchy` API. ### Server-Server API @@ -116,8 +116,8 @@ For the federation API provides all the information needed in this MSC, but it also provides a few additional fields and one level of children of this room. -Additionally the `encryption` and `version` fields are added to the responses for -each room. +Additionally the `encryption` and `room_version` fields are added to the +responses for each room. In theory one could also add the `max_depth` parameter with allowed values of 0 and 1, so that child rooms are excluded, but this performance optimization does @@ -211,5 +211,6 @@ Some implementations still use `/_matrix/client/unstable/im.nheko.summary/rooms/{roomIdOrAlias}/summary`, but this was a mistake in this MSC. Endpoints using aliases shouldn't be under /rooms. -Additionally the fields `encryption` and `version` in the summaries are prefixed -with `im.nheko.summary` as well since it is new. +Additionally the fields `encryption` and `room_version` in the summaries are +prefixed with `im.nheko.summary` as well since it is new. The latter might still +be called `im.nheko.summary.version` in some implementations. From 1a8ecffde03db95fefb58c729862bc8d1e6d2b3a Mon Sep 17 00:00:00 2001 From: "DeepBlueV7.X" Date: Tue, 19 Jul 2022 15:11:23 +0000 Subject: [PATCH 18/27] Apply suggestions from code review Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/3266-room-summary.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index 41ecb2c7748..5c79a1f7a3d 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -17,8 +17,7 @@ Quite a few clients and tools have a need preview a room: tries to join my room alias or link. There are a few ways to request a room summary, but they only support some of -the use cases. The spaces summary API -([MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946)) only provides +the use cases. The [spaces hierarchy API](https://spec.matrix.org/v1.3/client-server-api/#get_matrixclientv1roomsroomidhierarchy) only provides limited control over what rooms to summarize and returns a lot more data than necessary. `{roomid}/initialSync` and `{roomid}/state/{event_type}` don't work over federation and are much heavier than necessary or need a lot of http calls @@ -27,7 +26,7 @@ for each room. ## Proposal A new client-server API, which allows you to fetch a summary of a room by id or -alias and a corresponding server-server API, to fetch a summary over federation. +alias, and a corresponding server-server API to fetch a summary over federation. ### Client-Server API @@ -48,7 +47,7 @@ GET /_matrix/client/r0/summary/{roomIdOrAlias}? (This is not under `/rooms`, because it can be used with an alias. - `roomIdOrAlias` can be the roomid or an alias to a room. -- `via` are servers, that should be tried to request a summary from, if it can't +- `via` are servers that should be tried to request a summary from, if it can't be generated locally. These can be from a matrix URI, matrix.to link or a `m.space.child` event for example. @@ -74,7 +73,7 @@ A response includes the stripped state in the following format: These are the same fields as those returned by `/publicRooms`, with a few additions: `room_type`, `membership`, `room_version` and `encryption`. -All those fields are already accessible as the stripped state according to +`room_type`, `room_version` and `encryption` are already accessible as part of the stripped state according to [MSC3173](https://github.com/matrix-org/matrix-doc/pull/3173), with the exception of `membership`. These are the same fields as in [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946) apart from the @@ -86,7 +85,7 @@ client anyway, this API just provides it as a convenience. | fieldname | description | rationale | | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | -| room_id | Id of the room | Useful, when the API is called with an alias or to disambiguate multiple responses clientside. | +| room_id | Id of the room | Useful when the API is called with an alias or to disambiguate multiple responses clientside. | | avatar_url | Avatar of the room | Copied from `publicRooms`. | | guest_can_join | If guests can join the room. | Copied from `publicRooms`. | | name | Name of the room | Copied from `publicRooms`. | @@ -125,8 +124,7 @@ not seem necessary at this time and could be added at any later point while degrading gracefully. (Originally there was a separate federation API for this, but it was decided -that lowering the duplication on the federation side is the way to go by the -author.) +by the author that lowering the duplication on the federation side is the way to go.) ## Potential issues From 82d8f3bf89330dde57c747d29936950200b00fd6 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Tue, 19 Jul 2022 18:01:33 +0200 Subject: [PATCH 19/27] Try to address review comments Signed-off-by: Nicolas Werner --- proposals/3266-room-summary.md | 78 ++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index 5c79a1f7a3d..7ad0c4c1bd5 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -31,15 +31,20 @@ alias, and a corresponding server-server API to fetch a summary over federation. ### Client-Server API The API returns the summary of the specified room, if the room could be found -and the client should be able to view its contents according to the join_rules, -history visibility, space membership and similar rules outlined in -[MSC3173](https://github.com/matrix-org/matrix-doc/pull/3173) as well as if the -user is already a member of that room. +and the client should be able to view its contents according to the same rules +[`/hierarchy`](https://spec.matrix.org/v1.3/client-server-api/#server-behaviour-19) +endpoint. This is generally described as being a "potential joiner", which +includes rules such as being a member of a room that allows joining a +[`restricted`](https://spec.matrix.org/v1.3/client-server-api/#restricted-rooms), +the room being +[knockable](https://spec.matrix.org/v1.3/client-server-api/#knocking-on-rooms), +public or you already being a member. For unauthenticated requests a response +should only be returned if the room is publically accessible. A request could look like this: ``` -GET /_matrix/client/r0/summary/{roomIdOrAlias}? +GET /_matrix/client/v1/summary/{roomIdOrAlias}? via=matrix.org& via=neko.dev ``` @@ -62,7 +67,7 @@ A response includes the stripped state in the following format: num_joined_members: 37, topic: "Tasty tasty cheese", world_readable: true, - join_rules: "public", + join_rule: "public", room_type: "m.space", membership: "invite", encryption: "m.megolm.v100", @@ -73,35 +78,41 @@ A response includes the stripped state in the following format: These are the same fields as those returned by `/publicRooms`, with a few additions: `room_type`, `membership`, `room_version` and `encryption`. -`room_type`, `room_version` and `encryption` are already accessible as part of the stripped state according to -[MSC3173](https://github.com/matrix-org/matrix-doc/pull/3173), with the -exception of `membership`. These are the same fields as in -[MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946) apart from the -adition of the membership field. The membership can already be accessed by a -client anyway, this API just provides it as a convenience. +`room_type`, `room_version` and `encryption` are already accessible as part of +the stripped state according to +https://spec.matrix.org/v1.3/client-server-api/#stripped-state , with the +exception of `membership`. These are the same fields as in the response to +[`/hierarchy`](https://spec.matrix.org/v1.3/client-server-api/#get_matrixclientv1roomsroomidhierarchy) +apart from the addition of the `room_type`, `membership`, `room_version` and +`encryption` fields. The membership can already be accessed by a client anyway, +this API just provides it as a convenience. #### Rationale and description of response fields | fieldname | description | rationale | | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | -| room_id | Id of the room | Useful when the API is called with an alias or to disambiguate multiple responses clientside. | -| avatar_url | Avatar of the room | Copied from `publicRooms`. | -| guest_can_join | If guests can join the room. | Copied from `publicRooms`. | -| name | Name of the room | Copied from `publicRooms`. | -| num_joined_members | Member count of the room | Copied from `publicRooms`. | -| topic | Topic of the room | Copied from `publicRooms`. | -| world_readable | If the room history can be read without joining. | Copied from `publicRooms`. | -| join_rules | Join rules of the room | Copied from `publicRooms`. | +| room_id | Required. Id of the room | Useful when the API is called with an alias or to disambiguate multiple responses clientside. | +| avatar_url | Optional. Avatar of the room | Copied from `publicRooms`. | +| guest_can_join | Required. If guests can join the room. | Copied from `publicRooms`. | +| name | Optional. Name of the room | Copied from `publicRooms`. | +| num_joined_members | Required. Member count of the room | Copied from `publicRooms`. | +| topic | Optional. Topic of the room | Copied from `publicRooms`. | +| world_readable | Required. If the room history can be read without joining. | Copied from `publicRooms`. | +| join_rule | Optional. Join rules of the room | Copied from `publicRooms`. | | room_type | Optional. Type of the room, if any, i.e. `m.space` | Used to distinguish rooms from spaces. | | room_version | Optional (for historical reasons). Version of the room. | Can be used by clients to show incompatibilities with a room early. | -| membership | The current membership of this user in the room. Usually `leave` if the room is fetched over federation. | Useful to distinguish invites and knocks from joined rooms. | +| membership | Optional (1). The current membership of this user in the room. Usually `leave` if the room is fetched over federation. | Useful to distinguish invites and knocks from joined rooms. | | encryption | Optional. If the room is encrypted this specified the algorithm used for this room. This is already accessible as stripped state. Currently a bool, but maybe the algorithm makes more sense? | Some users may only want to join encrypted rooms or clients may want to filter out encrypted rooms, if they don't support encryption. | It should be possible to call this API without authentication, but servers may rate limit how often they fetch information over federation more heavily, if the -user is unauthenticated. Also the fields `membership` will be -missing. +user is unauthenticated. + +(1) The field `membership` will not be present when called unauthenticated, but +is required when called authenticated. It should be `leave` if the server +doesn't know the users membership state (for example if the server is not known +to the local server). #### Modifications to `/_matrix/client/v1/rooms/{roomId}/hierarchy` @@ -110,10 +121,11 @@ For symmetry the `room_version` and `encryption` fields are also added to the ### Server-Server API -For the federation API -[MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946) is reused. This -provides all the information needed in this MSC, but it also provides a -few additional fields and one level of children of this room. +For the +[`/hierarchy`](https://spec.matrix.org/v1.3/server-server-api/#get_matrixfederationv1hierarchyroomid) +federation API is reused. This provides (with a few changes) all the information +needed in this MSC, but it also provides a few additional fields and one level +of children of this room. Additionally the `encryption` and `room_version` fields are added to the responses for each room. @@ -130,8 +142,9 @@ by the author that lowering the duplication on the federation side is the way to ### Performance -Clients may start calling this API very often instead of using the batched -summary API (MSC2946) for spaces or caching the state received via `/sync`. +Clients may start calling this API very often instead of using the +[`/hierarchy`](https://spec.matrix.org/v1.3/client-server-api/#get_matrixclientv1roomsroomidhierarchy) +for spaces or caching the state received via `/sync`. Looking up all the state events required for this API may cause performance issues in that case. @@ -140,9 +153,12 @@ apply rate limiting if necessary. ## Alternatives -- The spaces summary API could be used, but it returns more data than necessary +- The + [`/hierarchy`](https://spec.matrix.org/v1.3/client-server-api/#get_matrixclientv1roomsroomidhierarchy) + API could be used, but it returns more data than necessary by default (but it can be limited to just 1 room) such as all the - `m.space.child` events in a space. (We do reuse the federation API now.) + `m.space.child` events in a space, but also is missing the room version, + membership and the encryption field. (We do reuse the federation API now.) - For joined rooms, the `/sync` API can be used to get a summary for all joined rooms. Apart from not working for unjoined rooms, like knocks, invites and space children, `/sync` is very heavy for the server and the client needs to From 208a58cda993af65af7b0fbf7bd379d33281dd61 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sun, 24 Jul 2022 11:20:45 +0200 Subject: [PATCH 20/27] Fix incorrect statement about encryption being a bool Signed-off-by: Nicolas Werner --- proposals/3266-room-summary.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index 7ad0c4c1bd5..ecc169ce986 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -103,7 +103,7 @@ this API just provides it as a convenience. | room_type | Optional. Type of the room, if any, i.e. `m.space` | Used to distinguish rooms from spaces. | | room_version | Optional (for historical reasons). Version of the room. | Can be used by clients to show incompatibilities with a room early. | | membership | Optional (1). The current membership of this user in the room. Usually `leave` if the room is fetched over federation. | Useful to distinguish invites and knocks from joined rooms. | -| encryption | Optional. If the room is encrypted this specified the algorithm used for this room. This is already accessible as stripped state. Currently a bool, but maybe the algorithm makes more sense? | Some users may only want to join encrypted rooms or clients may want to filter out encrypted rooms, if they don't support encryption. | +| encryption | Optional. If the room is encrypted this specified the algorithm used for this room. This is already accessible as stripped state. | Some users may only want to join encrypted rooms or clients may want to filter out encrypted rooms, if they don't support encryption or not this algorithm. | It should be possible to call this API without authentication, but servers may rate limit how often they fetch information over federation more heavily, if the From 33f3733e63219f16aeaf713c6bb7629436ba9bfe Mon Sep 17 00:00:00 2001 From: "DeepBlueV7.X" Date: Tue, 26 Jul 2022 21:51:00 +0000 Subject: [PATCH 21/27] Apply suggestions from code review Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/3266-room-summary.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index ecc169ce986..49285139d0b 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -31,7 +31,7 @@ alias, and a corresponding server-server API to fetch a summary over federation. ### Client-Server API The API returns the summary of the specified room, if the room could be found -and the client should be able to view its contents according to the same rules +and the client should be able to view its contents according to the same rules as the [`/hierarchy`](https://spec.matrix.org/v1.3/client-server-api/#server-behaviour-19) endpoint. This is generally described as being a "potential joiner", which includes rules such as being a member of a room that allows joining a @@ -39,7 +39,7 @@ includes rules such as being a member of a room that allows joining a the room being [knockable](https://spec.matrix.org/v1.3/client-server-api/#knocking-on-rooms), public or you already being a member. For unauthenticated requests a response -should only be returned if the room is publically accessible. +should only be returned if the room is publicly accessible. A request could look like this: @@ -92,7 +92,7 @@ this API just provides it as a convenience. | fieldname | description | rationale | | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | -| room_id | Required. Id of the room | Useful when the API is called with an alias or to disambiguate multiple responses clientside. | +| room_id | Required. Id of the room | Useful when the API is called with an alias. | | avatar_url | Optional. Avatar of the room | Copied from `publicRooms`. | | guest_can_join | Required. If guests can join the room. | Copied from `publicRooms`. | | name | Optional. Name of the room | Copied from `publicRooms`. | From a5bc9ef6943c7b07d9a3d97077205dca33db55a9 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 27 Jul 2022 00:12:25 +0200 Subject: [PATCH 22/27] Split up the big alternatives section --- proposals/3266-room-summary.md | 143 +++++++++++++++++++++------------ 1 file changed, 90 insertions(+), 53 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index 49285139d0b..bca61c888b7 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -101,7 +101,7 @@ this API just provides it as a convenience. | world_readable | Required. If the room history can be read without joining. | Copied from `publicRooms`. | | join_rule | Optional. Join rules of the room | Copied from `publicRooms`. | | room_type | Optional. Type of the room, if any, i.e. `m.space` | Used to distinguish rooms from spaces. | -| room_version | Optional (for historical reasons). Version of the room. | Can be used by clients to show incompatibilities with a room early. | +| room_version | Optional (for historical reasons (2)). Version of the room. | Can be used by clients to show incompatibilities with a room early. | | membership | Optional (1). The current membership of this user in the room. Usually `leave` if the room is fetched over federation. | Useful to distinguish invites and knocks from joined rooms. | | encryption | Optional. If the room is encrypted this specified the algorithm used for this room. This is already accessible as stripped state. | Some users may only want to join encrypted rooms or clients may want to filter out encrypted rooms, if they don't support encryption or not this algorithm. | @@ -111,8 +111,16 @@ user is unauthenticated. (1) The field `membership` will not be present when called unauthenticated, but is required when called authenticated. It should be `leave` if the server -doesn't know the users membership state (for example if the server is not known -to the local server). +doesn't know about the room, since for all other membership states the server +would know about the room already. + +(2) Originally the `/hierarchy` endpoint didn't return the room version. It is +however a useful field, especially when you are considering to join a room. It +would also help with the +[validation of `/hierarchy` responses](https://github.com/matrix-org/synapse/blob/57d334a13d983406ea452dfa203bbe4837509c4e/synapse/handlers/room_summary.py#L662). +So until this MSC is supported by servers, the field will be missing over +federation and can't be added by the local server. After a certain migration +period this field could be made a required field. #### Modifications to `/_matrix/client/v1/rooms/{roomId}/hierarchy` @@ -135,8 +143,9 @@ and 1, so that child rooms are excluded, but this performance optimization does not seem necessary at this time and could be added at any later point while degrading gracefully. -(Originally there was a separate federation API for this, but it was decided -by the author that lowering the duplication on the federation side is the way to go.) +(Originally there was a separate federation API for this, but it was decided by +the author that lowering the duplication on the federation side is the way to +go.) ## Potential issues @@ -153,54 +162,82 @@ apply rate limiting if necessary. ## Alternatives -- The - [`/hierarchy`](https://spec.matrix.org/v1.3/client-server-api/#get_matrixclientv1roomsroomidhierarchy) - API could be used, but it returns more data than necessary - by default (but it can be limited to just 1 room) such as all the - `m.space.child` events in a space, but also is missing the room version, - membership and the encryption field. (We do reuse the federation API now.) -- For joined rooms, the `/sync` API can be used to get a summary for all joined - rooms. Apart from not working for unjoined rooms, like knocks, invites and - space children, `/sync` is very heavy for the server and the client needs to - cobble together information from the `state`, `timeline` and - [`summary`](https://github.com/matrix-org/matrix-doc/issues/688) sections to - calculate the room name, topic and other fields provided in this MSC. - Furthermore, the membership counts in the summary field are only included, if - the client is using lazy loading. - This MSC provides similar information as calling `/sync`, but it uses the - stripped state, which is needed to allow this to work for unjoined rooms and - it excludes `m.heroes` as well as membership events, since those are not - included in the stripped state of a room. (A client can call - `/joined_members` to receive those if needed. It may still make sense to - include heroes so that clients could construct a human-friendly room display - name in case both the name and the canonical alias are absent; but solving - the security implications with that may better be left to a separate MSC. -- The `/state` API could be used, but the response is much bigger than needed, - can't be cached as easily and may need more requests. This also doesn't work - over federation (yet). The variant of this API, which returns the full state - of a room, also does not return stripped events, which prevents it from - being used by non-members. The event for specific events DOES return - stripped events, but could not provide a member count for a room. -- Peeking could solve this too, but with additional overhead and - [MSC2753](https://github.com/matrix-org/matrix-doc/pull/2753) is much more - complex. You need to add a peek and remember to remove it. For many usecases - you just want to do one request to get info about a room, no history and no - updates. This MSC solves that by reusing the existing hierarchy APIs, - returns a lightweight response and provides a convenient API instead. -- This API could take a list of rooms with included `via`s for each room instead - of a single room (as a POST request). This may have performance benefits for - the federation API and a client could then easily request a summary of all - joined rooms. It could still request the summary of a single room by just - including only a single room in the POST or a convenience GET could be - provided by the server (that looks like this proposal). -- [MSC3429](https://github.com/matrix-org/matrix-doc/pull/3429) is an - alternative implementation, but it chooses a different layout. While this - layout might make sense in the future, it is inconsistent with the APIs - already in use, harder to use for clients (iterate array over directly - including the interesting fields) and can't reuse the federation API. In my - opinion an MSC in the future, that bases all summary APIs on a list of - stripped events seems like the more reasonable approach to me and would make - the APIs more extensible. +### The Space Summary / `/hierarchy` API + +The +[`/hierarchy`](https://spec.matrix.org/v1.3/client-server-api/#get_matrixclientv1roomsroomidhierarchy) +API could be used, but it returns more data than necessary by default (but it +can be limited to just 1 room) such as all the `m.space.child` events in a +space, but also is missing the room version, membership and the encryption +field. + +Additionally the `/hierarchy` API doesn't work using aliases. This currently +doesn't allow users to preview rooms not known to the local server over +federation. While the user can resolve the alias and then call the `/hierarchy` +API using the resolved roomid, a roomid is not a routable entity, so the server +never receives the information which servers to ask about the requested rooms. +This MSC resolves that by providing a way to pass server names to ask for the +room as well as the alias directly. + +For server to server communication the efficiency is not as important, which is +why we use the same API as the `/hierarchy` API to fetch the data over +federation. + +### The `sync` API + +For joined rooms, the `/sync` API can be used to get a summary for all joined +rooms. Apart from not working for unjoined rooms, like knocks, invites and space +children, `/sync` is very heavy for the server and the client needs to cobble +together information from the `state`, `timeline` and +[`summary`](https://github.com/matrix-org/matrix-doc/issues/688) sections to +calculate the room name, topic and other fields provided in this MSC. + +Furthermore, the membership counts in the summary field are only included, if +the client is using lazy loading. This MSC provides similar information as +calling `/sync`, but it uses the stripped state, which is needed to allow this +to work for unjoined rooms and it excludes `m.heroes` as well as membership +events, since those are not included in the stripped state of a room. (A client +can call `/joined_members` to receive those if needed. It may still make sense +to include heroes so that clients could construct a human-friendly room display +name in case both the name and the canonical alias are absent; but solving the +security implications with that may better be left to a separate MSC. + +### The `/state` API + +The `/state` API could be used, but the response is much bigger than needed, +can't be cached as easily and may need more requests. This also doesn't work +over federation (yet). The variant of this API, which returns the full state of +a room, also does not return stripped events, which prevents it from being used +by non-members. The event for specific events DOES return stripped events, but +could not provide a member count for a room. + +### Proper peeking + +Peeking could solve this too, but with additional overhead and +[MSC2753](https://github.com/matrix-org/matrix-doc/pull/2753) is much more +complex. You need to add a peek and remember to remove it. For many usecases you +just want to do one request to get info about a room, no history and no updates. +This MSC solves that by reusing the existing hierarchy APIs, returns a +lightweight response and provides a convenient API instead. + +### A more batched API + +This API could take a list of rooms with included `via`s for each room instead +of a single room (as a POST request). This may have performance benefits for the +federation API and a client could then easily request a summary of all joined +rooms. It could still request the summary of a single room by just including +only a single room in the POST or a convenience GET could be provided by the +server (that looks like this proposal). + +### MSC3429: Individual room preview API (closed) + +[MSC3429](https://github.com/matrix-org/matrix-doc/pull/3429) is an alternative +implementation, but it chooses a different layout. While this layout might make +sense in the future, it is inconsistent with the APIs already in use, harder to +use for clients (iterate array over directly including the interesting fields) +and can't reuse the federation API. In my opinion an MSC in the future, that +bases all summary APIs on a list of stripped events seems like the more +reasonable approach to me and would make the APIs more extensible. ## Security considerations From ac3d5da5608abba8295fff357da0f9e760d847fa Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 27 Jul 2022 00:19:05 +0200 Subject: [PATCH 23/27] Collapse the same descriptions for publicRooms and hierarchy into one --- proposals/3266-room-summary.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index bca61c888b7..7b6563aa8c1 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -75,17 +75,16 @@ A response includes the stripped state in the following format: } ``` -These are the same fields as those returned by `/publicRooms`, with a few -additions: `room_type`, `membership`, `room_version` and `encryption`. +These are the same fields as those returned by `/publicRooms` or +[`/hierarchy`](https://spec.matrix.org/v1.3/client-server-api/#get_matrixclientv1roomsroomidhierarchy) +, with a few additions: `room_type`, `membership`, `room_version` and +`encryption`. `room_type`, `room_version` and `encryption` are already accessible as part of the stripped state according to -https://spec.matrix.org/v1.3/client-server-api/#stripped-state , with the -exception of `membership`. These are the same fields as in the response to -[`/hierarchy`](https://spec.matrix.org/v1.3/client-server-api/#get_matrixclientv1roomsroomidhierarchy) -apart from the addition of the `room_type`, `membership`, `room_version` and -`encryption` fields. The membership can already be accessed by a client anyway, -this API just provides it as a convenience. +https://spec.matrix.org/v1.3/client-server-api/#stripped-state . The +`membership` is not, but a client could access that in various different ways +already. This API just makes this more convenient. #### Rationale and description of response fields From dba67050c55322916c0cd199676ebec1a6043d91 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 27 Jul 2022 00:31:41 +0200 Subject: [PATCH 24/27] Shorten the 'accessible' section again --- proposals/3266-room-summary.md | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index 7b6563aa8c1..a5267a4233f 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -30,16 +30,11 @@ alias, and a corresponding server-server API to fetch a summary over federation. ### Client-Server API -The API returns the summary of the specified room, if the room could be found -and the client should be able to view its contents according to the same rules as the -[`/hierarchy`](https://spec.matrix.org/v1.3/client-server-api/#server-behaviour-19) -endpoint. This is generally described as being a "potential joiner", which -includes rules such as being a member of a room that allows joining a -[`restricted`](https://spec.matrix.org/v1.3/client-server-api/#restricted-rooms), -the room being -[knockable](https://spec.matrix.org/v1.3/client-server-api/#knocking-on-rooms), -public or you already being a member. For unauthenticated requests a response -should only be returned if the room is publicly accessible. +The API returns a summary of the given room, provided the user is either already +a member, or has the necessary permissions to join. (For example, the user may +be a member of a room mentioned in an `allow` condition in the join rules of a +restricted room.) For unauthenticated requests a response should only be +returned if the room is publicly accessible. A request could look like this: From 97191196c9d41e75d8a00ca41df05717c3b798eb Mon Sep 17 00:00:00 2001 From: "DeepBlueV7.X" Date: Mon, 1 Aug 2022 11:08:21 +0000 Subject: [PATCH 25/27] Update proposals/3266-room-summary.md Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/3266-room-summary.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index a5267a4233f..db9078451c9 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -108,13 +108,9 @@ is required when called authenticated. It should be `leave` if the server doesn't know about the room, since for all other membership states the server would know about the room already. -(2) Originally the `/hierarchy` endpoint didn't return the room version. It is -however a useful field, especially when you are considering to join a room. It -would also help with the -[validation of `/hierarchy` responses](https://github.com/matrix-org/synapse/blob/57d334a13d983406ea452dfa203bbe4837509c4e/synapse/handlers/room_summary.py#L662). -So until this MSC is supported by servers, the field will be missing over -federation and can't be added by the local server. After a certain migration -period this field could be made a required field. +(2) Prior to this MSC, `/_matrix/federation/v1/hierarchy/{roomId}` doesn't +return the room version, so `room_version` may be unavailable for remote +rooms. #### Modifications to `/_matrix/client/v1/rooms/{roomId}/hierarchy` From 2ad832c6e6a60748810ec0f9ec3d77107774594f Mon Sep 17 00:00:00 2001 From: "DeepBlueV7.X" Date: Wed, 14 Dec 2022 01:37:38 +0000 Subject: [PATCH 26/27] Update proposals/3266-room-summary.md --- proposals/3266-room-summary.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index db9078451c9..f3d0dbebbb3 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -119,9 +119,9 @@ For symmetry the `room_version` and `encryption` fields are also added to the ### Server-Server API -For the +For the server side the federation API of the [`/hierarchy`](https://spec.matrix.org/v1.3/server-server-api/#get_matrixfederationv1hierarchyroomid) -federation API is reused. This provides (with a few changes) all the information +endpoint is reused. This provides (with a few changes) all the information needed in this MSC, but it also provides a few additional fields and one level of children of this room. From 81fd90469c7be8dcde21b2e4e7edc49ee2850add Mon Sep 17 00:00:00 2001 From: "DeepBlueV7.X" Date: Sat, 31 Dec 2022 02:47:32 +0000 Subject: [PATCH 27/27] Update proposals/3266-room-summary.md Co-authored-by: Alexey Rusakov --- proposals/3266-room-summary.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3266-room-summary.md b/proposals/3266-room-summary.md index f3d0dbebbb3..524a2fbc1b8 100644 --- a/proposals/3266-room-summary.md +++ b/proposals/3266-room-summary.md @@ -190,7 +190,7 @@ events, since those are not included in the stripped state of a room. (A client can call `/joined_members` to receive those if needed. It may still make sense to include heroes so that clients could construct a human-friendly room display name in case both the name and the canonical alias are absent; but solving the -security implications with that may better be left to a separate MSC. +security implications with that may better be left to a separate MSC.) ### The `/state` API