Merge branch 'master' of github.com:matrix-org/matrix-doc into erikj/public_rooms
This commit is contained in:
commit
a69d6c63c6
34 changed files with 857 additions and 186 deletions
|
@ -170,7 +170,12 @@ paths:
|
||||||
``public_chat``: =>
|
``public_chat``: =>
|
||||||
``join_rules`` is set to ``public``.
|
``join_rules`` is set to ``public``.
|
||||||
``history_visibility`` is set to ``shared``.
|
``history_visibility`` is set to ``shared``.
|
||||||
|
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.
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: Information about the newly created room.
|
description: Information about the newly created room.
|
||||||
|
|
|
@ -28,4 +28,8 @@ properties:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
contains_url:
|
||||||
|
type: boolean
|
||||||
|
description: If ``true``, includes only events with a url key in their content. If
|
||||||
|
``false``, excludes those events.
|
||||||
type: object
|
type: object
|
||||||
|
|
|
@ -13,6 +13,6 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
accessToken:
|
accessToken:
|
||||||
type: apiKey
|
type: apiKey
|
||||||
description: The access_token returned by a call to ``/login`` or ``/tokenrefresh``
|
description: The access_token returned by a call to ``/login`` or ``/register``
|
||||||
name: access_token
|
name: access_token
|
||||||
in: query
|
in: query
|
||||||
|
|
|
@ -90,15 +90,6 @@ paths:
|
||||||
description: |-
|
description: |-
|
||||||
An access token for the account.
|
An access token for the account.
|
||||||
This access token can then be used to authorize other requests.
|
This access token can then be used to authorize other requests.
|
||||||
The access token may expire at some point, and if so, it SHOULD come with a ``refresh_token``.
|
|
||||||
There is no specific error message to indicate that a request has failed because
|
|
||||||
an access token has expired; instead, if a client has reason to believe its
|
|
||||||
access token is valid, and it receives an auth error, they should attempt to
|
|
||||||
refresh for a new token on failure, and retry the request with the new token.
|
|
||||||
refresh_token:
|
|
||||||
type: string
|
|
||||||
description: |-
|
|
||||||
Optional. A ``refresh_token`` may be exchanged for a new ``access_token`` using the |/tokenrefresh|_ API endpoint.
|
|
||||||
home_server:
|
home_server:
|
||||||
type: string
|
type: string
|
||||||
description: The hostname of the homeserver on which the account has been registered.
|
description: The hostname of the homeserver on which the account has been registered.
|
||||||
|
@ -123,67 +114,3 @@ paths:
|
||||||
"$ref": "definitions/error.yaml"
|
"$ref": "definitions/error.yaml"
|
||||||
tags:
|
tags:
|
||||||
- Session management
|
- Session management
|
||||||
"/tokenrefresh":
|
|
||||||
post:
|
|
||||||
summary: Exchanges a refresh token for an access token.
|
|
||||||
description: |-
|
|
||||||
Exchanges a refresh token for a new access token.
|
|
||||||
This is intended to be used if the access token has expired.
|
|
||||||
|
|
||||||
The server MUST invalidate the supplied ``refresh_token`` if the
|
|
||||||
request is successful. It MUST also invalidate the ``access_token``
|
|
||||||
which was issued at the same time as the ``refresh_token``, if it
|
|
||||||
has not already expired.
|
|
||||||
security:
|
|
||||||
- accessToken: []
|
|
||||||
parameters:
|
|
||||||
- in: body
|
|
||||||
name: body
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
example: |-
|
|
||||||
{
|
|
||||||
"refresh_token": "a1b2c3"
|
|
||||||
}
|
|
||||||
properties:
|
|
||||||
refresh_token:
|
|
||||||
type: string
|
|
||||||
description: The refresh token which was issued by the server.
|
|
||||||
required: ["refresh_token"]
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: |-
|
|
||||||
The refresh token was accepted, and a new access token has been issued.
|
|
||||||
The passed refresh token is no longer valid and cannot be used.
|
|
||||||
A new refresh token will have been returned unless some policy does
|
|
||||||
not allow the user to continue to renew their session.
|
|
||||||
examples:
|
|
||||||
application/json: |-
|
|
||||||
{
|
|
||||||
"access_token": "bearwithme123",
|
|
||||||
"refresh_token": "exchangewithme987"
|
|
||||||
}
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
access_token:
|
|
||||||
type: string
|
|
||||||
description: |-
|
|
||||||
An access token for the account.
|
|
||||||
This access token can then be used to authorize other requests.
|
|
||||||
The access token may expire at some point, and if so, it SHOULD come with a ``refresh_token``.
|
|
||||||
refresh_token:
|
|
||||||
type: string
|
|
||||||
description: Optional. A new ``refresh_token`` which may be exchanged for another new ``access_token``.
|
|
||||||
403:
|
|
||||||
description: |-
|
|
||||||
The exchange attempt failed. For example, the refresh token may have already been used.
|
|
||||||
examples:
|
|
||||||
application/json: |-
|
|
||||||
{"errcode": "M_FORBIDDEN"}
|
|
||||||
429:
|
|
||||||
description: This request was rate-limited.
|
|
||||||
schema:
|
|
||||||
"$ref": "definitions/error.yaml"
|
|
||||||
tags:
|
|
||||||
- Session management
|
|
||||||
|
|
|
@ -75,6 +75,13 @@ paths:
|
||||||
description: |-
|
description: |-
|
||||||
The maximum number of events to return. Default: 10.
|
The maximum number of events to return. Default: 10.
|
||||||
x-example: "3"
|
x-example: "3"
|
||||||
|
- in: query
|
||||||
|
type: string
|
||||||
|
name: filter
|
||||||
|
description: |-
|
||||||
|
A JSON RoomEventFilter to filter returned events with.
|
||||||
|
x-example: |-
|
||||||
|
{"contains_url":true}
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: A list of messages with a new token to request more.
|
description: A list of messages with a new token to request more.
|
||||||
|
|
142
api/client-server/notifications.yaml
Normal file
142
api/client-server/notifications.yaml
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
# Copyright 2016 OpenMarket Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
swagger: '2.0'
|
||||||
|
info:
|
||||||
|
title: "Matrix Client-Server Notifications API"
|
||||||
|
version: "1.0.0"
|
||||||
|
host: localhost:8008
|
||||||
|
schemes:
|
||||||
|
- https
|
||||||
|
- http
|
||||||
|
basePath: /_matrix/client/%CLIENT_MAJOR_VERSION%
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
securityDefinitions:
|
||||||
|
$ref: definitions/security.yaml
|
||||||
|
paths:
|
||||||
|
"/notifications":
|
||||||
|
get:
|
||||||
|
summary: Gets a list of events that the user has been notified about
|
||||||
|
description: |-
|
||||||
|
This API is used to paginate through the list of events that the
|
||||||
|
user has been, or would have been notified about.
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
type: string
|
||||||
|
name: from
|
||||||
|
description: Pagination token given to retrieve the next set of events.
|
||||||
|
required: false
|
||||||
|
x-example: "xxxxx"
|
||||||
|
- in: query
|
||||||
|
type: number
|
||||||
|
name: limit
|
||||||
|
description: Limit on the number of events to return in this request.
|
||||||
|
required: false
|
||||||
|
x-example: "20"
|
||||||
|
- in: query
|
||||||
|
name: only
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
Allows basic filtering of events returned. Supply ``highlight``
|
||||||
|
to return only events where the notification had the highlight
|
||||||
|
tweak set.
|
||||||
|
required: false
|
||||||
|
x-example: "highlight"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: A batch of events is being returned
|
||||||
|
examples:
|
||||||
|
application/json: |-
|
||||||
|
{
|
||||||
|
"next_token": "abcdef",
|
||||||
|
"notifications": [
|
||||||
|
{
|
||||||
|
"actions": [
|
||||||
|
"notify"
|
||||||
|
],
|
||||||
|
"profile_tag": "hcbvkzxhcvb",
|
||||||
|
"read": true,
|
||||||
|
"room_id": "!abcdefg:example.com",
|
||||||
|
"ts": 1475508881945,
|
||||||
|
"event": {
|
||||||
|
"sender": "@alice:example.com",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"age": 124524,
|
||||||
|
"txn_id": "1234",
|
||||||
|
"content": {
|
||||||
|
"body": "I am a fish",
|
||||||
|
"msgtype": "m.text"
|
||||||
|
},
|
||||||
|
"origin_server_ts": 1417731086797,
|
||||||
|
"event_id": "$74686972643033:example.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required: ["notifications"]
|
||||||
|
properties:
|
||||||
|
next_token:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
The token to supply in the ``from`` param of the next
|
||||||
|
``/notifications`` request in order to request more
|
||||||
|
events. If this is absent, there are no more results.
|
||||||
|
notifications:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
required: ["actions", "event", "read", "room_id", "ts"]
|
||||||
|
title: Notification
|
||||||
|
properties:
|
||||||
|
actions:
|
||||||
|
type: array
|
||||||
|
description: |-
|
||||||
|
The action(s) to perform when the conditions for this rule are met.
|
||||||
|
See `Push Rules: API`_.
|
||||||
|
items:
|
||||||
|
type:
|
||||||
|
- object
|
||||||
|
- string
|
||||||
|
event:
|
||||||
|
type: object
|
||||||
|
title: Event
|
||||||
|
description: The Event object for the event that triggered the notification.
|
||||||
|
allOf:
|
||||||
|
- "$ref": "definitions/event.yaml"
|
||||||
|
profile_tag:
|
||||||
|
type: string
|
||||||
|
description: The profile tag of the rule that matched this event.
|
||||||
|
read:
|
||||||
|
type: boolean
|
||||||
|
description: |-
|
||||||
|
Indicates whether the user has sent a read receipt indicating
|
||||||
|
that they have read this message.
|
||||||
|
room_id:
|
||||||
|
type: string
|
||||||
|
description: The ID of the room in which the event was posted.
|
||||||
|
ts:
|
||||||
|
type: integer
|
||||||
|
description: |-
|
||||||
|
The unix timestamp at which the event notification was sent,
|
||||||
|
in milliseconds.
|
||||||
|
description: The list of events that triggered notifications.
|
||||||
|
tags:
|
||||||
|
- Push notifications
|
|
@ -39,6 +39,9 @@ paths:
|
||||||
|
|
||||||
- `guest` accounts. These accounts may have limited permissions and may not be supported by all servers.
|
- `guest` accounts. These accounts may have limited permissions and may not be supported by all servers.
|
||||||
|
|
||||||
|
If registration is successful, this endpoint will issue an access token
|
||||||
|
the client can use to authorize itself in subsequent requests.
|
||||||
|
|
||||||
parameters:
|
parameters:
|
||||||
- in: query
|
- in: query
|
||||||
name: kind
|
name: kind
|
||||||
|
@ -90,8 +93,7 @@ paths:
|
||||||
{
|
{
|
||||||
"user_id": "@cheeky_monkey:matrix.org",
|
"user_id": "@cheeky_monkey:matrix.org",
|
||||||
"access_token": "abc123",
|
"access_token": "abc123",
|
||||||
"home_server": "matrix.org",
|
"home_server": "matrix.org"
|
||||||
"refresh_token": "def456"
|
|
||||||
}
|
}
|
||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
|
@ -104,16 +106,6 @@ paths:
|
||||||
description: |-
|
description: |-
|
||||||
An access token for the account.
|
An access token for the account.
|
||||||
This access token can then be used to authorize other requests.
|
This access token can then be used to authorize other requests.
|
||||||
The access token may expire at some point, and if so, it SHOULD come with a ``refresh_token``.
|
|
||||||
There is no specific error message to indicate that a request has failed because
|
|
||||||
an access token has expired; instead, if a client has reason to believe its
|
|
||||||
access token is valid, and it receives an auth error, they should attempt to
|
|
||||||
refresh for a new token on failure, and retry the request with the new token.
|
|
||||||
refresh_token:
|
|
||||||
type: string
|
|
||||||
# TODO: Work out how to linkify /tokenrefresh
|
|
||||||
description: |-
|
|
||||||
(optional) A ``refresh_token`` may be exchanged for a new ``access_token`` using the /tokenrefresh API endpoint.
|
|
||||||
home_server:
|
home_server:
|
||||||
type: string
|
type: string
|
||||||
description: The hostname of the homeserver on which the account has been registered.
|
description: The hostname of the homeserver on which the account has been registered.
|
||||||
|
|
|
@ -246,7 +246,7 @@ paths:
|
||||||
200:
|
200:
|
||||||
description: |-
|
description: |-
|
||||||
A list of members of the room. If you are joined to the room then
|
A list of members of the room. If you are joined to the room then
|
||||||
this will be the current members of the room. If you have left te
|
this will be the current members of the room. If you have left the
|
||||||
room then this will be the members of the room when you left.
|
room then this will be the members of the room when you left.
|
||||||
examples:
|
examples:
|
||||||
application/json: |-
|
application/json: |-
|
||||||
|
|
|
@ -236,6 +236,12 @@ paths:
|
||||||
The global private data created by this user.
|
The global private data created by this user.
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: "definitions/event_batch.yaml"
|
- $ref: "definitions/event_batch.yaml"
|
||||||
|
to_device:
|
||||||
|
title: ToDevice
|
||||||
|
type: object
|
||||||
|
description: |-
|
||||||
|
Information on the send-to-device messages for the client
|
||||||
|
device, as defined in |send_to_device_sync|_.
|
||||||
examples:
|
examples:
|
||||||
application/json: |-
|
application/json: |-
|
||||||
{
|
{
|
||||||
|
|
89
api/client-server/to_device.yaml
Normal file
89
api/client-server/to_device.yaml
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
# Copyright 2016 OpenMarket Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
swagger: '2.0'
|
||||||
|
info:
|
||||||
|
title: "Matrix Client-Server Send-to-device API"
|
||||||
|
version: "1.0.0"
|
||||||
|
host: localhost:8008
|
||||||
|
schemes:
|
||||||
|
- https
|
||||||
|
- http
|
||||||
|
basePath: /_matrix/client/%CLIENT_MAJOR_VERSION%
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
securityDefinitions:
|
||||||
|
$ref: definitions/security.yaml
|
||||||
|
paths:
|
||||||
|
"/sendToDevice/{eventType}/{txnId}":
|
||||||
|
put:
|
||||||
|
summary: Send an event to a given set of devices.
|
||||||
|
description: |-
|
||||||
|
This endpoint is used to send send-to-device events to a set of
|
||||||
|
client devices.
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
type: string
|
||||||
|
name: eventType
|
||||||
|
description: The type of event to send.
|
||||||
|
required: true
|
||||||
|
x-example: "m.new_device"
|
||||||
|
- in: path
|
||||||
|
name: txnId
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
The transaction ID for this event. Clients should generate an
|
||||||
|
ID unique across requests with the same access token; it will be
|
||||||
|
used by the server to ensure idempotency of requests.
|
||||||
|
required: true
|
||||||
|
x-example: "35"
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
title: body
|
||||||
|
properties:
|
||||||
|
messages:
|
||||||
|
type: object
|
||||||
|
description: |-
|
||||||
|
The messages to send. A map from user ID, to a map from
|
||||||
|
device ID to message body. The device ID may also be `*`,
|
||||||
|
meaning all known devices for the user.
|
||||||
|
additionalProperties:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: object
|
||||||
|
title: EventContent
|
||||||
|
description: Message content
|
||||||
|
example: {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"TLLBEANAAG": {
|
||||||
|
"example_content_key": "value"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description:
|
||||||
|
The message was successfully sent.
|
||||||
|
examples:
|
||||||
|
application/json: |-
|
||||||
|
{}
|
||||||
|
tags:
|
||||||
|
- Send-to-Device messaging
|
|
@ -19,7 +19,7 @@ host: localhost:8090
|
||||||
schemes:
|
schemes:
|
||||||
- https
|
- https
|
||||||
- http
|
- http
|
||||||
basePath: /_matrix/identity/v1/api
|
basePath: /_matrix/identity/api/v1
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
paths:
|
paths:
|
||||||
|
|
|
@ -19,7 +19,7 @@ host: localhost:8090
|
||||||
schemes:
|
schemes:
|
||||||
- https
|
- https
|
||||||
- http
|
- http
|
||||||
basePath: /_matrix/identity/v1/api
|
basePath: /_matrix/identity/api/v1
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
paths:
|
paths:
|
||||||
|
|
|
@ -8,21 +8,11 @@
|
||||||
which support push rules, but any other clients implementing
|
which support push rules, but any other clients implementing
|
||||||
the push rules API should be aware of this change. This
|
the push rules API should be aware of this change. This
|
||||||
makes it simple to mute rooms correctly in the API.
|
makes it simple to mute rooms correctly in the API.
|
||||||
|
(`#373 <https://github.com/matrix-org/matrix-doc/pull/373>`_).
|
||||||
- Spec clarifications:
|
- Remove ``/tokenrefresh`` from the API.
|
||||||
|
(`#395 <https://github.com/matrix-org/matrix-doc/pull/395>`_).
|
||||||
- Spell out the way that state is handled by ``POST /createRoom``
|
- Remove requirement that tokens used in token-based login be macaroons.
|
||||||
(`#362 <https://github.com/matrix-org/matrix-doc/pull/362>`_).
|
(`#395 <https://github.com/matrix-org/matrix-doc/pull/395>`_).
|
||||||
- Emphasise that ``POST /tokenrefresh`` should expire the access token
|
|
||||||
(`#363 <https://github.com/matrix-org/matrix-doc/pull/363>`_).
|
|
||||||
- Clarify the fields which are applicable to different types of push rule
|
|
||||||
(`#365 <https://github.com/matrix-org/matrix-doc/pull/365>`_).
|
|
||||||
- A number of clarifications to authentication
|
|
||||||
(`#371 <https://github.com/matrix-org/matrix-doc/pull/371>`_).
|
|
||||||
- Correct references to ``user_id`` which should have been ``sender``
|
|
||||||
(`#376 <https://github.com/matrix-org/matrix-doc/pull/376>`_).
|
|
||||||
- Correct inconsistent specification of ``redacted_because`` fields and their
|
|
||||||
values (`#378 <https://github.com/matrix-org/matrix-doc/pull/378>`_).
|
|
||||||
|
|
||||||
- Changes to the API which will be backwards-compatible for clients:
|
- Changes to the API which will be backwards-compatible for clients:
|
||||||
|
|
||||||
|
@ -35,11 +25,38 @@
|
||||||
- Add top-level ``account_data`` key to the responses to ``GET /sync`` and
|
- Add top-level ``account_data`` key to the responses to ``GET /sync`` and
|
||||||
``GET /initialSync``
|
``GET /initialSync``
|
||||||
(`#380 <https://github.com/matrix-org/matrix-doc/pull/380>`_).
|
(`#380 <https://github.com/matrix-org/matrix-doc/pull/380>`_).
|
||||||
|
- Add ``is_direct`` flag to |/createRoom|_ and invite member event.
|
||||||
|
Add 'Direct Messaging' module.
|
||||||
|
(`#389 <https://github.com/matrix-org/matrix-doc/pull/389>`_).
|
||||||
|
- Add ``contains_url`` option to ``RoomEventFilter``.
|
||||||
|
(`#390 <https://github.com/matrix-org/matrix-doc/pull/390>`_).
|
||||||
|
- Add ``filter`` optional query param to ``/messages``
|
||||||
|
(`#390 <https://github.com/matrix-org/matrix-doc/pull/390>`_).
|
||||||
|
- Add "Send-to-Device messaging" module
|
||||||
|
(`#386 <https://github.com/matrix-org/matrix-doc/pull/386>`_).
|
||||||
|
- Require that User-Interactive auth fallback pages call
|
||||||
|
``window.postMessage`` to notify apps of completion
|
||||||
|
(`#398 <https://github.com/matrix-org/matrix-doc/pull/398>`_).
|
||||||
- Add pagination and filter support to ``/publicRooms``. Change response to
|
- Add pagination and filter support to ``/publicRooms``. Change response to
|
||||||
omit fields rather than return ``null``. Add estimate of total number of
|
omit fields rather than return ``null``. Add estimate of total number of
|
||||||
rooms in list.
|
rooms in list.
|
||||||
(`#388 <https://github.com/matrix-org/matrix-doc/pull/388>`_).
|
(`#388 <https://github.com/matrix-org/matrix-doc/pull/388>`_).
|
||||||
|
|
||||||
|
- Spec clarifications:
|
||||||
|
|
||||||
|
- Spell out the way that state is handled by ``POST /createRoom``
|
||||||
|
(`#362 <https://github.com/matrix-org/matrix-doc/pull/362>`_).
|
||||||
|
- Clarify the fields which are applicable to different types of push rule
|
||||||
|
(`#365 <https://github.com/matrix-org/matrix-doc/pull/365>`_).
|
||||||
|
- A number of clarifications to authentication
|
||||||
|
(`#371 <https://github.com/matrix-org/matrix-doc/pull/371>`_).
|
||||||
|
- Correct references to ``user_id`` which should have been ``sender``
|
||||||
|
(`#376 <https://github.com/matrix-org/matrix-doc/pull/376>`_).
|
||||||
|
- Correct inconsistent specification of ``redacted_because`` fields and their
|
||||||
|
values (`#378 <https://github.com/matrix-org/matrix-doc/pull/378>`_).
|
||||||
|
- Mark required fields in response objects as such
|
||||||
|
(`#394 <https://github.com/matrix-org/matrix-doc/pull/394>`_).
|
||||||
|
|
||||||
r0.2.0
|
r0.2.0
|
||||||
======
|
======
|
||||||
|
|
||||||
|
|
9
event-schemas/examples/m.direct
Normal file
9
event-schemas/examples/m.direct
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"type": "m.direct",
|
||||||
|
"content": {
|
||||||
|
"@bob:example.com": [
|
||||||
|
"!abcdefgh:example.com",
|
||||||
|
"!hgfedcba:example.com"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
21
event-schemas/schema/m.direct
Normal file
21
event-schemas/schema/m.direct
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
allOf:
|
||||||
|
- $ref: core-event-schema/event.yaml
|
||||||
|
description: |-
|
||||||
|
A map of which rooms are considered 'direct' rooms for specific users
|
||||||
|
is kept in ``account_data`` in an event of type ``m.direct``. The
|
||||||
|
content of this event is an object where the keys are the user IDs
|
||||||
|
and values are lists of room ID strings of the 'direct' rooms for
|
||||||
|
that user ID.
|
||||||
|
properties:
|
||||||
|
content:
|
||||||
|
additionalProperties:
|
||||||
|
type: array
|
||||||
|
title: User ID
|
||||||
|
type: object
|
||||||
|
type:
|
||||||
|
enum:
|
||||||
|
- m.direct
|
||||||
|
type: string
|
||||||
|
title: Direct Chat Mapping
|
||||||
|
type: object
|
|
@ -39,6 +39,9 @@ properties:
|
||||||
- leave
|
- leave
|
||||||
- ban
|
- ban
|
||||||
type: string
|
type: string
|
||||||
|
is_direct:
|
||||||
|
description: Flag indicating if the room containing this event was created with the intention of being a direct chat. See `Direct Messaging`_.
|
||||||
|
type: boolean
|
||||||
third_party_invite:
|
third_party_invite:
|
||||||
properties:
|
properties:
|
||||||
display_name:
|
display_name:
|
||||||
|
|
|
@ -27,6 +27,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/golang-lru"
|
"github.com/hashicorp/golang-lru"
|
||||||
|
@ -83,19 +84,15 @@ func accessTokenQuerystring() string {
|
||||||
return fmt.Sprintf("?access_token=%s", *accessToken)
|
return fmt.Sprintf("?access_token=%s", *accessToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
func gitClone(url string, shared bool) (string, error) {
|
func gitClone(url string, directory string, shared bool) error {
|
||||||
directory := path.Join("/tmp/matrix-doc", strconv.FormatInt(rand.Int63(), 10))
|
|
||||||
if err := os.MkdirAll(directory, permissionsOwnerFull); err != nil {
|
|
||||||
return "", fmt.Errorf("error making directory %s: %v", directory, err)
|
|
||||||
}
|
|
||||||
args := []string{"clone", url, directory}
|
args := []string{"clone", url, directory}
|
||||||
if shared {
|
if shared {
|
||||||
args = append(args, "--shared")
|
args = append(args, "--shared")
|
||||||
}
|
}
|
||||||
if err := runGitCommand(directory, args); err != nil {
|
if err := runGitCommand(directory, args); err != nil {
|
||||||
return "", err
|
return err
|
||||||
}
|
}
|
||||||
return directory, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func gitCheckout(path, sha string) error {
|
func gitCheckout(path, sha string) error {
|
||||||
|
@ -159,6 +156,16 @@ func generate(dir string) error {
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
return fmt.Errorf("error generating spec: %v\nOutput from gendoc:\n%v", err, b.String())
|
return fmt.Errorf("error generating spec: %v\nOutput from gendoc:\n%v", err, b.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cheekily dump the swagger docs into the gen directory so they can be
|
||||||
|
// served by serveSpec
|
||||||
|
cmd = exec.Command("python", "dump-swagger.py", "gen/api-docs.json")
|
||||||
|
cmd.Dir = path.Join(dir, "scripts")
|
||||||
|
cmd.Stderr = &b
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return fmt.Errorf("error generating api docs: %v\nOutput from dump-swagger:\n%v", err, b.String())
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,8 +202,14 @@ func (s *server) generateAt(sha string) (dst string, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dst, err = makeTempDir()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Printf("Generating %s in %s\n", sha, dst)
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
dst, err = gitClone(s.matrixDocCloneURL, true)
|
err = gitClone(s.matrixDocCloneURL, dst, true)
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -219,7 +232,7 @@ func (s *server) getSHAOf(ref string) (string, error) {
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("error generating spec: %v\nOutput from gendoc:\n%v", err, b.String())
|
return "", fmt.Errorf("error generating spec: %v\nOutput from git:\n%v", err, b.String())
|
||||||
}
|
}
|
||||||
return strings.TrimSpace(b.String()), nil
|
return strings.TrimSpace(b.String()), nil
|
||||||
}
|
}
|
||||||
|
@ -396,6 +409,11 @@ func (s *server) serveSpec(w http.ResponseWriter, req *http.Request) {
|
||||||
cache.Add(sha, pathToContent)
|
cache.Add(sha, pathToContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if requestedPath == "api-docs.json" {
|
||||||
|
// allow other swagger UIs access to our swagger
|
||||||
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
}
|
||||||
|
|
||||||
if b, ok := pathToContent[requestedPath]; ok {
|
if b, ok := pathToContent[requestedPath]; ok {
|
||||||
w.Write(b)
|
w.Write(b)
|
||||||
return
|
return
|
||||||
|
@ -588,12 +606,6 @@ func (srv *server) makeIndex(w http.ResponseWriter, req *http.Request) {
|
||||||
writeError(w, 500, err)
|
writeError(w, 500, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s := "<body><ul>"
|
|
||||||
for _, pull := range pulls {
|
|
||||||
s += fmt.Sprintf(`<li>%d: <a href="%s">%s</a>: <a href="%s">%s</a>: <a href="spec/%d/">spec</a> <a href="diff/html/%d/">spec diff</a> <a href="diff/rst/%d/">rst diff</a></li>`,
|
|
||||||
pull.Number, pull.User.HTMLURL, pull.User.Login, pull.HTMLURL, pull.Title, pull.Number, pull.Number, pull.Number)
|
|
||||||
}
|
|
||||||
s += "</ul>"
|
|
||||||
|
|
||||||
branches, err := srv.getBranches()
|
branches, err := srv.getBranches()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -601,7 +613,48 @@ func (srv *server) makeIndex(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s += `<div>View the spec at:<ul>`
|
// write our stuff into a buffer so that we can change our minds
|
||||||
|
// and write a 500 if it all goes wrong.
|
||||||
|
var b bytes.Buffer
|
||||||
|
b.Write([]byte(`
|
||||||
|
<head>
|
||||||
|
<script>
|
||||||
|
function redirectToApiDocs(relativePath) {
|
||||||
|
var url = new URL(window.location);
|
||||||
|
url.pathname += relativePath;
|
||||||
|
var newLoc = "http://matrix.org/docs/api/client-server/?url=" + encodeURIComponent(url);
|
||||||
|
window.location = newLoc;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body><ul>
|
||||||
|
`))
|
||||||
|
|
||||||
|
tmpl, err := template.New("pr entry").Parse(`
|
||||||
|
<li>{{.Number}}:
|
||||||
|
<a href="{{.User.HTMLURL}}">{{.User.Login}}</a>:
|
||||||
|
<a href="{{.HTMLURL}}">{{.Title}}</a>:
|
||||||
|
<a href="spec/{{.Number}}/">spec</a>
|
||||||
|
<a href="#" onclick="redirectToApiDocs('spec/{{.Number}}/api-docs.json')">api docs</a>
|
||||||
|
<a href="diff/html/{{.Number}}/">spec diff</a>
|
||||||
|
<a href="diff/rst/{{.Number}}/">rst diff</a>
|
||||||
|
</li>
|
||||||
|
`)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pull := range pulls {
|
||||||
|
err = tmpl.Execute(&b, pull)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, 500, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.Write([]byte(`
|
||||||
|
</ul>
|
||||||
|
<div>View the spec at:<ul>
|
||||||
|
`))
|
||||||
branchNames := []string{}
|
branchNames := []string{}
|
||||||
for _, branch := range branches {
|
for _, branch := range branches {
|
||||||
if strings.HasPrefix(branch, "drafts/") {
|
if strings.HasPrefix(branch, "drafts/") {
|
||||||
|
@ -611,15 +664,14 @@ func (srv *server) makeIndex(w http.ResponseWriter, req *http.Request) {
|
||||||
branchNames = append(branchNames, "HEAD")
|
branchNames = append(branchNames, "HEAD")
|
||||||
for _, branch := range branchNames {
|
for _, branch := range branchNames {
|
||||||
href := "spec/" + url.QueryEscape(branch) + "/"
|
href := "spec/" + url.QueryEscape(branch) + "/"
|
||||||
s += fmt.Sprintf(`<li><a href="%s">%s</a></li>`, href, branch)
|
fmt.Fprintf(&b, `<li><a href="%s">%s</a></li>`, href, branch)
|
||||||
if *includesDir != "" {
|
if *includesDir != "" {
|
||||||
s += fmt.Sprintf(`<li><a href="%s?matrixdotorgstyle=1">%s, styled like matrix.org</a></li>`,
|
fmt.Fprintf(&b, `<li><a href="%s?matrixdotorgstyle=1">%s, styled like matrix.org</a></li>`,
|
||||||
href, branch)
|
href, branch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s += "</ul></div></body>"
|
b.Write([]byte("</ul></div></body>"))
|
||||||
|
b.WriteTo(w)
|
||||||
io.WriteString(w, s)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ignoreExitCodeOne(err error) error {
|
func ignoreExitCodeOne(err error) error {
|
||||||
|
@ -655,10 +707,14 @@ func main() {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
rand.Seed(time.Now().Unix())
|
rand.Seed(time.Now().Unix())
|
||||||
masterCloneDir, err := gitClone(matrixDocCloneURL, false)
|
masterCloneDir, err := makeTempDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
log.Printf("Creating master clone dir %s\n", masterCloneDir)
|
||||||
|
if err = gitClone(matrixDocCloneURL, masterCloneDir, false); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
s := server{matrixDocCloneURL: masterCloneDir}
|
s := server{matrixDocCloneURL: masterCloneDir}
|
||||||
http.HandleFunc("/spec/", forceHTML(s.serveSpec))
|
http.HandleFunc("/spec/", forceHTML(s.serveSpec))
|
||||||
http.HandleFunc("/diff/rst/", s.serveRSTDiff)
|
http.HandleFunc("/diff/rst/", s.serveRSTDiff)
|
||||||
|
@ -691,3 +747,11 @@ func initCache() error {
|
||||||
styledSpecCache = c2
|
styledSpecCache = c2
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeTempDir() (string, error) {
|
||||||
|
directory := path.Join("/tmp/matrix-doc", strconv.FormatInt(rand.Int63(), 10))
|
||||||
|
if err := os.MkdirAll(directory, permissionsOwnerFull); err != nil {
|
||||||
|
return "", fmt.Errorf("error making directory %s: %v", directory, err)
|
||||||
|
}
|
||||||
|
return directory, nil
|
||||||
|
}
|
||||||
|
|
|
@ -158,14 +158,23 @@ recommended.
|
||||||
|
|
||||||
Client Authentication
|
Client Authentication
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
Most API endpoints require the user to identify themselves by presenting
|
Most API endpoints require the user to identify themselves by presenting
|
||||||
previously obtained credentials in the form of an ``access_token`` query
|
previously obtained credentials in the form of an ``access_token`` query
|
||||||
parameter.
|
parameter. An access token is typically obtained via the `Login`_ or
|
||||||
|
`Registration`_ processes.
|
||||||
|
|
||||||
When credentials are required but missing or invalid, the HTTP call will
|
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
|
return with a status of 401 and the error code, ``M_MISSING_TOKEN`` or
|
||||||
``M_UNKNOWN_TOKEN`` respectively.
|
``M_UNKNOWN_TOKEN`` respectively.
|
||||||
|
|
||||||
|
.. NOTE::
|
||||||
|
|
||||||
|
This specification does not mandate a particular format for the access
|
||||||
|
token. Clients should treat it as an opaque byte sequence. Servers are free
|
||||||
|
to choose an appropriate format. Server implementors may like to investigate
|
||||||
|
`macaroons <macaroon_>`_.
|
||||||
|
|
||||||
User-Interactive Authentication API
|
User-Interactive Authentication API
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -249,7 +258,7 @@ complete auth type ``example.type.foo``, it might submit something like this:
|
||||||
|
|
||||||
POST /_matrix/client/r0/endpoint HTTP/1.1
|
POST /_matrix/client/r0/endpoint HTTP/1.1
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"a_request_parameter": "something",
|
"a_request_parameter": "something",
|
||||||
"another_request_parameter": "something else",
|
"another_request_parameter": "something else",
|
||||||
|
@ -289,8 +298,42 @@ successfully:
|
||||||
"session": "xxxxxx"
|
"session": "xxxxxx"
|
||||||
}
|
}
|
||||||
|
|
||||||
If the homeserver decides the attempt was unsuccessful, it returns an error
|
Individual stages may require more than one request to complete, in which case
|
||||||
message in the standard format:
|
the response will be as if the request was unauthenticated with the addition of
|
||||||
|
any other keys as defined by the auth type.
|
||||||
|
|
||||||
|
If the homeserver decides that an attempt on a stage was unsuccessful, but the
|
||||||
|
client may make a second attempt, it returns the same HTTP status 401 response
|
||||||
|
as above, with the addition of the standard ``errcode`` and ``error`` fields
|
||||||
|
describing the error. For example:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
HTTP/1.1 401 Unauthorized
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"errcode": "M_FORBIDDEN",
|
||||||
|
"error": "Invalid password",
|
||||||
|
"completed": [ "example.type.foo" ],
|
||||||
|
"flows": [
|
||||||
|
{
|
||||||
|
"stages": [ "example.type.foo", "example.type.bar" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"stages": [ "example.type.foo", "example.type.baz" ]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": {
|
||||||
|
"example.type.baz": {
|
||||||
|
"example_key": "foobar"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"session": "xxxxxx"
|
||||||
|
}
|
||||||
|
|
||||||
|
If the request fails for a reason other than authentication, the server returns an error
|
||||||
|
message in the standard format. For example:
|
||||||
|
|
||||||
.. code::
|
.. code::
|
||||||
|
|
||||||
|
@ -302,10 +345,6 @@ message in the standard format:
|
||||||
"error": "Something was wrong"
|
"error": "Something was wrong"
|
||||||
}
|
}
|
||||||
|
|
||||||
Individual stages may require more than one request to complete, in which case
|
|
||||||
the response will be as if the request was unauthenticated with the addition of
|
|
||||||
any other keys as defined by the auth type.
|
|
||||||
|
|
||||||
If the client has completed all stages of a flow, the homeserver performs the
|
If the client has completed all stages of a flow, the homeserver performs the
|
||||||
API call and returns the result as normal.
|
API call and returns the result as normal.
|
||||||
|
|
||||||
|
@ -389,7 +428,8 @@ To use this authentication type, clients should submit an auth dict as follows:
|
||||||
{
|
{
|
||||||
"type": "m.login.password",
|
"type": "m.login.password",
|
||||||
"user": "<user_id or user localpart>",
|
"user": "<user_id or user localpart>",
|
||||||
"password": "<password>"
|
"password": "<password>",
|
||||||
|
"session": "<session ID>"
|
||||||
}
|
}
|
||||||
|
|
||||||
Alternatively reply using a 3pid bound to the user's account on the homeserver
|
Alternatively reply using a 3pid bound to the user's account on the homeserver
|
||||||
|
@ -402,18 +442,13 @@ follows:
|
||||||
"type": "m.login.password",
|
"type": "m.login.password",
|
||||||
"medium": "<The medium of the third party identifier. Must be 'email'>",
|
"medium": "<The medium of the third party identifier. Must be 'email'>",
|
||||||
"address": "<The third party address of the user>",
|
"address": "<The third party address of the user>",
|
||||||
"password": "<password>"
|
"password": "<password>",
|
||||||
|
"session": "<session ID>"
|
||||||
}
|
}
|
||||||
|
|
||||||
In the case that the homeserver does not know about the supplied 3pid, the
|
In the case that the homeserver does not know about the supplied 3pid, the
|
||||||
homeserver must respond with 403 Forbidden.
|
homeserver must respond with 403 Forbidden.
|
||||||
|
|
||||||
.. WARNING::
|
|
||||||
Clients SHOULD enforce that the password provided is suitably complex. The
|
|
||||||
password SHOULD include a lower-case letter, an upper-case letter, a number
|
|
||||||
and a symbol and be at a minimum 8 characters in length. Servers MAY reject
|
|
||||||
weak passwords with an error code ``M_WEAK_PASSWORD``.
|
|
||||||
|
|
||||||
Google ReCaptcha
|
Google ReCaptcha
|
||||||
<<<<<<<<<<<<<<<<
|
<<<<<<<<<<<<<<<<
|
||||||
:Type:
|
:Type:
|
||||||
|
@ -427,7 +462,8 @@ To use this authentication type, clients should submit an auth dict as follows:
|
||||||
|
|
||||||
{
|
{
|
||||||
"type": "m.login.recaptcha",
|
"type": "m.login.recaptcha",
|
||||||
"response": "<captcha response>"
|
"response": "<captcha response>",
|
||||||
|
"session": "<session ID>"
|
||||||
}
|
}
|
||||||
|
|
||||||
Token-based
|
Token-based
|
||||||
|
@ -444,7 +480,8 @@ To use this authentication type, clients should submit an auth dict as follows:
|
||||||
{
|
{
|
||||||
"type": "m.login.token",
|
"type": "m.login.token",
|
||||||
"token": "<token>",
|
"token": "<token>",
|
||||||
"txn_id": "<client generated nonce>"
|
"txn_id": "<client generated nonce>",
|
||||||
|
"session": "<session ID>"
|
||||||
}
|
}
|
||||||
|
|
||||||
The ``nonce`` should be a random string generated by the client for the
|
The ``nonce`` should be a random string generated by the client for the
|
||||||
|
@ -460,8 +497,8 @@ server side, as well as potentially invalidating the token completely once the
|
||||||
device has successfully logged in (e.g. when we receive a request from the
|
device has successfully logged in (e.g. when we receive a request from the
|
||||||
newly provisioned access_token).
|
newly provisioned access_token).
|
||||||
|
|
||||||
The ``token`` must be a macaroon, with a caveat encoding the user id. There is
|
The server must encode the user id in the ``token``. There is therefore no need
|
||||||
therefore no need for the client to submit a separate username.
|
for the client to submit a separate username.
|
||||||
|
|
||||||
OAuth2-based
|
OAuth2-based
|
||||||
<<<<<<<<<<<<
|
<<<<<<<<<<<<
|
||||||
|
@ -511,7 +548,8 @@ To use this authentication type, clients should submit an auth dict as follows:
|
||||||
"client_secret": "<identity server client secret>",
|
"client_secret": "<identity server client secret>",
|
||||||
"id_server": "<url of identity server authed with, e.g. 'matrix.org:8090'>"
|
"id_server": "<url of identity server authed with, e.g. 'matrix.org:8090'>"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"session": "<session ID>"
|
||||||
}
|
}
|
||||||
|
|
||||||
Dummy Auth
|
Dummy Auth
|
||||||
|
@ -529,12 +567,13 @@ the type and session, if provided:
|
||||||
.. code:: json
|
.. code:: json
|
||||||
|
|
||||||
{
|
{
|
||||||
"type": "m.login.dummy"
|
"type": "m.login.dummy",
|
||||||
|
"session": "<session ID>"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Fallback
|
Fallback
|
||||||
<<<<<<<<
|
++++++++
|
||||||
Clients cannot be expected to be able to know how to process every single login
|
Clients cannot be expected to be able to know how to process every single login
|
||||||
type. If a client does not know how to handle a given login type, it can direct
|
type. If a client does not know how to handle a given login type, it can direct
|
||||||
the user to a web browser with the URL of a fallback page which will allow the
|
the user to a web browser with the URL of a fallback page which will allow the
|
||||||
|
@ -544,11 +583,93 @@ should open is::
|
||||||
/_matrix/client/%CLIENT_MAJOR_VERSION%/auth/<auth type>/fallback/web?session=<session ID>
|
/_matrix/client/%CLIENT_MAJOR_VERSION%/auth/<auth type>/fallback/web?session=<session ID>
|
||||||
|
|
||||||
Where ``auth type`` is the type name of the stage it is attempting and
|
Where ``auth type`` is the type name of the stage it is attempting and
|
||||||
``session id`` is the ID of the session given by the homeserver.
|
``session ID`` is the ID of the session given by the homeserver.
|
||||||
|
|
||||||
This MUST return an HTML page which can perform this authentication stage. This
|
This MUST return an HTML page which can perform this authentication stage. This
|
||||||
page must attempt to call the JavaScript function ``window.onAuthDone`` when
|
page must use the following JavaScript when the authentication has been
|
||||||
the authentication has been completed.
|
completed:
|
||||||
|
|
||||||
|
.. code:: javascript
|
||||||
|
|
||||||
|
if (window.onAuthDone) {
|
||||||
|
window.onAuthDone();
|
||||||
|
} else if (window.opener && window.opener.postMessage) {
|
||||||
|
window.opener.postMessage("authDone", "*");
|
||||||
|
}
|
||||||
|
|
||||||
|
This allows the client to either arrange for the global function ``onAuthDone``
|
||||||
|
to be defined in an embedded browser, or to use the HTML5 `cross-document
|
||||||
|
messaging <https://www.w3.org/TR/webmessaging/#web-messaging>`_ API, to receive
|
||||||
|
a notification that the authentication stage has been completed.
|
||||||
|
|
||||||
|
Once a client receives the notificaton that the authentication stage has been
|
||||||
|
completed, it should resubmit the request with an auth dict with just the
|
||||||
|
session ID:
|
||||||
|
|
||||||
|
.. code:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"session": "<session ID>"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Example
|
||||||
|
<<<<<<<
|
||||||
|
A client webapp might use the following javascript to open a popup window which will
|
||||||
|
handle unknown login types:
|
||||||
|
|
||||||
|
.. code:: javascript
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arguments:
|
||||||
|
* homeserverUrl: the base url of the homeserver (eg "https://matrix.org")
|
||||||
|
*
|
||||||
|
* apiEndpoint: the API endpoint being used (eg
|
||||||
|
* "/_matrix/client/%CLIENT_MAJOR_VERSION%/account/password")
|
||||||
|
*
|
||||||
|
* loginType: the loginType being attempted (eg "m.login.recaptcha")
|
||||||
|
*
|
||||||
|
* sessionID: the session ID given by the homeserver in earlier requests
|
||||||
|
*
|
||||||
|
* onComplete: a callback which will be called with the results of the request
|
||||||
|
*/
|
||||||
|
function unknownLoginType(homeserverUrl, apiEndpoint, loginType, sessionID, onComplete) {
|
||||||
|
var popupWindow;
|
||||||
|
|
||||||
|
var eventListener = function(ev) {
|
||||||
|
// check it's the right message from the right place.
|
||||||
|
if (ev.data !== "authDone" || ev.origin !== homeserverUrl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// close the popup
|
||||||
|
popupWindow.close();
|
||||||
|
window.removeEventListener("message", eventListener);
|
||||||
|
|
||||||
|
// repeat the request
|
||||||
|
var requestBody = {
|
||||||
|
auth: {
|
||||||
|
session: sessionID,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
request({
|
||||||
|
method:'POST', url:apiEndpint, json:requestBody,
|
||||||
|
}, onComplete);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener("message", eventListener);
|
||||||
|
|
||||||
|
var url = homeserverUrl +
|
||||||
|
"/_matrix/client/%CLIENT_MAJOR_VERSION%/auth/" +
|
||||||
|
encodeURIComponent(loginType) +
|
||||||
|
"/fallback/web?session=" +
|
||||||
|
encodeURIComponent(sessionID);
|
||||||
|
|
||||||
|
|
||||||
|
popupWindow = window.open(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Login
|
Login
|
||||||
~~~~~
|
~~~~~
|
||||||
|
@ -595,9 +716,9 @@ follows:
|
||||||
"token": "<login token>"
|
"token": "<login token>"
|
||||||
}
|
}
|
||||||
|
|
||||||
As with `token-based`_ interactive login, the ``token`` must be a macroon with
|
As with `token-based`_ interactive login, the ``token`` must encode the
|
||||||
a caveat which includes the user id. In the case that the token is not valid, the
|
user id. In the case that the token is not valid, the homeserver must respond
|
||||||
homeserver must respond with ``403 Forbidden`` and an error code of ``M_FORBIDDEN``.
|
with ``403 Forbidden`` and an error code of ``M_FORBIDDEN``.
|
||||||
|
|
||||||
{{login_cs_http_api}}
|
{{login_cs_http_api}}
|
||||||
|
|
||||||
|
@ -615,6 +736,8 @@ This returns an HTML and JavaScript page which can perform the entire login
|
||||||
process. The page will attempt to call the JavaScript function
|
process. The page will attempt to call the JavaScript function
|
||||||
``window.onLogin`` when login has been successfully completed.
|
``window.onLogin`` when login has been successfully completed.
|
||||||
|
|
||||||
|
.. _Registration:
|
||||||
|
|
||||||
Account registration and management
|
Account registration and management
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -1230,6 +1353,9 @@ have to wait in milliseconds before they can try again.
|
||||||
homeserver come up with their own idea, causing totally unpredictable performance over
|
homeserver come up with their own idea, causing totally unpredictable performance over
|
||||||
federated rooms?
|
federated rooms?
|
||||||
|
|
||||||
|
.. References
|
||||||
|
|
||||||
|
.. _`macaroon`: http://research.google.com/pubs/pub41892.html
|
||||||
|
|
||||||
.. Links through the external API docs are below
|
.. Links through the external API docs are below
|
||||||
.. =============================================
|
.. =============================================
|
||||||
|
@ -1237,15 +1363,15 @@ have to wait in milliseconds before they can try again.
|
||||||
.. |/initialSync| replace:: ``/initialSync``
|
.. |/initialSync| replace:: ``/initialSync``
|
||||||
.. _/initialSync: #get-matrix-client-%CLIENT_MAJOR_VERSION%-initialsync
|
.. _/initialSync: #get-matrix-client-%CLIENT_MAJOR_VERSION%-initialsync
|
||||||
|
|
||||||
.. |/tokenrefresh| replace:: ``/tokenrefresh``
|
|
||||||
.. _/tokenrefresh: #post-matrix-client-%CLIENT_MAJOR_VERSION%-tokenrefresh
|
|
||||||
|
|
||||||
.. |/sync| replace:: ``/sync``
|
.. |/sync| replace:: ``/sync``
|
||||||
.. _/sync: #get-matrix-client-%CLIENT_MAJOR_VERSION%-sync
|
.. _/sync: #get-matrix-client-%CLIENT_MAJOR_VERSION%-sync
|
||||||
|
|
||||||
.. |/events| replace:: ``/events``
|
.. |/events| replace:: ``/events``
|
||||||
.. _/events: #get-matrix-client-%CLIENT_MAJOR_VERSION%-events
|
.. _/events: #get-matrix-client-%CLIENT_MAJOR_VERSION%-events
|
||||||
|
|
||||||
|
.. |/createRoom| replace:: ``/createRoom``
|
||||||
|
.. _/createRoom: #post-matrix-client-%CLIENT_MAJOR_VERSION%-createroom
|
||||||
|
|
||||||
.. |/rooms/<room_id>/initialSync| replace:: ``/rooms/<room_id>/initialSync``
|
.. |/rooms/<room_id>/initialSync| replace:: ``/rooms/<room_id>/initialSync``
|
||||||
.. _/rooms/<room_id>/initialSync: #get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-initialsync
|
.. _/rooms/<room_id>/initialSync: #get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-initialsync
|
||||||
|
|
||||||
|
@ -1258,6 +1384,9 @@ have to wait in milliseconds before they can try again.
|
||||||
.. |/rooms/<room_id>/state| replace:: ``/rooms/<room_id>/state``
|
.. |/rooms/<room_id>/state| replace:: ``/rooms/<room_id>/state``
|
||||||
.. _/rooms/<room_id>/state: #get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-state
|
.. _/rooms/<room_id>/state: #get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-state
|
||||||
|
|
||||||
|
.. |/rooms/<room_id>/send| replace:: ``/rooms/<room_id>/send``
|
||||||
|
.. _/rooms/<room_id>/send: #put-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-send-eventtype-txnid
|
||||||
|
|
||||||
.. |/rooms/<room_id>/invite| replace:: ``/rooms/<room_id>/invite``
|
.. |/rooms/<room_id>/invite| replace:: ``/rooms/<room_id>/invite``
|
||||||
.. _/rooms/<room_id>/invite: #post-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-invite
|
.. _/rooms/<room_id>/invite: #post-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-invite
|
||||||
|
|
||||||
|
@ -1278,3 +1407,6 @@ have to wait in milliseconds before they can try again.
|
||||||
|
|
||||||
.. |/account/3pid| replace:: ``/account/3pid``
|
.. |/account/3pid| replace:: ``/account/3pid``
|
||||||
.. _/account/3pid: #post-matrix-client-%CLIENT_MAJOR_VERSION%-account-3pid
|
.. _/account/3pid: #post-matrix-client-%CLIENT_MAJOR_VERSION%-account-3pid
|
||||||
|
|
||||||
|
.. |/user/<user_id>/account_data/<type>| replace:: ``/user/<user_id>/account_data/<type>``
|
||||||
|
.. _/user/<user_id>/account_data/<type>: #put-matrix-client-%CLIENT_MAJOR_VERSION%-user-userid-account-data-type
|
||||||
|
|
|
@ -110,7 +110,7 @@ Creating a session
|
||||||
|
|
||||||
A client makes a call to::
|
A client makes a call to::
|
||||||
|
|
||||||
POST https://my.id.server:8090/_matrix/identity/v1/api/validate/email/requestToken
|
POST https://my.id.server:8090/_matrix/identity/api/v1/validate/email/requestToken
|
||||||
|
|
||||||
client_secret=monkeys_are_GREAT&
|
client_secret=monkeys_are_GREAT&
|
||||||
email=foo@bar.com&
|
email=foo@bar.com&
|
||||||
|
@ -147,7 +147,7 @@ Validating ownership of an email
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
A user may make either a ``GET`` or a ``POST`` request to
|
A user may make either a ``GET`` or a ``POST`` request to
|
||||||
``/_matrix/identity/v1/api/validate/email/submitToken`` with the following
|
``/_matrix/identity/api/v1/validate/email/submitToken`` with the following
|
||||||
parameters (either as query parameters or URL-encoded POST parameters):
|
parameters (either as query parameters or URL-encoded POST parameters):
|
||||||
- ``sid`` the sid for the session, generated by the ``requestToken`` call.
|
- ``sid`` the sid for the session, generated by the ``requestToken`` call.
|
||||||
- ``client_secret`` the client secret which was supplied to the ``requestToken`` call.
|
- ``client_secret`` the client secret which was supplied to the ``requestToken`` call.
|
||||||
|
@ -164,7 +164,7 @@ Checking non-published 3pid ownership
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
A client can check whether ownership of a 3pid was validated by making an
|
A client can check whether ownership of a 3pid was validated by making an
|
||||||
HTTP GET request to ``/_matrix/identity/v1/api/3pid/getValidated3pid``, passing
|
HTTP GET request to ``/_matrix/identity/api/v1/3pid/getValidated3pid``, passing
|
||||||
the ``sid`` and ``client_secret`` as query parameters from the ``requestToken``
|
the ``sid`` and ``client_secret`` as query parameters from the ``requestToken``
|
||||||
call.
|
call.
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ Publishing a validated association
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
An association between a session and a Matrix user ID can be published by making
|
An association between a session and a Matrix user ID can be published by making
|
||||||
a URL-encoded HTTP POST request to ``/_matrix/identity/v1/api/3pid/bind`` with
|
a URL-encoded HTTP POST request to ``/_matrix/identity/api/v1/3pid/bind`` with
|
||||||
the following parameters::
|
the following parameters::
|
||||||
|
|
||||||
sid=sid&
|
sid=sid&
|
||||||
|
@ -256,7 +256,7 @@ At a later point, if the owner of that particular 3pid binds it with a Matrix us
|
||||||
|
|
||||||
Where the signature is produced using a long-term private key.
|
Where the signature is produced using a long-term private key.
|
||||||
|
|
||||||
Also, the generated ephemeral public key will be listed as valid on requests to ``/_matrix/identity/v1/api/pubkey/ephemeral/isvalid``.
|
Also, the generated ephemeral public key will be listed as valid on requests to ``/_matrix/identity/api/v1/pubkey/ephemeral/isvalid``.
|
||||||
|
|
||||||
Ephemeral invitation signing
|
Ephemeral invitation signing
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
58
specification/modules/dm.rst
Normal file
58
specification/modules/dm.rst
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
.. Copyright 2016 OpenMarket Ltd
|
||||||
|
..
|
||||||
|
.. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
.. you may not use this file except in compliance with the License.
|
||||||
|
.. You may obtain a copy of the License at
|
||||||
|
..
|
||||||
|
.. http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
..
|
||||||
|
.. Unless required by applicable law or agreed to in writing, software
|
||||||
|
.. distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
.. See the License for the specific language governing permissions and
|
||||||
|
.. limitations under the License.
|
||||||
|
|
||||||
|
Direct Messaging
|
||||||
|
================
|
||||||
|
|
||||||
|
.. _module:dm:
|
||||||
|
|
||||||
|
All communication over Matrix happens within a room. It is sometimes
|
||||||
|
desirable to offer users the concept of speaking directly to one
|
||||||
|
particular person. This module defines a way of marking certain rooms
|
||||||
|
as 'direct chats' with a given person. This does not restrict the chat
|
||||||
|
to being between exactly two people since this would preclude the
|
||||||
|
presence of automated 'bot' users or even a 'personal assistant' who is
|
||||||
|
able to answer direct messages on behalf of the user in their absence.
|
||||||
|
|
||||||
|
A room may not necessarily be considered 'direct' by all members of the
|
||||||
|
room, but a signalling mechanism exists to propagate the information of
|
||||||
|
whether a chat is 'direct' to an invitee.
|
||||||
|
|
||||||
|
Events
|
||||||
|
------
|
||||||
|
|
||||||
|
{{m_direct_event}}
|
||||||
|
|
||||||
|
Client behaviour
|
||||||
|
----------------
|
||||||
|
To start a direct chat with another user, the inviting user's client
|
||||||
|
should set the ``is_direct`` flag to |/createRoom|_. The client should do
|
||||||
|
this whenever the flow the user has followed is one where their
|
||||||
|
intention is to speak directly with another person, as opposed to bringing that
|
||||||
|
person in to a shared room. For example, clicking on 'Start Chat' beside a
|
||||||
|
person's profile picture would imply the ``is_direct`` flag should be set.
|
||||||
|
|
||||||
|
The invitee's client may use the ``is_direct`` flag in the `m.room.member`_
|
||||||
|
event to automatically mark the room as a direct chat but this is not
|
||||||
|
required: it may for example, prompt the user, or ignore the flag altogether.
|
||||||
|
|
||||||
|
Both the inviting client and the invitee's client should record the fact that
|
||||||
|
the room is a direct chat by storing an ``m.direct`` event in the account data
|
||||||
|
using |/user/<user_id>/account_data/<type>|_.
|
||||||
|
|
||||||
|
Server behaviour
|
||||||
|
----------------
|
||||||
|
When the ``is_direct`` flag is given to |/createRoom|_, the home
|
||||||
|
server must set the ``is_direct`` flag in the invite member event for any users
|
||||||
|
invited in the |/createRoom|_ call.
|
|
@ -107,6 +107,15 @@ There is a single API endpoint for this, as described below.
|
||||||
|
|
||||||
.. _pushers: `def:pushers`_
|
.. _pushers: `def:pushers`_
|
||||||
|
|
||||||
|
Listing Notifications
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
A client can retrieve a list of events that it has been notified about. This
|
||||||
|
may be useful so that users can see a summary of what important messages they
|
||||||
|
have received.
|
||||||
|
|
||||||
|
{{notifications_cs_http_api}}
|
||||||
|
|
||||||
Push Rules
|
Push Rules
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
A push rule is a single rule that states under what *conditions* an event should
|
A push rule is a single rule that states under what *conditions* an event should
|
||||||
|
|
146
specification/modules/send_to_device.rst
Normal file
146
specification/modules/send_to_device.rst
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
.. Copyright 2016 OpenMarket Ltd
|
||||||
|
..
|
||||||
|
.. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
.. you may not use this file except in compliance with the License.
|
||||||
|
.. You may obtain a copy of the License at
|
||||||
|
..
|
||||||
|
.. http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
..
|
||||||
|
.. Unless required by applicable law or agreed to in writing, software
|
||||||
|
.. distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
.. See the License for the specific language governing permissions and
|
||||||
|
.. limitations under the License.
|
||||||
|
|
||||||
|
Send-to-Device messaging
|
||||||
|
========================
|
||||||
|
|
||||||
|
.. _module:to_device:
|
||||||
|
|
||||||
|
This module provides a means by which clients can exchange signalling messages
|
||||||
|
without them being stored permanently as part of a shared communication
|
||||||
|
history. A message is delivered exactly once to each client device.
|
||||||
|
|
||||||
|
The primary motivation for this API is exchanging data that is meaningless or
|
||||||
|
undesirable to persist in the room DAG - for example, one-time authentication
|
||||||
|
tokens or key data. It is not intended for conversational data, which should be
|
||||||
|
sent using the normal |/rooms/<room_id>/send|_ API for consistency throughout
|
||||||
|
Matrix.
|
||||||
|
|
||||||
|
Client behaviour
|
||||||
|
----------------
|
||||||
|
To send a message to other devices, a client should call |/sendToDevice|_.
|
||||||
|
Only one message can be sent to each device per transaction, and they must all
|
||||||
|
have the same event type. The device ID in the request body can be set to ``*``
|
||||||
|
to request that the message be sent to all known devices.
|
||||||
|
|
||||||
|
If there are send-to-device messages waiting for a client, they will be
|
||||||
|
returned by |/sync|_, as detailed in `Extensions to /sync`_. Clients should
|
||||||
|
inspect the ``type`` of each returned event, and ignore any they do not
|
||||||
|
understand.
|
||||||
|
|
||||||
|
Server behaviour
|
||||||
|
----------------
|
||||||
|
Servers should store pending messages for local users until they are
|
||||||
|
successfully delivered to the destination device. When a client calls |/sync|_
|
||||||
|
with an access token which corresponds to a device with pending messages, the
|
||||||
|
server should list the pending messages, in order of arrival, in the response
|
||||||
|
body.
|
||||||
|
|
||||||
|
When the client calls ``/sync`` again with the ``next_batch`` token from the
|
||||||
|
first response, the server should infer that any send-to-device messages in
|
||||||
|
that response have been delivered successfully, and delete them from the store.
|
||||||
|
|
||||||
|
If there is a large queue of send-to-device messages, the server should
|
||||||
|
limit the number sent in each ``/sync`` response. 100 messages is recommended
|
||||||
|
as a reasonable limit.
|
||||||
|
|
||||||
|
If the client sends messages to users on remote domains, those messages should
|
||||||
|
be sent on to the remote servers via
|
||||||
|
`federation`_.
|
||||||
|
|
||||||
|
.. _`federation`: ../server_server/latest.html#send-to-device-messages
|
||||||
|
|
||||||
|
.. TODO-spec:
|
||||||
|
|
||||||
|
* Is a server allowed to delete undelivered messages? After how long? What
|
||||||
|
about if the device is deleted?
|
||||||
|
|
||||||
|
* If the destination HS doesn't support the ``m.direct_to_device`` EDU, it
|
||||||
|
will just get dumped. Should we indicate that to the client?
|
||||||
|
|
||||||
|
|
||||||
|
Protocol definitions
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
{{to_device_cs_http_api}}
|
||||||
|
|
||||||
|
.. TODO-spec:
|
||||||
|
|
||||||
|
* What should a server do if the user id or device id is unknown? Presumably
|
||||||
|
it shouldn't reject the request outright, because some of the destinations
|
||||||
|
may be valid. Should we add something to the response?
|
||||||
|
|
||||||
|
.. anchor for link from /sync api spec
|
||||||
|
.. |send_to_device_sync| replace:: Send-to-Device messaging
|
||||||
|
.. _send_to_device_sync:
|
||||||
|
|
||||||
|
Extensions to /sync
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
This module adds the following properties to the |/sync|_ response:
|
||||||
|
|
||||||
|
.. todo: generate this from a swagger definition?
|
||||||
|
|
||||||
|
========= ========= =======================================================
|
||||||
|
Parameter Type Description
|
||||||
|
========= ========= =======================================================
|
||||||
|
to_device ToDevice Optional. Information on the send-to-device messages
|
||||||
|
for the client device.
|
||||||
|
========= ========= =======================================================
|
||||||
|
|
||||||
|
``ToDevice``
|
||||||
|
|
||||||
|
========= ========= =============================================
|
||||||
|
Parameter Type Description
|
||||||
|
========= ========= =============================================
|
||||||
|
events [Event] List of send-to-device messages
|
||||||
|
========= ========= =============================================
|
||||||
|
|
||||||
|
``Event``
|
||||||
|
|
||||||
|
================ ============ ==================================================
|
||||||
|
Parameter Type Description
|
||||||
|
================ ============ ==================================================
|
||||||
|
content EventContent The content of this event. The fields in this
|
||||||
|
object will vary depending on the type of event.
|
||||||
|
sender string The Matrix user ID of the user who sent this
|
||||||
|
event.
|
||||||
|
type string The type of event.
|
||||||
|
================ ============ ==================================================
|
||||||
|
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
.. code:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"next_batch": "s72595_4483_1934",
|
||||||
|
"rooms": {"leave": {}, "join": {}, "invite": {}},
|
||||||
|
"to_device": {
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"sender": "@alice:example.com",
|
||||||
|
"type": "m.new_device",
|
||||||
|
"content": {
|
||||||
|
"device_id": "XYZABCDE",
|
||||||
|
"rooms": ["!726s6s6q:example.com"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.. |/sendToDevice| replace:: ``/sendToDevice``
|
||||||
|
.. _/sendToDevice: #put-matrix-client-%CLIENT_MAJOR_VERSION%-sendtodevice-eventtype-txnid
|
|
@ -974,3 +974,27 @@ The list of join candidates is a list of server names that are likely to hold
|
||||||
the given room; these are servers that the requesting server may wish to use as
|
the given room; these are servers that the requesting server may wish to use as
|
||||||
resident servers as part of the remote join handshake. This list may or may not
|
resident servers as part of the remote join handshake. This list may or may not
|
||||||
include the server answering the query.
|
include the server answering the query.
|
||||||
|
|
||||||
|
Send-to-device messaging
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
.. TODO: add modules to the federation spec and make this a module
|
||||||
|
|
||||||
|
The server API for send-to-device messaging is based on the following
|
||||||
|
EDU. There are no PDUs or Federation Queries involved.
|
||||||
|
|
||||||
|
Each send-to-device message should be sent to the destination server using
|
||||||
|
the following EDU::
|
||||||
|
|
||||||
|
EDU type: m.direct_to_device
|
||||||
|
|
||||||
|
Content keys:
|
||||||
|
sender: user ID of the sender
|
||||||
|
|
||||||
|
type: event type for the message
|
||||||
|
|
||||||
|
message_id: unique id for the message: used for idempotence
|
||||||
|
|
||||||
|
messages: The messages to send. A map from user ID, to a map from device ID
|
||||||
|
to message body. The device ID may also be *, meaning all known devices
|
||||||
|
for the user.
|
||||||
|
|
|
@ -41,6 +41,7 @@ groups: # reusable blobs of files when prefixed with 'group:'
|
||||||
- modules/receipts.rst
|
- modules/receipts.rst
|
||||||
- modules/presence.rst
|
- modules/presence.rst
|
||||||
- modules/content_repo.rst
|
- modules/content_repo.rst
|
||||||
|
- modules/send_to_device.rst
|
||||||
- modules/end_to_end_encryption.rst
|
- modules/end_to_end_encryption.rst
|
||||||
- modules/history_visibility.rst
|
- modules/history_visibility.rst
|
||||||
- modules/push.rst
|
- modules/push.rst
|
||||||
|
@ -53,6 +54,7 @@ groups: # reusable blobs of files when prefixed with 'group:'
|
||||||
- modules/admin.rst
|
- modules/admin.rst
|
||||||
- modules/event_context.rst
|
- modules/event_context.rst
|
||||||
- modules/cas_login.rst
|
- modules/cas_login.rst
|
||||||
|
- modules/dm.rst
|
||||||
|
|
||||||
|
|
||||||
title_styles: ["=", "-", "~", "+", "^", "`", "@", ":"]
|
title_styles: ["=", "-", "~", "+", "^", "`", "@", ":"]
|
||||||
|
|
|
@ -5,7 +5,7 @@ categories: projects client
|
||||||
thumbnail: https://matrix.org/blog/wp-content/uploads/2015/08/vector030216-400x284.png
|
thumbnail: https://matrix.org/blog/wp-content/uploads/2015/08/vector030216-400x284.png
|
||||||
author: Riot.im
|
author: Riot.im
|
||||||
description: Riot is a glossy web client with an emphasis on performance and usability
|
description: Riot is a glossy web client with an emphasis on performance and usability
|
||||||
maturity: Late beta
|
maturity: Released
|
||||||
---
|
---
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
layout: project
|
layout: project
|
||||||
title: Try Matrix Now!
|
title: Try Matrix Now!
|
||||||
categories: projects client
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<html>
|
<html>
|
||||||
|
|
|
@ -5,7 +5,7 @@ categories: projects client
|
||||||
thumbnail: /docs/projects/images/vector-iOS-small.png
|
thumbnail: /docs/projects/images/vector-iOS-small.png
|
||||||
description: Riot is a glossy client with an emphasis on performance and usability
|
description: Riot is a glossy client with an emphasis on performance and usability
|
||||||
author: Riot.im
|
author: Riot.im
|
||||||
maturity: Beta
|
maturity: Released
|
||||||
---
|
---
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
layout: project
|
layout: project
|
||||||
title: Try Matrix Now!
|
title: Try Matrix Now!
|
||||||
categories: projects client
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<html>
|
<html>
|
||||||
|
|
|
@ -5,7 +5,7 @@ categories: projects client
|
||||||
thumbnail: /docs/projects/images/vector-android-small.png
|
thumbnail: /docs/projects/images/vector-android-small.png
|
||||||
description: Riot is a glossy client with an emphasis on performance and usability
|
description: Riot is a glossy client with an emphasis on performance and usability
|
||||||
author: Riot.im
|
author: Riot.im
|
||||||
maturity: Beta
|
maturity: Released
|
||||||
---
|
---
|
||||||
|
|
||||||

|

|
||||||
|
@ -13,6 +13,6 @@ maturity: Beta
|
||||||
# {{ page.title }}
|
# {{ page.title }}
|
||||||
The Android version of the [Riot](https://matrix.org/docs/projects/client/riot.html) web client. Riot is a glossy client with focus on performance and usability.
|
The Android version of the [Riot](https://matrix.org/docs/projects/client/riot.html) web client. Riot is a glossy client with focus on performance and usability.
|
||||||
|
|
||||||
The code is available from [github](https://github.com/vector-im/vector-android), and the app is available from the [Google Play store](https://play.google.com/store/apps/details?id=im.riot) and (as "Vector") [F-Droid](https://f-droid.org/repository/browse/?fdfilter=vector&fdid=im.vector.alpha).
|
The code is available from [github](https://github.com/vector-im/vector-android), and the app is available from the [Google Play store](https://play.google.com/store/apps/details?id=im.vector.alpha) and [F-Droid](https://f-droid.org/repository/browse/?fdfilter=vector&fdid=im.vector.alpha).
|
||||||
|
|
||||||
If you want to help test the app, you can download development versions from [Jenkins](https://matrix.org/jenkins/job/VectorAndroidDevelop/).
|
If you want to help test the app, you can download development versions from [Jenkins](https://matrix.org/jenkins/job/VectorAndroidDevelop/).
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
layout: project
|
layout: project
|
||||||
title: Try Matrix Now!
|
title: Try Matrix Now!
|
||||||
categories: projects client
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<html>
|
<html>
|
||||||
|
|
13
supporting-docs/projects/2015-11-28-matrixtool.md
Normal file
13
supporting-docs/projects/2015-11-28-matrixtool.md
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
layout: project
|
||||||
|
title: MatrixTool
|
||||||
|
categories: projects other
|
||||||
|
description: Commands to interact with a Matrix homeserver
|
||||||
|
author: LeoNerd
|
||||||
|
maturity: Alpha
|
||||||
|
---
|
||||||
|
# {{ page.title }}
|
||||||
|
|
||||||
|
The tool provides a wrapper around a number of sub-commands that provide useful interactions with a Matrix homeserver.
|
||||||
|
|
||||||
|
You can grab it from [CPAN](http://search.cpan.org/~pevans/App-MatrixTool/).
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
layout: project
|
layout: project
|
||||||
title: Vector Desktop
|
title: Vector Desktop
|
||||||
categories: projects client
|
|
||||||
description: Desktop version of Vector
|
description: Desktop version of Vector
|
||||||
author: Steven Hammerton
|
author: Steven Hammerton
|
||||||
maturity: Alpha
|
maturity: Alpha
|
||||||
|
|
12
supporting-docs/projects/2016-09-13-telematrix.md
Normal file
12
supporting-docs/projects/2016-09-13-telematrix.md
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
layout: project
|
||||||
|
title: telematrix
|
||||||
|
categories: projects as
|
||||||
|
author: SijmenSchoon
|
||||||
|
maturity: Alpha
|
||||||
|
---
|
||||||
|
|
||||||
|
# {{ page.title }}
|
||||||
|
This project bridges [Telegram Messenger](https://telegram.org/) to Matrix. It's currently in early development, and not considered to be in a usable state yet.
|
||||||
|
|
||||||
|
Get it and report issues at [github](https://github.com/SijmenSchoon/telematrix)!
|
|
@ -96,8 +96,7 @@ def inherit_parents(obj):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_json_schema_object_fields(obj, enforce_title=False,
|
def get_json_schema_object_fields(obj, enforce_title=False):
|
||||||
mark_required=True):
|
|
||||||
# Algorithm:
|
# Algorithm:
|
||||||
# f.e. property => add field info (if field is object then recurse)
|
# f.e. property => add field info (if field is object then recurse)
|
||||||
if obj.get("type") != "object":
|
if obj.get("type") != "object":
|
||||||
|
@ -175,8 +174,7 @@ def get_json_schema_object_fields(obj, enforce_title=False,
|
||||||
try:
|
try:
|
||||||
logger.debug("Processing property %s.%s", obj_title, key_name)
|
logger.debug("Processing property %s.%s", obj_title, key_name)
|
||||||
required = key_name in required_keys
|
required = key_name in required_keys
|
||||||
res = process_prop(key_name, props[key_name], required,
|
res = process_prop(key_name, props[key_name], required)
|
||||||
mark_required)
|
|
||||||
|
|
||||||
first_table_rows.append(res["row"])
|
first_table_rows.append(res["row"])
|
||||||
tables.extend(res["tables"])
|
tables.extend(res["tables"])
|
||||||
|
@ -196,7 +194,7 @@ def get_json_schema_object_fields(obj, enforce_title=False,
|
||||||
|
|
||||||
return tables
|
return tables
|
||||||
|
|
||||||
def process_prop(key_name, prop, required, mark_required):
|
def process_prop(key_name, prop, required):
|
||||||
prop = inherit_parents(prop)
|
prop = inherit_parents(prop)
|
||||||
|
|
||||||
value_type = None
|
value_type = None
|
||||||
|
@ -213,7 +211,6 @@ def process_prop(key_name, prop, required, mark_required):
|
||||||
nested_objects = get_json_schema_object_fields(
|
nested_objects = get_json_schema_object_fields(
|
||||||
prop,
|
prop,
|
||||||
enforce_title=True,
|
enforce_title=True,
|
||||||
mark_required=mark_required,
|
|
||||||
)
|
)
|
||||||
value_type = nested_objects[0]["title"]
|
value_type = nested_objects[0]["title"]
|
||||||
value_id = value_type
|
value_id = value_type
|
||||||
|
@ -226,7 +223,6 @@ def process_prop(key_name, prop, required, mark_required):
|
||||||
nested_objects = get_json_schema_object_fields(
|
nested_objects = get_json_schema_object_fields(
|
||||||
items,
|
items,
|
||||||
enforce_title=True,
|
enforce_title=True,
|
||||||
mark_required=mark_required,
|
|
||||||
)
|
)
|
||||||
value_id = nested_objects[0]["title"]
|
value_id = nested_objects[0]["title"]
|
||||||
value_type = "[%s]" % value_id
|
value_type = "[%s]" % value_id
|
||||||
|
@ -269,7 +265,7 @@ def process_prop(key_name, prop, required, mark_required):
|
||||||
value_type = " or ".join(value_type)
|
value_type = " or ".join(value_type)
|
||||||
|
|
||||||
|
|
||||||
if required and mark_required:
|
if required:
|
||||||
desc = "**Required.** " + desc
|
desc = "**Required.** " + desc
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -284,10 +280,9 @@ def process_prop(key_name, prop, required, mark_required):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_tables_for_schema(schema, mark_required=True):
|
def get_tables_for_schema(schema):
|
||||||
schema = inherit_parents(schema)
|
schema = inherit_parents(schema)
|
||||||
tables = get_json_schema_object_fields(schema,
|
tables = get_json_schema_object_fields(schema)
|
||||||
mark_required=mark_required)
|
|
||||||
|
|
||||||
# the result may contain duplicates, if objects are referred to more than
|
# the result may contain duplicates, if objects are referred to more than
|
||||||
# once. Filter them out.
|
# once. Filter them out.
|
||||||
|
@ -470,9 +465,7 @@ class MatrixUnits(Units):
|
||||||
elif res_type and Units.prop(good_response, "schema/properties"):
|
elif res_type and Units.prop(good_response, "schema/properties"):
|
||||||
# response is an object:
|
# response is an object:
|
||||||
schema = good_response["schema"]
|
schema = good_response["schema"]
|
||||||
res_tables = get_tables_for_schema(schema,
|
res_tables = get_tables_for_schema(schema)
|
||||||
mark_required=False,
|
|
||||||
)
|
|
||||||
endpoint["res_tables"].extend(res_tables)
|
endpoint["res_tables"].extend(res_tables)
|
||||||
elif res_type and Units.prop(good_response, "schema/items"):
|
elif res_type and Units.prop(good_response, "schema/items"):
|
||||||
# response is an array:
|
# response is an array:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue