From ae8ec6603c2edaa5047e68352e4a1f97549bb16f Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 27 Aug 2020 18:35:03 +0100 Subject: [PATCH] Spec how a client is notified of pending knock progress --- proposals/2403-knock.md | 115 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 112 insertions(+), 3 deletions(-) diff --git a/proposals/2403-knock.md b/proposals/2403-knock.md index 31530b5a..926561a1 100644 --- a/proposals/2403-knock.md +++ b/proposals/2403-knock.md @@ -57,8 +57,13 @@ knocks. ## Client-Server API Two new endpoints are introduced in the Client-Server API (similarly to -join): `POST /_matrix/client/r0/rooms/{roomId}/knock` and -`POST /_matrix/client/r0/knock/{roomIdOrAlias}`. +join): `POST /_matrix/client/r0/rooms/{roomId}/knock` and `POST +/_matrix/client/r0/knock/{roomIdOrAlias}`. These allow the client to state +their intent to knock on a room. + +Additionally, additions to the `GET /_matrix/client/r0/sync` endpoint are +introduced. These allow a client to receive information about the status of +their knock attempt. ### `POST /_matrix/client/r0/rooms/{roomId}/knock` The path parameter (`roomId`) is the room on which you want to knock. It is @@ -117,7 +122,7 @@ string parameter, `reason`, which is the reason you want to join the room. A request could look as follows: ``` -POST /_matrix/client/r0/knock/%23monkeys%3Amatrix.org?server_name=matrix.org&server_name=elsewhere.ca HTTP/1.1 +POST /_matrix/client/r0/knock/%23foxes%3Amatrix.org?server_name=matrix.org&server_name=elsewhere.ca HTTP/1.1 Content-Type: application/json { @@ -129,6 +134,110 @@ Content-Type: application/json The possible responses are the same as for the `POST /_matrix/client/r0/rooms/{roomId}/knock` endpoint. +### Extensions to `GET /_matrix/client/r0/sync` + +In [the response to +`/sync`](https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-sync) +is a `rooms` field. This is a dictionary which currently contains keys +`join`, `invite` and `leave`, which each provide information to the client on +various membership states regarding the user. + +It is proposed to add a fourth possible key to `rooms`, called `knock`. Its +value is a mapping from room ID to room information. The room information is +a mapping from a key `knock_state` to another mapping with key `events` being +a list of `StrippedStateEvent`. `StrippedStateEvent`s are defined as state +events that only contain the `sender`, `type`, `state_key` and `content` +keys. This behaviour matches `invite_events` which already exists to provide +information to the client their current room invites. + +These stripped state events contain information about the room, most notably +the room's name and avatar. A client will need this information to show a +nice representation of pending knocked rooms. Only `m.room.name`, +`m.room.avatar`, `m.room.join_rules` and `m.room.membership` state events +should be included here, rather than all room state event types. +Additionally, only `m.room.membership` events of the knocking user should be +included. + +This prevents unneeded state from the room leaking out, and also speeds +things up (think not sending over hundreds of membership events from big +rooms). + +XXX: Is `m.room.canonical_alias` worth allowing here for any reason? + +The following is an example of knock state coming down `/sync`. + +Request: +``` +GET /_matrix/client/r0/sync HTTP/1.1 +Content-Type: application/json +``` + +Response: +```json +{ + ... + "rooms": { + "knock": { + "!abcdefghijklmo:example.com": { + "knock_state": { + events: [ + { + "content": { + "join_rule": "knock" + }, + "sender": "@room_admin:example.com", + "state_key": "", + "type": "m.room.join_rules" + }, + { + "content": { + "name": "Some cool room" + }, + "sender": "@room_admin:example.com", + "state_key": "", + "type": "m.room.name" + }, + { + "content": { + "url": "mxc://example.com/xyz54321" + }, + "sender": "@room_admin:example.com", + "state_key": "", + "type": "m.room.avatar" + }, + { + "content": { + "avatar_url": "mxc://example.org/abc1234", + "displayname": "Knocking User", + "membership": "knock" + }, + "origin_server_ts": 1598548763903, + "sender": "@knocking_user:example.org", + "state_key": "@knocking_user:example.org", + "type": "m.room.member", + "unsigned": { + "age": 5 + }, + "event_id": "$12345" + } + ] + } + } + } + }, + ... +} +``` + +Once a knock has been made, a user in the room can decide whether they want +to accept or deny the knock. If they accept, they will invite the knocker, +which the knocker will be notified about through existing flows. + +If they deny, then a leave membership event is sent in the room, and the +knocking user will be notified through existing flows (matching the behaviour +of when an invite is recinded). + + ## Server-Server API Similarly to join and leave over federation, a ping-pong game with two new endpoints is introduced: `make_knock` and `send_knock`. Both endpoints must