# 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 Client-Server Client Config 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:
  "/keys/upload":
    post:
      summary: Upload end-to-end encryption keys.
      description: |-
        Publishes end-to-end encryption keys for the device.
      operationId: uploadKeys
      security:
        - accessToken: []
      parameters:
        - in: body
          name: keys
          description: |-
            The keys to be published
          schema:
            type: object
            properties:
              device_keys:
                description: |-
                  Identity keys for the device. May be absent if no new
                  identity keys are required.
                allOf:
                  - $ref: definitions/device_keys.yaml
              one_time_keys:
                type: object
                description: |-
                  One-time public keys for "pre-key" messages.  The names of
                  the properties should be in the format
                  ``<algorithm>:<key_id>``. The format of the key is determined
                  by the `key algorithm <#key-algorithms>`_.

                  May be absent if no new one-time keys are required.
                additionalProperties:
                  type:
                    - string
                    - object
                    # XXX: We can't define an actual object here, so we have to hope
                    # that people will look at the swagger source or can figure it out
                    # from the other endpoints/example.
                    # - type: object
                    #   title: KeyObject
                    #   properties:
                    #     key:
                    #       type: string
                    #       description: The key, encoded using unpadded base64.
                    #     signatures:
                    #       type: object
                    #       description: |-
                    #         Signature for the device. Mapped from user ID to signature object.
                    #       additionalProperties:
                    #         type: string
                    #   required: ['key', 'signatures']
                example: {
                  "curve25519:AAAAAQ": "/qyvZvwjiTxGdGU0RCguDCLeR+nmsb3FfNG3/Ve4vU8",
                  "signed_curve25519:AAAAHg": {
                    "key": "zKbLg+NrIjpnagy+pIY6uPL4ZwEG2v+8F9lmgsnlZzs",
                    "signatures": {
                      "@alice:example.com": {
                        "ed25519:JLAFKJWSCS": "FLWxXqGbwrb8SM3Y795eB6OA8bwBcoMZFXBqnTn58AYWZSqiD45tlBVcDa2L7RwdKXebW/VzDlnfVJ+9jok1Bw"
                      }
                    }
                  },
                  "signed_curve25519:AAAAHQ": {
                    "key": "j3fR3HemM16M7CWhoI4Sk5ZsdmdfQHsKL1xuSft6MSw",
                    "signatures": {
                      "@alice:example.com": {
                        "ed25519:JLAFKJWSCS": "IQeCEPb9HFk217cU9kw9EOiusC6kMIkoIRnbnfOh5Oc63S1ghgyjShBGpu34blQomoalCyXWyhaaT3MrLZYQAA"
                      }
                    }
                  }
                }
      responses:
        200:
          description:
            The provided keys were sucessfully uploaded.
          schema:
            type: object
            properties:
              one_time_key_counts:
                type: object
                additionalProperties:
                  type: integer
                description: |-
                  For each key algorithm, the number of unclaimed one-time keys
                  of that type currently held on the server for this device.
                example:
                  curve25519: 10
                  signed_curve25519: 20
            required:
              - one_time_key_counts

      tags:
        - End-to-end encryption
  "/keys/query":
    post:
      summary: Download device identity keys.
      description: |-
        Returns the current devices and identity keys for the given users.
      operationId: queryKeys
      security:
        - accessToken: []
      parameters:
        - in: body
          name: query
          description: |-
            Query defining the keys to be downloaded
          schema:
            type: object
            properties:
              timeout:
                type: integer
                description: |-
                  The time (in milliseconds) to wait when downloading keys from
                  remote servers. 10 seconds is the recommended default.
                example: 10000
              device_keys:
                type: object
                description: |-
                  The keys to be downloaded. A map from user ID, to a list of
                  device IDs, or to an empty list to indicate all devices for the
                  corresponding user.
                additionalProperties:
                  type: array
                  items:
                    type: string
                    description: "device ID"
                example:
                  "@alice:example.com": []
              token:
                type: string
                description: |-
                  If the client is fetching keys as a result of a device update received
                  in a sync request, this should be the 'since' token of that sync request,
                  or any later sync token. This allows the server to ensure its response
                  contains the keys advertised by the notification in that sync.
            required:
              - device_keys

      responses:
        200:
          description:
            The device information
          schema:
            type: object
            properties:
              failures:
                type: object
                description: |-
                  If any remote homeservers could not be reached, they are
                  recorded here. The names of the properties are the names of
                  the unreachable servers.

                  If the homeserver could be reached, but the user or device
                  was unknown, no failure is recorded. Instead, the corresponding
                  user or device is missing from the ``device_keys`` result.
                additionalProperties:
                  type: object
                example: {}
              device_keys:
                type: object
                description: |-
                  Information on the queried devices. A map from user ID, to a
                  map from device ID to device information.  For each device,
                  the information returned will be the same as uploaded via
                  ``/keys/upload``, with the addition of an ``unsigned``
                  property.
                additionalProperties:
                  type: object
                  additionalProperties:
                    allOf:
                      - $ref: definitions/device_keys.yaml
                    properties:
                      unsigned:
                        title: UnsignedDeviceInfo
                        type: object
                        description: |-
                          Additional data added to the device key information
                          by intermediate servers, and not covered by the
                          signatures.
                        properties:
                          device_display_name:
                            type: string
                            description:
                              The display name which the user set on the device.
                example:
                  "@alice:example.com":
                    JLAFKJWSCS: {
                      "user_id": "@alice:example.com",
                      "device_id": "JLAFKJWSCS",
                      "algorithms": [
                        "m.olm.v1.curve25519-aes-sha256",
                        "m.megolm.v1.aes-sha"
                      ],
                      "keys": {
                        "curve25519:JLAFKJWSCS": "3C5BFWi2Y8MaVvjM8M22DBmh24PmgR0nPvJOIArzgyI",
                        "ed25519:JLAFKJWSCS": "lEuiRJBit0IG6nUf5pUzWTUEsRVVe/HJkoKuEww9ULI"
                      },
                      "signatures": {
                        "@alice:example.com": {
                          "ed25519:JLAFKJWSCS": "dSO80A01XiigH3uBiDVx/EjzaoycHcjq9lfQX0uWsqxl2giMIiSPR8a4d291W1ihKJL/a+myXS367WT6NAIcBA"
                        }
                      },
                      "unsigned": {
                        "device_display_name": "Alice's mobile phone"
                      }
                    }

      tags:
        - End-to-end encryption
  "/keys/claim":
    post:
      summary: Claim one-time encryption keys.
      description: |-
        Claims one-time keys for use in pre-key messages.
      operationId: claimKeys
      security:
        - accessToken: []
      parameters:
        - in: body
          name: query
          description: |-
            Query defining the keys to be claimed
          schema:
            type: object
            properties:
              timeout:
                type: integer
                description: |-
                  The time (in milliseconds) to wait when downloading keys from
                  remote servers. 10 seconds is the recommended default.
                example: 10000
              one_time_keys:
                type: object
                description: |-
                  The keys to be claimed. A map from user ID, to a map from
                  device ID to algorithm name.
                additionalProperties:
                  type: object
                  additionalProperties:
                    type: string
                    description: algorithm
                    example: "signed_curve25519"
                example: {
                  "@alice:example.com": { "JLAFKJWSCS": "signed_curve25519" }
                }
            required:
              - one_time_keys
      responses:
        200:
          description:
            The claimed keys.
          schema:
            type: object
            properties:
              failures:
                type: object
                description: |-
                  If any remote homeservers could not be reached, they are
                  recorded here. The names of the properties are the names of
                  the unreachable servers.

                  If the homeserver could be reached, but the user or device
                  was unknown, no failure is recorded. Instead, the corresponding
                  user or device is missing from the ``one_time_keys`` result.
                additionalProperties:
                  type: object
                example: {}
              one_time_keys:
                type: object
                description: |-
                  One-time keys for the queried devices. A map from user ID, to a
                  map from devices to a map from ``<algorithm>:<key_id>`` to the key object.

                  See the `key algorithms <#key-algorithms>`_ section for information
                  on the Key Object format.
                additionalProperties:
                  type: object
                  additionalProperties:
                    type:
                      - string
                      - object
                      # XXX: We can't define an actual object here, so we have to hope
                      # that people will look at the swagger source or can figure it out
                      # from the other endpoints/example.
                      # - type: object
                      #   title: KeyObject
                      #   properties:
                      #     key:
                      #       type: string
                      #       description: The key, encoded using unpadded base64.
                      #     signatures:
                      #       type: object
                      #       description: |-
                      #         Signature for the device. Mapped from user ID to signature object.
                      #       additionalProperties:
                      #         type: string
                      #   required: ['key', 'signatures']
                example: {
                  "@alice:example.com": {
                    "JLAFKJWSCS": {
                      "signed_curve25519:AAAAHg": {
                        "key": "zKbLg+NrIjpnagy+pIY6uPL4ZwEG2v+8F9lmgsnlZzs",
                        "signatures": {
                          "@alice:example.com": {
                            "ed25519:JLAFKJWSCS": "FLWxXqGbwrb8SM3Y795eB6OA8bwBcoMZFXBqnTn58AYWZSqiD45tlBVcDa2L7RwdKXebW/VzDlnfVJ+9jok1Bw"
                          }
                        }
                      }
                    }
                  }
                }
            required: ['one_time_keys']
      tags:
        - End-to-end encryption
  "/keys/changes":
    get:
      summary: Query users with recent device key updates.
      description: |-
        Gets a list of users who have updated their device identity keys since a
        previous sync token.

        The server should include in the results any users who:

        * currently share a room with the calling user (ie, both users have
          membership state ``join``); *and*
        * added new device identity keys or removed an existing device with
          identity keys, between ``from`` and ``to``.
      operationId: getKeysChanges
      security:
        - accessToken: []
      parameters:
        - in: query
          name: from
          type: string
          description: |-
             The desired start point of the list. Should be the ``next_batch`` field
             from a response to an earlier call to |/sync|. Users who have not
             uploaded new device identity keys since this point, nor deleted
             existing devices with identity keys since then, will be excluded
             from the results.
          required: true
          x-example: "s72594_4483_1934"
        - in: query
          name: to
          type: string
          description: |-
             The desired end point of the list. Should be the ``next_batch``
             field from a recent call to |/sync| - typically the most recent
             such call. This may be used by the server as a hint to check its
             caches are up to date.
          required: true
          x-example: "s75689_5632_2435"
      responses:
        200:
          description:
            The list of users who updated their devices.
          schema:
            type: object
            properties:
              changed:
                type: array
                items:
                  type: string
                description: |-
                  The Matrix User IDs of all users who updated their device
                  identity keys.
                example: ["@alice:example.com", "@bob:example.org"]
              left:
                type: array
                items:
                  type: string
                description: |-
                  The Matrix User IDs of all users who may have left all
                  the end-to-end encrypted rooms they previously shared
                  with the user.
                example: ["@clara:example.com", "@doug:example.org"]
      tags:
        - End-to-end encryption