From ccd7bb32d5bfb76206e97e2e8e659dcb54e17434 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 27 Sep 2016 12:17:05 +0100 Subject: [PATCH 01/57] Specification for direct-to-device messages --- api/client-server/sync.yaml | 6 + api/client-server/to_device.yaml | 89 +++++++++++++ changelogs/client_server.rst | 2 + specification/modules/store_and_forward.rst | 140 ++++++++++++++++++++ specification/server_server_api.rst | 24 ++++ specification/targets.yaml | 1 + 6 files changed, 262 insertions(+) create mode 100644 api/client-server/to_device.yaml create mode 100644 specification/modules/store_and_forward.rst diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 8bfdd48a..2f77345d 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -236,6 +236,12 @@ paths: The global private data created by this user. allOf: - $ref: "definitions/event_batch.yaml" + to_device: + title: ToDevice + type: object + description: |- + Information on the store-and-forward messages for the client device, as defined in + |store_and_forward_sync|_. examples: application/json: |- { diff --git a/api/client-server/to_device.yaml b/api/client-server/to_device.yaml new file mode 100644 index 00000000..589ec0d7 --- /dev/null +++ b/api/client-server/to_device.yaml @@ -0,0 +1,89 @@ +# Copyright 2016 OpenMarket Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +swagger: '2.0' +info: + title: "Matrix Client-Server Send-to-device API" + version: "1.0.0" +host: localhost:8008 +schemes: + - https + - http +basePath: /_matrix/client/%CLIENT_MAJOR_VERSION% +consumes: + - application/json +produces: + - application/json +securityDefinitions: + $ref: definitions/security.yaml +paths: + "/sendToDevice/{eventType}/{txnId}": + put: + summary: Send to-device event to a given set of devices. + description: |- + This endpoint is used to send store-and-forward events to a set of + client devices. + security: + - accessToken: [] + parameters: + - in: path + type: string + name: eventType + description: The type of event to send. + required: true + x-example: "m.new_device" + - in: path + name: txnId + type: string + description: |- + The transaction ID for this event. Clients should generate an + ID unique across requests with the same access token; it will be + used by the server to ensure idempotency of requests. + required: true + x-example: "35" + - in: body + name: body + required: true + schema: + type: object + title: body + properties: + messages: + type: object + description: |- + The messages to send. A map from user ID, to a map from + device ID to message body. The device ID may also be `*`, + meaning all known devices for the user. + additionalProperties: + type: object + additionalProperties: + type: object + title: EventContent + description: Message content + example: { + "@alice:example.com": { + "tLLbenaag": { + "example_content_key": "value" + } + } + } + responses: + 200: + description: + The message was successfully sent. + examples: + application/json: |- + {} + tags: + - Store-and-forward messaging diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index d7384e31..bd75fb28 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -35,6 +35,8 @@ - Add top-level ``account_data`` key to the responses to ``GET /sync`` and ``GET /initialSync`` (`#380 `_). + - Add "Store-and-Forward messaging" module + (`#386 `_). r0.2.0 ====== diff --git a/specification/modules/store_and_forward.rst b/specification/modules/store_and_forward.rst new file mode 100644 index 00000000..0f41412d --- /dev/null +++ b/specification/modules/store_and_forward.rst @@ -0,0 +1,140 @@ +.. Copyright 2016 OpenMarket Ltd +.. +.. Licensed under the Apache License, Version 2.0 (the "License"); +.. you may not use this file except in compliance with the License. +.. You may obtain a copy of the License at +.. +.. http://www.apache.org/licenses/LICENSE-2.0 +.. +.. Unless required by applicable law or agreed to in writing, software +.. distributed under the License is distributed on an "AS IS" BASIS, +.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +.. See the License for the specific language governing permissions and +.. limitations under the License. + +Store-and-Forward messaging +=========================== + +.. _module:to_device: + +This module provides a means by which clients can exchange signalling messages +without them being stored permanently as part of a shared communication +history. A message is delivered exactly once to each client device. + +Client behaviour +---------------- +To send a message to other devices, a client should call |/sendToDevice|_. +Only one message can be sent to each device per transaction, and they must all +have the same event type. The device ID in the request body can be set to ``*`` +to request that the message be sent to all known devices. + +If there are store-and-forward messages waiting for a client, they will be +returned by |/sync|_, as detailed in `Extensions to /sync`_. Clients should +inspect the ``type`` of each returned event, and ignore any they do not +understand. + +Server behaviour +---------------- +Servers should store pending messages for local users until they are +successfully delivered to the destination device. When a client calls |/sync|_ +with an access token which corresponds to a device with pending messages, the +server should list the pending messages, in order of arrival, in the response +body. + +When the client calls ``/sync`` again with the ``next_batch`` token from the +first response, the server should infer that any store-and-forward messages in +that response have been delivered successfully, and delete them from the store. + +If there is a large queue of store-and-forward messages, the server should +limit the number sent in each ``/sync`` response. 100 messages is recommended +as a reasonable limit. + +If the client sends messages to users on remote domains, those messages should +be sent on to the remote servers via +`federation`_. + +.. _`federation`: ../server_server/latest.html#store-and-forward-messages + +.. TODO-spec: + + * Is a server allowed to delete undelivered messages? After how long? What + about if the device is deleted? + + * If the destination HS doesn't support the ``m.direct_to_device`` EDU, it + will just get dumped. Should we indicate that to the client? + + +Protocol definitions +-------------------- + +{{to_device_cs_http_api}} + +.. TODO-spec: + + * What should a server do if the user id or device id is unknown? Presumably + it shouldn't reject the request outright, because some of the destinations + may be valid. Should we add something to the response? + +.. anchor for link from /sync api spec +.. |store_and_forward_sync| replace:: Store-and-Forward messaging +.. _store_and_forward_sync: + +Extensions to /sync +~~~~~~~~~~~~~~~~~~~ + +This module adds the following properties to the |/sync|_ response: + +.. todo: generate this from a swagger definition? + +========= ========= ======================================================= +Parameter Type Description +========= ========= ======================================================= +to_device ToDevice Optional. Information on the store-and-forward messages + for the client device. +========= ========= ======================================================= + +``ToDevice`` + +========= ========= ============================================= +Parameter Type Description +========= ========= ============================================= +events [Event] List of store-and-forward messages +========= ========= ============================================= + +``Event`` + +================ ============ ================================================== +Parameter Type Description +================ ============ ================================================== +content EventContent The content of this event. The fields in this + object will vary depending on the type of event. +sender string The Matrix user ID of the user who sent this + event. +type string The type of event. +================ ============ ================================================== + + +Example response: + +.. code:: json + + { + "next_batch": "s72595_4483_1934", + "rooms": {"leave": {}, "join": {}, "invite": {}}, + "to_device": { + "events": [ + { + "sender": "@alice:example.com", + "type": "m.new_device", + "content": { + "device_id": "XYZABCDE", + "rooms": ["!726s6s6q:example.com"] + } + } + ] + } + } + + +.. |/sendToDevice| replace:: ``/sendToDevice`` +.. _/sendToDevice: #put-matrix-client-%CLIENT_MAJOR_VERSION%-sendtodevice-eventtype-txnid diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 5c8a456a..1d4b7249 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -974,3 +974,27 @@ The list of join candidates is a list of server names that are likely to hold the given room; these are servers that the requesting server may wish to use as resident servers as part of the remote join handshake. This list may or may not include the server answering the query. + +Store-and-forward messages +-------------------------- + +.. TODO: add modules to the federation spec and make this a module + +The server API for store-and-forward messaging is based on the following +EDU. There are no PDUs or Federation Queries involved. + +Each store-and-forward message should be sent to the destination server using +the following EDU:: + + EDU type: m.direct_to_device + + Content keys: + sender: user ID of the sender + + type: event type for the message + + message_id: unique id for the message: used for idempotence + + messages: The messages to send. A map from user ID, to a map from device ID + to message body. The device ID may also be *, meaning all known devices + for the user. diff --git a/specification/targets.yaml b/specification/targets.yaml index 6cbfa917..ca2e0044 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -41,6 +41,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/receipts.rst - modules/presence.rst - modules/content_repo.rst + - modules/store_and_forward.rst - modules/end_to_end_encryption.rst - modules/history_visibility.rst - modules/push.rst From 3a5cbd14c3ec4e27e9de4e616ef61b0ef89c2273 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Thu, 29 Sep 2016 11:25:12 +0100 Subject: [PATCH 02/57] Add /createRoom is_direct flag --- api/client-server/create_room.yaml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/api/client-server/create_room.yaml b/api/client-server/create_room.yaml index 9107e185..2e7cc0ad 100644 --- a/api/client-server/create_room.yaml +++ b/api/client-server/create_room.yaml @@ -170,7 +170,15 @@ paths: ``public_chat``: => ``join_rules`` is set to ``public``. ``history_visibility`` is set to ``shared``. - + is_direct: + type: boolean + description: |- + This flag shows that the intent for this room is to be a + one-to-one 'direct' conversation with the invitee. The + invitee's client should indicate this in the UI to the user, + as should the inviter. This is to keep the intent for new rooms + synchronised at first. Both users may subsequently choose to + tag the room differently. responses: 200: description: Information about the newly created room. From ebaaa7e3b335f436681ecbd7c2cfbde047292803 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 29 Sep 2016 13:18:45 +0100 Subject: [PATCH 03/57] Review feedback * store-and-forward -> send-to-device * describe motivation * device ids are 10 capital chars * etc --- api/client-server/sync.yaml | 4 +-- api/client-server/to_device.yaml | 8 +++--- specification/client_server_api.rst | 3 +++ ...ore_and_forward.rst => send_to_device.rst} | 26 ++++++++++++------- specification/server_server_api.rst | 8 +++--- specification/targets.yaml | 2 +- 6 files changed, 30 insertions(+), 21 deletions(-) rename specification/modules/{store_and_forward.rst => send_to_device.rst} (83%) diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 2f77345d..66f7d935 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -240,8 +240,8 @@ paths: title: ToDevice type: object description: |- - Information on the store-and-forward messages for the client device, as defined in - |store_and_forward_sync|_. + Information on the send-to-device messages for the client + device, as defined in |send_to_device_sync|_. examples: application/json: |- { diff --git a/api/client-server/to_device.yaml b/api/client-server/to_device.yaml index 589ec0d7..16af1182 100644 --- a/api/client-server/to_device.yaml +++ b/api/client-server/to_device.yaml @@ -30,9 +30,9 @@ securityDefinitions: paths: "/sendToDevice/{eventType}/{txnId}": put: - summary: Send to-device event to a given set of devices. + summary: Send an event to a given set of devices. description: |- - This endpoint is used to send store-and-forward events to a set of + This endpoint is used to send send-to-device events to a set of client devices. security: - accessToken: [] @@ -73,7 +73,7 @@ paths: description: Message content example: { "@alice:example.com": { - "tLLbenaag": { + "TLLBEANAAG": { "example_content_key": "value" } } @@ -86,4 +86,4 @@ paths: application/json: |- {} tags: - - Store-and-forward messaging + - Send-to-Device messaging diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index a74129b5..6eb24823 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1258,6 +1258,9 @@ have to wait in milliseconds before they can try again. .. |/rooms//state| replace:: ``/rooms//state`` .. _/rooms//state: #get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-state +.. |/rooms//send| replace:: ``/rooms//send`` +.. _/rooms//send: #put-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-send-eventtype-txnid + .. |/rooms//invite| replace:: ``/rooms//invite`` .. _/rooms//invite: #post-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-invite diff --git a/specification/modules/store_and_forward.rst b/specification/modules/send_to_device.rst similarity index 83% rename from specification/modules/store_and_forward.rst rename to specification/modules/send_to_device.rst index 0f41412d..dd85a992 100644 --- a/specification/modules/store_and_forward.rst +++ b/specification/modules/send_to_device.rst @@ -12,8 +12,8 @@ .. See the License for the specific language governing permissions and .. limitations under the License. -Store-and-Forward messaging -=========================== +Send-to-Device messaging +======================== .. _module:to_device: @@ -21,6 +21,12 @@ This module provides a means by which clients can exchange signalling messages without them being stored permanently as part of a shared communication history. A message is delivered exactly once to each client device. +The primary motivation for this API is exchanging data that is meaningless or +undesirable to persist in the room DAG - for example, one-time authentication +tokens or key data. It is not intended for conversational data, which should be +sent using the normal |/rooms//send|_ API for consistency throughout +Matrix. + Client behaviour ---------------- To send a message to other devices, a client should call |/sendToDevice|_. @@ -28,7 +34,7 @@ Only one message can be sent to each device per transaction, and they must all have the same event type. The device ID in the request body can be set to ``*`` to request that the message be sent to all known devices. -If there are store-and-forward messages waiting for a client, they will be +If there are send-to-device messages waiting for a client, they will be returned by |/sync|_, as detailed in `Extensions to /sync`_. Clients should inspect the ``type`` of each returned event, and ignore any they do not understand. @@ -42,10 +48,10 @@ server should list the pending messages, in order of arrival, in the response body. When the client calls ``/sync`` again with the ``next_batch`` token from the -first response, the server should infer that any store-and-forward messages in +first response, the server should infer that any send-to-device messages in that response have been delivered successfully, and delete them from the store. -If there is a large queue of store-and-forward messages, the server should +If there is a large queue of send-to-device messages, the server should limit the number sent in each ``/sync`` response. 100 messages is recommended as a reasonable limit. @@ -53,7 +59,7 @@ If the client sends messages to users on remote domains, those messages should be sent on to the remote servers via `federation`_. -.. _`federation`: ../server_server/latest.html#store-and-forward-messages +.. _`federation`: ../server_server/latest.html#send-to-device-messages .. TODO-spec: @@ -76,8 +82,8 @@ Protocol definitions may be valid. Should we add something to the response? .. anchor for link from /sync api spec -.. |store_and_forward_sync| replace:: Store-and-Forward messaging -.. _store_and_forward_sync: +.. |send_to_device_sync| replace:: Send-to-Device messaging +.. _send_to_device_sync: Extensions to /sync ~~~~~~~~~~~~~~~~~~~ @@ -89,7 +95,7 @@ This module adds the following properties to the |/sync|_ response: ========= ========= ======================================================= Parameter Type Description ========= ========= ======================================================= -to_device ToDevice Optional. Information on the store-and-forward messages +to_device ToDevice Optional. Information on the send-to-device messages for the client device. ========= ========= ======================================================= @@ -98,7 +104,7 @@ to_device ToDevice Optional. Information on the store-and-forward messages ========= ========= ============================================= Parameter Type Description ========= ========= ============================================= -events [Event] List of store-and-forward messages +events [Event] List of send-to-device messages ========= ========= ============================================= ``Event`` diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 1d4b7249..5d7f2b17 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -975,15 +975,15 @@ the given room; these are servers that the requesting server may wish to use as resident servers as part of the remote join handshake. This list may or may not include the server answering the query. -Store-and-forward messages --------------------------- +Send-to-device messaging +------------------------ .. TODO: add modules to the federation spec and make this a module -The server API for store-and-forward messaging is based on the following +The server API for send-to-device messaging is based on the following EDU. There are no PDUs or Federation Queries involved. -Each store-and-forward message should be sent to the destination server using +Each send-to-device message should be sent to the destination server using the following EDU:: EDU type: m.direct_to_device diff --git a/specification/targets.yaml b/specification/targets.yaml index ca2e0044..129cfe11 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -41,7 +41,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/receipts.rst - modules/presence.rst - modules/content_repo.rst - - modules/store_and_forward.rst + - modules/send_to_device.rst - modules/end_to_end_encryption.rst - modules/history_visibility.rst - modules/push.rst From 4f1c2f23ee2c76b1b5995f92da7a0198501752ee Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 29 Sep 2016 13:21:46 +0100 Subject: [PATCH 04/57] Changelog fix store-and-forward -> send-to-device --- changelogs/client_server.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index bd75fb28..10a6876a 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -35,7 +35,7 @@ - Add top-level ``account_data`` key to the responses to ``GET /sync`` and ``GET /initialSync`` (`#380 `_). - - Add "Store-and-Forward messaging" module + - Add "Send-to-Device messaging" module (`#386 `_). r0.2.0 From 085131b61717bb2fa3ad6fa3e9d671a61005c37d Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Thu, 29 Sep 2016 11:38:32 +0100 Subject: [PATCH 05/57] Add contains_url filter option --- api/client-server/definitions/room_event_filter.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/client-server/definitions/room_event_filter.yaml b/api/client-server/definitions/room_event_filter.yaml index a3bb6852..c2923eae 100644 --- a/api/client-server/definitions/room_event_filter.yaml +++ b/api/client-server/definitions/room_event_filter.yaml @@ -28,4 +28,8 @@ properties: items: type: string type: array + contains_url: + type: boolean + description: If specified will filter events based on if they have a url key in their + content. type: object From 37f6769a3c454d14e89817154cb85c9870e8c42e Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Thu, 29 Sep 2016 13:40:20 +0100 Subject: [PATCH 06/57] Spec filter param on /messagse --- api/client-server/message_pagination.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index 853e0ec3..9370325b 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -75,6 +75,11 @@ paths: description: |- The maximum number of events to return. Default: 10. x-example: "3" + - in: query + type: string + name: filter + description: |- + A url encoded JSON RoomEventFilter to filter returned events with. responses: 200: description: A list of messages with a new token to request more. From d01d1a07a6832de36f3f2cfb32d9ddac67e9d4c4 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Thu, 29 Sep 2016 17:19:54 +0100 Subject: [PATCH 07/57] Add changelog --- changelogs/client_server.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index d7384e31..7a8536e3 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -35,6 +35,8 @@ - Add top-level ``account_data`` key to the responses to ``GET /sync`` and ``GET /initialSync`` (`#380 `_). + - Add ``is_direct`` flag to ``/createRoom``. + (`#389 `_). r0.2.0 ====== From 51248dd0c8ccef868c00883bcc4e9f18026ab6a4 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Thu, 29 Sep 2016 17:22:43 +0100 Subject: [PATCH 08/57] Update changelog --- changelogs/client_server.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index d7384e31..19c996da 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -35,6 +35,10 @@ - Add top-level ``account_data`` key to the responses to ``GET /sync`` and ``GET /initialSync`` (`#380 `_). + - Add ``contains_url`` to ``RoomEventFilter``. + (`#390 `_). + - Add ``filter`` query param to ``/messages`` + (`#390 `_). r0.2.0 ====== From b121feebce9524eb1ce4102bc0c012369c85a3d5 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 30 Sep 2016 11:24:51 +0100 Subject: [PATCH 09/57] Comment what the is_direct flag actually does --- api/client-server/create_room.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/client-server/create_room.yaml b/api/client-server/create_room.yaml index 2e7cc0ad..87289682 100644 --- a/api/client-server/create_room.yaml +++ b/api/client-server/create_room.yaml @@ -179,6 +179,8 @@ paths: as should the inviter. This is to keep the intent for new rooms synchronised at first. Both users may subsequently choose to tag the room differently. + This adds an ``is_direct`` flag to the content of any invites + sent. responses: 200: description: Information about the newly created room. From 7919e8e1596529cbc9dcace43250c08f2f397f0c Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 30 Sep 2016 15:02:27 +0100 Subject: [PATCH 10/57] Update wording. --- api/client-server/definitions/room_event_filter.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/client-server/definitions/room_event_filter.yaml b/api/client-server/definitions/room_event_filter.yaml index c2923eae..7d9184b5 100644 --- a/api/client-server/definitions/room_event_filter.yaml +++ b/api/client-server/definitions/room_event_filter.yaml @@ -30,6 +30,6 @@ properties: type: array contains_url: type: boolean - description: If specified will filter events based on if they have a url key in their - content. + description: If ``true``, includes only events with a url key in their content. If + ``false``, excludes those events. type: object From a10fe9fa434f8b9e8c485b55143c107680f99992 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 30 Sep 2016 15:04:42 +0100 Subject: [PATCH 11/57] Update changelog --- changelogs/client_server.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index 19c996da..ec74bda9 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -35,9 +35,9 @@ - Add top-level ``account_data`` key to the responses to ``GET /sync`` and ``GET /initialSync`` (`#380 `_). - - Add ``contains_url`` to ``RoomEventFilter``. + - Add ``contains_url`` option to ``RoomEventFilter``. (`#390 `_). - - Add ``filter`` query param to ``/messages`` + - Add ``filter`` optional query param to ``/messages`` (`#390 `_). r0.2.0 From 069aa86a108c85b09aa46bc29406283ce1c76339 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 30 Sep 2016 15:06:11 +0100 Subject: [PATCH 12/57] Update wording and add example to filter param --- api/client-server/message_pagination.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index 9370325b..005b8fb3 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -79,7 +79,9 @@ paths: type: string name: filter description: |- - A url encoded JSON RoomEventFilter to filter returned events with. + A JSON RoomEventFilter to filter returned events with. + x-example: |- + {"contains_url":true} responses: 200: description: A list of messages with a new token to request more. From 08001b7768d271c6447a7e3c8a73166cbc60d920 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 1 Oct 2016 18:49:33 +0100 Subject: [PATCH 13/57] remove spurious blank clients from try-it-now page --- supporting-docs/projects/2014-06-09-vector.md | 1 - supporting-docs/projects/2015-04-03-vector-ios.md | 1 - supporting-docs/projects/2015-06-02-vector-android.md | 1 - supporting-docs/projects/2016-02-06-vector-desktop.md | 1 - 4 files changed, 4 deletions(-) diff --git a/supporting-docs/projects/2014-06-09-vector.md b/supporting-docs/projects/2014-06-09-vector.md index 3f49be69..4f0ea2f5 100644 --- a/supporting-docs/projects/2014-06-09-vector.md +++ b/supporting-docs/projects/2014-06-09-vector.md @@ -1,7 +1,6 @@ --- layout: project title: Try Matrix Now! -categories: projects client --- diff --git a/supporting-docs/projects/2015-04-03-vector-ios.md b/supporting-docs/projects/2015-04-03-vector-ios.md index 2d295483..11fc618e 100644 --- a/supporting-docs/projects/2015-04-03-vector-ios.md +++ b/supporting-docs/projects/2015-04-03-vector-ios.md @@ -1,7 +1,6 @@ --- layout: project title: Try Matrix Now! -categories: projects client --- diff --git a/supporting-docs/projects/2015-06-02-vector-android.md b/supporting-docs/projects/2015-06-02-vector-android.md index 0af7c7b1..9d4e585e 100644 --- a/supporting-docs/projects/2015-06-02-vector-android.md +++ b/supporting-docs/projects/2015-06-02-vector-android.md @@ -1,7 +1,6 @@ --- layout: project title: Try Matrix Now! -categories: projects client --- diff --git a/supporting-docs/projects/2016-02-06-vector-desktop.md b/supporting-docs/projects/2016-02-06-vector-desktop.md index f6664f81..7355ccfc 100644 --- a/supporting-docs/projects/2016-02-06-vector-desktop.md +++ b/supporting-docs/projects/2016-02-06-vector-desktop.md @@ -1,7 +1,6 @@ --- layout: project title: Vector Desktop -categories: projects client description: Desktop version of Vector author: Steven Hammerton maturity: Alpha From 1320a86cbed1fefc545604adf903a669119b4925 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 3 Oct 2016 12:36:46 +0100 Subject: [PATCH 14/57] Serve the api docs from the speculator There are a few parts to this: * when we generate the spec for a particular git sha, also run the script which turns our yaml api descriptions into a swagger json file. * tweak serveSpec to add another header when serving the generated json. * add a link to the generated index which will (via js hackery) redirect to our hosted swagger UI at http://matrix.org/docs/api/client-server, with a "url" query-param pointing at the generated json. Also, factor makeTempDir out of gitClone, so that we can give clearer log lines. --- scripts/speculator/main.go | 108 +++++++++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 22 deletions(-) diff --git a/scripts/speculator/main.go b/scripts/speculator/main.go index b433a327..87ee4bf6 100644 --- a/scripts/speculator/main.go +++ b/scripts/speculator/main.go @@ -27,6 +27,7 @@ import ( "strings" "sync" "syscall" + "text/template" "time" "github.com/hashicorp/golang-lru" @@ -83,19 +84,15 @@ func accessTokenQuerystring() string { return fmt.Sprintf("?access_token=%s", *accessToken) } -func gitClone(url string, shared bool) (string, error) { - directory := path.Join("/tmp/matrix-doc", strconv.FormatInt(rand.Int63(), 10)) - if err := os.MkdirAll(directory, permissionsOwnerFull); err != nil { - return "", fmt.Errorf("error making directory %s: %v", directory, err) - } +func gitClone(url string, directory string, shared bool) error { args := []string{"clone", url, directory} if shared { args = append(args, "--shared") } if err := runGitCommand(directory, args); err != nil { - return "", err + return err } - return directory, nil + return nil } func gitCheckout(path, sha string) error { @@ -159,6 +156,16 @@ func generate(dir string) error { if err := cmd.Run(); err != nil { return fmt.Errorf("error generating spec: %v\nOutput from gendoc:\n%v", err, b.String()) } + + // cheekily dump the swagger docs into the gen directory so they can be + // served by serveSpec + cmd = exec.Command("python", "dump-swagger.py", "gen/api-docs.json") + cmd.Dir = path.Join(dir, "scripts") + cmd.Stderr = &b + if err := cmd.Run(); err != nil { + return fmt.Errorf("error generating api docs: %v\nOutput from dump-swagger:\n%v", err, b.String()) + } + return nil } @@ -195,8 +202,14 @@ func (s *server) generateAt(sha string) (dst string, err error) { return } } + + dst, err = makeTempDir() + if err != nil { + return + } + log.Printf("Generating %s in %s\n", sha, dst) s.mu.Lock() - dst, err = gitClone(s.matrixDocCloneURL, true) + err = gitClone(s.matrixDocCloneURL, dst, true) s.mu.Unlock() if err != nil { return @@ -219,7 +232,7 @@ func (s *server) getSHAOf(ref string) (string, error) { err := cmd.Run() s.mu.Unlock() if err != nil { - return "", fmt.Errorf("error generating spec: %v\nOutput from gendoc:\n%v", err, b.String()) + return "", fmt.Errorf("error generating spec: %v\nOutput from git:\n%v", err, b.String()) } return strings.TrimSpace(b.String()), nil } @@ -396,6 +409,11 @@ func (s *server) serveSpec(w http.ResponseWriter, req *http.Request) { cache.Add(sha, pathToContent) } + if requestedPath == "api-docs.json" { + // allow other swagger UIs access to our swagger + w.Header().Set("Access-Control-Allow-Origin", "*") + } + if b, ok := pathToContent[requestedPath]; ok { w.Write(b) return @@ -588,12 +606,6 @@ func (srv *server) makeIndex(w http.ResponseWriter, req *http.Request) { writeError(w, 500, err) return } - s := "
    " - for _, pull := range pulls { - s += fmt.Sprintf(`
  • %d: %s: %s: spec spec diff rst diff
  • `, - pull.Number, pull.User.HTMLURL, pull.User.Login, pull.HTMLURL, pull.Title, pull.Number, pull.Number, pull.Number) - } - s += "
" branches, err := srv.getBranches() if err != nil { @@ -601,7 +613,48 @@ func (srv *server) makeIndex(w http.ResponseWriter, req *http.Request) { return } - s += `
View the spec at:
    ` + // write our stuff into a buffer so that we can change our minds + // and write a 500 if it all goes wrong. + var b bytes.Buffer + b.Write([]byte(` + + + +
      +`)) + + tmpl, err := template.New("pr entry").Parse(` +
    • {{.Number}}: + {{.User.Login}}: + {{.Title}}: + spec + api docs + spec diff + rst diff +
    • +`) + if err != nil { + log.Fatal(err) + } + + for _, pull := range pulls { + err = tmpl.Execute(&b, pull) + if err != nil { + writeError(w, 500, err) + return + } + } + b.Write([]byte(` +
    +
    View the spec at:
      +`)) branchNames := []string{} for _, branch := range branches { if strings.HasPrefix(branch, "drafts/") { @@ -611,15 +664,14 @@ func (srv *server) makeIndex(w http.ResponseWriter, req *http.Request) { branchNames = append(branchNames, "HEAD") for _, branch := range branchNames { href := "spec/" + url.QueryEscape(branch) + "/" - s += fmt.Sprintf(`
    • %s
    • `, href, branch) + fmt.Fprintf(&b, `
    • %s
    • `, href, branch) if *includesDir != "" { - s += fmt.Sprintf(`
    • %s, styled like matrix.org
    • `, + fmt.Fprintf(&b, `
    • %s, styled like matrix.org
    • `, href, branch) } } - s += "
    " - - io.WriteString(w, s) + b.Write([]byte("
")) + b.WriteTo(w) } func ignoreExitCodeOne(err error) error { @@ -655,10 +707,14 @@ func main() { log.Fatal(err) } rand.Seed(time.Now().Unix()) - masterCloneDir, err := gitClone(matrixDocCloneURL, false) + masterCloneDir, err := makeTempDir() if err != nil { log.Fatal(err) } + log.Printf("Creating master clone dir %s\n", masterCloneDir) + if err = gitClone(matrixDocCloneURL, masterCloneDir, false); err != nil { + log.Fatal(err) + } s := server{matrixDocCloneURL: masterCloneDir} http.HandleFunc("/spec/", forceHTML(s.serveSpec)) http.HandleFunc("/diff/rst/", s.serveRSTDiff) @@ -691,3 +747,11 @@ func initCache() error { styledSpecCache = c2 return err } + +func makeTempDir() (string, error) { + directory := path.Join("/tmp/matrix-doc", strconv.FormatInt(rand.Int63(), 10)) + if err := os.MkdirAll(directory, permissionsOwnerFull); err != nil { + return "", fmt.Errorf("error making directory %s: %v", directory, err) + } + return directory, nil +} From 23d5073820633718539aa6cfa992a02d4c3c24fc Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 3 Oct 2016 14:03:23 +0100 Subject: [PATCH 15/57] Mark required fields in response objects as such Actually this means we can remove a bunch of code which special-cased this. --- changelogs/client_server.rst | 2 ++ templating/matrix_templates/units.py | 21 +++++++-------------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index d7384e31..9358d86f 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -23,6 +23,8 @@ (`#376 `_). - Correct inconsistent specification of ``redacted_because`` fields and their values (`#378 `_). + - Mark required fields in response objects as such + (`#394 `_). - Changes to the API which will be backwards-compatible for clients: diff --git a/templating/matrix_templates/units.py b/templating/matrix_templates/units.py index ee5b40a6..f362f63d 100644 --- a/templating/matrix_templates/units.py +++ b/templating/matrix_templates/units.py @@ -96,8 +96,7 @@ def inherit_parents(obj): return result -def get_json_schema_object_fields(obj, enforce_title=False, - mark_required=True): +def get_json_schema_object_fields(obj, enforce_title=False): # Algorithm: # f.e. property => add field info (if field is object then recurse) if obj.get("type") != "object": @@ -175,8 +174,7 @@ def get_json_schema_object_fields(obj, enforce_title=False, try: logger.debug("Processing property %s.%s", obj_title, key_name) required = key_name in required_keys - res = process_prop(key_name, props[key_name], required, - mark_required) + res = process_prop(key_name, props[key_name], required) first_table_rows.append(res["row"]) tables.extend(res["tables"]) @@ -196,7 +194,7 @@ def get_json_schema_object_fields(obj, enforce_title=False, return tables -def process_prop(key_name, prop, required, mark_required): +def process_prop(key_name, prop, required): prop = inherit_parents(prop) value_type = None @@ -213,7 +211,6 @@ def process_prop(key_name, prop, required, mark_required): nested_objects = get_json_schema_object_fields( prop, enforce_title=True, - mark_required=mark_required, ) value_type = nested_objects[0]["title"] value_id = value_type @@ -226,7 +223,6 @@ def process_prop(key_name, prop, required, mark_required): nested_objects = get_json_schema_object_fields( items, enforce_title=True, - mark_required=mark_required, ) value_id = nested_objects[0]["title"] value_type = "[%s]" % value_id @@ -269,7 +265,7 @@ def process_prop(key_name, prop, required, mark_required): value_type = " or ".join(value_type) - if required and mark_required: + if required: desc = "**Required.** " + desc return { @@ -284,10 +280,9 @@ def process_prop(key_name, prop, required, mark_required): } -def get_tables_for_schema(schema, mark_required=True): +def get_tables_for_schema(schema): schema = inherit_parents(schema) - tables = get_json_schema_object_fields(schema, - mark_required=mark_required) + tables = get_json_schema_object_fields(schema) # the result may contain duplicates, if objects are referred to more than # once. Filter them out. @@ -470,9 +465,7 @@ class MatrixUnits(Units): elif res_type and Units.prop(good_response, "schema/properties"): # response is an object: schema = good_response["schema"] - res_tables = get_tables_for_schema(schema, - mark_required=False, - ) + res_tables = get_tables_for_schema(schema) endpoint["res_tables"].extend(res_tables) elif res_type and Units.prop(good_response, "schema/items"): # response is an array: From 5fedc64230d20221a2758be145f3f01db17c4b06 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 3 Oct 2016 15:52:08 +0100 Subject: [PATCH 16/57] double space --- api/client-server/create_room.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client-server/create_room.yaml b/api/client-server/create_room.yaml index 87289682..c4a9c8ff 100644 --- a/api/client-server/create_room.yaml +++ b/api/client-server/create_room.yaml @@ -173,7 +173,7 @@ paths: is_direct: type: boolean description: |- - This flag shows that the intent for this room is to be a + This flag shows that the intent for this room is to be a one-to-one 'direct' conversation with the invitee. The invitee's client should indicate this in the UI to the user, as should the inviter. This is to keep the intent for new rooms From f4c7fdfd03344f8a4045a2126d858c95e7cc5013 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 3 Oct 2016 16:54:16 +0100 Subject: [PATCH 17/57] Remove references to refresh tokens and tokenrefresh refresh tokens are dead. --- api/client-server/definitions/security.yaml | 2 +- api/client-server/login.yaml | 73 --------------------- api/client-server/registration.yaml | 16 ++--- changelogs/client_server.rst | 37 ++++++----- specification/client_server_api.rst | 31 ++++++--- 5 files changed, 46 insertions(+), 113 deletions(-) diff --git a/api/client-server/definitions/security.yaml b/api/client-server/definitions/security.yaml index 0668eb95..bb78f0e3 100644 --- a/api/client-server/definitions/security.yaml +++ b/api/client-server/definitions/security.yaml @@ -13,6 +13,6 @@ # limitations under the License. accessToken: type: apiKey - description: The access_token returned by a call to ``/login`` or ``/tokenrefresh`` + description: The access_token returned by a call to ``/login`` or ``/register`` name: access_token in: query diff --git a/api/client-server/login.yaml b/api/client-server/login.yaml index 3ca397ea..7731f507 100644 --- a/api/client-server/login.yaml +++ b/api/client-server/login.yaml @@ -90,15 +90,6 @@ paths: description: |- An access token for the account. This access token can then be used to authorize other requests. - The access token may expire at some point, and if so, it SHOULD come with a ``refresh_token``. - There is no specific error message to indicate that a request has failed because - an access token has expired; instead, if a client has reason to believe its - access token is valid, and it receives an auth error, they should attempt to - refresh for a new token on failure, and retry the request with the new token. - refresh_token: - type: string - description: |- - Optional. A ``refresh_token`` may be exchanged for a new ``access_token`` using the |/tokenrefresh|_ API endpoint. home_server: type: string description: The hostname of the homeserver on which the account has been registered. @@ -123,67 +114,3 @@ paths: "$ref": "definitions/error.yaml" tags: - Session management - "/tokenrefresh": - post: - summary: Exchanges a refresh token for an access token. - description: |- - Exchanges a refresh token for a new access token. - This is intended to be used if the access token has expired. - - The server MUST invalidate the supplied ``refresh_token`` if the - request is successful. It MUST also invalidate the ``access_token`` - which was issued at the same time as the ``refresh_token``, if it - has not already expired. - security: - - accessToken: [] - parameters: - - in: body - name: body - schema: - type: object - example: |- - { - "refresh_token": "a1b2c3" - } - properties: - refresh_token: - type: string - description: The refresh token which was issued by the server. - required: ["refresh_token"] - responses: - 200: - description: |- - The refresh token was accepted, and a new access token has been issued. - The passed refresh token is no longer valid and cannot be used. - A new refresh token will have been returned unless some policy does - not allow the user to continue to renew their session. - examples: - application/json: |- - { - "access_token": "bearwithme123", - "refresh_token": "exchangewithme987" - } - schema: - type: object - properties: - access_token: - type: string - description: |- - An access token for the account. - This access token can then be used to authorize other requests. - The access token may expire at some point, and if so, it SHOULD come with a ``refresh_token``. - refresh_token: - type: string - description: Optional. A new ``refresh_token`` which may be exchanged for another new ``access_token``. - 403: - description: |- - The exchange attempt failed. For example, the refresh token may have already been used. - examples: - application/json: |- - {"errcode": "M_FORBIDDEN"} - 429: - description: This request was rate-limited. - schema: - "$ref": "definitions/error.yaml" - tags: - - Session management diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 6da04d45..8145824e 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -39,6 +39,9 @@ paths: - `guest` accounts. These accounts may have limited permissions and may not be supported by all servers. + If registration is successful, this endpoint will issue an access token + the client can use to authorize itself in subsequent requests. + parameters: - in: query name: kind @@ -90,8 +93,7 @@ paths: { "user_id": "@cheeky_monkey:matrix.org", "access_token": "abc123", - "home_server": "matrix.org", - "refresh_token": "def456" + "home_server": "matrix.org" } schema: type: object @@ -104,16 +106,6 @@ paths: description: |- An access token for the account. This access token can then be used to authorize other requests. - The access token may expire at some point, and if so, it SHOULD come with a ``refresh_token``. - There is no specific error message to indicate that a request has failed because - an access token has expired; instead, if a client has reason to believe its - access token is valid, and it receives an auth error, they should attempt to - refresh for a new token on failure, and retry the request with the new token. - refresh_token: - type: string - # TODO: Work out how to linkify /tokenrefresh - description: |- - (optional) A ``refresh_token`` may be exchanged for a new ``access_token`` using the /tokenrefresh API endpoint. home_server: type: string description: The hostname of the homeserver on which the account has been registered. diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index 60554fcb..b0678cd6 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -8,23 +8,11 @@ which support push rules, but any other clients implementing the push rules API should be aware of this change. This makes it simple to mute rooms correctly in the API. - -- Spec clarifications: - - - Spell out the way that state is handled by ``POST /createRoom`` - (`#362 `_). - - Emphasise that ``POST /tokenrefresh`` should expire the access token - (`#363 `_). - - Clarify the fields which are applicable to different types of push rule - (`#365 `_). - - A number of clarifications to authentication - (`#371 `_). - - Correct references to ``user_id`` which should have been ``sender`` - (`#376 `_). - - Correct inconsistent specification of ``redacted_because`` fields and their - values (`#378 `_). - - Mark required fields in response objects as such - (`#394 `_). + (`#373 `_). + - Remove ``/tokenrefresh`` from the API. + (`#395 `_). + - Remove requirement that tokens used in token-based login be macaroons. + (`#395 `_). - Changes to the API which will be backwards-compatible for clients: @@ -42,6 +30,21 @@ - Add ``filter`` optional query param to ``/messages`` (`#390 `_). +- Spec clarifications: + + - Spell out the way that state is handled by ``POST /createRoom`` + (`#362 `_). + - Clarify the fields which are applicable to different types of push rule + (`#365 `_). + - A number of clarifications to authentication + (`#371 `_). + - Correct references to ``user_id`` which should have been ``sender`` + (`#376 `_). + - Correct inconsistent specification of ``redacted_because`` fields and their + values (`#378 `_). + - Mark required fields in response objects as such + (`#394 `_). + r0.2.0 ====== diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index a74129b5..a2946d45 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -158,14 +158,23 @@ recommended. Client Authentication --------------------- + Most API endpoints require the user to identify themselves by presenting previously obtained credentials in the form of an ``access_token`` query -parameter. +parameter. An access token is typically obtained via the `Login`_ or +`Registration`_ processes. When credentials are required but missing or invalid, the HTTP call will return with a status of 401 and the error code, ``M_MISSING_TOKEN`` or ``M_UNKNOWN_TOKEN`` respectively. +.. NOTE:: + + This specification does not mandate a particular format for the access + token. Clients should treat it as an opaque byte sequence. Servers are free + to choose an appropriate format. Server implementors may like to investigate + `macaroons `_. + User-Interactive Authentication API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -249,7 +258,7 @@ complete auth type ``example.type.foo``, it might submit something like this: POST /_matrix/client/r0/endpoint HTTP/1.1 Content-Type: application/json - + { "a_request_parameter": "something", "another_request_parameter": "something else", @@ -460,8 +469,8 @@ server side, as well as potentially invalidating the token completely once the device has successfully logged in (e.g. when we receive a request from the newly provisioned access_token). -The ``token`` must be a macaroon, with a caveat encoding the user id. There is -therefore no need for the client to submit a separate username. +The server must encode the user id in the ``token``. There is therefore no need +for the client to submit a separate username. OAuth2-based <<<<<<<<<<<< @@ -595,9 +604,9 @@ follows: "token": "" } -As with `token-based`_ interactive login, the ``token`` must be a macroon with -a caveat which includes the user id. In the case that the token is not valid, the -homeserver must respond with ``403 Forbidden`` and an error code of ``M_FORBIDDEN``. +As with `token-based`_ interactive login, the ``token`` must encode the +user id. In the case that the token is not valid, the homeserver must respond +with ``403 Forbidden`` and an error code of ``M_FORBIDDEN``. {{login_cs_http_api}} @@ -615,6 +624,8 @@ This returns an HTML and JavaScript page which can perform the entire login process. The page will attempt to call the JavaScript function ``window.onLogin`` when login has been successfully completed. +.. _Registration: + Account registration and management ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1230,6 +1241,9 @@ have to wait in milliseconds before they can try again. homeserver come up with their own idea, causing totally unpredictable performance over federated rooms? +.. References + +.. _`macaroon`: http://research.google.com/pubs/pub41892.html .. Links through the external API docs are below .. ============================================= @@ -1237,9 +1251,6 @@ have to wait in milliseconds before they can try again. .. |/initialSync| replace:: ``/initialSync`` .. _/initialSync: #get-matrix-client-%CLIENT_MAJOR_VERSION%-initialsync -.. |/tokenrefresh| replace:: ``/tokenrefresh`` -.. _/tokenrefresh: #post-matrix-client-%CLIENT_MAJOR_VERSION%-tokenrefresh - .. |/sync| replace:: ``/sync`` .. _/sync: #get-matrix-client-%CLIENT_MAJOR_VERSION%-sync From 8fe8bd6a815c3f1fa38bb9e3942cfa9ff36399db Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 3 Oct 2016 17:33:45 +0100 Subject: [PATCH 18/57] Add is_direct to member event spec. --- api/client-server/create_room.yaml | 3 ++- event-schemas/schema/m.room.member | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/api/client-server/create_room.yaml b/api/client-server/create_room.yaml index c4a9c8ff..ce9ab46b 100644 --- a/api/client-server/create_room.yaml +++ b/api/client-server/create_room.yaml @@ -180,7 +180,8 @@ paths: synchronised at first. Both users may subsequently choose to tag the room differently. This adds an ``is_direct`` flag to the content of any invites - sent. + sent, which will appear in the content of the `m.room.member`_ + event. responses: 200: description: Information about the newly created room. diff --git a/event-schemas/schema/m.room.member b/event-schemas/schema/m.room.member index f9aa5051..adb9a831 100644 --- a/event-schemas/schema/m.room.member +++ b/event-schemas/schema/m.room.member @@ -39,6 +39,9 @@ properties: - leave - ban type: string + is_direct: + description: Flag indicating if this room was created with the intention of being a direct chat + type: boolean third_party_invite: properties: display_name: From 203ea993281d4babe8be45638bd1d395ab0a7827 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 3 Oct 2016 18:17:43 +0100 Subject: [PATCH 19/57] Spec m.direct --- specification/modules/dm.rst | 57 ++++++++++++++++++++++++++++++++++++ specification/targets.yaml | 1 + 2 files changed, 58 insertions(+) create mode 100644 specification/modules/dm.rst diff --git a/specification/modules/dm.rst b/specification/modules/dm.rst new file mode 100644 index 00000000..4747bd48 --- /dev/null +++ b/specification/modules/dm.rst @@ -0,0 +1,57 @@ +.. Copyright 2016 OpenMarket Ltd +.. +.. Licensed under the Apache License, Version 2.0 (the "License"); +.. you may not use this file except in compliance with the License. +.. You may obtain a copy of the License at +.. +.. http://www.apache.org/licenses/LICENSE-2.0 +.. +.. Unless required by applicable law or agreed to in writing, software +.. distributed under the License is distributed on an "AS IS" BASIS, +.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +.. See the License for the specific language governing permissions and +.. limitations under the License. + +Direct Messaging +================ + +.. _module:dm: + +All communications over Matrix happens within a room. It is sometimes +desireable to offer users the concept of speaking directly to one +particular person. This module defines a way of marking certain rooms +as 'direct chats' with a given person. This does not restrict the chat +to being between exactly two people since this would preclude the +presence of automated 'bot' users or even a 'personal assistant' who is +able to answer direct messages on behalf of the user in their absence. + +A room may not necessarily be considered 'direct' by all members of the +room, but a signalling mechanism exists to propagate the information of +whether a chat is 'direct' to an invitee. The invitee's client may +use this flag to automatically mark the room as a direct message but +this is not required: it may for example, prompt the user, ignore the +flag altogether. + +Events +------ + +A map of which rooms are considered 'direct' rooms for specific users +is kept in ``account_data`` in an event of type ``m.direct``. The +content of this event is an object where the keys are the user IDs +and values are lists of room ID strings of the 'direct' rooms for +that user ID. + +Example:: + + { + "@bob:example.com": [ + "!abcdefgh:example.com", + "!hgfedcba:example.com" + ] + } + + +When creating a room, the ``is_direct`` flag may be specified to signal +to the invitee that this is a direct chat. See +`GET /_matrix/client/unstable/initialSync`_. This flag appears as +``is_direct`` in the member event: see `m.room.member`_. diff --git a/specification/targets.yaml b/specification/targets.yaml index 6cbfa917..c63db5a6 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -53,6 +53,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/admin.rst - modules/event_context.rst - modules/cas_login.rst + - modules/dm.rst title_styles: ["=", "-", "~", "+", "^", "`", "@", ":"] From accb3941bfbb4a79fa46f3e81896718280bf1de3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 3 Oct 2016 18:20:45 +0100 Subject: [PATCH 20/57] Changelog --- changelogs/client_server.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index f156c96e..10d4f82e 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -37,7 +37,8 @@ - Add top-level ``account_data`` key to the responses to ``GET /sync`` and ``GET /initialSync`` (`#380 `_). - - Add ``is_direct`` flag to ``/createRoom``. + - Add ``is_direct`` flag to ``/createRoom`` and invite member event. + Add 'Direct Messaging' module. (`#389 `_). - Add ``contains_url`` option to ``RoomEventFilter``. (`#390 `_). From d39f662df5221aba99ed2ebcf1cb8f0855358f50 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 4 Oct 2016 11:57:24 +0100 Subject: [PATCH 21/57] PR feedback --- api/client-server/create_room.yaml | 12 +++--------- specification/modules/dm.rst | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/api/client-server/create_room.yaml b/api/client-server/create_room.yaml index ce9ab46b..811b1187 100644 --- a/api/client-server/create_room.yaml +++ b/api/client-server/create_room.yaml @@ -173,15 +173,9 @@ paths: is_direct: type: boolean description: |- - This flag shows that the intent for this room is to be a - one-to-one 'direct' conversation with the invitee. The - invitee's client should indicate this in the UI to the user, - as should the inviter. This is to keep the intent for new rooms - synchronised at first. Both users may subsequently choose to - tag the room differently. - This adds an ``is_direct`` flag to the content of any invites - sent, which will appear in the content of the `m.room.member`_ - event. + This flag makes the server set the is_direct flag on the + m.room.member events sent to the users in invite and + invite_3pid. See (Direct Messaging) for more information. responses: 200: description: Information about the newly created room. diff --git a/specification/modules/dm.rst b/specification/modules/dm.rst index 4747bd48..30f4067d 100644 --- a/specification/modules/dm.rst +++ b/specification/modules/dm.rst @@ -17,7 +17,7 @@ Direct Messaging .. _module:dm: -All communications over Matrix happens within a room. It is sometimes +All communication over Matrix happens within a room. It is sometimes desireable to offer users the concept of speaking directly to one particular person. This module defines a way of marking certain rooms as 'direct chats' with a given person. This does not restrict the chat From 976d41351e9dbd3b59306d996540c9b6b7da8d45 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 4 Oct 2016 12:43:41 +0100 Subject: [PATCH 22/57] spelling --- specification/modules/dm.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/dm.rst b/specification/modules/dm.rst index 30f4067d..54102e74 100644 --- a/specification/modules/dm.rst +++ b/specification/modules/dm.rst @@ -18,7 +18,7 @@ Direct Messaging .. _module:dm: All communication over Matrix happens within a room. It is sometimes -desireable to offer users the concept of speaking directly to one +desirable to offer users the concept of speaking directly to one particular person. This module defines a way of marking certain rooms as 'direct chats' with a given person. This does not restrict the chat to being between exactly two people since this would preclude the From 92291dcfda8a71988fa9b131871aa9deab2337b8 Mon Sep 17 00:00:00 2001 From: Oddvar Lovaas Date: Tue, 4 Oct 2016 12:52:34 +0100 Subject: [PATCH 23/57] Add MatrixTool, update the riots --- supporting-docs/projects/2014-06-09-riot.md | 2 +- supporting-docs/projects/2015-04-02-riot-ios.md | 2 +- supporting-docs/projects/2015-06-02-riot-android.md | 4 ++-- supporting-docs/projects/2015-11-28-matrixtool.md | 13 +++++++++++++ 4 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 supporting-docs/projects/2015-11-28-matrixtool.md diff --git a/supporting-docs/projects/2014-06-09-riot.md b/supporting-docs/projects/2014-06-09-riot.md index b5c2d4e3..80a9172c 100644 --- a/supporting-docs/projects/2014-06-09-riot.md +++ b/supporting-docs/projects/2014-06-09-riot.md @@ -5,7 +5,7 @@ categories: projects client thumbnail: https://matrix.org/blog/wp-content/uploads/2015/08/vector030216-400x284.png author: Riot.im description: Riot is a glossy web client with an emphasis on performance and usability -maturity: Late beta +maturity: Released --- ![screenshot](https://matrix.org/blog/wp-content/uploads/2015/08/vector030216-1080x745.png "{{ page.title }}") diff --git a/supporting-docs/projects/2015-04-02-riot-ios.md b/supporting-docs/projects/2015-04-02-riot-ios.md index 555601a1..e9dcb3b9 100644 --- a/supporting-docs/projects/2015-04-02-riot-ios.md +++ b/supporting-docs/projects/2015-04-02-riot-ios.md @@ -5,7 +5,7 @@ categories: projects client thumbnail: /docs/projects/images/vector-iOS-small.png description: Riot is a glossy client with an emphasis on performance and usability author: Riot.im -maturity: Beta +maturity: Released --- ![screenshot](/docs/projects/images/vector-iOS-large.png "{{ page.title }}") diff --git a/supporting-docs/projects/2015-06-02-riot-android.md b/supporting-docs/projects/2015-06-02-riot-android.md index a23e0afd..cedf4454 100644 --- a/supporting-docs/projects/2015-06-02-riot-android.md +++ b/supporting-docs/projects/2015-06-02-riot-android.md @@ -5,7 +5,7 @@ categories: projects client thumbnail: /docs/projects/images/vector-android-small.png description: Riot is a glossy client with an emphasis on performance and usability author: Riot.im -maturity: Beta +maturity: Released --- ![screenshot](/docs/projects/images/vector-android-large.png "{{ page.title }}") @@ -13,6 +13,6 @@ maturity: Beta # {{ page.title }} The Android version of the [Riot](https://matrix.org/docs/projects/client/riot.html) web client. Riot is a glossy client with focus on performance and usability. -The code is available from [github](https://github.com/vector-im/vector-android), and the app is available from the [Google Play store](https://play.google.com/store/apps/details?id=im.riot) and (as "Vector") [F-Droid](https://f-droid.org/repository/browse/?fdfilter=vector&fdid=im.vector.alpha). +The code is available from [github](https://github.com/vector-im/vector-android), and the app is available from the [Google Play store](https://play.google.com/store/apps/details?id=im.vector.alpha) and [F-Droid](https://f-droid.org/repository/browse/?fdfilter=vector&fdid=im.vector.alpha). If you want to help test the app, you can download development versions from [Jenkins](https://matrix.org/jenkins/job/VectorAndroidDevelop/). diff --git a/supporting-docs/projects/2015-11-28-matrixtool.md b/supporting-docs/projects/2015-11-28-matrixtool.md new file mode 100644 index 00000000..8acc0df7 --- /dev/null +++ b/supporting-docs/projects/2015-11-28-matrixtool.md @@ -0,0 +1,13 @@ +--- +layout: project +title: MatrixTool +categories: projects other +description: Commands to interact with a Matrix homeserver +author: LeoNerd +maturity: Alpha +--- +# {{ page.title }} + +The tool provides a wrapper around a number of sub-commands that provide useful interactions with a Matrix homeserver. + +You can grab it from [CPAN](http://search.cpan.org/~pevans/App-MatrixTool/). From 85bc989c026457d233bc50ed18698cf6690b89ef Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 4 Oct 2016 15:07:14 +0100 Subject: [PATCH 24/57] pr feedback --- event-schemas/examples/m.direct | 9 +++++++++ event-schemas/schema/m.direct | 23 ++++++++++++++++++++++ specification/modules/dm.rst | 35 ++++++++++++++++++++------------- 3 files changed, 53 insertions(+), 14 deletions(-) create mode 100644 event-schemas/examples/m.direct create mode 100644 event-schemas/schema/m.direct diff --git a/event-schemas/examples/m.direct b/event-schemas/examples/m.direct new file mode 100644 index 00000000..92f13daa --- /dev/null +++ b/event-schemas/examples/m.direct @@ -0,0 +1,9 @@ +{ + "type": "m.direct", + "content": { + "@bob:example.com": [ + "!abcdefgh:example.com", + "!hgfedcba:example.com" + ] + } +} diff --git a/event-schemas/schema/m.direct b/event-schemas/schema/m.direct new file mode 100644 index 00000000..4f568078 --- /dev/null +++ b/event-schemas/schema/m.direct @@ -0,0 +1,23 @@ +{ + "type": "object", + "title": "Direct Message Map Event", + "description": "Account Data event used to store which rooms are 'direct chats' for which users.", + "allOf": [{ + "$ref": "core-event-schema/event.yaml" + }], + "properties": { + "type": { + "type": "string", + "enum": ["m.direct"] + }, + "content": { + "type": "object", + "description": "Object mapping user IDs to lists of room IDs.", + "additionalProperties": { + "title": "User ID", + "type": "array" + } + } + }, + "required": ["type", "content"] +} diff --git a/specification/modules/dm.rst b/specification/modules/dm.rst index 54102e74..6170d98a 100644 --- a/specification/modules/dm.rst +++ b/specification/modules/dm.rst @@ -27,10 +27,7 @@ able to answer direct messages on behalf of the user in their absence. A room may not necessarily be considered 'direct' by all members of the room, but a signalling mechanism exists to propagate the information of -whether a chat is 'direct' to an invitee. The invitee's client may -use this flag to automatically mark the room as a direct message but -this is not required: it may for example, prompt the user, ignore the -flag altogether. +whether a chat is 'direct' to an invitee. Events ------ @@ -41,17 +38,27 @@ content of this event is an object where the keys are the user IDs and values are lists of room ID strings of the 'direct' rooms for that user ID. -Example:: - - { - "@bob:example.com": [ - "!abcdefgh:example.com", - "!hgfedcba:example.com" - ] - } - - When creating a room, the ``is_direct`` flag may be specified to signal to the invitee that this is a direct chat. See `GET /_matrix/client/unstable/initialSync`_. This flag appears as ``is_direct`` in the member event: see `m.room.member`_. + +{{m_direct_event}} + +Client behaviour +---------------- +The invitee's client may use the ``is_direct`` flag to automatically mark the +room as a direct message but this is not required: it may for example, prompt +the user, ignore the flag altogether. + +The inviter's client should set the ``is_direct`` flag to ``createRoom`` +whenever the flow the user has followed is one where their intention is to +speak directly with another person, as opposed to bringing that person in to a +shared room. For example, clicking on, 'Start Chat' beside a person's profile +picture would imply the ``is_direct`` flag should be set. + +Server behaviour +---------------- +When the ``is_direct`` flag is given to ``createRoom``, the home server must +set the ``is_direct`` flag in the invite member event for any users invited +in the ``createRoom`` call. From 8af90bfc2147439e7ad062d104941b49be177ceb Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 4 Oct 2016 15:08:48 +0100 Subject: [PATCH 25/57] Clarify 'this room' --- event-schemas/schema/m.room.member | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event-schemas/schema/m.room.member b/event-schemas/schema/m.room.member index adb9a831..06c4fa3b 100644 --- a/event-schemas/schema/m.room.member +++ b/event-schemas/schema/m.room.member @@ -40,7 +40,7 @@ properties: - ban type: string is_direct: - description: Flag indicating if this room was created with the intention of being a direct chat + description: Flag indicating if the room containing this event was created with the intention of being a direct chat. type: boolean third_party_invite: properties: From 8e096bdc48bd9c362fff074a3ec7742eacfb459e Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 4 Oct 2016 15:15:01 +0100 Subject: [PATCH 26/57] Link to createRoom, not initialsync --- specification/modules/dm.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/specification/modules/dm.rst b/specification/modules/dm.rst index 6170d98a..f204583e 100644 --- a/specification/modules/dm.rst +++ b/specification/modules/dm.rst @@ -38,9 +38,9 @@ content of this event is an object where the keys are the user IDs and values are lists of room ID strings of the 'direct' rooms for that user ID. -When creating a room, the ``is_direct`` flag may be specified to signal -to the invitee that this is a direct chat. See -`GET /_matrix/client/unstable/initialSync`_. This flag appears as +When creating a room, the ``is_direct`` flag may be specified to signal to the +invitee that this is a direct chat. See `POST +/_matrix/client/%CLIENT_MAJOR_VERSION%/createRoom`_. This flag appears as ``is_direct`` in the member event: see `m.room.member`_. {{m_direct_event}} From 1d7531e9a1c954530ca3a7a249c9fbb2643117ba Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 4 Oct 2016 17:51:35 +0100 Subject: [PATCH 27/57] Typo --- api/client-server/rooms.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client-server/rooms.yaml b/api/client-server/rooms.yaml index 5cbd144f..0bb268dd 100644 --- a/api/client-server/rooms.yaml +++ b/api/client-server/rooms.yaml @@ -246,7 +246,7 @@ paths: 200: description: |- A list of members of the room. If you are joined to the room then - this will be the current members of the room. If you have left te + this will be the current members of the room. If you have left the room then this will be the members of the room when you left. examples: application/json: |- From c16ba9488f28c44f0c0d13b10a9bd8d76a1bf36e Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 10:15:49 +0100 Subject: [PATCH 28/57] Spec notifs API --- api/client-server/notifications.yaml | 126 +++++++++++++++++++++++++++ specification/modules/push.rst | 9 ++ 2 files changed, 135 insertions(+) create mode 100644 api/client-server/notifications.yaml diff --git a/api/client-server/notifications.yaml b/api/client-server/notifications.yaml new file mode 100644 index 00000000..32fd12a1 --- /dev/null +++ b/api/client-server/notifications.yaml @@ -0,0 +1,126 @@ +# Copyright 2016 OpenMarket Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +swagger: '2.0' +info: + title: "Matrix Client-Server Notifications API" + version: "1.0.0" +host: localhost:8008 +schemes: + - https + - http +basePath: /_matrix/client/%CLIENT_MAJOR_VERSION% +consumes: + - application/json +produces: + - application/json +securityDefinitions: + $ref: definitions/security.yaml +paths: + "/notifications": + get: + summary: Gets a list of events that the user has been notified about + description: |- + This API is used to paginate through the list of events that the + user has been, or would have been notified about. + security: + - accessToken: [] + parameters: + - in: path + type: string + name: from + description: Pagination token given to retrieve the next set of events. + required: false + x-example: "xxxxx" + - in: path + type: number + name: limit + description: Limit on the number of events to return in this request. + required: false + x-example: "20" + - in: path + name: only + type: string + description: |- + Allows basic filtering of events returned. Supply ``hightlight`` + to return only events where the notification had the highlight + tweak set. + required: false + x-example: "highlight" + responses: + 200: + description: A batch of events is being returned + examples: + application/json: |- + { + "next_token": "abcdef", + "notifications": { + "actions": [ + "notify" + ], + "profile_tag", null, + "read", true, + "room_id", "!abcdefg:example.com", + "ts", "1475508881945", + "event", { + } + } + } + schema: + type: object + properties: + next_token: + type: string + description: |- + The token to supply in the ``from`` param of the next + ``/notifications`` request in order to request more + events. + notifications: + type: array + items: + type: object + title: notification + properties: + actions: + type: array + description: |- + The action(s) to perform when the conditions for this rule are met. + See `Push Rules: API`_. + items: + type: any + event: + type: object + title: Event + description: The Event object for the event that triggered the notification. + allOf: + - "$ref": "definitions/event.yaml" + profile_tag: + type: string + description: The profile tag of the rule that matched this event. + read: + type: boolean + description: |- + Indicates whether the user has sent a read receipt indicating + that they have read this message. + room_id: + type: string + description: The ID of the room in which the event was posted. + ts: + type: number + description: |- + The unix timestamp at which the event notification was sent, + in seconds. + description: The list of events that triggered notifications. + tags: + - Notifications API diff --git a/specification/modules/push.rst b/specification/modules/push.rst index ba98ea44..58c816b3 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -107,6 +107,15 @@ There is a single API endpoint for this, as described below. .. _pushers: `def:pushers`_ +Listing Notifications +~~~~~~~~~~~~~~~~~~~~~ + +A client can retrieve a list of events that it has been notified about. This +may be useful so that users can see a summary of what important messages they +have received. + +{{notifications_cs_http_api}} + Push Rules ~~~~~~~~~~ A push rule is a single rule that states under what *conditions* an event should From 41781e95b2d9e08578bf1b641af3176982381315 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 10:21:29 +0100 Subject: [PATCH 29/57] Attempt valid json --- api/client-server/notifications.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api/client-server/notifications.yaml b/api/client-server/notifications.yaml index 32fd12a1..c23864f3 100644 --- a/api/client-server/notifications.yaml +++ b/api/client-server/notifications.yaml @@ -69,11 +69,11 @@ paths: "actions": [ "notify" ], - "profile_tag", null, - "read", true, - "room_id", "!abcdefg:example.com", - "ts", "1475508881945", - "event", { + "profile_tag": null, + "read": true, + "room_id": "!abcdefg:example.com", + "ts": "1475508881945", + "event": { } } } From 595b75f299ac023a7f073bccf8fffc558b69023d Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 10:32:03 +0100 Subject: [PATCH 30/57] Try & make example closer to valid --- api/client-server/notifications.yaml | 32 +++++++++++++++++++--------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/api/client-server/notifications.yaml b/api/client-server/notifications.yaml index c23864f3..b875aa28 100644 --- a/api/client-server/notifications.yaml +++ b/api/client-server/notifications.yaml @@ -65,17 +65,29 @@ paths: application/json: |- { "next_token": "abcdef", - "notifications": { - "actions": [ - "notify" - ], - "profile_tag": null, - "read": true, - "room_id": "!abcdefg:example.com", - "ts": "1475508881945", - "event": { + "notifications": [ + { + "actions": [ + "notify" + ], + "profile_tag": null, + "read": true, + "room_id": "!abcdefg:example.com", + "ts": "1475508881945", + "event": { + "sender": "@alice:example.com", + "type": "m.room.message", + "age": 124524, + "txn_id": "1234", + "content": { + "body": "I am a fish", + "msgtype": "m.text" + }, + "origin_server_ts": 1417731086797, + "event_id": "$74686972643033:example.com" + } } - } + ] } schema: type: object From 136d5dc9add03002eb058f430604bd9cf3981f21 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 11:15:33 +0100 Subject: [PATCH 31/57] Almost valid... --- api/client-server/notifications.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/client-server/notifications.yaml b/api/client-server/notifications.yaml index b875aa28..80185440 100644 --- a/api/client-server/notifications.yaml +++ b/api/client-server/notifications.yaml @@ -70,10 +70,10 @@ paths: "actions": [ "notify" ], - "profile_tag": null, + "profile_tag": "hcbvkzxhcvb", "read": true, "room_id": "!abcdefg:example.com", - "ts": "1475508881945", + "ts": 1475508881945, "event": { "sender": "@alice:example.com", "type": "m.room.message", From c1fa342b9004bc1bbf91ae4f8bd74fc1e4ccd20a Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 11:21:06 +0100 Subject: [PATCH 32/57] Swagger is failing on type 'any' --- api/client-server/notifications.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/api/client-server/notifications.yaml b/api/client-server/notifications.yaml index 80185440..b65bb0a1 100644 --- a/api/client-server/notifications.yaml +++ b/api/client-server/notifications.yaml @@ -109,8 +109,6 @@ paths: description: |- The action(s) to perform when the conditions for this rule are met. See `Push Rules: API`_. - items: - type: any event: type: object title: Event From a463820d83708ebbb4f5caccdac17bdcc2aec61c Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 11:21:56 +0100 Subject: [PATCH 33/57] Typo --- api/client-server/notifications.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client-server/notifications.yaml b/api/client-server/notifications.yaml index b65bb0a1..af7b2e8a 100644 --- a/api/client-server/notifications.yaml +++ b/api/client-server/notifications.yaml @@ -53,7 +53,7 @@ paths: name: only type: string description: |- - Allows basic filtering of events returned. Supply ``hightlight`` + Allows basic filtering of events returned. Supply ``highlight`` to return only events where the notification had the highlight tweak set. required: false From 692e40bec97c671730552f258ce5d3c4eed22c27 Mon Sep 17 00:00:00 2001 From: Oddvar Lovaas Date: Wed, 5 Oct 2016 11:25:03 +0100 Subject: [PATCH 34/57] Add telematrix --- supporting-docs/projects/2016-09-13-telematrix.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 supporting-docs/projects/2016-09-13-telematrix.md diff --git a/supporting-docs/projects/2016-09-13-telematrix.md b/supporting-docs/projects/2016-09-13-telematrix.md new file mode 100644 index 00000000..29c46554 --- /dev/null +++ b/supporting-docs/projects/2016-09-13-telematrix.md @@ -0,0 +1,12 @@ +--- +layout: project +title: telematrix +categories: projects as +author: SijmenSchoon +maturity: Alpha +--- + +# {{ page.title }} +This project bridges [Telegram Messenger](https://telegram.org/) to Matrix. It's currently in early development, and not considered to be in a usable state yet. + +Get it and report issues at [github](https://github.com/SijmenSchoon/telematrix)! From a8d35b24099ecfa5c3f1eb8489fae138f9823a12 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 5 Oct 2016 11:25:49 +0100 Subject: [PATCH 35/57] UI Auth: servers should 401 when a request fails (ref https://matrix.org/jira/browse/SYN-744) --- specification/client_server_api.rst | 48 +++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 77dc90b6..6217b9fc 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -298,8 +298,42 @@ successfully: "session": "xxxxxx" } -If the homeserver decides the attempt was unsuccessful, it returns an error -message in the standard format: +Individual stages may require more than one request to complete, in which case +the response will be as if the request was unauthenticated with the addition of +any other keys as defined by the auth type. + +If the homeserver decides that an attempt on a stage was unsuccessful, but the +client may make a second attempt, it returns the same HTTP status 401 response +as above, with the addition of the standard ``errcode`` and ``error`` fields +describing the error. For example: + +.. code:: + + HTTP/1.1 401 Unauthorized + Content-Type: application/json + + { + "errcode": "M_FORBIDDEN", + "error": "Invalid password", + "completed": [ "example.type.foo" ], + "flows": [ + { + "stages": [ "example.type.foo", "example.type.bar" ] + }, + { + "stages": [ "example.type.foo", "example.type.baz" ] + } + ], + "params": { + "example.type.baz": { + "example_key": "foobar" + } + }, + "session": "xxxxxx" + } + +If the request fails for a reason other than authentication, the server returns an error +message in the standard format. For example: .. code:: @@ -311,10 +345,6 @@ message in the standard format: "error": "Something was wrong" } -Individual stages may require more than one request to complete, in which case -the response will be as if the request was unauthenticated with the addition of -any other keys as defined by the auth type. - If the client has completed all stages of a flow, the homeserver performs the API call and returns the result as normal. @@ -417,12 +447,6 @@ follows: In the case that the homeserver does not know about the supplied 3pid, the homeserver must respond with 403 Forbidden. -.. WARNING:: - Clients SHOULD enforce that the password provided is suitably complex. The - password SHOULD include a lower-case letter, an upper-case letter, a number - and a symbol and be at a minimum 8 characters in length. Servers MAY reject - weak passwords with an error code ``M_WEAK_PASSWORD``. - Google ReCaptcha <<<<<<<<<<<<<<<< :Type: From b4c89accb2210d66e22b2fe8d20b346615db7adb Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 11:48:14 +0100 Subject: [PATCH 36/57] Params in query, not path --- api/client-server/notifications.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/client-server/notifications.yaml b/api/client-server/notifications.yaml index af7b2e8a..c4983829 100644 --- a/api/client-server/notifications.yaml +++ b/api/client-server/notifications.yaml @@ -37,19 +37,19 @@ paths: security: - accessToken: [] parameters: - - in: path + - in: query type: string name: from description: Pagination token given to retrieve the next set of events. required: false x-example: "xxxxx" - - in: path + - in: query type: number name: limit description: Limit on the number of events to return in this request. required: false x-example: "20" - - in: path + - in: query name: only type: string description: |- From 4a020025bc2ca687f63ed357fd71a2a67d7b8123 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 11:51:48 +0100 Subject: [PATCH 37/57] Make swagger happpy These aren't strings, but 'any' causes swagger to break and leaving it out makes the doc fail to build. --- api/client-server/notifications.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/client-server/notifications.yaml b/api/client-server/notifications.yaml index c4983829..288987ab 100644 --- a/api/client-server/notifications.yaml +++ b/api/client-server/notifications.yaml @@ -109,6 +109,8 @@ paths: description: |- The action(s) to perform when the conditions for this rule are met. See `Push Rules: API`_. + items: + type: string event: type: object title: Event From b789251f70b879f2add117291939db7f39b82372 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 12:59:49 +0100 Subject: [PATCH 38/57] More PR feedback --- api/client-server/create_room.yaml | 6 +++--- event-schemas/schema/m.room.member | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/client-server/create_room.yaml b/api/client-server/create_room.yaml index 811b1187..a321b0f7 100644 --- a/api/client-server/create_room.yaml +++ b/api/client-server/create_room.yaml @@ -173,9 +173,9 @@ paths: is_direct: type: boolean description: |- - This flag makes the server set the is_direct flag on the - m.room.member events sent to the users in invite and - invite_3pid. See (Direct Messaging) for more information. + This flag makes the server set the ``is_direct`` flag on the + ``m.room.member`` events sent to the users in ``invite`` and + ``invite_3pid``. See `Direct Messaging`_ for more information. responses: 200: description: Information about the newly created room. diff --git a/event-schemas/schema/m.room.member b/event-schemas/schema/m.room.member index 06c4fa3b..4f4077a7 100644 --- a/event-schemas/schema/m.room.member +++ b/event-schemas/schema/m.room.member @@ -40,7 +40,7 @@ properties: - ban type: string is_direct: - description: Flag indicating if the room containing this event was created with the intention of being a direct chat. + description: Flag indicating if the room containing this event was created with the intention of being a direct chat. See `Direct Messaging`_. type: boolean third_party_invite: properties: From 4480553bf96b859d9a289db989dcd187a4a16f1e Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 13:12:14 +0100 Subject: [PATCH 39/57] Move m.direct description to the swagger Also change the swagger to yaml so I can put that description in it without having to figure out how to embed that in json. --- event-schemas/schema/m.direct | 44 +++++++++++++++++------------------ specification/modules/dm.rst | 12 +++------- 2 files changed, 24 insertions(+), 32 deletions(-) diff --git a/event-schemas/schema/m.direct b/event-schemas/schema/m.direct index 4f568078..b8a9cfc2 100644 --- a/event-schemas/schema/m.direct +++ b/event-schemas/schema/m.direct @@ -1,23 +1,21 @@ -{ - "type": "object", - "title": "Direct Message Map Event", - "description": "Account Data event used to store which rooms are 'direct chats' for which users.", - "allOf": [{ - "$ref": "core-event-schema/event.yaml" - }], - "properties": { - "type": { - "type": "string", - "enum": ["m.direct"] - }, - "content": { - "type": "object", - "description": "Object mapping user IDs to lists of room IDs.", - "additionalProperties": { - "title": "User ID", - "type": "array" - } - } - }, - "required": ["type", "content"] -} +--- +allOf: + - $ref: core-event-schema/event.yaml +description: |- + A map of which rooms are considered 'direct' rooms for specific users + is kept in ``account_data`` in an event of type ``m.direct``. The + content of this event is an object where the keys are the user IDs + and values are lists of room ID strings of the 'direct' rooms for + that user ID. +properties: + content: + additionalProperties: + type: array + title: User ID + type: object + type: + enum: + - m.direct + type: string +title: Direct Chat Mapping +type: object diff --git a/specification/modules/dm.rst b/specification/modules/dm.rst index f204583e..5ebfb169 100644 --- a/specification/modules/dm.rst +++ b/specification/modules/dm.rst @@ -32,21 +32,15 @@ whether a chat is 'direct' to an invitee. Events ------ -A map of which rooms are considered 'direct' rooms for specific users -is kept in ``account_data`` in an event of type ``m.direct``. The -content of this event is an object where the keys are the user IDs -and values are lists of room ID strings of the 'direct' rooms for -that user ID. +{{m_direct_event}} +Client behaviour +---------------- When creating a room, the ``is_direct`` flag may be specified to signal to the invitee that this is a direct chat. See `POST /_matrix/client/%CLIENT_MAJOR_VERSION%/createRoom`_. This flag appears as ``is_direct`` in the member event: see `m.room.member`_. -{{m_direct_event}} - -Client behaviour ----------------- The invitee's client may use the ``is_direct`` flag to automatically mark the room as a direct message but this is not required: it may for example, prompt the user, ignore the flag altogether. From d791f3500736b90914969ccf7654af7d693c7a54 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 13:13:50 +0100 Subject: [PATCH 40/57] Remove unnecessary paragraph --- specification/modules/dm.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/specification/modules/dm.rst b/specification/modules/dm.rst index 5ebfb169..639f7f85 100644 --- a/specification/modules/dm.rst +++ b/specification/modules/dm.rst @@ -36,11 +36,6 @@ Events Client behaviour ---------------- -When creating a room, the ``is_direct`` flag may be specified to signal to the -invitee that this is a direct chat. See `POST -/_matrix/client/%CLIENT_MAJOR_VERSION%/createRoom`_. This flag appears as -``is_direct`` in the member event: see `m.room.member`_. - The invitee's client may use the ``is_direct`` flag to automatically mark the room as a direct message but this is not required: it may for example, prompt the user, ignore the flag altogether. From e2024e58297d9517434ca7a2cce8f966bdb6e4a5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 13:22:30 +0100 Subject: [PATCH 41/57] Add note on how to use the account data event --- specification/modules/dm.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specification/modules/dm.rst b/specification/modules/dm.rst index 639f7f85..4785f5b1 100644 --- a/specification/modules/dm.rst +++ b/specification/modules/dm.rst @@ -38,7 +38,8 @@ Client behaviour ---------------- The invitee's client may use the ``is_direct`` flag to automatically mark the room as a direct message but this is not required: it may for example, prompt -the user, ignore the flag altogether. +the user, ignore the flag altogether. To do this, it stores this event in +account data using the ``account_data`` API: see `Client Config`_. The inviter's client should set the ``is_direct`` flag to ``createRoom`` whenever the flow the user has followed is one where their intention is to From 3f66ba713cf7fc9e05a6eacd864a032a3d57cdc7 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 13:25:42 +0100 Subject: [PATCH 42/57] Reference m.room.member section --- specification/modules/dm.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/specification/modules/dm.rst b/specification/modules/dm.rst index 4785f5b1..32c3ebfa 100644 --- a/specification/modules/dm.rst +++ b/specification/modules/dm.rst @@ -36,10 +36,11 @@ Events Client behaviour ---------------- -The invitee's client may use the ``is_direct`` flag to automatically mark the -room as a direct message but this is not required: it may for example, prompt -the user, ignore the flag altogether. To do this, it stores this event in -account data using the ``account_data`` API: see `Client Config`_. +The invitee's client may use the ``is_direct`` flag in `m.room.member`_ to +automatically mark the room as a direct message but this is not required: it +may for example, prompt the user, ignore the flag altogether. To do this, it +stores this event in account data using the ``account_data`` API: see `Client +Config`_. The inviter's client should set the ``is_direct`` flag to ``createRoom`` whenever the flow the user has followed is one where their intention is to From 2259a00ba263d4d2ef5143756d1adfbe841e063e Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 13:29:43 +0100 Subject: [PATCH 43/57] links --- specification/modules/dm.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/specification/modules/dm.rst b/specification/modules/dm.rst index 32c3ebfa..5b15e3b3 100644 --- a/specification/modules/dm.rst +++ b/specification/modules/dm.rst @@ -42,14 +42,14 @@ may for example, prompt the user, ignore the flag altogether. To do this, it stores this event in account data using the ``account_data`` API: see `Client Config`_. -The inviter's client should set the ``is_direct`` flag to ``createRoom`` -whenever the flow the user has followed is one where their intention is to -speak directly with another person, as opposed to bringing that person in to a -shared room. For example, clicking on, 'Start Chat' beside a person's profile -picture would imply the ``is_direct`` flag should be set. +The inviter's client should set the ``is_direct`` flag to ``createRoom`` +(`Creation`_) whenever the flow the user has followed is one where their +intention is to speak directly with another person, as opposed to bringing that +person in to a shared room. For example, clicking on, 'Start Chat' beside a +person's profile picture would imply the ``is_direct`` flag should be set. Server behaviour ---------------- -When the ``is_direct`` flag is given to ``createRoom``, the home server must -set the ``is_direct`` flag in the invite member event for any users invited -in the ``createRoom`` call. +When the ``is_direct`` flag is given to ``createRoom`` (`Creation`_), the home +server must set the ``is_direct`` flag in the invite member event for any users +invited in the ``createRoom`` call. From 2a987c33695fa2c260eba5bf17cc1a5089814a70 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 18:19:17 +0100 Subject: [PATCH 44/57] Linkify endpoints properly --- specification/client_server_api.rst | 3 +++ specification/modules/dm.rst | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index a74129b5..f12b495b 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1246,6 +1246,9 @@ have to wait in milliseconds before they can try again. .. |/events| replace:: ``/events`` .. _/events: #get-matrix-client-%CLIENT_MAJOR_VERSION%-events +.. |/createRoom| replace:: ``/createRoom`` +.. _/createRoom: #post-matrix-client-%CLIENT_MAJOR_VERSION%-createroom + .. |/rooms//initialSync| replace:: ``/rooms//initialSync`` .. _/rooms//initialSync: #get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-initialsync diff --git a/specification/modules/dm.rst b/specification/modules/dm.rst index 5b15e3b3..d148b945 100644 --- a/specification/modules/dm.rst +++ b/specification/modules/dm.rst @@ -42,14 +42,14 @@ may for example, prompt the user, ignore the flag altogether. To do this, it stores this event in account data using the ``account_data`` API: see `Client Config`_. -The inviter's client should set the ``is_direct`` flag to ``createRoom`` -(`Creation`_) whenever the flow the user has followed is one where their +The inviter's client should set the ``is_direct`` flag to .. |/createRoom|_ +whenever the flow the user has followed is one where their intention is to speak directly with another person, as opposed to bringing that person in to a shared room. For example, clicking on, 'Start Chat' beside a person's profile picture would imply the ``is_direct`` flag should be set. Server behaviour ---------------- -When the ``is_direct`` flag is given to ``createRoom`` (`Creation`_), the home +When the ``is_direct`` flag is given to .. |/createRoom|_, the home server must set the ``is_direct`` flag in the invite member event for any users invited in the ``createRoom`` call. From fd8c1a43c763df842220a955baf144c92079f2ef Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 18:22:03 +0100 Subject: [PATCH 45/57] ms, not s. Also add required flags --- api/client-server/notifications.yaml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/api/client-server/notifications.yaml b/api/client-server/notifications.yaml index 288987ab..f0ca4ec7 100644 --- a/api/client-server/notifications.yaml +++ b/api/client-server/notifications.yaml @@ -93,6 +93,7 @@ paths: type: object properties: next_token: + required: false type: string description: |- The token to supply in the ``from`` param of the next @@ -100,12 +101,14 @@ paths: events. notifications: type: array + required: true items: type: object title: notification properties: actions: type: array + required: true description: |- The action(s) to perform when the conditions for this rule are met. See `Push Rules: API`_. @@ -113,26 +116,31 @@ paths: type: string event: type: object + required: true title: Event description: The Event object for the event that triggered the notification. allOf: - "$ref": "definitions/event.yaml" profile_tag: type: string + required: false description: The profile tag of the rule that matched this event. read: type: boolean + required: true description: |- Indicates whether the user has sent a read receipt indicating that they have read this message. room_id: type: string + required: true description: The ID of the room in which the event was posted. ts: type: number + required: true description: |- The unix timestamp at which the event notification was sent, - in seconds. + in milliseconds. description: The list of events that triggered notifications. tags: - Notifications API From 14944fe237247ba6a1b1eb3a6b01bbcea555f706 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 18:26:42 +0100 Subject: [PATCH 46/57] More PR feedback --- api/client-server/notifications.yaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/api/client-server/notifications.yaml b/api/client-server/notifications.yaml index f0ca4ec7..2625e417 100644 --- a/api/client-server/notifications.yaml +++ b/api/client-server/notifications.yaml @@ -98,13 +98,14 @@ paths: description: |- The token to supply in the ``from`` param of the next ``/notifications`` request in order to request more - events. + events. If this is absent, there are no more results. notifications: type: array required: true items: type: object - title: notification + title: Notification + required: true properties: actions: type: array @@ -136,11 +137,11 @@ paths: required: true description: The ID of the room in which the event was posted. ts: - type: number + type: integer required: true description: |- The unix timestamp at which the event notification was sent, in milliseconds. description: The list of events that triggered notifications. tags: - - Notifications API + - Push notifications From af2c74c1867db0f9c4f84c787202d71add8779a7 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 18:50:14 +0100 Subject: [PATCH 47/57] Revert `required`s They're not boolean flags for object fields --- api/client-server/notifications.yaml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/api/client-server/notifications.yaml b/api/client-server/notifications.yaml index 2625e417..35e08bdf 100644 --- a/api/client-server/notifications.yaml +++ b/api/client-server/notifications.yaml @@ -93,7 +93,6 @@ paths: type: object properties: next_token: - required: false type: string description: |- The token to supply in the ``from`` param of the next @@ -101,15 +100,12 @@ paths: events. If this is absent, there are no more results. notifications: type: array - required: true items: type: object title: Notification - required: true properties: actions: type: array - required: true description: |- The action(s) to perform when the conditions for this rule are met. See `Push Rules: API`_. @@ -117,28 +113,23 @@ paths: type: string event: type: object - required: true title: Event description: The Event object for the event that triggered the notification. allOf: - "$ref": "definitions/event.yaml" profile_tag: type: string - required: false description: The profile tag of the rule that matched this event. read: type: boolean - required: true description: |- Indicates whether the user has sent a read receipt indicating that they have read this message. room_id: type: string - required: true description: The ID of the room in which the event was posted. ts: type: integer - required: true description: |- The unix timestamp at which the event notification was sent, in milliseconds. From bd753d4bf454ee0cab6751c8d109e9b47d09e51c Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 5 Oct 2016 18:53:08 +0100 Subject: [PATCH 48/57] Re-add required flags the correct way --- api/client-server/notifications.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/client-server/notifications.yaml b/api/client-server/notifications.yaml index 35e08bdf..f49f87f2 100644 --- a/api/client-server/notifications.yaml +++ b/api/client-server/notifications.yaml @@ -91,6 +91,7 @@ paths: } schema: type: object + required: ["notifications"] properties: next_token: type: string @@ -102,6 +103,7 @@ paths: type: array items: type: object + required: ["actions", "event", "read", "room_id", "ts"] title: Notification properties: actions: From e2736ba1674b14dcb9fa5dfddd9adebb417255f3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 6 Oct 2016 10:12:08 +0100 Subject: [PATCH 49/57] Linkify createroom in changelog too --- changelogs/client_server.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index 10d4f82e..0386166b 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -37,7 +37,7 @@ - Add top-level ``account_data`` key to the responses to ``GET /sync`` and ``GET /initialSync`` (`#380 `_). - - Add ``is_direct`` flag to ``/createRoom`` and invite member event. + - Add ``is_direct`` flag to .. |/createRoom|_ and invite member event. Add 'Direct Messaging' module. (`#389 `_). - Add ``contains_url`` option to ``RoomEventFilter``. From 301595c071856538cc97c85266a81b68d02c7704 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 6 Oct 2016 11:15:44 +0100 Subject: [PATCH 50/57] Linkify account_data API Also change other links because it turns out the .. isn't part of the syntax --- changelogs/client_server.rst | 2 +- specification/client_server_api.rst | 3 +++ specification/modules/dm.rst | 7 +++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index 0386166b..273ac85c 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -37,7 +37,7 @@ - Add top-level ``account_data`` key to the responses to ``GET /sync`` and ``GET /initialSync`` (`#380 `_). - - Add ``is_direct`` flag to .. |/createRoom|_ and invite member event. + - Add ``is_direct`` flag to |/createRoom|_ and invite member event. Add 'Direct Messaging' module. (`#389 `_). - Add ``contains_url`` option to ``RoomEventFilter``. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index f12b495b..38dcd188 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1281,3 +1281,6 @@ have to wait in milliseconds before they can try again. .. |/account/3pid| replace:: ``/account/3pid`` .. _/account/3pid: #post-matrix-client-%CLIENT_MAJOR_VERSION%-account-3pid + +.. |/user//account_data/| replace:: ``/user//account_data/`` +.. _/user//account_data/: #put-matrix-client-%CLIENT_MAJOR_VERSION%-user-userid-account-data-type diff --git a/specification/modules/dm.rst b/specification/modules/dm.rst index d148b945..26c5d85a 100644 --- a/specification/modules/dm.rst +++ b/specification/modules/dm.rst @@ -39,10 +39,9 @@ Client behaviour The invitee's client may use the ``is_direct`` flag in `m.room.member`_ to automatically mark the room as a direct message but this is not required: it may for example, prompt the user, ignore the flag altogether. To do this, it -stores this event in account data using the ``account_data`` API: see `Client -Config`_. +stores this event in account data using the |/user//account_data/|_ API. -The inviter's client should set the ``is_direct`` flag to .. |/createRoom|_ +The inviter's client should set the ``is_direct`` flag to |/createRoom|_ whenever the flow the user has followed is one where their intention is to speak directly with another person, as opposed to bringing that person in to a shared room. For example, clicking on, 'Start Chat' beside a @@ -50,6 +49,6 @@ person's profile picture would imply the ``is_direct`` flag should be set. Server behaviour ---------------- -When the ``is_direct`` flag is given to .. |/createRoom|_, the home +When the ``is_direct`` flag is given to |/createRoom|_, the home server must set the ``is_direct`` flag in the invite member event for any users invited in the ``createRoom`` call. From 96b6fb0129131e7adf6bc0c0c9c0dc57f91d7f2e Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 6 Oct 2016 11:16:56 +0100 Subject: [PATCH 51/57] 'In the m.room.member' event --- specification/modules/dm.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/specification/modules/dm.rst b/specification/modules/dm.rst index 26c5d85a..f46a01a5 100644 --- a/specification/modules/dm.rst +++ b/specification/modules/dm.rst @@ -36,10 +36,11 @@ Events Client behaviour ---------------- -The invitee's client may use the ``is_direct`` flag in `m.room.member`_ to -automatically mark the room as a direct message but this is not required: it -may for example, prompt the user, ignore the flag altogether. To do this, it -stores this event in account data using the |/user//account_data/|_ API. +The invitee's client may use the ``is_direct`` flag in the `m.room.member`_ +event to automatically mark the room as a direct message but this is not +required: it may for example, prompt the user, ignore the flag altogether. To +do this, it stores this event in account data using the +|/user//account_data/|_ API. The inviter's client should set the ``is_direct`` flag to |/createRoom|_ whenever the flow the user has followed is one where their From ed2d3644409a091e0c034ba8da3ae15c6f0c249c Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 6 Oct 2016 11:17:43 +0100 Subject: [PATCH 52/57] consistency --- specification/modules/dm.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/dm.rst b/specification/modules/dm.rst index f46a01a5..8bba7411 100644 --- a/specification/modules/dm.rst +++ b/specification/modules/dm.rst @@ -52,4 +52,4 @@ Server behaviour ---------------- When the ``is_direct`` flag is given to |/createRoom|_, the home server must set the ``is_direct`` flag in the invite member event for any users -invited in the ``createRoom`` call. +invited in the |/createRoom|_ call. From e0a434b248f5b6629a9d8387efc120a6469b5408 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 6 Oct 2016 11:20:05 +0100 Subject: [PATCH 53/57] Aaha, found a syntax that swagger will accept! --- api/client-server/notifications.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/client-server/notifications.yaml b/api/client-server/notifications.yaml index f49f87f2..8a5e9553 100644 --- a/api/client-server/notifications.yaml +++ b/api/client-server/notifications.yaml @@ -112,7 +112,9 @@ paths: The action(s) to perform when the conditions for this rule are met. See `Push Rules: API`_. items: - type: string + type: + - object + - string event: type: object title: Event From 83b89aa1ceb0d07ba96c128f33a32d1799c24bd7 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 6 Oct 2016 17:17:35 +0100 Subject: [PATCH 54/57] dm: clarify client behaviour --- specification/modules/dm.rst | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/specification/modules/dm.rst b/specification/modules/dm.rst index 8bba7411..a89d3522 100644 --- a/specification/modules/dm.rst +++ b/specification/modules/dm.rst @@ -36,18 +36,21 @@ Events Client behaviour ---------------- -The invitee's client may use the ``is_direct`` flag in the `m.room.member`_ -event to automatically mark the room as a direct message but this is not -required: it may for example, prompt the user, ignore the flag altogether. To -do this, it stores this event in account data using the -|/user//account_data/|_ API. - -The inviter's client should set the ``is_direct`` flag to |/createRoom|_ -whenever the flow the user has followed is one where their +To start a direct chat with another user, the inviting user's client +should set the ``is_direct`` flag to |/createRoom|_. The client should do +this whenever the flow the user has followed is one where their intention is to speak directly with another person, as opposed to bringing that -person in to a shared room. For example, clicking on, 'Start Chat' beside a +person in to a shared room. For example, clicking on 'Start Chat' beside a person's profile picture would imply the ``is_direct`` flag should be set. +The invitee's client may use the ``is_direct`` flag in the `m.room.member`_ +event to automatically mark the room as a direct chat but this is not +required: it may for example, prompt the user, or ignore the flag altogether. + +Both the inviting client and the invitee's client should record the fact that +the room is a direct chat by storing an ``m.direct`` event in the account data +using |/user//account_data/|_. + Server behaviour ---------------- When the ``is_direct`` flag is given to |/createRoom|_, the home From e850fd718dd726609c590a501d120c490b6462c4 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 6 Oct 2016 19:54:49 +0100 Subject: [PATCH 55/57] window.postmessage for Interactive Auth fallback Require that User-Interactive auth fallback pages call `window.postMessage` to notify apps of completion. --- changelogs/client_server.rst | 3 + specification/client_server_api.rst | 107 +++++++++++++++++++++++++--- 2 files changed, 100 insertions(+), 10 deletions(-) diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index 465565e1..fc539dc0 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -34,6 +34,9 @@ (`#390 `_). - Add "Send-to-Device messaging" module (`#386 `_). + - Require that User-Interactive auth fallback pages call + ``window.postMessage`` to notify apps of completion + (`#398 `_). - Spec clarifications: diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index e12f6f40..21e2d03e 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -428,7 +428,8 @@ To use this authentication type, clients should submit an auth dict as follows: { "type": "m.login.password", "user": "", - "password": "" + "password": "", + "session": "" } Alternatively reply using a 3pid bound to the user's account on the homeserver @@ -441,7 +442,8 @@ follows: "type": "m.login.password", "medium": "", "address": "", - "password": "" + "password": "", + "session": "" } In the case that the homeserver does not know about the supplied 3pid, the @@ -460,7 +462,8 @@ To use this authentication type, clients should submit an auth dict as follows: { "type": "m.login.recaptcha", - "response": "" + "response": "", + "session": "" } Token-based @@ -477,7 +480,8 @@ To use this authentication type, clients should submit an auth dict as follows: { "type": "m.login.token", "token": "", - "txn_id": "" + "txn_id": "", + "session": "" } The ``nonce`` should be a random string generated by the client for the @@ -544,7 +548,8 @@ To use this authentication type, clients should submit an auth dict as follows: "client_secret": "", "id_server": "" } - ] + ], + "session": "" } Dummy Auth @@ -562,12 +567,13 @@ the type and session, if provided: .. code:: json { - "type": "m.login.dummy" + "type": "m.login.dummy", + "session": "" } Fallback -<<<<<<<< +++++++++ Clients cannot be expected to be able to know how to process every single login type. If a client does not know how to handle a given login type, it can direct the user to a web browser with the URL of a fallback page which will allow the @@ -577,11 +583,92 @@ should open is:: /_matrix/client/%CLIENT_MAJOR_VERSION%/auth//fallback/web?session= Where ``auth type`` is the type name of the stage it is attempting and -``session id`` is the ID of the session given by the homeserver. +``session ID`` is the ID of the session given by the homeserver. This MUST return an HTML page which can perform this authentication stage. This -page must attempt to call the JavaScript function ``window.onAuthDone`` when -the authentication has been completed. +page must use the following JavaScript when the authentication has been +completed: + +.. code:: javascript + + if (window.onAuthDone) { + window.onAuthDone(); + } else if (window.opener && window.opener.postMessage) { + window.opener.postMessage("authDone", "*"); + } + +This allows the client to either arrange for the global function ``onAuthDone`` +to be defined in an embedded browser, or to use the HTML5 `cross-document +messaging `_ API, to receive +a notification that the authentication stage has been completed. + +Once a client receives the notificaton that the authentication stage has been +completed, it should resubmit the request with an auth dict with just the +session ID: + +.. code:: json + + { + "session": "" + } + + +Example +<<<<<<< +A client webapp might use the following javascript to open a popup window which will +handle unknown login types: + +.. code:: javascript + + /** + * Arguments: + * homeserverUrl: the base url of the homeserver (eg "https://matrix.org") + * + * apiEndpoint: the API endpoint being used (eg + * "/_matrix/client/%CLIENT_MAJOR_VERSION%/account/password") + * + * loginType: the loginType being attempted (eg "m.login.recaptcha") + * + * sessionID: the session ID given by the homeserver in earlier requests + * + * onComplete: a callback which will be called with the results of the request + */ + function unknownLoginType(homeserverUrl, apiEndpoint, loginType, sessionID, onComplete) { + var popupWindow; + + var eventListener = function(ev) { + if (ev.data !== "authDone" ) { + return; + } + + // close the popup + popupWindow.close(); + window.removeEventListener("message", eventListener); + + // repeat the request + var requestBody = { + auth: { + session: sessionID, + }, + }; + + request({ + method:'POST', url:apiEndpint, json:requestBody, + }, onComplete); + }; + + window.addEventListener("message", eventListener); + + var url = homeserverUrl + + "/_matrix/client/%CLIENT_MAJOR_VERSION%/auth/" + + encodeURIComponent(loginType) + + "/fallback/web?session=" + + encodeURIComponent(sessionID); + + + popupWindow = window.open(url); + } + Login ~~~~~ From 6c88d698ae7d095617437e22e801b7ece7837d6d Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 7 Oct 2016 16:26:28 +0100 Subject: [PATCH 56/57] uia fallback example: check event origin --- specification/client_server_api.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 21e2d03e..d95164c5 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -637,10 +637,11 @@ handle unknown login types: var popupWindow; var eventListener = function(ev) { - if (ev.data !== "authDone" ) { + // check it's the right message from the right place. + if (ev.data !== "authDone" || ev.origin !== homeserverUrl) { return; } - + // close the popup popupWindow.close(); window.removeEventListener("message", eventListener); From 49ee00c361ebbd3e01003bd0b34aa165d1dcaeab Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 7 Oct 2016 18:17:45 +0100 Subject: [PATCH 57/57] Use the right path for the identity API --- api/identity/lookup.yaml | 2 +- api/identity/pubkey.yaml | 2 +- specification/identity_service_api.rst | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/api/identity/lookup.yaml b/api/identity/lookup.yaml index c02ec3b5..83c3b661 100644 --- a/api/identity/lookup.yaml +++ b/api/identity/lookup.yaml @@ -19,7 +19,7 @@ host: localhost:8090 schemes: - https - http -basePath: /_matrix/identity/v1/api +basePath: /_matrix/identity/api/v1 produces: - application/json paths: diff --git a/api/identity/pubkey.yaml b/api/identity/pubkey.yaml index c8101281..40d2a237 100644 --- a/api/identity/pubkey.yaml +++ b/api/identity/pubkey.yaml @@ -19,7 +19,7 @@ host: localhost:8090 schemes: - https - http -basePath: /_matrix/identity/v1/api +basePath: /_matrix/identity/api/v1 produces: - application/json paths: diff --git a/specification/identity_service_api.rst b/specification/identity_service_api.rst index f6e22a1a..3be9d9eb 100644 --- a/specification/identity_service_api.rst +++ b/specification/identity_service_api.rst @@ -110,7 +110,7 @@ Creating a session A client makes a call to:: - POST https://my.id.server:8090/_matrix/identity/v1/api/validate/email/requestToken + POST https://my.id.server:8090/_matrix/identity/api/v1/validate/email/requestToken client_secret=monkeys_are_GREAT& email=foo@bar.com& @@ -147,7 +147,7 @@ Validating ownership of an email ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A user may make either a ``GET`` or a ``POST`` request to -``/_matrix/identity/v1/api/validate/email/submitToken`` with the following +``/_matrix/identity/api/v1/validate/email/submitToken`` with the following parameters (either as query parameters or URL-encoded POST parameters): - ``sid`` the sid for the session, generated by the ``requestToken`` call. - ``client_secret`` the client secret which was supplied to the ``requestToken`` call. @@ -164,7 +164,7 @@ Checking non-published 3pid ownership ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A client can check whether ownership of a 3pid was validated by making an -HTTP GET request to ``/_matrix/identity/v1/api/3pid/getValidated3pid``, passing +HTTP GET request to ``/_matrix/identity/api/v1/3pid/getValidated3pid``, passing the ``sid`` and ``client_secret`` as query parameters from the ``requestToken`` call. @@ -183,7 +183,7 @@ Publishing a validated association ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ An association between a session and a Matrix user ID can be published by making -a URL-encoded HTTP POST request to ``/_matrix/identity/v1/api/3pid/bind`` with +a URL-encoded HTTP POST request to ``/_matrix/identity/api/v1/3pid/bind`` with the following parameters:: sid=sid& @@ -256,7 +256,7 @@ At a later point, if the owner of that particular 3pid binds it with a Matrix us Where the signature is produced using a long-term private key. -Also, the generated ephemeral public key will be listed as valid on requests to ``/_matrix/identity/v1/api/pubkey/ephemeral/isvalid``. +Also, the generated ephemeral public key will be listed as valid on requests to ``/_matrix/identity/api/v1/pubkey/ephemeral/isvalid``. Ephemeral invitation signing ----------------------------