diff --git a/api/application-service/application_service.yaml b/api/application-service/application_service.yaml index 42c0c0cfe..bc6e45d5d 100644 --- a/api/application-service/application_service.yaml +++ b/api/application-service/application_service.yaml @@ -32,6 +32,10 @@ paths: description: |- This API is called by the homeserver when it wants to push an event (or batch of events) to the application service. + + Note that the application service should distinguish state events + from message events via the presence of a ``state_key``, rather than + via the event type. operationId: sendTransaction parameters: - in: path @@ -44,7 +48,7 @@ paths: x-example: "35" - in: body name: body - description: A list of events + description: A list of events. schema: type: object example: { @@ -92,121 +96,6 @@ paths: } schema: type: object - "/rooms/{roomAlias}": - get: - summary: Query if a room alias should exist on the application service. - description: |- - This endpoint is invoked by the homeserver on an application service to query - the existence of a given room alias. The homeserver will only query room - aliases inside the application service's ``aliases`` namespace. The - homeserver will send this request when it receives a request to join a - room alias within the application service's namespace. - operationId: queryRoomByAlias - parameters: - - in: path - name: roomAlias - type: string - description: The room alias being queried. - required: true - x-example: "#magicforest:example.com" - responses: - 200: - description: |- - The application service indicates that this room alias exists. The - application service MUST have created a room and associated it with - the queried room alias using the client-server API. Additional - information about the room such as its name and topic can be set - before responding. - examples: - application/json: { - } - schema: - type: object - 401: - description: |- - The homeserver has not supplied credentials to the application service. - Optional error information can be included in the body of this response. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - 403: - description: |- - The credentials supplied by the homeserver were rejected. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - 404: - description: |- - The application service indicates that this room alias does not exist. - Optional error information can be included in the body of this response. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - "/users/{userId}": - get: - summary: Query if a user should exist on the application service. - description: |- - This endpoint is invoked by the homeserver on an application service to query - the existence of a given user ID. The homeserver will only query user IDs - inside the application service's ``users`` namespace. The homeserver will - send this request when it receives an event for an unknown user ID in - the application service's namespace. - operationId: queryUserById - parameters: - - in: path - name: userId - type: string - description: The user ID being queried. - required: true - x-example: "@alice:example.com" - responses: - 200: - description: |- - The application service indicates that this user exists. The application - service MUST create the user using the client-server API. - examples: - application/json: { - } - schema: - type: object - 401: - description: |- - The homeserver has not supplied credentials to the application service. - Optional error information can be included in the body of this response. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - 403: - description: |- - The credentials supplied by the homeserver were rejected. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml - 404: - description: |- - The application service indicates that this user does not exist. - Optional error information can be included in the body of this response. - examples: - application/json: { - "errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND" - } - schema: - $ref: ../client-server/definitions/errors/error.yaml "/_matrix/app/unstable/thirdparty/protocol/{protocol}": get: summary: Retrieve metadata about a specific protocol that the application service supports. diff --git a/api/application-service/query_room.yaml b/api/application-service/query_room.yaml new file mode 100644 index 000000000..b885cb860 --- /dev/null +++ b/api/application-service/query_room.yaml @@ -0,0 +1,86 @@ +# Copyright 2016 OpenMarket Ltd +# Copyright 2018 New Vector 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 Application Service API" + version: "1.0.0" +host: localhost:8008 +schemes: + - https + - http +basePath: "/" +consumes: + - application/json +produces: + - application/json +paths: + "/rooms/{roomAlias}": + get: + summary: Query if a room alias should exist on the application service. + description: |- + This endpoint is invoked by the homeserver on an application service to query + the existence of a given room alias. The homeserver will only query room + aliases inside the application service's ``aliases`` namespace. The + homeserver will send this request when it receives a request to join a + room alias within the application service's namespace. + operationId: queryRoomByAlias + parameters: + - in: path + name: roomAlias + type: string + description: The room alias being queried. + required: true + x-example: "#magicforest:example.com" + responses: + 200: + description: |- + The application service indicates that this room alias exists. The + application service MUST have created a room and associated it with + the queried room alias using the client-server API. Additional + information about the room such as its name and topic can be set + before responding. + examples: + application/json: {} + schema: + type: object + 401: + description: |- + The homeserver has not supplied credentials to the application service. + Optional error information can be included in the body of this response. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + 403: + description: |- + The credentials supplied by the homeserver were rejected. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + 404: + description: |- + The application service indicates that this room alias does not exist. + Optional error information can be included in the body of this response. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml diff --git a/api/application-service/query_user.yaml b/api/application-service/query_user.yaml new file mode 100644 index 000000000..0431b5e49 --- /dev/null +++ b/api/application-service/query_user.yaml @@ -0,0 +1,83 @@ +# Copyright 2016 OpenMarket Ltd +# Copyright 2018 New Vector 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 Application Service API" + version: "1.0.0" +host: localhost:8008 +schemes: + - https + - http +basePath: "/" +consumes: + - application/json +produces: + - application/json +paths: + "/users/{userId}": + get: + summary: Query if a user should exist on the application service. + description: |- + This endpoint is invoked by the homeserver on an application service to query + the existence of a given user ID. The homeserver will only query user IDs + inside the application service's ``users`` namespace. The homeserver will + send this request when it receives an event for an unknown user ID in + the application service's namespace, such as a room invite. + operationId: queryUserById + parameters: + - in: path + name: userId + type: string + description: The user ID being queried. + required: true + x-example: "@alice:example.com" + responses: + 200: + description: |- + The application service indicates that this user exists. The application + service MUST create the user using the client-server API. + examples: + application/json: {} + schema: + type: object + 401: + description: |- + The homeserver has not supplied credentials to the application service. + Optional error information can be included in the body of this response. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_UNAUTHORIZED" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + 403: + description: |- + The credentials supplied by the homeserver were rejected. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_FORBIDDEN" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml + 404: + description: |- + The application service indicates that this user does not exist. + Optional error information can be included in the body of this response. + examples: + application/json: { + "errcode": "COM.EXAMPLE.MYAPPSERVICE_NOT_FOUND" + } + schema: + $ref: ../client-server/definitions/errors/error.yaml diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 8f0319d5a..1cf66fe1f 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -66,7 +66,7 @@ paths: medium: type: string description: The medium of the third party identifier. - enum: ["email"] + enum: ["email", "msisdn"] address: type: string description: The third party identifier address. @@ -143,7 +143,21 @@ paths: validation tokens when adding an email address to an account. This API's parameters and response is identical to that of the HS API |/register/email/requestToken|_ endpoint. - operationId: requestTokenTo3PID + operationId: requestTokenTo3PIDEmail responses: 200: - description: An email was sent to the given address + description: An email was sent to the given address. + "/account/3pid/msisdn/requestToken": + post: + summary: Requests a validation token be sent to the given email address for the purpose of adding a phone number to an account. + description: |- + Proxies the identity server API ``validate/msisdn/requestToken``, but + first checks that the given phone number is **not** already associated + with an account on this Home Server. This API should be used to request + validation tokens when adding a phone number to an account. This API's + parameters and response is identical to that of the HS API + |/register/msisdn/requestToken|_ endpoint. + operationId: requestTokenTo3PIDMSISDN + responses: + 200: + description: An SMS message was sent to the given phone number. diff --git a/api/client-server/create_room.yaml b/api/client-server/create_room.yaml index 1795d547a..ac0c3b162 100644 --- a/api/client-server/create_room.yaml +++ b/api/client-server/create_room.yaml @@ -39,16 +39,20 @@ paths: apply the events implied by the request in the following order: 0. A default ``m.room.power_levels`` event, giving the room creator - (and not other members) permission to send state events. + (and not other members) permission to send state events. Overridden + by the ``power_level_content_override`` parameter. - 1. Events set by the ``preset``. + 1. Events set by the ``preset``. Currently these are the ``m.room.join_rules``, + ``m.room.history_visibility``, and ``m.room.guest_access`` state events. 2. Events listed in ``initial_state``, in the order that they are listed. - 3. Events implied by ``name`` and ``topic``. + 3. Events implied by ``name`` and ``topic`` (``m.room.name`` and ``m.room.topic`` + state events). - 4. Invite events implied by ``invite`` and ``invite_3pid``. + 4. Invite events implied by ``invite`` and ``invite_3pid`` (``m.room.member`` with + ``membership: invite`` and ``m.room.third_party_invite``). The available presets do the following with respect to room state: @@ -60,6 +64,9 @@ paths: ``public_chat`` ``public`` ``shared`` ``forbidden`` ======================== ============== ====================== ================ ========= + The server will create a ``m.room.create`` event in the room with the + requesting user as the creator, alongside other keys provided in the + ``creation_content``. operationId: createRoom security: - accessToken: [] @@ -70,14 +77,14 @@ paths: schema: type: object example: { - "preset": "public_chat", - "room_alias_name": "thepub", - "name": "The Grand Duke Pub", - "topic": "All about happy hour", - "creation_content": { - "m.federate": false - } + "preset": "public_chat", + "room_alias_name": "thepub", + "name": "The Grand Duke Pub", + "topic": "All about happy hour", + "creation_content": { + "m.federate": false } + } properties: visibility: type: string @@ -98,6 +105,9 @@ paths: created the room. For example, if this was set to "foo" and sent to the homeserver "example.com" the complete room alias would be ``#foo:example.com``. + + The complete room alias will become the canonical alias for + the room. name: type: string description: |- @@ -149,10 +159,10 @@ paths: title: CreationContent type: object description: |- - Extra keys to be added to the content of the ``m.room.create``. - The server will clobber the following keys: ``creator``, ``room_version``. - Future versions of the specification may allow the server to clobber - other keys. + Extra keys, such as ``m.federate``, to be added to the content + of the `m.room.create`_ event. The server will clobber the following + keys: ``creator``, ``room_version``. Future versions of the specification + may allow the server to clobber other keys. initial_state: type: array description: |- @@ -183,16 +193,25 @@ paths: description: |- Convenience parameter for setting various default state events based on a preset. + + If unspecified, the server should use the ``visibility`` to determine + which preset to use. A visbility of ``public`` equates to a preset of + ``public_chat`` and ``private`` visibility equates to a preset of + ``private_chat``. 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. - guest_can_join: - type: boolean + power_level_content_override: + title: Power Level Event Content + type: object description: |- - Allows guests to join the room. See `Guest Access`_ for more information. + The power level content to override in the default power level + event. This object is applied on top of the generated `m.room.power_levels`_ + event content prior to it being sent to the room. Defaults to + overriding nothing. responses: 200: description: Information about the newly created room. @@ -204,10 +223,11 @@ paths: type: string description: |- The created room's ID. + required: ['room_id'] examples: application/json: { - "room_id": "!sefiuhWgwghwWgh:example.com" - } + "room_id": "!sefiuhWgwghwWgh:example.com" + } 400: description: |- @@ -226,6 +246,5 @@ paths: ``M_INVALID_ROOM_STATE``). schema: "$ref": "definitions/errors/error.yaml" - tags: - Room creation diff --git a/api/client-server/keys.yaml b/api/client-server/keys.yaml index 6e995c2ce..55f8a5a53 100644 --- a/api/client-server/keys.yaml +++ b/api/client-server/keys.yaml @@ -194,7 +194,7 @@ paths: "user_id": "@alice:example.com", "device_id": "JLAFKJWSCS", "algorithms": [ - "m.olm.curve25519-aes-sha256", + "m.olm.v1.curve25519-aes-sha256", "m.megolm.v1.aes-sha" ], "keys": { @@ -247,7 +247,7 @@ paths: description: algorithm example: "signed_curve25519" example: - "@alice:example.com": { "JLAFKJWSCS": "curve25519" } + "@alice:example.com": { "JLAFKJWSCS": "signed_curve25519" } required: - one_time_keys responses: diff --git a/api/client-server/openid.yaml b/api/client-server/openid.yaml new file mode 100644 index 000000000..4b89232ea --- /dev/null +++ b/api/client-server/openid.yaml @@ -0,0 +1,103 @@ +# Copyright 2018 New Vector 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 OpenID 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: + "/user/{userId}/openid/request_token": + post: + summary: Get an OpenID token object to verify the requester's identity. + description: |- + Gets an OpenID token object that the requester may supply to another + service to verify their identity in Matrix. The generated token is only + valid for exchanging for user information from the federation API for + OpenID. + + The access token generated is only valid for the OpenID API. It cannot + be used to request another OpenID access token or call ``/sync``, for + example. + operationId: requestOpenIdToken + security: + - accessToken: [] + parameters: + - in: path + type: string + name: userId + description: |- + The user to request and OpenID token for. Should be the user who + is authenticated for the request. + required: true + x-example: "@alice:example.com" + - in: body + name: body + description: An empty object. Reserved for future expansion. + required: true + schema: + type: object + example: {} + responses: + 200: + description: |- + OpenID token information. This response is nearly compatible with the + response documented in the `OpenID 1.0 Specification `_ + with the only difference being the lack of an ``id_token``. Instead, + the Matrix homeserver's name is provided. + examples: + application/json: { + "access_token": "SomeT0kenHere", + "token_type": "Bearer", + "matrix_server_name": "example.com", + "expires_in": 3600, + } + schema: + type: object + properties: + access_token: + type: string + description: |- + An access token the consumer may use to verify the identity of + the person who generated the token. This is given to the federation + API ``GET /openid/userinfo``. + token_type: + type: string + description: The string ``Bearer``. + matrix_server_name: + type: string + description: |- + The homeserver domain the consumer should use when attempting to + verify the user's identity. + expires_in: + type: int + description: |- + The number of seconds before this token expires and a new one must + be generated. + required: ['access_token', 'token_type', 'matrix_server_name', 'expires_in'] + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" + tags: + - OpenID diff --git a/api/client-server/pusher.yaml b/api/client-server/pusher.yaml index 938014c60..d232baf9f 100644 --- a/api/client-server/pusher.yaml +++ b/api/client-server/pusher.yaml @@ -1,4 +1,5 @@ # Copyright 2016 OpenMarket Ltd +# Copyright 2018 New Vector Ltd # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -31,30 +32,30 @@ paths: get: summary: Gets the current pushers for the authenticated user description: |- - Gets all currently active pushers for the authenticated user + Gets all currently active pushers for the authenticated user. operationId: getPushers security: - accessToken: [] responses: 200: - description: The pushers for this user + description: The pushers for this user. examples: application/json: { - "pushers": [ - { - "pushkey": "Xp/MzCt8/9DcSNE9cuiaoT5Ac55job3TdLSSmtmYl4A=", - "kind": "http", - "app_id": "face.mcapp.appy.prod", - "app_display_name": "Appy McAppface", - "device_display_name": "Alice's Phone", - "profile_tag": "xyz", - "lang": "en-US", - "data": { - "url": "https://example.com/_matrix/push/v1/notify" - } + "pushers": [ + { + "pushkey": "Xp/MzCt8/9DcSNE9cuiaoT5Ac55job3TdLSSmtmYl4A=", + "kind": "http", + "app_id": "face.mcapp.appy.prod", + "app_display_name": "Appy McAppface", + "device_display_name": "Alice's Phone", + "profile_tag": "xyz", + "lang": "en-US", + "data": { + "url": "https://example.com/_matrix/push/v1/notify" } - ] - } + } + ] + } schema: type: object properties: @@ -70,7 +71,7 @@ paths: pushkey: type: string description: |- - This is a unique identifier for this pusher. See `/set` for + This is a unique identifier for this pusher. See ``/set`` for more detail. Max length, 512 bytes. kind: @@ -115,6 +116,19 @@ paths: description: |- Required if ``kind`` is ``http``. The URL to use to send notifications to. + format: + type: string + description: |- + The format to use when sending notifications to the Push + Gateway. + required: + - pushkey + - app_id + - kind + - app_display_name + - device_display_name + - lang + - data tags: - Push notifications "/pushers/set": @@ -130,23 +144,24 @@ paths: parameters: - in: body name: pusher - description: The pusher information + description: The pusher information. required: true schema: type: object example: { - "lang": "en", - "kind": "http", - "app_display_name": "Mat Rix", - "device_display_name": "iPhone 9", - "profile_tag": "xxyyzz", - "app_id": "com.example.app.ios", - "pushkey": "APA91bHPRgkF3JUikC4ENAHEeMrd41Zxv3hVZjC9KtT8OvPVGJ-hQMRKRrZuJAEcl7B338qju59zJMjw2DELjzEvxwYv7hH5Ynpc1ODQ0aT4U4OFEeco8ohsN5PjL1iC2dNtk2BAokeMCg2ZXKqpc8FXKmhX94kIxQ", - "data": { - "url": "https://push-gateway.location.here" - }, - "append": false - } + "lang": "en", + "kind": "http", + "app_display_name": "Mat Rix", + "device_display_name": "iPhone 9", + "profile_tag": "xxyyzz", + "app_id": "com.example.app.ios", + "pushkey": "APA91bHPRgkF3JUikC4ENAHEeMrd41Zxv3hVZjC9KtT8OvPVGJ-hQMRKRrZuJAEcl7B338qju59zJMjw2DELjzEvxwYv7hH5Ynpc1ODQ0aT4U4OFEeco8ohsN5PjL1iC2dNtk2BAokeMCg2ZXKqpc8FXKmhX94kIxQ", + "data": { + "url": "https://push-gateway.location.here/_matrix/push/v1/notify", + "format": "event_id_only" + }, + "append": false + } properties: pushkey: type: string @@ -157,11 +172,15 @@ paths: for APNS or the Registration ID for GCM. If your notification client has no such concept, use any unique identifier. Max length, 512 bytes. + + If the ``kind`` is ``"email"``, this is the email address to + send notifications to. kind: type: string description: |- The kind of pusher to configure. ``"http"`` makes a pusher that - sends HTTP pokes. ``null`` deletes the pusher. + sends HTTP pokes. ``"email"`` makes a pusher that emails the + user with unread notifications. ``null`` deletes the pusher. app_id: type: string description: |- @@ -169,6 +188,8 @@ paths: It is recommended that this end with the platform, such that different platform versions get different app identifiers. Max length, 64 chars. + + If the ``kind`` is ``"email"``, this is ``"m.email"``. app_display_name: type: string description: |- @@ -188,7 +209,7 @@ paths: type: string description: |- The preferred language for receiving notifications (e.g. 'en' - or 'en-US') + or 'en-US'). data: type: object description: |- @@ -201,7 +222,17 @@ paths: type: string description: |- Required if ``kind`` is ``http``. The URL to use to send - notifications to. + notifications to. MUST be an HTTPS URL with a path of + ``/_matrix/push/v1/notify``. + example: "https://push-gateway.location.here/_matrix/push/v1/notify" + format: + type: string + description: |- + The format to send notifications in to Push Gateways if the + ``kind`` is ``http``. The details about what fields the + homeserver should send to the push gateway are defined in the + `Push Gateway Specification`_. Currently the only format + available is 'event_id_only'. append: type: boolean description: |- @@ -216,17 +247,17 @@ paths: 200: description: The pusher was set. examples: - application/json: { - } + application/json: {} schema: - type: object # empty json object + type: object + description: An empty object. 400: description: One or more of the pusher values were invalid. examples: application/json: { - "error": "Missing parameters: lang, data", - "errcode": "M_MISSING_PARAM" - } + "error": "Missing parameters: lang, data", + "errcode": "M_MISSING_PARAM" + } schema: "$ref": "definitions/errors/error.yaml" 429: diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 6ae4ddd37..56da9addb 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -196,11 +196,9 @@ paths: description: |- Proxies the identity server API ``validate/email/requestToken``, but first checks that the given email address is not already associated - with an account on this Home Server. Note that, for consistency, - this API takes JSON objects, though the Identity Server API takes - ``x-www-form-urlencoded`` parameters. See the Identity Server API for + with an account on this Home Server. See the Identity Server API for further information. - operationId: requestTokenToRegister + operationId: requestTokenToRegisterEmail parameters: - in: body name: body @@ -252,6 +250,71 @@ paths: } schema: "$ref": "definitions/errors/error.yaml" + "/register/msisdn/requestToken": + post: + summary: Requests a validation token be sent to the given phone number for the purpose of registering an account + description: |- + Proxies the identity server API ``validate/msisdn/requestToken``, but + first checks that the given phone number is not already associated + with an account on this Home Server. See the Identity Server API for + further information. + operationId: requestTokenToRegisterMSISDN + parameters: + - in: body + name: body + schema: + type: object + properties: + id_server: + type: string + description: The ID server to send the onward request to as a hostname with an appended colon and port number if the port is not the default. + example: "id.matrix.org" + client_secret: + type: string + description: Client-generated secret string used to protect this session. + example: "this_is_my_secret_string" + country: + type: string + description: |- + The two-letter uppercase ISO country code that the number in + ``phone_number`` should be parsed as if it were dialled from. + phone_number: + type: string + description: The phone number. + example: "example@example.com" + send_attempt: + type: number + description: Used to distinguish protocol level retries from requests to re-send the SMS message. + example: 1 + required: ["client_secret", "country", "phone_number", "send_attempt"] + responses: + 200: + description: |- + An SMS message has been sent to the specified phone number. + Note that this may be an SMS message containing the validation token or it may be informing + the user of an error. + examples: + application/json: {} + schema: + type: object + 400: + description: |- + Part of the request was invalid. This may include one of the following error codes: + + * ``M_THREEPID_IN_USE`` : The phone number is already registered to an account on this server. + However, if the home server has the ability to send SMS message, it is recommended that the server + instead send an SMS message to the user with instructions on how to reset their password. + This prevents malicious parties from being able to determine if a given phone number + has an account on the Home Server in question. + * ``M_SERVER_NOT_TRUSTED`` : The ``id_server`` parameter refers to an ID server + that is not trusted by this Home Server. + examples: + application/json: { + "errcode": "M_THREEPID_IN_USE", + "error": "The specified address is already in use" + } + schema: + "$ref": "definitions/errors/error.yaml" "/account/password": post: summary: "Changes a user's password." @@ -319,10 +382,32 @@ paths: .. |/register/email/requestToken| replace:: ``/register/email/requestToken`` .. _/register/email/requestToken: #post-matrix-client-%CLIENT_MAJOR_VERSION%-register-email-requesttoken - operationId: requestTokenToResetPassword + operationId: requestTokenToResetPasswordEmail responses: 200: description: An email was sent to the given address + "/account/password/msisdn/requestToken": + post: + summary: Requests a validation token be sent to the given phone number for the purpose of resetting a user's password. + description: |- + Proxies the identity server API ``validate/msisdn/requestToken``, but + first checks that the given phone number **is** associated with an account + on this Home Server. This API should be used to request + validation tokens when authenticating for the + `account/password` endpoint. This API's parameters and response are + identical to that of the HS API |/register/msisdn/requestToken|_ except that + `M_THREEPID_NOT_FOUND` may be returned if no account matching the + given email address could be found. The server may instead send an + SMS message to the given address prompting the user to create an account. + `M_THREEPID_IN_USE` may not be returned. + + .. |/register/msisdn/requestToken| replace:: ``/register/msisdn/requestToken`` + + .. _/register/msisdn/requestToken: #post-matrix-client-%CLIENT_MAJOR_VERSION%-register-email-requesttoken + operationId: requestTokenToResetPasswordMSISDN + responses: + 200: + description: An SMS message was sent to the given phone number. "/account/deactivate": post: summary: "Deactivate a user's account." diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 34659dd06..4b44c20e1 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -253,6 +253,14 @@ paths: description: |- Information on end-to-end device updates, as specified in |device_lists_sync|_. + device_one_time_keys_count: + title: One-time keys count + type: object + additionalProperties: + type: integer + description: |- + Information on end-to-end encryption keys, as specified + in |device_lists_sync|_. examples: application/json: { "next_batch": "s72595_4483_1934", diff --git a/api/identity/phone_associations.yaml b/api/identity/phone_associations.yaml new file mode 100644 index 000000000..c2cc6cfe7 --- /dev/null +++ b/api/identity/phone_associations.yaml @@ -0,0 +1,203 @@ +# Copyright 2018 New Vector 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 Identity Service Phone Number Associations API" + version: "1.0.0" +host: localhost:8090 +schemes: + - https + - http +basePath: /_matrix/identity/api/v1 +produces: + - application/json +paths: + "/validate/msisdn/requestToken": + post: + summary: Request a token for validating a phone number. + description: |- + Create a session for validating a phone number. + + The identity service will send an SMS message containing a token. If + that token is presented to the identity service in the future, it + indicates that that user was able to read the SMS for that phone + number, and so we validate ownership of the phone number. + + Note that Home Servers offer APIs that proxy this API, adding + additional behaviour on top, for example, + ``/register/msisdn/requestToken`` is designed specifically for use when + registering an account and therefore will inform the user if the phone + number given is already registered on the server. + + Note: for backwards compatibility with older versions of this + specification, the parameters may also be specified as + ``application/x-form-www-urlencoded`` data. However, this usage is + deprecated. + operationId: msisdnRequestToken + parameters: + - in: body + name: body + schema: + type: object + example: { + "client_secret": "monkeys_are_GREAT", + "country": "GB", + "phone_number": "07700900001", + "send_attempt": 1 + } + properties: + client_secret: + type: string + description: A unique string used to identify the validation attempt. + country: + type: string + description: |- + The two-letter uppercase ISO country code that the number in + ``phone_number`` should be parsed as if it were dialled from. + phone_number: + type: string + description: The phone number to validate. + send_attempt: + type: integer + description: |- + Optional. If specified, the server will only send an SMS if + the ``send_attempt`` is a number greater than the most recent + one which it has seen (or if it has never seen one), scoped + to that ``country`` + ``phone_number`` + ``client_secret`` + triple. This is to avoid repeatedly sending the same SMS in + the case of request retries between the POSTing user and the + identity service. The client should increment this value if + they desire a new SMS (e.g. a reminder) to be sent. + next_link: + type: string + description: |- + Optional. When the validation is completed, the identity + service will redirect the user to this URL. + required: ["client_secret", "country", "phone_number"] + responses: + 200: + description: + Session created. + examples: + application/json: { + "sid": "1234" + } + schema: + type: object + properties: + sid: + type: string + description: The session ID. + 400: + description: | + An error ocurred. Some possible errors are: + + - ``M_INVALID_ADDRESS``: The phone number provided was invalid. + - ``M_SEND_ERROR``: The validation SMS could not be sent. + "/validate/msisdn/submitToken": + post: + summary: Validate ownership of a phone number. + description: |- + Validate ownership of a phone number. + + If the three parameters are consistent with a set generated by a + ``requestToken`` call, ownership of the phone number is considered to + have been validated. This does not publish any information publicly, or + associate the phone number address with any Matrix user + ID. Specifically, calls to ``/lookup`` will not show a binding. + + Note: for backwards compatibility with older versions of this + specification, the parameters may also be specified as + ``application/x-form-www-urlencoded`` data. However, this usage is + deprecated. + operationId: msisdnSubmitTokenPost + parameters: + - in: body + name: body + schema: + type: object + example: { + "sid": "1234", + "client_secret": "monkeys_are_GREAT", + "token": "atoken" + } + properties: + sid: + type: string + description: The session ID, generated by the ``requestToken`` call. + client_secret: + type: string + description: The client secret that was supplied to the ``requestToken`` call. + token: + type: string + description: The token generated by the ``requestToken`` call and sent to the user. + required: ["sid", "client_secret", "token"] + responses: + 200: + description: + The success of the validation. + examples: + application/json: { + "success": true + } + schema: + type: object + properties: + success: + type: boolean + description: Whether the validation was successful or not. + get: + summary: Validate ownership of a phone number. + description: |- + Validate ownership of a phone number. + + If the three parameters are consistent with a set generated by a + ``requestToken`` call, ownership of the phone number address is + considered to have been validated. This does not publish any + information publicly, or associate the phone number with any Matrix + user ID. Specifically, calls to ``/lookup`` will not show a binding. + + Note that, in contrast with the POST version, this endpoint will be + used by end-users, and so the response should be human-readable. + operationId: msisdnSubmitTokenGet + parameters: + - in: query + type: string + name: sid + required: true + description: The session ID, generated by the ``requestToken`` call. + x-example: 1234 + - in: query + type: string + name: client_secret + required: true + description: The client secret that was supplied to the ``requestToken`` call. + x-example: monkeys_are_GREAT + - in: query + type: string + name: token + required: true + description: The token generated by the ``requestToken`` call and sent to the user. + x-example: atoken + responses: + "200": + description: Phone number is validated. + "3xx": + description: |- + Phone number address is validated, and the ``next_link`` parameter + was provided to the ``requestToken`` call. The user must be + redirected to the URL provided by the ``next_link`` parameter. + "4xx": + description: + Validation failed. diff --git a/api/push-gateway/push_notifier.yaml b/api/push-gateway/push_notifier.yaml index 9b6e78d35..4a6cb8f75 100644 --- a/api/push-gateway/push_notifier.yaml +++ b/api/push-gateway/push_notifier.yaml @@ -1,4 +1,5 @@ # Copyright 2016 OpenMarket Ltd +# Copyright 2018 New Vector Ltd # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,7 +20,7 @@ host: localhost:8008 schemes: - https - http -basePath: /_matrix/push/%CLIENT_MAJOR_VERSION% +basePath: /_matrix/push/v1 consumes: - application/json produces: @@ -38,14 +39,14 @@ paths: Notifications about a particular event will normally cause the user to be alerted in some way. It is therefore necessary to perform duplicate - suppression for such notifications using the `event_id` field to avoid + suppression for such notifications using the ``event_id`` field to avoid retries of this HTTP API causing duplicate alerts. The operation of updating counts of unread notifications should be idempotent and therefore do not require duplicate suppression. - Notifications are sent to the URL configured when the pusher is - created. This means that the HTTP path may be different depending on the - push gateway. + Notifications are sent to the URL configured when the pusher is created. + This means that the HTTP path may be different depending on the push + gateway. operationId: notify parameters: - in: body @@ -55,36 +56,36 @@ paths: schema: type: object example: { - "notification": { - "id": "$3957tyerfgewrf384", - "room_id": "!slw48wfj34rtnrf:example.com", - "type": "m.room.message", - "sender": "@exampleuser:matrix.org", - "sender_display_name": "Major Tom", - "room_name": "Mission Control", - "room_alias": "#exampleroom:matrix.org", - "prio": "high", - "content": { - "msgtype": "m.text", - "body": "I'm floating in a most peculiar way." - }, - "counts": { - "unread" : 2, - "missed_calls": 1 - }, - "devices": [ - { - "app_id": "org.matrix.matrixConsole.ios", - "pushkey": "V2h5IG9uIGVhcnRoIGRpZCB5b3UgZGVjb2RlIHRoaXM/", - "pushkey_ts": 12345678, - "data" : {}, - "tweaks": { - "sound": "bing" - } + "notification": { + "id": "$3957tyerfgewrf384", + "room_id": "!slw48wfj34rtnrf:example.com", + "type": "m.room.message", + "sender": "@exampleuser:matrix.org", + "sender_display_name": "Major Tom", + "room_name": "Mission Control", + "room_alias": "#exampleroom:matrix.org", + "prio": "high", + "content": { + "msgtype": "m.text", + "body": "I'm floating in a most peculiar way." + }, + "counts": { + "unread" : 2, + "missed_calls": 1 + }, + "devices": [ + { + "app_id": "org.matrix.matrixConsole.ios", + "pushkey": "V2h5IG9uIGVhcnRoIGRpZCB5b3UgZGVjb2RlIHRoaXM/", + "pushkey_ts": 12345678, + "data" : {}, + "tweaks": { + "sound": "bing" } - ] - } + } + ] } + } required: ["notification"] properties: notification: @@ -111,14 +112,10 @@ paths: type: string description: |- The type of the event as in the event's ``type`` field. - Required if the notification relates to a specific - Matrix event. sender: type: string description: |- The sender of the event as in the corresponding event field. - Required if the notification relates to a specific - Matrix event. sender_display_name: type: string description: |- @@ -148,15 +145,16 @@ paths: type: object title: EventContent description: |- - The ``content`` field from the event, if present. If the - event had no content field, this field is omitted. + The ``content`` field from the event, if present. The pusher + may omit this if the event had no content or for any other + reason. counts: type: object title: Counts description: |- This is a dictionary of the current number of unacknowledged communications for the recipient user. Counts whose value is - zero are omitted. + zero should be omitted. properties: unread: type: integer @@ -180,10 +178,10 @@ paths: app_id: type: string description: |- - The app_id given when the pusher was created. + The ``app_id`` given when the pusher was created. pushkey: type: string - description: The pushkey given when the pusher was created. + description: The ``pushkey`` given when the pusher was created. pushkey_ts: type: integer description: |- @@ -202,13 +200,14 @@ paths: description: |- A dictionary of customisations made to the way this notification is to be presented. These are added by push rules. + required: ['app_id', 'pushkey'] responses: 200: description: A list of rejected push keys. examples: application/json: { - "rejected": [ "V2h5IG9uIGVhcnRoIGRpZCB5b3UgZGVjb2RlIHRoaXM/" ] - } + "rejected": [ "V2h5IG9uIGVhcnRoIGRpZCB5b3UgZGVjb2RlIHRoaXM/" ] + } schema: type: object # empty json object properties: @@ -222,7 +221,8 @@ paths: pushkeys and remove the associated pushers. It may not necessarily be the notification in the request that failed: it could be that a previous notification to the same pushkey - failed. + failed. May be empty. items: type: string - description: A pushkey + description: A pushkey that has been rejected. + required: ['rejected'] diff --git a/api/server-server/backfill.yaml b/api/server-server/backfill.yaml index f9f105e2e..6b3cfaef0 100644 --- a/api/server-server/backfill.yaml +++ b/api/server-server/backfill.yaml @@ -24,6 +24,8 @@ consumes: - application/json produces: - application/json +securityDefinitions: + $ref: definitions/security.yaml paths: "/backfill/{roomId}": get: @@ -33,6 +35,8 @@ paths: Starting from the PDU ID(s) given in the ``v`` argument, the PDUs that preceded it are retrieved, up to the total number given by the ``limit``. operationId: backfillRoom + security: + - signedRequest: [] parameters: - in: path name: roomId @@ -85,6 +89,8 @@ paths: walk of the ``prev_events`` for the ``latest_events``, ignoring any events in ``earliest_events`` and stopping at the ``limit``. operationId: getMissingPreviousEvents + security: + - signedRequest: [] parameters: - in: path name: roomId diff --git a/api/server-server/definitions/event-schemas/m.presence.yaml b/api/server-server/definitions/event-schemas/m.presence.yaml new file mode 100644 index 000000000..7f47add4d --- /dev/null +++ b/api/server-server/definitions/event-schemas/m.presence.yaml @@ -0,0 +1,71 @@ +# Copyright 2018 New Vector 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. + +type: object +title: m.presence +description: |- + An EDU representing presence updates for users of the sending homeserver. +allOf: + - $ref: ../edu.yaml + - type: object + properties: + edu_type: + type: enum + enum: ['m.presence'] + description: The string ``m.presence`` + example: "m.presence" + content: + type: object + description: The presence updates and requests. + title: Presence Update + properties: + push: + type: array + description: |- + A list of presence updates that the receiving server is likely + to be interested in. + items: + type: object + title: User Presence Update + properties: + user_id: + type: string + description: The user ID this presence EDU is for. + example: "@john:matrix.org" + presence: + type: enum + enum: ['offline', 'unavailable', 'online'] + description: The presence of the user. + example: "online" + status_msg: + type: string + description: An optional description to accompany the presence. + example: "Making cupcakes" + last_active_ago: + type: integer + format: int64 + description: |- + The number of milliseconds that have elapsed since the user + last did something. + example: 5000 + currently_active: + type: boolean + description: |- + True if the user is likely to be interacting with their + client. This may be indicated by the user having a + ``last_active_ago`` within the last few minutes. Defaults + to false. + example: true + required: ['user_id', 'presence', 'last_active_ago'] + required: ['push'] diff --git a/api/server-server/definitions/event-schemas/m.presence_accept.yaml b/api/server-server/definitions/event-schemas/m.presence_accept.yaml new file mode 100644 index 000000000..3ba78b477 --- /dev/null +++ b/api/server-server/definitions/event-schemas/m.presence_accept.yaml @@ -0,0 +1,46 @@ +# Copyright 2018 New Vector 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. + +type: object +title: m.presence_accept +description: |- + An EDU representing approval for the observing user to subscribe to the + presence of the the observed user. +allOf: + - $ref: ../edu.yaml + - type: object + properties: + edu_type: + type: enum + enum: ['m.presence_accept'] + description: The string ``m.presence_accept`` + example: "m.presence_accept" + content: + type: object + description: The invite information. + title: Invite Information + properties: + observed_user: + type: string + description: |- + The user ID that has approved the ``observer_user`` to + subscribe to their presence. + example: "@alice:elsewhere.com" + observer_user: + type: string + description: |- + The user ID that requested to subscribe to the presence of + the ``observed_user``. + example: "@john:matrix.org" + required: ['observer_user', 'observed_user'] diff --git a/api/server-server/definitions/event-schemas/m.presence_deny.yaml b/api/server-server/definitions/event-schemas/m.presence_deny.yaml new file mode 100644 index 000000000..2eb6feec9 --- /dev/null +++ b/api/server-server/definitions/event-schemas/m.presence_deny.yaml @@ -0,0 +1,55 @@ +# Copyright 2018 New Vector 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. + +type: object +title: m.presence_deny +description: |- + An EDU representing a declination or revocation for the observing user + to subscribe to the presence of the observed user. +example: { + "origin": "domain.com", + "destination": "elsewhere.org", + "edu_type": "m.presence_deny", + "content": { + "observed_user": "@alice:elsewhere.org", + "observer_user": "@john:domain.com" + } +} +allOf: + - $ref: ../edu.yaml + - type: object + properties: + edu_type: + type: enum + enum: ['m.presence_deny'] + description: The string ``m.presence_deny`` + example: "m.presence_deny" + content: + type: object + description: The invite information. + title: Invite Information + properties: + observed_user: + type: string + description: |- + The user ID that has declined or revoked the ``observer_user`` from + subscribing to their presence. + example: "@alice:elsewhere.com" + observer_user: + type: string + description: |- + The user ID that requested to subscribe to the presence of + the ``observed_user``. + example: "@john:matrix.org" + required: ['observer_user', 'observed_user'] diff --git a/api/server-server/definitions/event-schemas/m.presence_invite.yaml b/api/server-server/definitions/event-schemas/m.presence_invite.yaml new file mode 100644 index 000000000..a584897b7 --- /dev/null +++ b/api/server-server/definitions/event-schemas/m.presence_invite.yaml @@ -0,0 +1,45 @@ +# Copyright 2018 New Vector 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. + +type: object +title: m.presence_invite +description: |- + An EDU representing a request to subscribe to a user's presence. +allOf: + - $ref: ../edu.yaml + - type: object + properties: + edu_type: + type: enum + enum: ['m.presence_invite'] + description: The string ``m.presence_invite`` + example: "m.presence_invite" + content: + type: object + description: The invite information. + title: Invite Information + properties: + observed_user: + type: string + description: |- + The user ID the ``observer_user`` would like to subscribe + to the presence of. + example: "@alice:elsewhere.com" + observer_user: + type: string + description: |- + The user ID that is wishing to subscribe to the presence of + the ``observed_user``. + example: "@john:matrix.org" + required: ['observer_user', 'observed_user'] diff --git a/api/server-server/definitions/event-schemas/m.receipt.yaml b/api/server-server/definitions/event-schemas/m.receipt.yaml new file mode 100644 index 000000000..7f13ebee3 --- /dev/null +++ b/api/server-server/definitions/event-schemas/m.receipt.yaml @@ -0,0 +1,82 @@ +# Copyright 2018 New Vector 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. + +type: object +title: m.receipt +description: |- + An EDU representing receipt updates for users of the sending homeserver. + When receiving receipts, the server should only update entries that are + listed in the EDU. Receipts previously received that do not appear in the + EDU should not be removed or otherwise manipulated. +allOf: + - $ref: ../edu.yaml + - type: object + properties: + edu_type: + type: enum + enum: ['m.receipt'] + description: The string ``m.receipt`` + example: "m.receipt" + content: + type: object + description: |- + Receipts for a particular room. The string key is the room ID for + which the receipts under it belong. + additionalProperties: + type: object + title: Room Receipts + properties: + # We strongly define the receipt type to help spec future ones later + # on. At that point, m.read can become optional (maybe). + "m.read": + type: object + description: Read receipts for users in the room. + title: User Read Receipt + properties: + event_ids: + type: array + description: |- + The extremity event IDs that the user has read up to. + minItems: 1 + maxItems: 1 + items: + type: string + example: ['$read_this_event:matrix.org'] + data: + type: object + description: Metadata for the read receipt. + title: Read Receipt Metadata + properties: + ts: + type: integer + format: int64 + description: |- + A POSIX timestamp in milliseconds for when the user read + the event specified in the read receipt. + example: 1533358089009 + required: ['ts'] + required: ['event_ids', 'data'] + required: ['m.read'] + example: { + "!some_room:domain.com": { + "m.read": { + "@john:matrix.org": { + "event_ids": ["$read_this_event:matrix.org"], + "data": { + "ts": 1533358089009 + } + } + } + } + } diff --git a/api/server-server/definitions/event-schemas/m.typing.yaml b/api/server-server/definitions/event-schemas/m.typing.yaml new file mode 100644 index 000000000..ccbecf535 --- /dev/null +++ b/api/server-server/definitions/event-schemas/m.typing.yaml @@ -0,0 +1,46 @@ +# Copyright 2018 New Vector 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. + +type: object +title: m.typing +description: A typing notification EDU for a user in a room. +allOf: + - $ref: ../edu.yaml + - type: object + properties: + edu_type: + type: enum + enum: ['m.typing'] + description: The string ``m.typing`` + example: "m.typing" + content: + type: object + description: The typing notification. + title: Typing Notification + properties: + room_id: + type: string + description: |- + The room where the user's typing status has been updated. + example: "!somewhere:matrix.org" + user_id: + type: string + description: |- + The user ID that has had their typing status changed. + example: "@john:matrix.org" + typing: + type: boolean + description: Whether the user is typing in the room or not. + example: true + required: ['room_id', 'user_id', 'typing'] diff --git a/api/server-server/definitions/security.yaml b/api/server-server/definitions/security.yaml new file mode 100644 index 000000000..6c9cc8085 --- /dev/null +++ b/api/server-server/definitions/security.yaml @@ -0,0 +1,19 @@ +# Copyright 2018 New Vector 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. +signedRequest: + type: apiKey + description: |- + The ``Authorization`` header defined in the `Authentication`_ section. + name: Authorization + in: header diff --git a/api/server-server/definitions/unsigned_pdu.yaml b/api/server-server/definitions/unsigned_pdu.yaml index ab2812244..64991d227 100644 --- a/api/server-server/definitions/unsigned_pdu.yaml +++ b/api/server-server/definitions/unsigned_pdu.yaml @@ -78,7 +78,10 @@ properties: required: ['sha256'] depth: type: integer - description: The maximum depth of the ``prev_events``, plus one. + description: |- + The maximum depth of the ``prev_events``, plus one. Must be less than the + maximum value for an integer (2^63 - 1). If the room's depth is already at + the limit, the depth must be set to the limit. example: 12 auth_events: type: array diff --git a/api/server-server/event_auth.yaml b/api/server-server/event_auth.yaml index f55afddc8..8857131fa 100644 --- a/api/server-server/event_auth.yaml +++ b/api/server-server/event_auth.yaml @@ -24,6 +24,8 @@ consumes: - application/json produces: - application/json +securityDefinitions: + $ref: definitions/security.yaml paths: "/event_auth/{roomId}/{eventId}": get: @@ -31,6 +33,8 @@ paths: description: |- Retrieves the complete auth chain for a given event. operationId: getEventAuth + security: + - signedRequest: [] parameters: - in: path name: roomId @@ -72,6 +76,8 @@ paths: bottom-up after sorting each chain by depth then by event ID. The differences are then discovered and returned as the response to this API call. operationId: compareEventAuth + security: + - signedRequest: [] parameters: - in: path name: roomId diff --git a/api/server-server/events.yaml b/api/server-server/events.yaml index e87a06859..cf3988a20 100644 --- a/api/server-server/events.yaml +++ b/api/server-server/events.yaml @@ -22,6 +22,8 @@ schemes: basePath: /_matrix/federation/v1 produces: - application/json +securityDefinitions: + $ref: definitions/security.yaml paths: "/state/{roomId}": get: @@ -29,6 +31,8 @@ paths: description: |- Retrieves a snapshot of a room's state at a given event. operationId: getRoomState + security: + - signedRequest: [] parameters: - in: path name: roomId @@ -74,6 +78,8 @@ paths: event IDs. This performs the same function as calling ``/state/{roomId}``, however this returns just the event IDs rather than the full events. operationId: getRoomStateIds + security: + - signedRequest: [] parameters: - in: path name: roomId @@ -117,6 +123,8 @@ paths: description: |- Retrieves a single event. operationId: getEvent + security: + - signedRequest: [] parameters: - in: path name: eventId diff --git a/api/server-server/invites.yaml b/api/server-server/invites.yaml index 98d53d498..6d905e178 100644 --- a/api/server-server/invites.yaml +++ b/api/server-server/invites.yaml @@ -24,6 +24,8 @@ consumes: - application/json produces: - application/json +securityDefinitions: + $ref: definitions/security.yaml paths: "/invite/{roomId}/{eventId}": put: @@ -33,6 +35,8 @@ paths: homeserver and the invited homeserver, it can be sent to all of the servers in the room by the inviting homeserver. operationId: sendInvite + security: + - signedRequest: [] parameters: - in: path name: roomId diff --git a/api/server-server/joins.yaml b/api/server-server/joins.yaml index f054f1e0e..4902ea9e1 100644 --- a/api/server-server/joins.yaml +++ b/api/server-server/joins.yaml @@ -24,6 +24,8 @@ consumes: - application/json produces: - application/json +securityDefinitions: + $ref: definitions/security.yaml paths: "/make_join/{roomId}/{userId}": get: @@ -32,6 +34,8 @@ paths: Asks the receiving server to return information that the sending server will need to prepare a join event to get into the room. operationId: makeJoin + security: + - signedRequest: [] parameters: - in: path name: roomId @@ -178,6 +182,8 @@ paths: Submits a signed join event to the resident server for it to accept it into the room's graph. operationId: sendJoin + security: + - signedRequest: [] parameters: - in: path name: roomId diff --git a/api/server-server/leaving.yaml b/api/server-server/leaving.yaml index 28bcf42cf..be08acba6 100644 --- a/api/server-server/leaving.yaml +++ b/api/server-server/leaving.yaml @@ -24,6 +24,8 @@ consumes: - application/json produces: - application/json +securityDefinitions: + $ref: definitions/security.yaml paths: "/make_leave/{roomId}/{userId}": get: @@ -32,6 +34,8 @@ paths: Asks the receiving server to return information that the sending server will need to prepare a leave event to get out of the room. operationId: makeLeave + security: + - signedRequest: [] parameters: - in: path name: roomId @@ -151,6 +155,8 @@ paths: Submits a signed leave event to the resident server for it to accept it into the room's graph. operationId: sendLeave + security: + - signedRequest: [] parameters: - in: path name: roomId diff --git a/api/server-server/openid.yaml b/api/server-server/openid.yaml new file mode 100644 index 000000000..0eac48c84 --- /dev/null +++ b/api/server-server/openid.yaml @@ -0,0 +1,63 @@ +# Copyright 2017 Kamax.io +# Copyright 2018 New Vector 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 Federation OpenID API" + version: "1.0.0" +host: localhost:8448 +schemes: + - https +basePath: /_matrix/federation/v1 +produces: + - application/json +paths: + "/openid/userinfo": + get: + summary: Exchange an OpenID token for user information + description: |- + Exchanges an OpenID access token for information about the user + who generated the token. Currently this only exposes the Matrix + User ID of the owner. + operationId: exchangeOpenIdToken + parameters: + - in: path + name: access_token + type: string + description: |- + The OpenID access token to get information about the owner for. + required: true + x-example: SomeT0kenHere + responses: + 200: + description: |- + Information about the user who generated the OpenID access token. + schema: + type: object + properties: + sub: + type: string + description: The Matrix User ID who generated the token. + example: "@alice:example.com" + required: ['sub'] + 401: + description: The token was not recognized or has expired. + schema: + $ref: "../client-server/definitions/errors/error.yaml" + examples: + application/json: { + "errcode": "M_UNKNOWN_TOKEN", + "error": "Access token unknown or expired" + } diff --git a/api/server-server/public_rooms.yaml b/api/server-server/public_rooms.yaml index 6cd07449b..d162568f8 100644 --- a/api/server-server/public_rooms.yaml +++ b/api/server-server/public_rooms.yaml @@ -22,6 +22,8 @@ schemes: basePath: /_matrix/federation/v1 produces: - application/json +securityDefinitions: + $ref: definitions/security.yaml paths: "/publicRooms": get: @@ -31,6 +33,8 @@ paths: rooms that are listed on another homeserver's directory, just those listed on the receiving homeserver's directory. operationId: getPublicRooms + security: + - signedRequest: [] parameters: - in: query name: limit diff --git a/api/server-server/query.yaml b/api/server-server/query.yaml index f569549e3..dc14724c5 100644 --- a/api/server-server/query.yaml +++ b/api/server-server/query.yaml @@ -23,6 +23,8 @@ schemes: basePath: /_matrix/federation/v1 produces: - application/json +securityDefinitions: + $ref: definitions/security.yaml paths: "/query/{queryType}": get: @@ -32,6 +34,8 @@ paths: arguments are dependent on which type of query is being made. Known query types are specified as their own endpoints as an extension to this definition. operationId: queryInfo + security: + - signedRequest: [] parameters: - in: path name: queryType @@ -54,6 +58,8 @@ paths: Servers may wish to cache the response to this query to avoid requesting the information too often. operationId: queryRoomDirectory + security: + - signedRequest: [] parameters: - in: query name: room_alias @@ -110,6 +116,9 @@ paths: Servers may wish to cache the response to this query to avoid requesting the information too often. + operationId: queryProfile + security: + - signedRequest: [] parameters: - in: query name: user_id diff --git a/api/server-server/third_party_invite.yaml b/api/server-server/third_party_invite.yaml index 754a3282e..5c12247cf 100644 --- a/api/server-server/third_party_invite.yaml +++ b/api/server-server/third_party_invite.yaml @@ -24,6 +24,8 @@ consumes: - application/json produces: - application/json +securityDefinitions: + $ref: definitions/security.yaml paths: "/exchange_third_party_invite/{roomId}": put: @@ -34,6 +36,8 @@ paths: an invite as per the `Inviting to a room`_ section before returning a response to this request. operationId: exchangeThirdPartyInvite + security: + - signedRequest: [] parameters: - in: path name: roomId diff --git a/api/server-server/transactions.yaml b/api/server-server/transactions.yaml index 4f4c6b28e..8d810ad59 100644 --- a/api/server-server/transactions.yaml +++ b/api/server-server/transactions.yaml @@ -24,6 +24,8 @@ consumes: - application/json produces: - application/json +securityDefinitions: + $ref: definitions/security.yaml paths: "/send/{txnId}": put: @@ -36,6 +38,8 @@ paths: The sending server must wait and retry for a 200 OK response before sending a transaction with a different ``txnId`` to the receiving server. operationId: sendTransaction + security: + - signedRequest: [] parameters: - in: path name: txnId diff --git a/changelogs/client_server/newsfragments/1284.clarification b/changelogs/client_server/newsfragments/1284.clarification new file mode 100644 index 000000000..7bc92f479 --- /dev/null +++ b/changelogs/client_server/newsfragments/1284.clarification @@ -0,0 +1 @@ +Clarify ``changed`` field behaviour in device tracking process diff --git a/changelogs/client_server/newsfragments/1284.feature b/changelogs/client_server/newsfragments/1284.feature new file mode 100644 index 000000000..c658142e8 --- /dev/null +++ b/changelogs/client_server/newsfragments/1284.feature @@ -0,0 +1,7 @@ +End-to-end encryption for group chats: + + - Olm and Megolm messaging algorithms. + - ``m.room.encrypted``, ``m.room.encryption``, ``m.room_key`` events. + - Device verification process. + - ``device_one_time_keys_count`` sync parameter. + - ``device_lists:left`` sync parameter. diff --git a/changelogs/client_server/newsfragments/1506.feature b/changelogs/client_server/newsfragments/1506.feature new file mode 100644 index 000000000..62ad12603 --- /dev/null +++ b/changelogs/client_server/newsfragments/1506.feature @@ -0,0 +1 @@ +Document and improve client interaction with pushers. diff --git a/changelogs/client_server/newsfragments/1507.new b/changelogs/client_server/newsfragments/1507.new new file mode 100644 index 000000000..6cc468702 --- /dev/null +++ b/changelogs/client_server/newsfragments/1507.new @@ -0,0 +1 @@ +``POST /account/3pid/msisdn/requestToken``, ``POST /register/msisdn/requestToken``, and ``POST /account/password/msisdn/requestToken`` \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1517.clarification b/changelogs/client_server/newsfragments/1517.clarification new file mode 100644 index 000000000..b16928c1e --- /dev/null +++ b/changelogs/client_server/newsfragments/1517.clarification @@ -0,0 +1 @@ +Clarify how access tokens are meant to be supplied to the homeserver. \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1518.clarification b/changelogs/client_server/newsfragments/1518.clarification new file mode 100644 index 000000000..3e2adea34 --- /dev/null +++ b/changelogs/client_server/newsfragments/1518.clarification @@ -0,0 +1 @@ +Document additional parameters on the ``/createRoom`` API. \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1542.feature b/changelogs/client_server/newsfragments/1542.feature new file mode 100644 index 000000000..7e94bdc5a --- /dev/null +++ b/changelogs/client_server/newsfragments/1542.feature @@ -0,0 +1 @@ +Guests can now call /context and /event to fetch events diff --git a/event-schemas/examples/m.room.encrypted#megolm b/event-schemas/examples/m.room.encrypted#megolm new file mode 100644 index 000000000..1f9b75208 --- /dev/null +++ b/event-schemas/examples/m.room.encrypted#megolm @@ -0,0 +1,14 @@ +{ + "content": { + "algorithm": "m.megolm.v1.aes-sha2", + "ciphertext": "AwgAEnACgAkLmt6qF84IK++J7UDH2Za1YVchHyprqTqsg...", + "device_id": "RJYKSTBOIE", + "sender_key": "IlRMeOPX2e0MurIyfWEucYBRVOEEUMrOHqn/8mLqMjA", + "session_id": "X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ" + }, + "event_id": "$WLGTSEFSEF:localhost", + "room_id": "!Cuyf34gef24t:localhost", + "origin_server_ts": 1476648761524, + "sender": "@example:localhost", + "type": "m.room.encrypted" +} diff --git a/event-schemas/examples/m.room.encrypted#olm b/event-schemas/examples/m.room.encrypted#olm new file mode 100644 index 000000000..abb23c31e --- /dev/null +++ b/event-schemas/examples/m.room.encrypted#olm @@ -0,0 +1,14 @@ +{ + "type": "m.room.encrypted", + "sender": "@example:localhost", + "content": { + "algorithm": "m.olm.v1.curve25519-aes-sha2", + "sender_key": "Szl29ksW/L8yZGWAX+8dY1XyFi+i5wm+DRhTGkbMiwU", + "ciphertext": { + "7qZcfnBmbEGzxxaWfBjElJuvn7BZx+lSz/SvFrDF/z8": { + "type": 0, + "body": "AwogGJJzMhf/S3GQFXAOrCZ3iKyGU5ZScVtjI0KypTYrW..." + } + } + } +} diff --git a/event-schemas/examples/m.room.encryption b/event-schemas/examples/m.room.encryption new file mode 100644 index 000000000..08f152396 --- /dev/null +++ b/event-schemas/examples/m.room.encryption @@ -0,0 +1,13 @@ +{ + "content": { + "algorithm": "m.megolm.v1.aes-sha2", + "rotation_period_ms": 604800000, + "rotation_period_msgs": 100 + }, + "event_id": "$WLGTSEFJJKJ:localhost", + "origin_server_ts": 1476648761524, + "sender": "@example:localhost", + "room_id": "!Cuyf34gef24t:localhost", + "state_key": "", + "type": "m.room.encryption" +} diff --git a/event-schemas/examples/m.room_key b/event-schemas/examples/m.room_key new file mode 100644 index 000000000..53f83e522 --- /dev/null +++ b/event-schemas/examples/m.room_key @@ -0,0 +1,9 @@ +{ + "content": { + "algorithm": "m.megolm.v1.aes-sha2", + "room_id": "!Cuyf34gef24t:localhost", + "session_id": "X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ", + "session_key": "AgAAAADxKHa9uFxcXzwYoNueL5Xqi69IkD4sni8LlfJL7qNBEY..." + }, + "type": "m.room_key" +} diff --git a/event-schemas/schema/m.room.encrypted b/event-schemas/schema/m.room.encrypted new file mode 100644 index 000000000..6825be1d2 --- /dev/null +++ b/event-schemas/schema/m.room.encrypted @@ -0,0 +1,61 @@ +--- +allOf: + - $ref: core-event-schema/event.yaml + +description: |- + This event type is used when sending encrypted events. It can be used either + within a room (in which case it will have all of the `Room Event fields`_), or + as a `to-device`_ event. + +properties: + content: + properties: + algorithm: + type: string + enum: + - m.olm.curve25519-aes-sha256 + - m.megolm.v1.aes-sha + description: |- + The encryption algorithm used to encrypt this event. The + value of this field determines which other properties will be + present. + ciphertext: + oneOf: + - type: string + - type: object + additionalProperties: + type: object + title: CiphertextInfo + properties: + body: + type: string + description: The encrypted payload. + type: + type: integer + description: The Olm message type. + description: |- + The encrypted content of the event. Either the encrypted payload + itself, in the case of a Megolm event, or a map from the recipient + Curve25519 identity key to ciphertext information, in the case of an + Olm event. For more details, see `Messaging Algorithms`_. + sender_key: + type: string + description: The Curve25519 key of the sender. + device_id: + type: string + description: The ID of the sending device. Required with Megolm. + session_id: + type: string + description: |- + The ID of the session used to encrypt the message. Required with + Megolm. + required: + - algorithm + - sender_key + - ciphertext + type: object + type: + enum: + - m.room.encrypted + type: string +type: object diff --git a/event-schemas/schema/m.room.encryption b/event-schemas/schema/m.room.encryption new file mode 100644 index 000000000..d7c4d4294 --- /dev/null +++ b/event-schemas/schema/m.room.encryption @@ -0,0 +1,36 @@ +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: Defines how messages sent in this room should be encrypted. +properties: + content: + properties: + algorithm: + type: string + enum: + - "m.megolm.v1.aes-sha2" + description: |- + The encryption algorithm to be used to encrypt messages sent in this + room. + rotation_period_ms: + type: integer + description: |- + How long the session should be used before changing it. ``604800000`` + (a week) is the recommended default. + rotation_period_msgs: + type: integer + description: |- + How many messages should be sent before changing the session. ``100`` is the + recommended default. + required: + - algorithm + type: object + state_key: + description: A zero-length string. + pattern: '^$' + type: string + type: + enum: + - m.room.encryption + type: string +type: object diff --git a/event-schemas/schema/m.room_key b/event-schemas/schema/m.room_key new file mode 100644 index 000000000..ef8c51c08 --- /dev/null +++ b/event-schemas/schema/m.room_key @@ -0,0 +1,35 @@ +--- +allOf: + - $ref: core-event-schema/event.yaml + +description: |- + This event type is used to exchange keys for end-to-end encryption. Typically + it is encrypted as an ``m.room.encrypted`` event, then sent as a `to-device`_ event. +properties: + content: + properties: + algorithm: + type: string + enum: ["m.megolm.v1.aes-sha2"] + description: |- + The encryption algorithm the key in this event is to be used with. + room_id: + type: string + description: The room where the key is used. + session_id: + type: string + description: The ID of the session that the key is for. + session_key: + type: string + description: The key to be exchanged. + required: + - algorithm + - room_id + - session_id + - session_key + type: object + type: + enum: + - m.room_key + type: string +type: object diff --git a/meta/documentation_style.rst b/meta/documentation_style.rst index e60c7847e..c6bb62bf4 100644 --- a/meta/documentation_style.rst +++ b/meta/documentation_style.rst @@ -32,6 +32,12 @@ complete specification to be merged correctly. These characters are: If you find yourself using ``^`` or beyond, you should rethink your document layout if possible. +Correct capitalisation for long section names +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Headings should start with a capital letter, and use lower-case otherwise. + + TODOs ----- diff --git a/scripts/templating/matrix_templates/templates/schema-definition.tmpl b/scripts/templating/matrix_templates/templates/schema-definition.tmpl index 42a7ae476..e2be12e8a 100644 --- a/scripts/templating/matrix_templates/templates/schema-definition.tmpl +++ b/scripts/templating/matrix_templates/templates/schema-definition.tmpl @@ -1,6 +1,6 @@ {% import 'tables.tmpl' as tables -%} -``{{definition.title}}`` Schema +``{{definition.title}}`` schema {{(11 + definition.title | length) * title_kind}} {% if 'description' in definition %} diff --git a/specification/application_service_api.rst b/specification/application_service_api.rst index b4950eac0..08e3b0626 100644 --- a/specification/application_service_api.rst +++ b/specification/application_service_api.rst @@ -1,4 +1,5 @@ .. Copyright 2016 OpenMarket Ltd +.. Copyright 2018 New Vector Ltd .. .. Licensed under the Apache License, Version 2.0 (the "License"); .. you may not use this file except in compliance with the License. @@ -39,7 +40,7 @@ This version of the specification is generated from Application Services -------------------- Application services are passive and can only observe events from a given -homeserver. They can inject events into rooms they are participating in. +homeserver (HS). They can inject events into rooms they are participating in. They cannot prevent events from being sent, nor can they modify the content of the event being sent. In order to observe events from a homeserver, the homeserver needs to be configured to pass certain types of traffic to the @@ -68,7 +69,13 @@ Registration Application services register "namespaces" of user IDs, room aliases and room IDs. These namespaces are represented as regular expressions. An application service is said to be "interested" in a given event if one of the IDs in the event match -the regular expression provided by the application service. An application +the regular expression provided by the application service, such as the room having +an alias or ID in the relevant namespaces. Similarly, the application service is +said to be interested in a given event if one of the application service's namespaced +users is the target of the event, or is a joined member of the room where the event +occurred. + +An application service can also state whether they should be the only ones who can manage a specified namespace. This is referred to as an "exclusive" namespace. An exclusive namespace prevents humans and other application @@ -83,7 +90,7 @@ regular expressions and look like: users: - exclusive: true - regex: @irc.freenode.net_.* + regex: @_irc.freenode.net_.* The registration is represented by a series of key-value pairs, which this @@ -105,12 +112,17 @@ traffic to the AS is: aliases: [] # Namespaces of room aliases which should be delegated to the AS rooms: [] # Namespaces of room ids which should be delegated to the AS +Exclusive user and alias namespaces should begin with an underscore after the +sigil to avoid collisions with other users on the homeserver. Application +services should additionally attempt to identify the service they represent +in the reserved namespace. For example, ``@_irc_.*`` would be a good namespace +to register for an application service which deals with IRC. + .. WARNING:: If the homeserver in question has multiple application services, each ``as_token`` and ``id`` MUST be unique per application service as these are used to identify the application service. The homeserver MUST enforce this. - Homeserver -> Application Service API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -163,6 +175,10 @@ this request (e.g. to join a room alias). the application service about information about the entity such as room ID to room alias mappings. +{{query_user_as_http_api}} + +{{query_room_as_http_api}} + HTTP APIs +++++++++ @@ -185,29 +201,34 @@ homeserver. Identity assertion ++++++++++++++++++ The client-server API infers the user ID from the ``access_token`` provided in -every request. It would be an annoying amount of book-keeping to maintain tokens -for every virtual user. It would be preferable if the application service could -use the CS API with its own ``as_token`` instead, and specify the virtual user -they wish to be acting on behalf of. For real users, this would require -additional permissions granting the AS permission to masquerade as a matrix user. +every request. To avoid the application service from having to keep track of each +user's access token, the application service should identify itself to the Client-Server +API by providing its ``as_token`` for the ``access_token`` alongside the user the +application service would like to masquerade as. Inputs: - - Application service token (``access_token``) + - Application service token (``as_token``) - User ID in the AS namespace to act as. Notes: - - This will apply on all aspects of the CS API, except for Account Management. + - This applies to all aspects of the Client-Server API, except for Account Management. - The ``as_token`` is inserted into ``access_token`` which is usually where the - client token is. This is done on purpose to allow application services to - reuse client SDKs. + client token is, such as via the query string or ``Authorization`` header. This + is done on purpose to allow application services to reuse client SDKs. + - The ``access_token`` should be supplied through the ``Authorization`` header where + possible to prevent the token appearing in HTTP request logs by accident. -:: +The application service may specify the virtual user to act as through use of a +``user_id`` query string parameter on the request. The user specified in the query +string must be covered by one of the application service's ``user`` namespaces. If +the parameter is missing, the homeserver is to assume the application service intends +to act as the user implied by the ``sender_localpart`` property of the registration. + +An example request would be:: - /path?access_token=$token&user_id=$userid + GET /_matrix/client/%CLIENT_MAJOR_VERSION%/account/whoami?user_id=@_irc_user:example.org + Authorization: Bearer YourApplicationServiceTokenHere - Query Parameters: - access_token: The application service token - user_id: The desired user ID to act as. Timestamp massaging +++++++++++++++++++ @@ -217,17 +238,17 @@ need to be able to adjust the ``origin_server_ts`` value to do this. Inputs: - Application service token (``as_token``) - - Desired timestamp + - Desired timestamp (in milliseconds since the unix epoch) + Notes: - This will only apply when sending events. :: - /path?access_token=$token&ts=$timestamp + PUT /_matrix/client/r0/rooms/!somewhere:domain.com/send/m.room.message/txnId?ts=1534535223283 + Authorization: Bearer YourApplicationServiceTokenHere - Query Parameters added to the send event APIs only: - access_token: The application service token - ts: The desired timestamp + Content: The event to send, as per the Client-Server API. Server admin style permissions ++++++++++++++++++++++++++++++ @@ -250,12 +271,13 @@ including the AS token on a ``/register`` request, along with a login type of :: - /register?access_token=$as_token + POST /_matrix/client/%CLIENT_MAJOR_VERSION%/register + Authorization: Bearer YourApplicationServiceTokenHere Content: { type: "m.login.application_service", - username: "" + username: "_irc_example" } Application services which attempt to create users or aliases *outside* of @@ -264,78 +286,19 @@ normal users who attempt to create users or aliases *inside* an application service-defined namespace will receive the same ``M_EXCLUSIVE`` error code, but only if the application service has defined the namespace as ``exclusive``. -ID conventions -~~~~~~~~~~~~~~ -.. TODO-spec - - Giving HSes the freedom to namespace still feels like the Right Thing here. - - Exposing a public API provides the consistency which was the main complaint - against namespacing. - - This may have knock-on effects for the AS registration API. E.g. why don't - we let ASes specify the *URI* regex they want? - -This concerns the well-defined conventions for mapping 3P network IDs to matrix -IDs, which we expect clients to be able to do by themselves. - -User IDs -++++++++ -Matrix users may wish to directly contact a virtual user, e.g. to send an email. -The URI format is a well-structured way to represent a number of different ID -types, including: - -- MSISDNs (``tel``) -- Email addresses (``mailto``) -- IRC nicks (``irc`` - https://tools.ietf.org/html/draft-butcher-irc-url-04) -- XMPP (XEP-0032) -- SIP URIs (RFC 3261) - -As a result, virtual user IDs SHOULD relate to their URI counterpart. This -mapping from URI to user ID can be expressed in a number of ways: +Using ``/sync`` and ``/events`` ++++++++++++++++++++++++++++++++ -- Expose a C-S API on the HS which takes URIs and responds with user IDs. -- Munge the URI with the user ID. +Application services wishing to use ``/sync`` or ``/events`` from the Client-Server +API MUST do so with a virtual user (provide a ``user_id`` via the query string). It +is expected that the application service use the transactions pushed to it to +handle events rather than syncing with the user implied by ``sender_localpart``. -Exposing an API would allow HSes to internally map user IDs however they like, -at the cost of an extra round trip (of which the response can be cached). -Munging the URI would allow clients to apply the mapping locally, but would force -user X on service Y to always map to the same munged user ID. Considering the -exposed API could just be applying this munging, there is more flexibility if -an API is exposed. - -:: - - GET /_matrix/app/%CLIENT_MAJOR_VERSION%/user?uri=$url_encoded_uri - - Returns 200 OK: - { - user_id: - } - -Room Aliases -++++++++++++ -We may want to expose some 3P network rooms so Matrix users can join them directly, -e.g. IRC rooms. We don't want to expose every 3P network room though, e.g. -``mailto``, ``tel``. Rooms which are publicly accessible (e.g. IRC rooms) can be -exposed as an alias by the application service. Private rooms -(e.g. sending an email to someone) should not -be exposed in this way, but should instead operate using normal invite/join semantics. -Therefore, the ID conventions discussed below are only valid for public rooms which -expose room aliases. - -Matrix users may wish to join XMPP rooms (e.g. using XEP-0045) or IRC rooms. In both -cases, these rooms can be expressed as URIs. For consistency, these "room" URIs -SHOULD be mapped in the same way as "user" URIs. - -:: +Event fields +~~~~~~~~~~~~ - GET /_matrix/app/%CLIENT_MAJOR_VERSION%/alias?uri=$url_encoded_uri +.. TODO-TravisR: Fix this section to be a general "3rd party networks" section - Returns 200 OK: - { - alias: - } - -Event fields -++++++++++++ We recommend that any events that originated from a remote network should include an ``external_url`` field in their content to provide a way for Matrix clients to link into the 'native' client from which the event originated. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index bd9b8dca6..71c600975 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -198,10 +198,6 @@ previously obtained credentials in the form of an ``access_token`` query parameter or through an Authorization Header of ``Bearer $access_token``. 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 @@ -209,6 +205,24 @@ return with a status of 401 and the error code, ``M_MISSING_TOKEN`` or to choose an appropriate format. Server implementors may like to investigate `macaroons `_. +Using access tokens +~~~~~~~~~~~~~~~~~~~ + +Access tokens may be provided in two ways, both of which the homeserver MUST +support: + +1. Via a query string parameter, ``access_token=TheTokenHere``. +#. Via a request header, ``Authorization: Bearer TheTokenHere``. + +Clients are encouraged to use the ``Authorization`` header where possible +to prevent the access token being leaked in access/HTTP logs. The query +string should only be used in cases where the ``Authorization`` header is +inaccessible for the client. + +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. + Relationship between access tokens and devices ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/specification/identity_service_api.rst b/specification/identity_service_api.rst index cb0795939..3b037caf0 100644 --- a/specification/identity_service_api.rst +++ b/specification/identity_service_api.rst @@ -119,6 +119,11 @@ Email associations {{email_associations_is_http_api}} +Phone number associations +~~~~~~~~~~~~~~~~~~~~~~~~~ + +{{phone_associations_is_http_api}} + General ~~~~~~~ diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 1f778bc2c..fa461cc28 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -21,12 +21,6 @@ Matrix optionally supports end-to-end encryption, allowing rooms to be created whose conversation contents is not decryptable or interceptable on any of the participating homeservers. -.. WARNING:: - - End to end encryption is being worked on and will be coming soon. This - section is incomplete. You can read more about what's underway at - http://matrix.org/speculator/spec/drafts%2Fe2e/client_server/unstable.html#end-to-end-encryption. - Key Distribution ---------------- Encryption and Authentication in Matrix is based around public-key @@ -159,7 +153,7 @@ It is therefore expected that each client will maintain a list of devices for a number of users (in practice, typically each user with whom we share an encrypted room). Furthermore, it is likely that this list will need to be persisted between invocations of the client application (to preserve device -verification data and to alert Alice if Bob suddently gets a new +verification data and to alert Alice if Bob suddenly gets a new device). Alice's client can maintain a list of Bob's devices via the following @@ -176,9 +170,10 @@ process: flag. #. During its normal processing of responses to |/sync|_, Alice's client - inspects the |device_lists|_ field. If it is tracking the device lists of - any of the listed users, then it marks the device lists for those users - outdated, and initiates another request to |/keys/query|_ for them. + inspects the ``changed`` property of the |device_lists|_ field. If it is + tracking the device lists of any of the listed users, then it marks the + device lists for those users outdated, and initiates another request to + |/keys/query|_ for them. #. Periodically, Alice's client stores the ``next_batch`` field of the result from |/sync|_ in persistent storage. If Alice later restarts her client, it @@ -214,6 +209,18 @@ process: that the first request's results are ignored (possibly by cancelling the request). +.. Note:: + + When Bob and Alice share a room, with Bob tracking Alice's devices, she may leave + the room and then add a new device. Bob will not be notified of this change, + as he doesn't share a room anymore with Alice. When they start sharing a + room again, Bob has an out-of-date list of Alice's devices. In order to address + this issue, Bob's homeserver will add Alice's user ID to the ``changed`` property of + the ``device_lists`` field, thus Bob will update his list of Alice's devices as part + of his normal processing. Note that Bob can also be notified when he stops sharing + any room with Alice by inspecting the ``left`` property of the ``device_lists`` + field, and as a result should remove her from its list of tracked users. + .. |device_lists| replace:: ``device_lists`` .. _`device_lists`: `device_lists_sync`_ @@ -228,10 +235,238 @@ A homeserver should rate-limit the number of one-time keys that a given user or remote server can claim. A homeserver should discard the public part of a one time key once it has given that key to another user. +Device verification +------------------- + +Before Alice sends Bob encrypted data, or trusts data received from him, she +may want to verify that she is actually communicating with him, rather than a +man-in-the-middle. This verification process requires an out-of-band channel: +there is no way to do it within Matrix without trusting the administrators of +the homeservers. + +In Matrix, the basic process for device verification is for Alice to verify +that the public Ed25519 signing key she received via ``/keys/query`` for Bob's +device corresponds to the private key in use by Bob's device. For now, it is +recommended that clients provide mechanisms by which the user can see: + +1. The public part of their device's Ed25519 signing key, encoded using + `unpadded Base64`_. + +2. The list of devices in use for each user in a room, along with the public + Ed25519 signing key for each device, again encoded using unpadded Base64. + +Alice can then meet Bob in person, or contact him via some other trusted +medium, and ask him to read out the Ed25519 key shown on his device. She +compares this with the value shown for his device on her client. + +Device verification may reach one of several conclusions. For example: + +* Alice may "accept" the device. This means that she is satisfied that the + device belongs to Bob. She can then encrypt sensitive material for that + device, and knows that messages received were sent from that device. + +* Alice may "reject" the device. She will do this if she knows or suspects + that Bob does not control that device (or equivalently, does not trust + Bob). She will not send sensitive material to that device, and cannot trust + messages apparently received from it. + +* Alice may choose to skip the device verification process. She is not able + to verify that the device actually belongs to Bob, but has no reason to + suspect otherwise. The encryption protocol continues to protect against + passive eavesdroppers. + +.. NOTE:: + + Once the signing key has been verified, it is then up to the encryption + protocol to verify that a given message was sent from a device holding that + Ed25519 private key, or to encrypt a message so that it may only be + decrypted by such a device. For the Olm protocol, this is documented at + https://matrix.org/git/olm/about/docs/signing.rst. + +Messaging Algorithms +-------------------- + +Messaging Algorithm Names +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Messaging algorithm names use the extensible naming scheme used throughout this +specification. Algorithm names that start with ``m.`` are reserved for +algorithms defined by this specification. Implementations wanting to experiment +with new algorithms must be uniquely globally namespaced following Java's package +naming conventions. + +Algorithm names should be short and meaningful, and should list the primitives +used by the algorithm so that it is easier to see if the algorithm is using a +broken primitive. + +A name of ``m.olm.v1`` is too short: it gives no information about the primitives +in use, and is difficult to extend for different primitives. However a name of +``m.olm.v1.ecdh-curve25519-hdkfsha256.hmacsha256.hkdfsha256-aes256-cbc-hmac64sha256`` +is too long despite giving a more precise description of the algorithm: it adds +to the data transfer overhead and sacrifices clarity for human readers without +adding any useful extra information. + +``m.olm.v1.curve25519-aes-sha2`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The name ``m.olm.v1.curve25519-aes-sha2`` corresponds to version 1 of the Olm +ratchet, as defined by the `Olm specification`_. This uses: + +* Curve25519 for the initial key agreement. +* HKDF-SHA-256 for ratchet key derivation. +* Curve25519 for the root key ratchet. +* HMAC-SHA-256 for the chain key ratchet. +* HKDF-SHA-256, AES-256 in CBC mode, and 8 byte truncated HMAC-SHA-256 for authenticated encryption. + +Devices that support Olm must include "m.olm.v1.curve25519-aes-sha2" in their +list of supported messaging algorithms, must list a Curve25519 device key, and +must publish Curve25519 one-time keys. + +An event encrypted using Olm has the following format: + +.. code:: json + + { + "type": "m.room.encrypted", + "content": { + "algorithm": "m.olm.v1.curve25519-aes-sha2", + "sender_key": "", + "ciphertext": { + "": { + "type": 0, + "body": "" + } + } + } + } + +``ciphertext`` is a mapping from device Curve25519 key to an encrypted payload +for that device. ``body`` is a Base64-encoded Olm message body. ``type`` is an +integer indicating the type of the message body: 0 for the initial pre-key +message, 1 for ordinary messages. + +Olm sessions will generate messages with a type of 0 until they receive a +message. Once a session has decrypted a message it will produce messages with +a type of 1. + +When a client receives a message with a type of 0 it must first check if it +already has a matching session. If it does then it will use that session to +try to decrypt the message. If there is no existing session then the client +must create a new session and use the new session to decrypt the message. A +client must not persist a session or remove one-time keys used by a session +until it has successfully decrypted a message using that session. + +Messages with type 1 can only be decrypted with an existing session. If there +is no matching session, the client must treat this as an invalid message. + +The plaintext payload is of the form: + +.. code:: json + + { + "type": "", + "content": "", + "sender": "", + "recipient": "", + "recipient_keys": { + "ed25519": "" + }, + "keys": { + "ed25519": "" + } + } + +The type and content of the plaintext message event are given in the payload. + +Other properties are included in order to prevent an attacker from publishing +someone else's curve25519 keys as their own and subsequently claiming to have +sent messages which they didn't. +``sender`` must correspond to the user who sent the event, ``recipient`` to +the local user, and ``recipient_keys`` to the local ed25519 key. + +Clients must confirm that the ``sender_key`` and the ``ed25519`` field value +under the ``keys`` property match the keys returned by |/keys/query|_ for +the given user, and must also verify the signature of the payload. Without +this check, a client cannot be sure that the sender device owns the private +part of the ed25519 key it claims to have in the Olm payload. +This is crucial when the ed25519 key corresponds to a verified device. + +``m.megolm.v1.aes-sha2`` +~~~~~~~~~~~~~~~~~~~~~~~~ + +The name ``m.megolm.v1.aes-sha2`` corresponds to version 1 of the Megolm +ratchet, as defined by the `Megolm specification`_. This uses: + +* HMAC-SHA-256 for the hash ratchet. +* HKDF-SHA-256, AES-256 in CBC mode, and 8 byte truncated HMAC-SHA-256 for authenticated encryption. +* Ed25519 for message authenticity. + +Devices that support Megolm must support Olm, and include "m.megolm.v1.aes-sha2" in +their list of supported messaging algorithms. + +An event encrypted using Megolm has the following format: + +.. code:: json + + { + "type": "m.room.encrypted", + "content": { + "algorithm": "m.megolm.v1.aes-sha2", + "sender_key": "", + "device_id": "", + "session_id": "", + "ciphertext": "" + } + } + +The encrypted payload can contain any message event. The plaintext is of the form: + +.. code:: json + + { + "type": "", + "content": "", + "room_id": "" + } + +We include the room ID in the payload, because otherwise the homeserver would +be able to change the room a message was sent in. + +Clients must guard against replay attacks by keeping track of the ratchet indices +of Megolm sessions. They should reject messages with a ratchet index that they +have already decrypted. Care should be taken in order to avoid false positives, as a +client may decrypt the same event twice as part of its normal processing. + +As with Olm events, clients must confirm that the ``sender_key`` belongs to the user +who sent the message. The same reasoning applies, but the sender ed25519 key has to be +inferred from the ``keys.ed25519`` property of the event which established the Megolm +session. + +In order to enable end-to-end encryption in a room, clients can send a +``m.room.encryption`` state event specifying ``m.megolm.v1.aes-sha2`` as its +``algorithm`` property. + +When creating a Megolm session in a room, clients must share the corresponding session +key using Olm with the intended recipients, so that they can decrypt future messages +encrypted using this session. A ``m.room_key`` event is used to do this. Clients +must also handle ``m.room_key`` events sent by other devices in order to decrypt their +messages. Protocol definitions -------------------- +Events +~~~~~~ + +{{m_room_encryption_event}} + +{{m_room_encrypted_event}} + +{{m_room_key_event}} + +Key management API +~~~~~~~~~~~~~~~~~~ + {{keys_cs_http_api}} @@ -249,6 +484,9 @@ specified). The client is expected to use |/keys/query|_ or |/keys/changes|_ for the equivalent functionality after an initial sync, as documented in `Tracking the device list for a user`_. +It also adds a ``one_time_keys_count`` property. Note the spelling difference +with the ``one_time_key_counts`` property in the |/keys/upload|_ response. + .. todo: generate this from a swagger definition? .. device_lists: { changed: ["@user:server", ... ]}, @@ -258,6 +496,9 @@ Parameter Type Description ============ =========== ===================================================== device_lists DeviceLists Optional. Information on e2e device updates. Note: only present on an incremental sync. +|device_otk| {string: Optional. For each key algorithm, the number of + integer} unclaimed one-time keys currently held on the server + for this device. ============ =========== ===================================================== ``DeviceLists`` @@ -265,10 +506,20 @@ device_lists DeviceLists Optional. Information on e2e device updates. Note: ========= ========= ============================================= Parameter Type Description ========= ========= ============================================= -changed [string] List of users who have updated their device identity keys - since the previous sync response. +changed [string] List of users who have updated their device identity keys, + or who now share an encrypted room with the client since + the previous sync response. +left [string] List of users with whom we do not share any encrypted rooms + anymore since the previous sync response. ========= ========= ============================================= +.. NOTE:: + + For optimal performance, Alice should be added to ``changed`` in Bob's sync only + when she adds a new device, or when Alice and Bob now share a room but didn't + share any room previously. However, for the sake of simpler logic, a server + may add Alice to ``changed`` when Alice and Bob share a new room, even if they + previously already shared a room. Example response: @@ -281,17 +532,27 @@ Example response: "changed": [ "@alice:example.com", ], + "left": [ + "@bob:example.com", + ], }, + "device_one_time_keys_count": { + "curve25519": 10, + "signed_curve25519": 20 + } } .. References .. _ed25519: http://ed25519.cr.yp.to/ .. _curve25519: https://cr.yp.to/ecdh.html +.. _`Olm specification`: http://matrix.org/docs/spec/olm.html +.. _`Megolm specification`: http://matrix.org/docs/spec/megolm.html .. _`Signing JSON`: ../appendices.html#signing-json .. |m.olm.v1.curve25519-aes-sha2| replace:: ``m.olm.v1.curve25519-aes-sha2`` +.. |device_otk| replace:: device_one_time_keys_count .. |/keys/upload| replace:: ``/keys/upload`` .. _/keys/upload: #post-matrix-client-%CLIENT_MAJOR_VERSION%-keys-upload diff --git a/specification/modules/guest_access.rst b/specification/modules/guest_access.rst index 4e04aa0df..d579da833 100644 --- a/specification/modules/guest_access.rst +++ b/specification/modules/guest_access.rst @@ -50,6 +50,8 @@ The following API endpoints are allowed to be accessed by guest accounts for retrieving events: * `GET /rooms/:room_id/state <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-state>`_ +* `GET /rooms/:room_id/context/:event_id <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-context-eventid>`_ +* `GET /rooms/:room_id/event/:event_id <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-event-eventid>`_ * `GET /rooms/:room_id/state/:event_type/:state_key <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-state-eventtype-statekey>`_ * `GET /rooms/:room_id/messages <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-messages>`_ * `GET /rooms/:room_id/initialSync <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-initialsync>`_ diff --git a/specification/modules/openid.rst b/specification/modules/openid.rst new file mode 100644 index 000000000..63406719c --- /dev/null +++ b/specification/modules/openid.rst @@ -0,0 +1,24 @@ +.. Copyright 2018 New Vector 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. + +OpenID +====== + +.. _module:openid: + +This module allows users to verify their identity with a third party service. The +third party service does need to be matrix-aware in that it will need to know to +resolve matrix homeservers to exchange the user's token for identity information. + +{{openid_cs_http_api}} diff --git a/specification/modules/push.rst b/specification/modules/push.rst index 9bb65b965..e9ee8c90d 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -622,3 +622,5 @@ shouldn't be sent in the push itself where possible. Instead, Push Gateways should send a "sync" command to instruct the client to get new events from the homeserver directly. + +.. _`Push Gateway Specification`: ../push_gateway/unstable.html diff --git a/specification/push_gateway.rst b/specification/push_gateway.rst index 29a41bf7c..e4a9d6ea8 100644 --- a/specification/push_gateway.rst +++ b/specification/push_gateway.rst @@ -67,4 +67,9 @@ This describes the format used by "HTTP" pushers to send notifications of events to Push Gateways. If the endpoint returns an HTTP error code, the homeserver SHOULD retry for a reasonable amount of time using exponential backoff. +When pushing notifications for events, the hoemserver is expected to include all of +the event-related fields in the ``/notify`` request. When the homeserver is performing +a push where the ``format`` is ``"event_id_only"``, only the ``event_id``, ``room_id``, +``counts``, and ``devices`` are required to be populated. + {{push_notifier_push_http_api}} diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 472aca125..dbde8b104 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -606,7 +606,7 @@ the events it is missing. {{backfill_ss_http_api}} Retrieving events ----------------- +----------------- In some circumstances, a homeserver may be missing a particular event or information about the room which cannot be easily determined from backfilling. These APIs provide @@ -812,68 +812,58 @@ should be retrieved for. {{public_rooms_ss_http_api}} +Typing Notifications +-------------------- + +When a server's users send typing notifications, those notifications need to +be sent to other servers in the room so their users are aware of the same +state. Receiving servers should verify that the user is in the room, and is +a user belonging to the sending server. + +{{definition_ss_event_schemas_m_typing}} + Presence -------- The server API for presence is based entirely on exchange of the following EDUs. There are no PDUs or Federation Queries involved. -Performing a presence update and poll subscription request:: - - EDU type: m.presence - - Content keys: - push: (optional): list of push operations. - Each should be an object with the following keys: - user_id: string containing a User ID - presence: "offline"|"unavailable"|"online"|"free_for_chat" - status_msg: (optional) string of free-form text - last_active_ago: milliseconds since the last activity by the user +Servers should only send presence updates for users that the receiving server +would be interested in. This can include the receiving server sharing a room +with a given user, or a user on the receiving server has added one of the +sending server's users to their presence list. - poll: (optional): list of strings giving User IDs +Clients may define lists of users that they are interested in via "Presence +Lists" through the `Client-Server API`_. When users are added to a presence +list, a ``m.presence_invite`` EDU is sent to them. The user may then accept +or deny their involvement in the list by sending either an ``m.presence_accept`` +or ``m.presence_deny`` EDU back. - unpoll: (optional): list of strings giving User IDs - -The presence of this combined message is two-fold: it informs the recipient -server of the current status of one or more users on the sending server (by the -``push`` key), and it maintains the list of users on the recipient server that -the sending server is interested in receiving updates for, by adding (by the -``poll`` key) or removing them (by the ``unpoll`` key). The ``poll`` and -``unpoll`` lists apply *changes* to the implied list of users; any existing IDs -that the server sent as ``poll`` operations in a previous message are not -removed until explicitly requested by a later ``unpoll``. - -On receipt of a message containing a non-empty ``poll`` list, the receiving -server should immediately send the sending server a presence update EDU of its -own, containing in a ``push`` list the current state of every user that was in -the original EDU's ``poll`` list. - -Sending a presence invite:: +.. TODO-doc + - Explain the timing-based round-trip reduction mechanism for presence + messages + - Explain the zero-byte presence inference logic + See also: docs/client-server/model/presence - EDU type: m.presence_invite +{{definition_ss_event_schemas_m_presence}} - Content keys: - observed_user: string giving the User ID of the user whose presence is - requested (i.e. the recipient of the invite) - observer_user: string giving the User ID of the user who is requesting to - observe the presence (i.e. the sender of the invite) +{{definition_ss_event_schemas_m_presence_invite}} -Accepting a presence invite:: +{{definition_ss_event_schemas_m_presence_accept}} - EDU type: m.presence_accept +{{definition_ss_event_schemas_m_presence_deny}} - Content keys - as for m.presence_invite -Rejecting a presence invite:: +Receipts +-------- - EDU type: m.presence_deny +Receipts are EDUs used to communicate a marker for a given event. Currently the +only kind of receipt supported is a "read receipt", or where in the event graph +the user has read up to. - Content keys - as for m.presence_invite +Read receipts for events events that a user sent do not need to be sent. It is +implied that by sending the event the user has read up to the event. -.. TODO-doc - - Explain the timing-based round-trip reduction mechanism for presence - messages - - Explain the zero-byte presence inference logic - See also: docs/client-server/model/presence +{{definition_ss_event_schemas_m_receipt}} Querying for information ------------------------ @@ -888,6 +878,18 @@ that can be made. {{query_ss_http_api}} +OpenID +------ + +Third party services can exchange an access token previously generated by the +`Client-Server API` for information about a user. This can help verify that a +user is who they say they are without granting full access to the user's account. + +Access tokens generated by the OpenID API are only good for the OpenID API and +nothing else. + +{{openid_ss_http_api}} + Send-to-device messaging ------------------------ diff --git a/specification/targets.yaml b/specification/targets.yaml index 53957e0af..5480bbc5a 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -66,6 +66,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/stickers.rst - modules/report_content.rst - modules/third_party_networks.rst + - modules/openid.rst title_styles: ["=", "-", "~", "+", "^", "`", "@", ":"]