Skip to content
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

MSC3266: Room summary API #3266

Open
wants to merge 27 commits into
base: old_master
Choose a base branch
from
Open
Changes from 25 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
642f4e1
Room summary proposal
deepbluev7 Jul 4, 2021
188b6e5
Remove alias resolution step from the federation API
deepbluev7 Jul 5, 2021
dc5b372
Reference #688 in the alternatives section
deepbluev7 Jul 12, 2021
975ece5
Remove `is_direct` from response
deepbluev7 Jul 14, 2021
d148acf
Fix unstable prefixes for implementations which keep the prefix and r…
deepbluev7 Jul 14, 2021
6776863
Add allowed_room_ids field
deepbluev7 Jul 14, 2021
df376a3
Extend rationale for additional fields to reference MSC2946
deepbluev7 Jul 14, 2021
43eecf0
Add bulk API as an alternative
deepbluev7 Jul 14, 2021
66fee23
Remove federation API and address feedback
deepbluev7 Oct 6, 2021
469b77b
fix prefixes again
deepbluev7 Oct 20, 2021
04f807b
Remove extensions to federation API since that MSC is amended now
deepbluev7 Oct 20, 2021
f1233c4
Fix minor inaccuracy about the spaces sumary api
deepbluev7 Dec 3, 2021
5fc2f5b
Add encryption field back
deepbluev7 May 2, 2022
9e41b45
Add room version field
deepbluev7 May 2, 2022
cab37e5
Apply suggestions from code review
deepbluev7 May 2, 2022
a93190f
Add a bit more reasoning
deepbluev7 May 2, 2022
8186b72
version -> room_version
deepbluev7 May 4, 2022
1a8ecff
Apply suggestions from code review
deepbluev7 Jul 19, 2022
82d8f3b
Try to address review comments
deepbluev7 Jul 19, 2022
208a58c
Fix incorrect statement about encryption being a bool
deepbluev7 Jul 24, 2022
33f3733
Apply suggestions from code review
deepbluev7 Jul 26, 2022
a5bc9ef
Split up the big alternatives section
deepbluev7 Jul 26, 2022
ac3d5da
Collapse the same descriptions for publicRooms and hierarchy into one
deepbluev7 Jul 26, 2022
dba6705
Shorten the 'accessible' section again
deepbluev7 Jul 26, 2022
9719119
Update proposals/3266-room-summary.md
deepbluev7 Aug 1, 2022
2ad832c
Update proposals/3266-room-summary.md
deepbluev7 Dec 14, 2022
81fd904
Update proposals/3266-room-summary.md
deepbluev7 Dec 31, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
257 changes: 257 additions & 0 deletions proposals/3266-room-summary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
# MSC3266: Room Summary API
KitsuneRal marked this conversation as resolved.
Show resolved Hide resolved

deepbluev7 marked this conversation as resolved.
Show resolved Hide resolved
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
deepbluev7 marked this conversation as resolved.
Show resolved Hide resolved
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).
- 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 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
for each room.

## Proposal
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We appear to be missing error conditions from the MSC: what if the room doesn't exist? is invalid? unroutable?


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 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
Comment on lines +33 to +35
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear if this includes invites. It probably should, but that should be explicitly mentioned in the MSC.

restricted room.) For unauthenticated requests a response should only be
returned if the room is publicly accessible.
Comment on lines +33 to +37
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, so this means being knockable is not sufficient to make the contents visible ( since a user who has not yet received an invite to a knockable room lacks the necessary permissions to join it).

So this seems to be in conflict with the current Synapse implementation.

We may need to reach a decision on matrix-org/matrix-spec#1186 if we are to avoid the two endpoints having subtly different behaviour.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention was always to allow access to the same rooms the hierarchy API allows access to. I don't think we need to wait for a decision on those spec issues, since the behaviour should be the same in any case. I added the explicit mention of that intention back.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This MSC is still unclear in what it wants, imo. If it just wants to use the same conditions as /hierarchy then it can just say that (independent of us fixing matrix-org/matrix-spec#1184). Currently, it forbids knockable rooms which appears to be an anti-goal of this MSC.

Suggested phrasing:

The API returns a summary of the given room, provided the user has reasonable justification to see those details. At present, this would mean that the room would normally be returned by /hierarchy, which includes knockable, restricted, and public rooms. Invite-only rooms would not be accessible by this API unless the user was already joined to that room.


A request could look like this:

```
GET /_matrix/client/v1/summary/{roomIdOrAlias}?
via=matrix.org&
via=neko.dev
```

(This is not under `/rooms`, because it can be used with an alias.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, but can we call it room_summary ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really care about the name, but all the other endpoints are called /join/ and such as well, so I thought /summary/ would be more consistent with that, since it is followed by a room id/alias.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that for /join and /knock, it's a bit more obvious that we're talking about a room. /summary could be anything, really.

I'd be interested what other people think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a strong opinion on it, so we can change to to whatever, but I would appreciate some more opinions since otherwise I might need to flip flop between names again.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's call it /room_summary - there's a good chance we'll want other entities to be summarized in the future and it'd be annoying to fix/replace the API endpoint for them.


- `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.
Comment on lines +50 to +52
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The vias feel insufficiently specified, despite I think everyone "knowing" what you mean:

  • Are they required? (no)
  • Are they the same as https://spec.matrix.org/v1.3/appendices/#routing ? (yes - please add the link)
  • Where is "locally"? (the server, but could be argued to be on the client side with the current language)
  • How does the client pick servers for an arbitrary room? (it is most often told what they are, but in the case of the room directory or bare room ID it might have to guess/hope for the best, just like with regular joins)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec text for this same parameter (but with a different name) on the /join/ endpoint is this:

The servers to attempt to join the room through. One of the servers must be participating in the room.

Why does an MSC need to be more specific then the spec? It is needed when otherwise the room can't be routed to. If that is the case, depends on what room you are previewing. If you know you are joined already, you don't need it. If you pass an alias, you don't need it. If you got a random room and you know some vias, there is no harm in just passing them. Some examples where those vias can be from is already listed in the line you are commenting on, but if a client provides more ways to preview a room it might have client side fields for that, like a text field a user can enter servers in, and I don't think that needs to be specified?

Copy link
Member

@KitsuneRal KitsuneRal Dec 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AIUI, linking to appendices/#routing effectively answers the questions regarding "locally" and the choice of servers?


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_rule: "public",
room_type: "m.space",
membership: "invite",
encryption: "m.megolm.v100",
room_version: "9001",
}
```

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`.
Comment on lines +73 to +76
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of taking this approach, why not just do what /hierarchy did and use a PublicRoomsChunk explicitly, extending the schema of that? (the benefit being that all 3 related endpoints get a room_type, membership, room_version, and encryption instead of having to subschema the nightmare a second time)

Maintaining several similar objects is not ideal from a spec perspective.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, this implicitly specifies to reuse the "PublicRoomsChunk", but most people probably would not know what that means. I think it is clearer to name the endpoint, that already returns this value than using the name of the value, that most people probably don't remember what it is. At least I mostly ignore those names unless I work with the OpenAPI JSON directly.

I also copied this wording originally from the space summary MSCs. It only uses the PublicRoomsChunk name in one example, it generally talks about the return value of publicRooms otherwise.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that we tend to change sub-structure names in OpenAPI occasionally (that doesn't alter the shape of the OpenAPI, generated code notwithstanding), I agree with @deepbluev7 that the current text is good enough.


`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 . The
`membership` is not, but a client could access that in various different ways
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is the client meant to use the membership field? Even with the table below, the client should already have several other ways of knowing its current membership - is this really the best endpoint to reveal such information?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some clients don't call /sync. Having to use an extra endpoint to fetch this endpoint is opposite to the goals of this endpoint. In general the reason to call a summary endpoint is to do less calls than generating all that info yourself.

For example, if you want to join a room, you might want to generate a preview first. Then you want to name the button differently depending on if you are joined to the room or not. If you have all joined rooms cached locally, you can fetch that info from there, but some clients do not have that info without doing another request. And the server needs to check the join state anyway to generate some of the results, so it should not have an additional cost to just put that in the summary.

already. This API just makes this more convenient.


#### Rationale and description of response fields

| fieldname | description | rationale |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| 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`. |
| 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`. |
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the introduction of knock_restricted, knowing the join rule isn't sufficient to know which method the room can be joined via. As such the response should also include the allowedRoomIds, that the user is joined to or so.

| 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 (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. |

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.
Comment on lines +102 to +104
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear: does this mean the endpoint can be rate limited regardless of authentication? It might be safer to just list it like the spec does:

Rate limited: Yes
Requires authentication: No, because ...

though I'm also not entirely convinced this should be allowed to be unauthenticated - the MSC needs to describe the usecase so it can be rationalized.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is already an implementation of this, that can't use authentication, is that not enough? It is also the second example in the introduction...

matrix.to may want to show avatar and name of a room.


(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 about the room, since for all other membership states the server
would know about the room already.

(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`

For symmetry the `room_version` and `encryption` fields are also added to the
`/hierarchy` API.
Comment on lines +117 to +118
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please just use PublicRoomsChunk 😭

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean ChildRoomsChunk. And again, I think those names are confusing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(FWIW - the name ChildRoomsChunk was introduced (by me) in a clarification PR (not MSC) solely for the purpose of describing, well, child rooms in /hierarchy. Refactoring those sub-schema names is certainly not something for this MSC (we rarely, if ever, did it in the previous MSC practice). PublicRoomsChunk is used in a couple of places across the API; I agree the name could be better but it actually reflects the current usage of this group of fields.)

I think it's a good question for SCT on the status of those names, how much we have to preserve them etc.; in the meantime, I would suggest keeping the text as it is to avoid accidental confusion.


### Server-Server API

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
deepbluev7 marked this conversation as resolved.
Show resolved Hide resolved
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.

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.
richvdh marked this conversation as resolved.
Show resolved Hide resolved

(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

### Performance

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.

To mitigate that, servers are recommended to cache the response for this API and
apply rate limiting if necessary.

## Alternatives

### 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.
Comment on lines +161 to +162
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this hardly seems like an unsurmountable problem... The argument for it dealing mostly with spaces is quite strong, but saying it's missing fields is just asking for an MSC to add the fields :p

The key with the alternatives section is it needs to describe why a solution isn't valid, so, why is writing an MSC for adding the fields a bad idea? (answer: it's because of the focus on spaces - it would be confusing to client developers to call a Spaces endpoint to get a non-Space summary, though there is an unargued point about shifting the complexity onto the server instead, as this MSC does).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This MSC actually adds most of those fields to the /hierarchy endpoint as well. But the EXISTING endpoint is not an alternative to this MSC, since it lacks those fields. Of course those could be added, but it is not the only reason why it currently can't be used for this. This sentence is just an additional complication that people would notice, when they try to use the /hierarchy endpoint as is without extending it.


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.
Comment on lines +164 to +170
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is all made invalid by the summary endpoint having to reduce itself down to a room ID before going out over federation? How is it any more routable if the server does the resolution instead of the client?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the client resolves the alias, only the client knows the server that resolved the alias.

If the server resolves the alias, it receives a list of servers that it can join via, which it can then use to query for the summary. This is the same behavior as with every other endpoint that takes an alias (apart from the room directory endpoints themselves, I guess). Usually asking the server about the room the alias is hosted on is entirely sufficient though. Apart from the directory, there is no endpoint which passes an alias over federation, so I don't see how that would be an issue in this case now?


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.
deepbluev7 marked this conversation as resolved.
Show resolved Hide resolved

### 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

This API may leak data, if implemented incorrectly or malicious servers could
return wrong results for a summary.
Comment on lines +234 to +235
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is true with any endpoint - the leak for this endpoint would more be that people could be surprised by the amount of metadata returned, such as in the case of matrix-org/matrix-spec#1186

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So should I just delete that line? I do think it is a genuine concern.


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 be used for denial of service type attacks. Appropriate
ratelimiting and caching should be able to mitigate that.

## Unstable prefix
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also define a new unstable_features flag for GET /_matrix/client/versions.

For example, adapting from MSC3026:

servers implementing this MSC must expose a flag in GET /_matrix/client/versions responses, under unstable_features, named im.nheko.msc3266, which is set to true.

Other MSCs that define an unstable_features are MSC2432, MSC2666, MSC2285, MSC3827, and MSC3440.


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/summary/{roomIdOrAlias}`.

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 `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.