Merge branch 'master' into appservice-swagger
Conflicts: specification/application_service_api.rst
This commit is contained in:
commit
f95d19cecd
24 changed files with 914 additions and 392 deletions
148
api/client-server/v1/create_room.yaml
Normal file
148
api/client-server/v1/create_room.yaml
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
swagger: '2.0'
|
||||||
|
info:
|
||||||
|
title: "Matrix Client-Server v1 Room Creation API"
|
||||||
|
version: "1.0.0"
|
||||||
|
host: localhost:8008
|
||||||
|
schemes:
|
||||||
|
- https
|
||||||
|
- http
|
||||||
|
basePath: /_matrix/client/api/v1
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
securityDefinitions:
|
||||||
|
accessToken:
|
||||||
|
type: apiKey
|
||||||
|
description: The user_id or application service access_token
|
||||||
|
name: access_token
|
||||||
|
in: query
|
||||||
|
paths:
|
||||||
|
"/createRoom":
|
||||||
|
post:
|
||||||
|
summary: Create a new room
|
||||||
|
description: |-
|
||||||
|
Create a new room with various configuration options.
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
description: The desired room configuration.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
example: |-
|
||||||
|
{
|
||||||
|
"preset": "public_chat",
|
||||||
|
"room_alias_name": "thepub",
|
||||||
|
"name": "The Grand Duke Pub",
|
||||||
|
"topic": "All about happy hour",
|
||||||
|
"creation_content": {
|
||||||
|
"m.federate": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
properties:
|
||||||
|
visibility:
|
||||||
|
type: string
|
||||||
|
enum: ["public", "private"]
|
||||||
|
description: |-
|
||||||
|
A ``public`` visibility indicates that the room will be shown
|
||||||
|
in the published room list. A ``private`` visibility will hide
|
||||||
|
the room from the published room list. Rooms default to
|
||||||
|
``private`` visibility if this key is not included. NB: This
|
||||||
|
should not be confused with ``join_rules`` which also uses the
|
||||||
|
word ``public``.
|
||||||
|
room_alias_name:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
The desired room alias **local part**. If this is included, a
|
||||||
|
room alias will be created and mapped to the newly created
|
||||||
|
room. The alias will belong on the *same* home server which
|
||||||
|
created the room. For example, if this was set to "foo" and
|
||||||
|
sent to the homeserver "example.com" the complete room alias
|
||||||
|
would be ``#foo:example.com``.
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
If this is included, an ``m.room.name`` event will be sent
|
||||||
|
into the room to indicate the name of the room. See Room
|
||||||
|
Events for more information on ``m.room.name``.
|
||||||
|
topic:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
If this is included, an ``m.room.topic`` event will be sent
|
||||||
|
into the room to indicate the topic for the room. See Room
|
||||||
|
Events for more information on ``m.room.topic``.
|
||||||
|
invite:
|
||||||
|
type: array
|
||||||
|
description: |-
|
||||||
|
A list of user IDs to invite to the room. This will tell the
|
||||||
|
server to invite everyone in the list to the newly created room.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
creation_content:
|
||||||
|
title: CreationContent
|
||||||
|
type: object
|
||||||
|
description: |-
|
||||||
|
Extra keys to be added to the content of the ``m.room.create``.
|
||||||
|
The server will clober the following keys: ``creator``. Future
|
||||||
|
versions of the specification may allow the server to clobber
|
||||||
|
other keys.
|
||||||
|
initial_state:
|
||||||
|
type: array
|
||||||
|
description: |-
|
||||||
|
A list of state events to set in the new room. This allows
|
||||||
|
the user to override the default state events set in the new
|
||||||
|
room. The expected format of the state events are an object
|
||||||
|
with type, state_key and content keys set.
|
||||||
|
Takes precedence over events set by ``presets``, but gets
|
||||||
|
overriden by ``name`` and ``topic`` keys.
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
title: StateEvent
|
||||||
|
properties:
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
state_key:
|
||||||
|
type: string
|
||||||
|
content:
|
||||||
|
type: string
|
||||||
|
preset:
|
||||||
|
type: string
|
||||||
|
enum: ["private_chat", "public_chat", "trusted_private_chat"]
|
||||||
|
description: |-
|
||||||
|
Convenience parameter for setting various default state events
|
||||||
|
based on a preset. Must be either:
|
||||||
|
|
||||||
|
``private_chat`` =>
|
||||||
|
``join_rules`` is set to ``invite``.
|
||||||
|
``history_visibility`` is set to ``shared``.
|
||||||
|
|
||||||
|
``trusted_private_chat`` =>
|
||||||
|
``join_rules`` is set to ``invite``.
|
||||||
|
``history_visibility`` is set to ``shared``.
|
||||||
|
All invitees are given the same power level as the room creator.
|
||||||
|
|
||||||
|
``public_chat``: =>
|
||||||
|
``join_rules`` is set to ``public``.
|
||||||
|
``history_visibility`` is set to ``shared``.
|
||||||
|
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Information about the newly created room.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
description: Information about the newly created room.
|
||||||
|
properties:
|
||||||
|
room_id:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
The created room's ID.
|
||||||
|
examples:
|
||||||
|
application/json: |-
|
||||||
|
{
|
||||||
|
"room_id": "!sefiuhWgwghwWgh:example.com"
|
||||||
|
}
|
||||||
|
400:
|
||||||
|
description: >
|
||||||
|
The request body is malformed or the room alias specified is already taken.
|
131
api/client-server/v1/message_pagination.yaml
Normal file
131
api/client-server/v1/message_pagination.yaml
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
swagger: '2.0'
|
||||||
|
info:
|
||||||
|
title: "Matrix Client-Server v1 Rooms API"
|
||||||
|
version: "1.0.0"
|
||||||
|
host: localhost:8008
|
||||||
|
schemes:
|
||||||
|
- https
|
||||||
|
- http
|
||||||
|
basePath: /_matrix/client/api/v1
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
securityDefinitions:
|
||||||
|
accessToken:
|
||||||
|
type: apiKey
|
||||||
|
description: The user_id or application service access_token
|
||||||
|
name: access_token
|
||||||
|
in: query
|
||||||
|
paths:
|
||||||
|
"/rooms/{roomId}/messages":
|
||||||
|
get:
|
||||||
|
summary: Get a list of events for this room
|
||||||
|
description: |-
|
||||||
|
This API returns a list of message and state events for a room. It uses
|
||||||
|
pagination query parameters to paginate history in the room.
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
type: string
|
||||||
|
name: roomId
|
||||||
|
description: The room to get events from.
|
||||||
|
required: true
|
||||||
|
x-example: "!636q39766251:example.com"
|
||||||
|
- in: query
|
||||||
|
type: string
|
||||||
|
name: from
|
||||||
|
description: |-
|
||||||
|
The token to start returning events from. This token can be obtained
|
||||||
|
from the initial sync API.
|
||||||
|
required: true
|
||||||
|
x-example: "s345_678_333"
|
||||||
|
- in: query
|
||||||
|
type: string
|
||||||
|
enum: ["b", "f"]
|
||||||
|
name: dir
|
||||||
|
description: |-
|
||||||
|
The direction to return events from.
|
||||||
|
required: true
|
||||||
|
x-example: "b"
|
||||||
|
- in: query
|
||||||
|
type: integer
|
||||||
|
name: limit
|
||||||
|
description: |-
|
||||||
|
The maximum number of events to return. Default: 10.
|
||||||
|
x-example: "3"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: A list of messages with a new token to request more.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
description: A list of messages with a new token to request more.
|
||||||
|
properties:
|
||||||
|
start:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
The token to start paginating from. If ``dir=b`` this will be
|
||||||
|
the token supplied in ``from``.
|
||||||
|
end:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
The token the pagination ends at. If ``dir=b`` this token should
|
||||||
|
be used again to request even earlier events.
|
||||||
|
chunk:
|
||||||
|
type: array
|
||||||
|
description: |-
|
||||||
|
A list of room events.
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
title: RoomEvent
|
||||||
|
examples:
|
||||||
|
application/json: |-
|
||||||
|
{
|
||||||
|
"start": "t47429-4392820_219380_26003_2265",
|
||||||
|
"end": "t47409-4357353_219380_26003_2265",
|
||||||
|
"chunk": [
|
||||||
|
{
|
||||||
|
"origin_server_ts": 1444812213737,
|
||||||
|
"user_id": "@alice:example.com",
|
||||||
|
"event_id": "$1444812213350496Caaaa:example.com",
|
||||||
|
"content": {
|
||||||
|
"body": "hello world",
|
||||||
|
"msgtype":"m.text"
|
||||||
|
},
|
||||||
|
"room_id":"!Xq3620DUiqCaoxq:example.com",
|
||||||
|
"type":"m.room.message",
|
||||||
|
"age": 1042
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"origin_server_ts": 1444812194656 ,
|
||||||
|
"user_id": "@bob:example.com",
|
||||||
|
"event_id": "$1444812213350496Cbbbb:example.com",
|
||||||
|
"content": {
|
||||||
|
"body": "the world is big",
|
||||||
|
"msgtype":"m.text"
|
||||||
|
},
|
||||||
|
"room_id":"!Xq3620DUiqCaoxq:example.com",
|
||||||
|
"type":"m.room.message",
|
||||||
|
"age": 20123
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"origin_server_ts": 1444812163990,
|
||||||
|
"user_id": "@bob:example.com",
|
||||||
|
"event_id": "$1444812213350496Ccccc:example.com",
|
||||||
|
"content": {
|
||||||
|
"name": "New room name"
|
||||||
|
},
|
||||||
|
"prev_content": {
|
||||||
|
"name": "Old room name"
|
||||||
|
},
|
||||||
|
"state_key": "",
|
||||||
|
"room_id":"!Xq3620DUiqCaoxq:example.com",
|
||||||
|
"type":"m.room.name",
|
||||||
|
"age": 50789
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
403:
|
||||||
|
description: >
|
||||||
|
You aren't a member of the room.
|
|
@ -30,7 +30,9 @@ paths:
|
||||||
- in: query
|
- in: query
|
||||||
type: string
|
type: string
|
||||||
name: from
|
name: from
|
||||||
description: The token to stream from.
|
description: |-
|
||||||
|
The token to stream from. This token is either from a previous
|
||||||
|
request to this API or from the initial sync API.
|
||||||
required: false
|
required: false
|
||||||
x-example: "s3456_9_0"
|
x-example: "s3456_9_0"
|
||||||
- in: query
|
- in: query
|
||||||
|
@ -39,16 +41,6 @@ paths:
|
||||||
description: The maximum time in milliseconds to wait for an event.
|
description: The maximum time in milliseconds to wait for an event.
|
||||||
required: false
|
required: false
|
||||||
x-example: "35000"
|
x-example: "35000"
|
||||||
- in: query
|
|
||||||
type: string
|
|
||||||
name: archived
|
|
||||||
description: |-
|
|
||||||
Whether to include rooms that the user has left. If absent then
|
|
||||||
only rooms that the user has been invited to or has joined are
|
|
||||||
included. If set to "true" then rooms that the user has left are
|
|
||||||
included as well.
|
|
||||||
required: false
|
|
||||||
x-example: "true"
|
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: "The events received, which may be none."
|
description: "The events received, which may be none."
|
||||||
|
@ -78,19 +70,19 @@ paths:
|
||||||
start:
|
start:
|
||||||
type: string
|
type: string
|
||||||
description: |-
|
description: |-
|
||||||
A token which correlates to the first value in ``chunk``. Used
|
A token which correlates to the first value in ``chunk``. This
|
||||||
for pagination.
|
is usually the same token supplied to ``from=``.
|
||||||
end:
|
end:
|
||||||
type: string
|
type: string
|
||||||
description: |-
|
description: |-
|
||||||
A token which correlates to the last value in ``chunk``. Used
|
A token which correlates to the last value in ``chunk``. This
|
||||||
for pagination.
|
token should be used in the next request to ``/events``.
|
||||||
chunk:
|
chunk:
|
||||||
type: array
|
type: array
|
||||||
description: "An array of events."
|
description: "An array of events."
|
||||||
items:
|
items:
|
||||||
type: object
|
type: object
|
||||||
title: RoomEvent
|
title: Event
|
||||||
allOf:
|
allOf:
|
||||||
- "$ref": "core-event-schema/room_event.json"
|
- "$ref": "core-event-schema/room_event.json"
|
||||||
400:
|
400:
|
||||||
|
@ -110,6 +102,16 @@ paths:
|
||||||
description: The maximum number of messages to return for each room.
|
description: The maximum number of messages to return for each room.
|
||||||
required: false
|
required: false
|
||||||
x-example: "2"
|
x-example: "2"
|
||||||
|
- in: query
|
||||||
|
type: boolean
|
||||||
|
name: archived
|
||||||
|
description: |-
|
||||||
|
Whether to include rooms that the user has left. If ``false`` then
|
||||||
|
only rooms that the user has been invited to or has joined are
|
||||||
|
included. If set to ``true`` then rooms that the user has left are
|
||||||
|
included as well. By default this is ``false``.
|
||||||
|
required: false
|
||||||
|
x-example: "true"
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: The user's current state.
|
description: The user's current state.
|
||||||
|
|
101
api/client-server/v2_alpha/registration.yaml
Normal file
101
api/client-server/v2_alpha/registration.yaml
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
swagger: '2.0'
|
||||||
|
info:
|
||||||
|
title: "Matrix Client-Server v2 Registration API"
|
||||||
|
version: "1.0.0"
|
||||||
|
host: localhost:8008
|
||||||
|
schemes:
|
||||||
|
- https
|
||||||
|
- http
|
||||||
|
basePath: /_matrix/client/api/v2_alpha
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
paths:
|
||||||
|
"/register":
|
||||||
|
post:
|
||||||
|
summary: Register for an account on this homeserver.
|
||||||
|
description: |-
|
||||||
|
Register for an account on this homeserver.
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
example: |-
|
||||||
|
{
|
||||||
|
"username": "cheeky_monkey",
|
||||||
|
"password": "ilovebananas",
|
||||||
|
"bind_email": false
|
||||||
|
}
|
||||||
|
properties:
|
||||||
|
bind_email:
|
||||||
|
type: boolean
|
||||||
|
description: |-
|
||||||
|
If true, the server binds the email used for authentication to
|
||||||
|
the Matrix ID with the ID Server.
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
The local part of the desired Matrix ID. If omitted,
|
||||||
|
the homeserver MUST generate a Matrix ID local part.
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
description: The desired password for the account.
|
||||||
|
required: ["password"]
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: The account has been registered.
|
||||||
|
examples:
|
||||||
|
application/json: |-
|
||||||
|
{
|
||||||
|
"user_id": "@cheeky_monkey:matrix.org",
|
||||||
|
"access_token": "abc123",
|
||||||
|
"home_server": "matrix.org",
|
||||||
|
"refresh_token": "def456"
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
user_id:
|
||||||
|
type: string
|
||||||
|
description: The fully-qualified Matrix ID that has been registered.
|
||||||
|
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``.
|
||||||
|
There is no specific error message to indicate that a request has failed because
|
||||||
|
an access token has expired; instead, if a client has reason to believe its
|
||||||
|
access token is valid, and it receives an auth error, they should attempt to
|
||||||
|
refresh for a new token on failure, and retry the request with the new token.
|
||||||
|
refresh_token:
|
||||||
|
type: string
|
||||||
|
# TODO: Work out how to linkify /tokenrefresh
|
||||||
|
description: |-
|
||||||
|
(optional) A ``refresh_token`` may be exchanged for a new ``access_token`` using the /tokenrefresh API endpoint.
|
||||||
|
home_server:
|
||||||
|
type: string
|
||||||
|
description: The hostname of the Home Server on which the account has been registered.
|
||||||
|
400:
|
||||||
|
description: |-
|
||||||
|
Part of the request was invalid. This may include one of the following error codes:
|
||||||
|
|
||||||
|
* ``M_USER_IN_USE`` : The desired user ID is already taken.
|
||||||
|
* ``M_EXCLUSIVE`` : The desired user ID is in the exclusive namespace
|
||||||
|
claimed by an application service.
|
||||||
|
|
||||||
|
These errors may be returned at any stage of the registration process,
|
||||||
|
including after authentication if the requested user ID was registered
|
||||||
|
whilst the client was performing authentication.
|
||||||
|
examples:
|
||||||
|
application/json: |-
|
||||||
|
{
|
||||||
|
"errcode": "M_USER_IN_USE",
|
||||||
|
"error": "Desired user ID is already taken."
|
||||||
|
}
|
||||||
|
429:
|
||||||
|
description: This request was rate-limited.
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/error.yaml"
|
|
@ -1,5 +1,11 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -e
|
||||||
# Runs z-schema over all of the schema files (looking for matching examples)
|
# Runs z-schema over all of the schema files (looking for matching examples)
|
||||||
|
|
||||||
|
if ! which z-schema; then
|
||||||
|
echo >&2 "Need to install z-schema; run: sudo npm install -g z-schema"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
find schema/v1/m.* | while read line
|
find schema/v1/m.* | while read line
|
||||||
do
|
do
|
||||||
split_path=(${line///// })
|
split_path=(${line///// })
|
||||||
|
|
18
event-schemas/examples/v1/m.room.avatar
Normal file
18
event-schemas/examples/v1/m.room.avatar
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"age": 242352,
|
||||||
|
"content": {
|
||||||
|
"info": {
|
||||||
|
"h": 398,
|
||||||
|
"w": 394,
|
||||||
|
"mimetype": "image/jpeg",
|
||||||
|
"size": 31037
|
||||||
|
},
|
||||||
|
"url": "mxc://localhost/JWEIFJgwEIhweiWJE"
|
||||||
|
},
|
||||||
|
"origin_server_ts": 1431961217939,
|
||||||
|
"event_id": "$WLGTSEFSEF:localhost",
|
||||||
|
"type": "m.room.avatar",
|
||||||
|
"state_key": "",
|
||||||
|
"room_id": "!Cuyf34gef24t:localhost",
|
||||||
|
"user_id": "@example:localhost"
|
||||||
|
}
|
|
@ -8,10 +8,34 @@
|
||||||
"token": "pc98",
|
"token": "pc98",
|
||||||
"public_key": "abc123",
|
"public_key": "abc123",
|
||||||
"key_validity_url": "https://magic.forest/verifykey",
|
"key_validity_url": "https://magic.forest/verifykey",
|
||||||
"signature": "q1w2e3",
|
"signed": {
|
||||||
|
"mxid": "@alice:localhost",
|
||||||
|
"token": "pc98",
|
||||||
|
"signatures": {
|
||||||
|
"magic.forest": {
|
||||||
|
"ed25519:0": "poi098"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"sender": "@zun:zun.soft"
|
"sender": "@zun:zun.soft"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"invite_room_state": [
|
||||||
|
{
|
||||||
|
"type": "m.room.name",
|
||||||
|
"state_key": "",
|
||||||
|
"content": {
|
||||||
|
"name": "Forest of Magic"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "m.room.join_rules",
|
||||||
|
"state_key": "",
|
||||||
|
"content": {
|
||||||
|
"join_rules": "invite"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"state_key": "@alice:localhost",
|
"state_key": "@alice:localhost",
|
||||||
"origin_server_ts": 1431961217939,
|
"origin_server_ts": 1431961217939,
|
||||||
"event_id": "$WLGTSEFSEF:localhost",
|
"event_id": "$WLGTSEFSEF:localhost",
|
||||||
|
|
64
event-schemas/schema/v1/m.room.avatar
Normal file
64
event-schemas/schema/v1/m.room.avatar
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
{
|
||||||
|
"title": "RoomAvatar",
|
||||||
|
"description": "A picture that is associated with the room. This can be displayed alongside the room information.",
|
||||||
|
"type": "object",
|
||||||
|
"allOf": [{
|
||||||
|
"$ref": "core-event-schema/state_event.json"
|
||||||
|
}],
|
||||||
|
"properties": {
|
||||||
|
"content": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"url": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The URL to the image."
|
||||||
|
},
|
||||||
|
"thumbnail_url": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The URL to the thumbnail of the image."
|
||||||
|
},
|
||||||
|
"thumbnail_info": {
|
||||||
|
"type": "object",
|
||||||
|
"title": "ImageInfo",
|
||||||
|
"description": "Metadata about the image referred to in ``thumbnail_url``.",
|
||||||
|
"allOf": [{
|
||||||
|
"$ref": "core-event-schema/msgtype_infos/image_info.json"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"info": {
|
||||||
|
"type": "object",
|
||||||
|
"title": "ImageInfo",
|
||||||
|
"description": "Metadata about the image referred to in ``url``.",
|
||||||
|
"properties": {
|
||||||
|
"size": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "Size of the image in bytes."
|
||||||
|
},
|
||||||
|
"w": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "The width of the image in pixels."
|
||||||
|
},
|
||||||
|
"h": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "The height of the image in pixels."
|
||||||
|
},
|
||||||
|
"mimetype": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The mimetype of the image, e.g. ``image/jpeg``."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["url"]
|
||||||
|
},
|
||||||
|
"state_key": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "A zero-length string.",
|
||||||
|
"pattern": "^$"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["m.room.avatar"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"title": "The current membership state of a user in the room.",
|
"title": "The current membership state of a user in the room.",
|
||||||
"description": "Adjusts the membership state for a user in a room. It is preferable to use the membership APIs (``/rooms/<room id>/invite`` etc) when performing membership actions rather than adjusting the state directly as there are a restricted set of valid transformations. For example, user A cannot force user B to join a room, and trying to force this state change directly will fail. The ``third_party_invite`` property will be set if the invite was an ``m.room.third_party_invite`` event, and absent if the invite was an ``m.room.member`` event.",
|
"description": "Adjusts the membership state for a user in a room. It is preferable to use the membership APIs (``/rooms/<room id>/invite`` etc) when performing membership actions rather than adjusting the state directly as there are a restricted set of valid transformations. For example, user A cannot force user B to join a room, and trying to force this state change directly will fail. \n\nThe ``third_party_invite`` property will be set if the invite was an ``m.room.third_party_invite`` event, and absent if the invite was an ``m.room.member`` event.\n\nThis event also includes an ``invite_room_state`` key **outside the** ``content`` **key**. This contains an array of ``StrippedState`` Events. These events provide information on a few select state events such as the room name.",
|
||||||
"allOf": [{
|
"allOf": [{
|
||||||
"$ref": "core-event-schema/state_event.json"
|
"$ref": "core-event-schema/state_event.json"
|
||||||
}],
|
}],
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
},
|
},
|
||||||
"third_party_invite": {
|
"third_party_invite": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"title": "invite",
|
"title": "Invite",
|
||||||
"properties": {
|
"properties": {
|
||||||
"token": {
|
"token": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
@ -38,16 +38,32 @@
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "A base64-encoded ed25519 key with which token must be signed."
|
"description": "A base64-encoded ed25519 key with which token must be signed."
|
||||||
},
|
},
|
||||||
"signature": {
|
"signed": {
|
||||||
|
"type": "object",
|
||||||
|
"title": "signed",
|
||||||
|
"properties": {
|
||||||
|
"mxid": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "A base64-encoded signature of token with public_key."
|
"description": "The invited matrix user ID. Must be equal to the user_id property of the event."
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The token property of the containing third_party_invite object."
|
||||||
|
},
|
||||||
|
"signatures": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "A single signature from the verifying server, in the format specified by the Signing Events section.",
|
||||||
|
"title": "Signatures"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["mxid", "signatures", "token"]
|
||||||
},
|
},
|
||||||
"sender": {
|
"sender": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The matrix user ID of the user who send the invite which is being used."
|
"description": "The matrix user ID of the user who send the invite which is being used."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["token", "key_validity_url", "public_key", "signature", "sender"]
|
"required": ["token", "key_validity_url", "public_key", "sender", "signed"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["membership"]
|
"required": ["membership"]
|
||||||
|
@ -65,17 +81,23 @@
|
||||||
"description": "A subset of the state of the room at the time of the invite, if ``membership`` is ``invite``",
|
"description": "A subset of the state of the room at the time of the invite, if ``membership`` is ``invite``",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"title": "StateEvent",
|
"title": "StrippedState",
|
||||||
"description": "A stripped down state event, with only the ``type``, ``state_key`` and ``content`` keys.",
|
"description": "A stripped down state event, with only the ``type``, ``state_key`` and ``content`` keys.",
|
||||||
|
"required": ["type", "state_key", "content"],
|
||||||
"properties": {
|
"properties": {
|
||||||
"type": {
|
"type": {
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"description": "The ``type`` for the event.",
|
||||||
|
"enum": ["m.room.join_rules", "m.room.canonical_alias", "m.room.avatar", "m.room.name"]
|
||||||
},
|
},
|
||||||
"state_key": {
|
"state_key": {
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"description": "The ``state_key`` for the event."
|
||||||
},
|
},
|
||||||
"content": {
|
"content": {
|
||||||
"type": "object"
|
"title": "EventContent",
|
||||||
|
"type": "object",
|
||||||
|
"description": "The ``content`` for the event."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ Threat: Unrecoverable Consistency Violations
|
||||||
++++++++++++++++++++++++++++++++++++++++++++
|
++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
An attacker could send messages which created an unrecoverable "split-brain"
|
An attacker could send messages which created an unrecoverable "split-brain"
|
||||||
state in the cluster such that the victim's servers could no longer dervive a
|
state in the cluster such that the victim's servers could no longer derive a
|
||||||
consistent view of the chatroom state.
|
consistent view of the chatroom state.
|
||||||
|
|
||||||
Threat: Bad History
|
Threat: Bad History
|
||||||
|
@ -63,7 +63,7 @@ Spoofing
|
||||||
An attacker could try to send a message claiming to be from the victim without
|
An attacker could try to send a message claiming to be from the victim without
|
||||||
the victim having sent the message in order to:
|
the victim having sent the message in order to:
|
||||||
|
|
||||||
* Impersonate the victim while performing illict activity.
|
* Impersonate the victim while performing illicit activity.
|
||||||
* Obtain privileges of the victim.
|
* Obtain privileges of the victim.
|
||||||
|
|
||||||
Threat: Altering Message Contents
|
Threat: Altering Message Contents
|
||||||
|
@ -81,7 +81,7 @@ with a phony "origin" field.
|
||||||
Spamming
|
Spamming
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
||||||
The attacker could try to send a high volume of solicicted or unsolicted
|
The attacker could try to send a high volume of solicited or unsolicited
|
||||||
messages to the victim in order to:
|
messages to the victim in order to:
|
||||||
|
|
||||||
* Find victims for scams.
|
* Find victims for scams.
|
|
@ -147,6 +147,9 @@ application services MUST implement these APIs. These APIs are defined below.
|
||||||
|
|
||||||
{{application_service_http_api}}
|
{{application_service_http_api}}
|
||||||
|
|
||||||
|
|
||||||
|
.. _create the user: `sect:asapi-permissions`_
|
||||||
|
|
||||||
Client-Server v2 API Extensions
|
Client-Server v2 API Extensions
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -165,11 +168,8 @@ additional permissions granting the AS permission to masquerade as a matrix user
|
||||||
|
|
||||||
Inputs:
|
Inputs:
|
||||||
- Application service token (``access_token``)
|
- Application service token (``access_token``)
|
||||||
|
|
||||||
Either:
|
|
||||||
- User ID in the AS namespace to act as.
|
- User ID in the AS namespace to act as.
|
||||||
Or:
|
|
||||||
- OAuth2 token of real user (which may end up being an access token)
|
|
||||||
Notes:
|
Notes:
|
||||||
- This will apply on all aspects of the CS API, except for Account Management.
|
- This will apply on all aspects of the CS API, except for Account Management.
|
||||||
- The ``as_token`` is inserted into ``access_token`` which is usually where the
|
- The ``as_token`` is inserted into ``access_token`` which is usually where the
|
||||||
|
@ -184,12 +184,6 @@ Notes:
|
||||||
access_token: The application service token
|
access_token: The application service token
|
||||||
user_id: The desired user ID to act as.
|
user_id: The desired user ID to act as.
|
||||||
|
|
||||||
/path?access_token=$token&user_token=$token
|
|
||||||
|
|
||||||
Query Parameters:
|
|
||||||
access_token: The application service token
|
|
||||||
user_token: The token granted to the AS by the real user
|
|
||||||
|
|
||||||
Timestamp massaging
|
Timestamp massaging
|
||||||
+++++++++++++++++++
|
+++++++++++++++++++
|
||||||
The application service may want to inject events at a certain time (reflecting
|
The application service may want to inject events at a certain time (reflecting
|
||||||
|
@ -212,6 +206,9 @@ Notes:
|
||||||
|
|
||||||
Server admin style permissions
|
Server admin style permissions
|
||||||
++++++++++++++++++++++++++++++
|
++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
.. _sect:asapi-permissions:
|
||||||
|
|
||||||
The home server needs to give the application service *full control* over its
|
The home server needs to give the application service *full control* over its
|
||||||
namespace, both for users and for room aliases. This means that the AS should
|
namespace, both for users and for room aliases. This means that the AS should
|
||||||
be able to create/edit/delete any room alias in its namespace, as well as
|
be able to create/edit/delete any room alias in its namespace, as well as
|
||||||
|
@ -238,7 +235,7 @@ including the AS token on a ``/register`` request, along with a login type of
|
||||||
|
|
||||||
Application services which attempt to create users or aliases *outside* of
|
Application services which attempt to create users or aliases *outside* of
|
||||||
their defined namespaces will receive an error code ``M_EXCLUSIVE``. Similarly,
|
their defined namespaces will receive an error code ``M_EXCLUSIVE``. Similarly,
|
||||||
normal users who attempt to create users or alises *inside* an application
|
normal users who attempt to create users or aliases *inside* an application
|
||||||
service-defined namespace will receive the same ``M_EXCLUSIVE`` error code,
|
service-defined namespace will receive the same ``M_EXCLUSIVE`` error code,
|
||||||
but only if the application service has defined the namespace as ``exclusive``.
|
but only if the application service has defined the namespace as ``exclusive``.
|
||||||
|
|
||||||
|
@ -291,9 +288,10 @@ an API is exposed.
|
||||||
Room Aliases
|
Room Aliases
|
||||||
++++++++++++
|
++++++++++++
|
||||||
We may want to expose some 3P network rooms so Matrix users can join them directly,
|
We may want to expose some 3P network rooms so Matrix users can join them directly,
|
||||||
e.g. IRC rooms. We don't want to expose every 3P network room though, e.g. mailto,
|
e.g. IRC rooms. We don't want to expose every 3P network room though, e.g.
|
||||||
tel. Rooms which are publicly accessible (e.g. IRC rooms) can be exposed as an alias by
|
``mailto``, ``tel``. Rooms which are publicly accessible (e.g. IRC rooms) can be
|
||||||
the application service. Private rooms (e.g. sending an email to someone) should not
|
exposed as an alias by the application service. Private rooms
|
||||||
|
(e.g. sending an email to someone) should not
|
||||||
be exposed in this way, but should instead operate using normal invite/join semantics.
|
be exposed in this way, but should instead operate using normal invite/join semantics.
|
||||||
Therefore, the ID conventions discussed below are only valid for public rooms which
|
Therefore, the ID conventions discussed below are only valid for public rooms which
|
||||||
expose room aliases.
|
expose room aliases.
|
||||||
|
@ -313,9 +311,9 @@ SHOULD be mapped in the same way as "user" URIs.
|
||||||
|
|
||||||
Event fields
|
Event fields
|
||||||
++++++++++++
|
++++++++++++
|
||||||
We recommend that any gatewayed events should include an ``external_url`` field
|
We recommend that any events that originated from a remote network should
|
||||||
in their content to provide a way for Matrix clients to link into the 'native'
|
include an ``external_url`` field in their content to provide a way for Matrix
|
||||||
client from which the event originated. For instance, this could contain the
|
clients to link into the 'native' client from which the event originated.
|
||||||
message-ID for emails/nntp posts, or a link to a blog comment when gatewaying
|
For instance, this could contain the message-ID for emails/nntp posts, or a link
|
||||||
blog comment traffic in & out of matrix
|
to a blog comment when bridging blog comment traffic in & out of Matrix.
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
Client-Server API
|
Client-Server API
|
||||||
=================
|
=================
|
||||||
|
|
||||||
Overview
|
|
||||||
--------
|
|
||||||
|
|
||||||
The client-server API provides a simple lightweight API to let clients send
|
The client-server API provides a simple lightweight API to let clients send
|
||||||
messages, control rooms and synchronise conversation history. It is designed to
|
messages, control rooms and synchronise conversation history. It is designed to
|
||||||
support both lightweight clients which store no state and lazy-load data from
|
support both lightweight clients which store no state and lazy-load data from
|
||||||
|
@ -31,7 +28,10 @@ return with a status of 401 and the error code, ``M_MISSING_TOKEN`` or
|
||||||
``M_UNKNOWN_TOKEN`` respectively.
|
``M_UNKNOWN_TOKEN`` respectively.
|
||||||
|
|
||||||
User-Interactive Authentication API
|
User-Interactive Authentication API
|
||||||
-----------------------------------
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. _sect:auth-api:
|
||||||
|
|
||||||
This section refers to API Version 2.
|
This section refers to API Version 2.
|
||||||
|
|
||||||
Some API endpoints such as ``login`` or ``register`` require authentication that
|
Some API endpoints such as ``login`` or ``register`` require authentication that
|
||||||
|
@ -159,7 +159,7 @@ absence of that login stage type in the 'completed' array indicating whether
|
||||||
that stage is complete.
|
that stage is complete.
|
||||||
|
|
||||||
Example
|
Example
|
||||||
~~~~~~~
|
+++++++
|
||||||
At a high level, the requests made for an API call completing an auth flow with
|
At a high level, the requests made for an API call completing an auth flow with
|
||||||
three stages will resemble the following diagram::
|
three stages will resemble the following diagram::
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ This specification defines the following login types:
|
||||||
- ``m.login.dummy``
|
- ``m.login.dummy``
|
||||||
|
|
||||||
Password-based
|
Password-based
|
||||||
~~~~~~~~~~~~~~
|
++++++++++++++
|
||||||
:Type:
|
:Type:
|
||||||
``m.login.password``
|
``m.login.password``
|
||||||
:Description:
|
:Description:
|
||||||
|
@ -222,7 +222,7 @@ To respond to this type, reply with an auth dict as follows::
|
||||||
weak passwords with an error code ``M_WEAK_PASSWORD``.
|
weak passwords with an error code ``M_WEAK_PASSWORD``.
|
||||||
|
|
||||||
Google ReCaptcha
|
Google ReCaptcha
|
||||||
~~~~~~~~~~~~~~~~
|
++++++++++++++++
|
||||||
:Type:
|
:Type:
|
||||||
``m.login.recaptcha``
|
``m.login.recaptcha``
|
||||||
:Description:
|
:Description:
|
||||||
|
@ -236,7 +236,7 @@ To respond to this type, reply with an auth dict as follows::
|
||||||
}
|
}
|
||||||
|
|
||||||
Token-based
|
Token-based
|
||||||
~~~~~~~~~~~
|
+++++++++++
|
||||||
:Type:
|
:Type:
|
||||||
``m.login.token``
|
``m.login.token``
|
||||||
:Description:
|
:Description:
|
||||||
|
@ -267,7 +267,7 @@ newly provisioned access_token).
|
||||||
The ``token`` must be a macaroon.
|
The ``token`` must be a macaroon.
|
||||||
|
|
||||||
OAuth2-based
|
OAuth2-based
|
||||||
~~~~~~~~~~~~
|
++++++++++++
|
||||||
:Type:
|
:Type:
|
||||||
``m.login.oauth2``
|
``m.login.oauth2``
|
||||||
:Description:
|
:Description:
|
||||||
|
@ -291,7 +291,7 @@ the OAuth flow has completed, the client retries the request with the session
|
||||||
only, as above.
|
only, as above.
|
||||||
|
|
||||||
Email-based (identity server)
|
Email-based (identity server)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
+++++++++++++++++++++++++++++
|
||||||
:Type:
|
:Type:
|
||||||
``m.login.email.identity``
|
``m.login.email.identity``
|
||||||
:Description:
|
:Description:
|
||||||
|
@ -316,7 +316,7 @@ To respond to this type, reply with an auth dict as follows::
|
||||||
}
|
}
|
||||||
|
|
||||||
Dummy Auth
|
Dummy Auth
|
||||||
~~~~~~~~~~
|
++++++++++
|
||||||
:Type:
|
:Type:
|
||||||
``m.login.dummy``
|
``m.login.dummy``
|
||||||
:Description:
|
:Description:
|
||||||
|
@ -333,7 +333,7 @@ if provided::
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
|
@ -349,16 +349,169 @@ 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 attempt to call the JavaScript function ``window.onAuthDone`` when
|
||||||
the authentication has been completed.
|
the authentication has been completed.
|
||||||
|
|
||||||
|
Registration
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
This section refers to API Version 2. These API calls currently use the prefix
|
||||||
|
``/_matrix/client/v2_alpha``.
|
||||||
|
|
||||||
|
Registering for a user account is done using the request::
|
||||||
|
|
||||||
|
POST $V2PREFIX/register
|
||||||
|
|
||||||
|
This API endpoint uses the `User-Interactive Authentication API`_.
|
||||||
|
This API endpoint does not require an access token.
|
||||||
|
|
||||||
|
.. _User-Interactive Authentication API: `sect:auth-api`_
|
||||||
|
|
||||||
|
The body of the POST request is a JSON object containing:
|
||||||
|
|
||||||
|
username
|
||||||
|
Optional. This is the local part of the desired Matrix ID. If omitted, the
|
||||||
|
Home Server must generate a Matrix ID local part.
|
||||||
|
password
|
||||||
|
Required. The desired password for the account.
|
||||||
|
bind_email
|
||||||
|
Optional. If ``true``, the server binds the email used for authentication to
|
||||||
|
the Matrix ID with the ID Server.
|
||||||
|
|
||||||
|
On success, this returns a JSON object with keys:
|
||||||
|
|
||||||
|
user_id
|
||||||
|
The fully-qualified Matrix ID that has been registered.
|
||||||
|
access_token
|
||||||
|
An access token for the new account.
|
||||||
|
home_server
|
||||||
|
The hostname of the Home Server on which the account has been registered.
|
||||||
|
refresh_token
|
||||||
|
A token that may be exchanged for a new ``access_token`` using the
|
||||||
|
``/tokenrefresh`` API endpoint.
|
||||||
|
|
||||||
|
This endpoint may also return the following error codes:
|
||||||
|
|
||||||
|
M_USER_IN_USE
|
||||||
|
If the Matrix ID is already in use
|
||||||
|
M_EXCLUSIVE
|
||||||
|
If the requested Matrix ID is in the exclusive namespace of an application
|
||||||
|
service.
|
||||||
|
|
||||||
|
Home Servers MUST perform the relevant checks and return these codes before
|
||||||
|
performing `User-Interactive Authentication`_, although they may also return
|
||||||
|
them after authentication is completed if, for example, the requested user ID
|
||||||
|
was registered whilst the client was performing authentication.
|
||||||
|
|
||||||
|
.. _User-Interactive Authentication: `sect:auth-api`_
|
||||||
|
|
||||||
|
Old V1 API docs: |register|_
|
||||||
|
|
||||||
|
{{login_http_api}}
|
||||||
|
|
||||||
|
Changing Password
|
||||||
|
+++++++++++++++++
|
||||||
|
This section refers to API Version 2. These API calls currently use the prefix
|
||||||
|
``/_matrix/client/v2_alpha``.
|
||||||
|
|
||||||
|
Request::
|
||||||
|
|
||||||
|
POST $V2PREFIX/account/password
|
||||||
|
|
||||||
|
This API endpoint uses the User-Interactive Authentication API. An access token
|
||||||
|
should be submitted to this endpoint if the client has an active session. The
|
||||||
|
Home Server may change the flows available depending on whether a valid access
|
||||||
|
token is provided.
|
||||||
|
|
||||||
|
The body of the POST request is a JSON object containing:
|
||||||
|
|
||||||
|
new_password
|
||||||
|
The new password for the account.
|
||||||
|
|
||||||
|
On success, an empty JSON object is returned.
|
||||||
|
|
||||||
|
The error code M_NOT_FOUND is returned if the user authenticated with a third
|
||||||
|
party identifier but the Home Server could not find a matching account in its
|
||||||
|
database.
|
||||||
|
|
||||||
|
Adding Account Administrative Contact Information
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
This section refers to API Version 2. These API calls currently use the prefix
|
||||||
|
``/_matrix/client/v2_alpha``.
|
||||||
|
|
||||||
|
Request::
|
||||||
|
|
||||||
|
POST $V2PREFIX/account/3pid
|
||||||
|
|
||||||
|
Used to add contact information to the user's account.
|
||||||
|
|
||||||
|
The body of the POST request is a JSON object containing:
|
||||||
|
|
||||||
|
threePidCreds
|
||||||
|
An object containing contact information.
|
||||||
|
bind
|
||||||
|
Optional. A boolean indicating whether the Home Server should also bind this
|
||||||
|
third party identifier to the account's matrix ID with the Identity Server. If
|
||||||
|
supplied and true, the Home Server must bind the 3pid accordingly.
|
||||||
|
|
||||||
|
The contact information object comprises:
|
||||||
|
|
||||||
|
id_server
|
||||||
|
The colon-separated hostname and port of the Identity Server used to
|
||||||
|
authenticate the third party identifier. If the port is the default, it and the
|
||||||
|
colon should be omitted.
|
||||||
|
sid
|
||||||
|
The session ID given by the Identity Server
|
||||||
|
client_secret
|
||||||
|
The client secret used in the session with the Identity Server.
|
||||||
|
|
||||||
|
On success, the empty JSON object is returned.
|
||||||
|
|
||||||
|
May also return error codes:
|
||||||
|
|
||||||
|
M_THREEPID_AUTH_FAILED
|
||||||
|
If the credentials provided could not be verified with the ID Server.
|
||||||
|
|
||||||
|
Fetching Currently Associated Contact Information
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
This section refers to API Version 2. These API calls currently use the prefix
|
||||||
|
``/_matrix/client/v2_alpha``.
|
||||||
|
|
||||||
|
Request::
|
||||||
|
|
||||||
|
GET $V2PREFIX/account/3pid
|
||||||
|
|
||||||
|
This returns a list of third party identifiers that the Home Server has
|
||||||
|
associated with the user's account. This is *not* the same as the list of third
|
||||||
|
party identifiers bound to the user's Matrix ID in Identity Servers. Identifiers
|
||||||
|
in this list may be used by the Home Server as, for example, identifiers that it
|
||||||
|
will accept to reset the user's account password.
|
||||||
|
|
||||||
|
Returns a JSON object with the key ``threepids`` whose contents is an array of
|
||||||
|
objects with the following keys:
|
||||||
|
|
||||||
|
medium
|
||||||
|
The medium of the 3pid (eg, ``email``)
|
||||||
|
address
|
||||||
|
The textual address of the 3pid, eg. the email address
|
||||||
|
|
||||||
Pagination
|
Pagination
|
||||||
----------
|
----------
|
||||||
|
|
||||||
Querying large datasets in Matrix always uses the same pagination API pattern to
|
.. NOTE::
|
||||||
|
The paths referred to in this section are not actual endpoints. They only
|
||||||
|
serve as examples to explain how pagination functions.
|
||||||
|
|
||||||
|
Pagination is the process of dividing a dataset into multiple discrete pages.
|
||||||
|
Matrix makes use of pagination to allow clients to view extremely large datasets.
|
||||||
|
These datasets are not limited to events in a room (for example clients may want
|
||||||
|
to paginate a list of rooms in addition to events within those rooms). Regardless
|
||||||
|
of *what* is being paginated, there is a common underlying API which is used to
|
||||||
to give clients a consistent way of selecting subsets of a potentially changing
|
to give clients a consistent way of selecting subsets of a potentially changing
|
||||||
dataset. Requests pass in ``from``, ``to`` and ``limit`` parameters which describe
|
dataset. Requests pass in ``from``, ``to``, ``dir`` and ``limit`` parameters
|
||||||
where to read from the stream. ``from`` and ``to`` are opaque textual 'stream
|
which describe where to read from the stream. ``from`` and ``to`` are opaque
|
||||||
tokens' which describe positions in the dataset. The response returns new
|
textual 'stream tokens' which describe the current position in the dataset.
|
||||||
``start`` and ``end`` stream token values which can then be passed to subsequent
|
The ``dir`` parameter is an enum representing the direction of events to return:
|
||||||
requests to continue pagination.
|
either ``f`` orwards or ``b`` ackwards. The response returns new ``start`` and
|
||||||
|
``end`` stream token values which can then be passed to subsequent requests to
|
||||||
|
continue pagination. Not all endpoints will make use of all the parameters
|
||||||
|
outlined here: see the specific endpoint in question for more information.
|
||||||
|
|
||||||
Pagination Request Query Parameters
|
Pagination Request Query Parameters
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -373,24 +526,26 @@ Query parameters:
|
||||||
limit:
|
limit:
|
||||||
integer - An integer representing the maximum number of items to
|
integer - An integer representing the maximum number of items to
|
||||||
return.
|
return.
|
||||||
|
dir:
|
||||||
|
f|b - The direction to return events in. Typically this is ``b`` to paginate
|
||||||
|
backwards in time.
|
||||||
|
|
||||||
'START' and 'END' are placeholder values used in these examples to describe the
|
'START' and 'END' are placeholder values used in these examples to describe the
|
||||||
start and end of the dataset respectively.
|
start and end of the dataset respectively.
|
||||||
|
|
||||||
Unless specified, the default pagination parameters are from=START, to=END,
|
Unless specified, the default pagination parameters are ``from=START``,
|
||||||
without a limit set. This allows you to hit an API like
|
``to=END``, without a limit set.
|
||||||
/events without any query parameters to get everything.
|
|
||||||
|
|
||||||
For example, the event stream has events E1 -> E15. The client wants the last 5
|
For example, if an endpoint had events E1 -> E15. The client wants the last 5
|
||||||
events and doesn't know any previous events::
|
events and doesn't know any previous events::
|
||||||
|
|
||||||
S E
|
S E
|
||||||
|-E1-E2-E3-E4-E5-E6-E7-E8-E9-E10-E11-E12-E13-E14-E15-|
|
|-E1-E2-E3-E4-E5-E6-E7-E8-E9-E10-E11-E12-E13-E14-E15-|
|
||||||
| | |
|
| | |
|
||||||
| _____| |
|
| _____| <--backwards-- |
|
||||||
|__________________ | ___________________|
|
|__________________ | | ________|
|
||||||
| | |
|
| | | |
|
||||||
GET /events?to=START&limit=5&from=END
|
GET /somepath?to=START&limit=5&dir=b&from=END
|
||||||
Returns:
|
Returns:
|
||||||
E15,E14,E13,E12,E11
|
E15,E14,E13,E12,E11
|
||||||
|
|
||||||
|
@ -407,7 +562,7 @@ now show page 3 (rooms R11 -> 15)::
|
||||||
Currently |
|
Currently |
|
||||||
viewing |
|
viewing |
|
||||||
|
|
|
|
||||||
GET /rooms/list?from=9&to=END&limit=5
|
GET /roomslist?from=9&to=END&limit=5
|
||||||
Returns: R11,R12,R13,R14,R15
|
Returns: R11,R12,R13,R14,R15
|
||||||
|
|
||||||
Note that tokens are treated in an *exclusive*, not inclusive, manner. The end
|
Note that tokens are treated in an *exclusive*, not inclusive, manner. The end
|
||||||
|
@ -435,9 +590,6 @@ Events
|
||||||
|
|
||||||
.. _sect:events:
|
.. _sect:events:
|
||||||
|
|
||||||
Overview
|
|
||||||
~~~~~~~~
|
|
||||||
|
|
||||||
The model of conversation history exposed by the client-server API can be
|
The model of conversation history exposed by the client-server API can be
|
||||||
considered as a list of events. The server 'linearises' the
|
considered as a list of events. The server 'linearises' the
|
||||||
eventually-consistent event graph of events into an 'event stream' at any given
|
eventually-consistent event graph of events into an 'event stream' at any given
|
||||||
|
@ -465,7 +617,7 @@ You can visualise the range of events being returned as::
|
||||||
| |
|
| |
|
||||||
start: '1-2-3' end: 'a-b-c'
|
start: '1-2-3' end: 'a-b-c'
|
||||||
|
|
||||||
Now, to receive future events in real-time on the eventstream, you simply GET
|
Now, to receive future events in real-time on the event stream, you simply GET
|
||||||
$PREFIX/events with a ``from`` parameter of 'a-b-c': in other words passing in the
|
$PREFIX/events with a ``from`` parameter of 'a-b-c': in other words passing in the
|
||||||
``end`` token returned by initial sync. The request blocks until new events are
|
``end`` token returned by initial sync. The request blocks until new events are
|
||||||
available or until your specified timeout elapses, and then returns a
|
available or until your specified timeout elapses, and then returns a
|
||||||
|
@ -495,34 +647,36 @@ To continue paginating backwards, one calls the /messages API again, supplying
|
||||||
the new ``start`` value as the ``from`` parameter.
|
the new ``start`` value as the ``from`` parameter.
|
||||||
|
|
||||||
|
|
||||||
Receiving live updates on a client
|
Syncing
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~
|
||||||
|
|
||||||
Clients receive new events by long-polling the home server via the
|
Clients receive new events by "long-polling" the home server via the events API.
|
||||||
$PREFIX/events API, specifying a timeout in milliseconds in the timeout
|
This involves specifying a timeout in the request which will hold
|
||||||
parameter. This will hold open the HTTP connection for a short period of time
|
open the HTTP connection for a short period of time waiting for new events,
|
||||||
waiting for new events, returning early if an event occurs. This is called the
|
returning early if an event occurs. Only the events API supports long-polling.
|
||||||
`Event Stream`_. All events which are visible to the client will appear in the
|
All events which are visible to the client will appear in the
|
||||||
event stream. When the request returns, an ``end`` token is included in the
|
events API. When the request returns, an ``end`` token is included in the
|
||||||
response. This token can be used in the next request to continue where the
|
response. This token can be used in the next request to continue where the
|
||||||
last request left off.
|
last request left off. Multiple events can be returned per long-poll.
|
||||||
|
|
||||||
All events must be de-duplicated based on their event ID.
|
.. Warning::
|
||||||
|
Events are ordered in this API according to the arrival time of the event on
|
||||||
.. TODO
|
the homeserver. This can conflict with other APIs which order events based on
|
||||||
is deduplication actually a hard requirement in CS v2?
|
their partial ordering in the event graph. This can result in duplicate events
|
||||||
|
being received (once per distinct API called). Clients SHOULD de-duplicate
|
||||||
|
events based on the event ID when this happens.
|
||||||
|
|
||||||
.. TODO-spec
|
.. TODO-spec
|
||||||
Do we ever return multiple events in a single request?
|
|
||||||
Don't we get lots of request setup RTT latency if we only do one event per request?
|
|
||||||
Do we ever support streaming requests? Why not websockets?
|
Do we ever support streaming requests? Why not websockets?
|
||||||
|
|
||||||
When the client first logs in, they will need to initially synchronise with
|
When the client first logs in, they will need to initially synchronise with
|
||||||
their home server. This is achieved via the |initialSync|_ API. This API also
|
their home server. This is achieved via the initial sync API described below.
|
||||||
returns an ``end`` token which can be used with the event stream. See the 'Room Sync' section below.
|
This API also returns an ``end`` token which can be used with the event stream.
|
||||||
|
|
||||||
Events in a room
|
{{sync_http_api}}
|
||||||
~~~~~~~~~~~~~~~~
|
|
||||||
|
Types of room events
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Room events are split into two categories:
|
Room events are split into two categories:
|
||||||
|
|
||||||
|
@ -534,7 +688,7 @@ Room events are split into two categories:
|
||||||
:Message events:
|
:Message events:
|
||||||
These are events which describe transient "once-off" activity in a room:
|
These are events which describe transient "once-off" activity in a room:
|
||||||
typically communication such as sending an instant message or setting up a
|
typically communication such as sending an instant message or setting up a
|
||||||
VoIP call. These used to be called 'non-state' events.
|
VoIP call.
|
||||||
|
|
||||||
This specification outlines several events, all with the event type prefix
|
This specification outlines several events, all with the event type prefix
|
||||||
``m.``. However, applications may wish to add their own type of event, and this
|
``m.``. However, applications may wish to add their own type of event, and this
|
||||||
|
@ -544,7 +698,7 @@ convention, e.g. ``com.example.myapp.event``. This ensures event types are
|
||||||
suitably namespaced for each application and reduces the risk of clashes.
|
suitably namespaced for each application and reduces the risk of clashes.
|
||||||
|
|
||||||
State events
|
State events
|
||||||
~~~~~~~~~~~~
|
++++++++++++
|
||||||
|
|
||||||
State events can be sent by ``PUT`` ing to
|
State events can be sent by ``PUT`` ing to
|
||||||
|/rooms/<room_id>/state/<event_type>/<state_key>|_. These events will be
|
|/rooms/<room_id>/state/<event_type>/<state_key>|_. These events will be
|
||||||
|
@ -587,7 +741,7 @@ In some cases, there may be no need for a ``state_key``, so it can be omitted::
|
||||||
See `Room Events`_ for the ``m.`` event specification.
|
See `Room Events`_ for the ``m.`` event specification.
|
||||||
|
|
||||||
Message events
|
Message events
|
||||||
~~~~~~~~~~~~~~
|
++++++++++++++
|
||||||
|
|
||||||
Message events can be sent by sending a request to
|
Message events can be sent by sending a request to
|
||||||
|/rooms/<room_id>/send/<event_type>|_. These requests *can* use transaction
|
|/rooms/<room_id>/send/<event_type>|_. These requests *can* use transaction
|
||||||
|
@ -603,69 +757,6 @@ example::
|
||||||
|
|
||||||
See `Room Events`_ for the ``m.`` event specification.
|
See `Room Events`_ for the ``m.`` event specification.
|
||||||
|
|
||||||
Syncing rooms
|
|
||||||
~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. NOTE::
|
|
||||||
This section is a work in progress.
|
|
||||||
|
|
||||||
When a client logs in, they may have a list of rooms which they have already
|
|
||||||
joined. These rooms may also have a list of events associated with them. The
|
|
||||||
purpose of 'syncing' is to present the current room and event information in a
|
|
||||||
convenient, compact manner. The events returned are not limited to room events;
|
|
||||||
presence events will also be returned. A single syncing API is provided:
|
|
||||||
|
|
||||||
- |initialSync|_ : A global sync which will present room and event information
|
|
||||||
for all rooms the user has joined.
|
|
||||||
|
|
||||||
.. TODO-spec room-scoped initial sync
|
|
||||||
- |/rooms/<room_id>/initialSync|_ : A sync scoped to a single room. Presents
|
|
||||||
room and event information for this room only.
|
|
||||||
- Room-scoped initial sync is Very Tricky because typically people would
|
|
||||||
want to sync the room then listen for any new content from that point
|
|
||||||
onwards. The event stream cannot do this for a single room currently.
|
|
||||||
As a result, commenting room-scoped initial sync at this time.
|
|
||||||
|
|
||||||
The |initialSync|_ API contains the following keys:
|
|
||||||
|
|
||||||
``presence``
|
|
||||||
Description:
|
|
||||||
Contains a list of presence information for users the client is interested
|
|
||||||
in.
|
|
||||||
Format:
|
|
||||||
A JSON array of ``m.presence`` events.
|
|
||||||
|
|
||||||
``end``
|
|
||||||
Description:
|
|
||||||
Contains an event stream token which can be used with the `Event Stream`_.
|
|
||||||
Format:
|
|
||||||
A string containing the event stream token.
|
|
||||||
|
|
||||||
``rooms``
|
|
||||||
Description:
|
|
||||||
Contains a list of room information for all rooms the client has joined,
|
|
||||||
and limited room information on rooms the client has been invited to.
|
|
||||||
Format:
|
|
||||||
A JSON array containing Room Information JSON objects.
|
|
||||||
|
|
||||||
Room Information:
|
|
||||||
Description:
|
|
||||||
Contains all state events for the room, along with a limited amount of
|
|
||||||
the most recent events, configured via the ``limit`` query
|
|
||||||
parameter. Also contains additional keys with room metadata, such as the
|
|
||||||
``room_id`` and the client's ``membership`` to the room.
|
|
||||||
Format:
|
|
||||||
A JSON object with the following keys:
|
|
||||||
``room_id``
|
|
||||||
A string containing the ID of the room being described.
|
|
||||||
``membership``
|
|
||||||
A string representing the client's membership status in this room.
|
|
||||||
``messages``
|
|
||||||
An event stream JSON object containing a ``chunk`` of recent
|
|
||||||
events (both state events and non-state events), along with an ``end`` token.
|
|
||||||
``state``
|
|
||||||
A JSON array containing all the current state events for this room.
|
|
||||||
|
|
||||||
Getting events for a room
|
Getting events for a room
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -673,6 +764,9 @@ There are several APIs provided to ``GET`` events for a room:
|
||||||
|
|
||||||
{{rooms_http_api}}
|
{{rooms_http_api}}
|
||||||
|
|
||||||
|
|
||||||
|
{{message_pagination_http_api}}
|
||||||
|
|
||||||
Redactions
|
Redactions
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
Since events are extensible it is possible for malicious users and/or servers
|
Since events are extensible it is possible for malicious users and/or servers
|
||||||
|
@ -723,140 +817,20 @@ Rooms
|
||||||
|
|
||||||
Creation
|
Creation
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
To create a room, a client has to use the |createRoom|_ API. There are various
|
The home server will create an ``m.room.create`` event when a room is created,
|
||||||
options which can be set when creating a room:
|
which serves as the root of the event graph for this room. This event also has a
|
||||||
|
|
||||||
``visibility``
|
|
||||||
Type:
|
|
||||||
String
|
|
||||||
Optional:
|
|
||||||
Yes
|
|
||||||
Value:
|
|
||||||
Either ``public`` or ``private``.
|
|
||||||
Description:
|
|
||||||
A ``public`` visibility indicates that the room will be shown in the public
|
|
||||||
room list. A ``private`` visibility will hide the room from the public room
|
|
||||||
list. Rooms default to ``private`` visibility if this key is not included.
|
|
||||||
|
|
||||||
``room_alias_name``
|
|
||||||
Type:
|
|
||||||
String
|
|
||||||
Optional:
|
|
||||||
Yes
|
|
||||||
Value:
|
|
||||||
The room alias localpart.
|
|
||||||
Description:
|
|
||||||
If this is included, a room alias will be created and mapped to the newly
|
|
||||||
created room. The alias will belong on the same home server which created
|
|
||||||
the room, e.g. ``!qadnasoi:domain.com >>> #room_alias_name:domain.com``
|
|
||||||
|
|
||||||
``name``
|
|
||||||
Type:
|
|
||||||
String
|
|
||||||
Optional:
|
|
||||||
Yes
|
|
||||||
Value:
|
|
||||||
The ``name`` value for the ``m.room.name`` state event.
|
|
||||||
Description:
|
|
||||||
If this is included, an ``m.room.name`` event will be sent into the room to
|
|
||||||
indicate the name of the room. See `Room Events`_ for more information on
|
|
||||||
``m.room.name``.
|
|
||||||
|
|
||||||
``topic``
|
|
||||||
Type:
|
|
||||||
String
|
|
||||||
Optional:
|
|
||||||
Yes
|
|
||||||
Value:
|
|
||||||
The ``topic`` value for the ``m.room.topic`` state event.
|
|
||||||
Description:
|
|
||||||
If this is included, an ``m.room.topic`` event will be sent into the room
|
|
||||||
to indicate the topic for the room. See `Room Events`_ for more information
|
|
||||||
on ``m.room.topic``.
|
|
||||||
|
|
||||||
``invite``
|
|
||||||
Type:
|
|
||||||
List
|
|
||||||
Optional:
|
|
||||||
Yes
|
|
||||||
Value:
|
|
||||||
A list of user ids to invite.
|
|
||||||
Description:
|
|
||||||
This will tell the server to invite everyone in the list to the newly
|
|
||||||
created room.
|
|
||||||
|
|
||||||
``creation_content``
|
|
||||||
Type:
|
|
||||||
Object
|
|
||||||
Optional:
|
|
||||||
Yes
|
|
||||||
Value:
|
|
||||||
Extra keys to be added to the content of the ``m.room.create``. The server
|
|
||||||
will clober the following keys: ``creator``. Future versions of this
|
|
||||||
spec may allow the server to clobber other keys if required.
|
|
||||||
Description:
|
|
||||||
Allows clients to add keys to the content of ``m.room.create``.
|
|
||||||
|
|
||||||
``preset``
|
|
||||||
Type:
|
|
||||||
String
|
|
||||||
Optional:
|
|
||||||
Yes
|
|
||||||
Value:
|
|
||||||
``private_chat``, ``trusted_private_chat`` or ``public_chat``
|
|
||||||
Description:
|
|
||||||
Convenience parameter for setting various default state events based on a
|
|
||||||
preset.
|
|
||||||
|
|
||||||
Three presets are defined:
|
|
||||||
|
|
||||||
- ``private_chat``: Sets the ``join_rules`` to ``invite`` and
|
|
||||||
``history_visibility`` to ``shared``
|
|
||||||
- ``trusted_private_chat``: Set the ``join_rules`` to ``invite``,
|
|
||||||
``history_visibility`` to ``shared`` and gives all invitees the same
|
|
||||||
power level as the creator.
|
|
||||||
- ``public_chat``: Sets the ``join_rules`` to ``public`` and
|
|
||||||
``history_visibility`` to ``shared``
|
|
||||||
|
|
||||||
``initial_state``
|
|
||||||
Type:
|
|
||||||
List
|
|
||||||
Optional:
|
|
||||||
Yes
|
|
||||||
Value:
|
|
||||||
A list of state events to set in the new room.
|
|
||||||
Description:
|
|
||||||
Allows the user to override the default state events set in the new room.
|
|
||||||
|
|
||||||
The expected format of the state events are an object with ``type``,
|
|
||||||
``state_key`` and ``content`` keys set.
|
|
||||||
|
|
||||||
Takes precedence over events set by ``presets``, but gets overriden by
|
|
||||||
``name`` and ``topic`` keys.
|
|
||||||
|
|
||||||
Example::
|
|
||||||
|
|
||||||
{
|
|
||||||
"preset": "public_chat",
|
|
||||||
"room_alias_name": "thepub",
|
|
||||||
"name": "The Grand Duke Pub",
|
|
||||||
"topic": "All about happy hour",
|
|
||||||
"creation_content": {
|
|
||||||
"m.federate": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
The home server will create a ``m.room.create`` event when the room is created,
|
|
||||||
which serves as the root of the PDU graph for this room. This event also has a
|
|
||||||
``creator`` key which contains the user ID of the room creator. It will also
|
``creator`` key which contains the user ID of the room creator. It will also
|
||||||
generate several other events in order to manage permissions in this room. This
|
generate several other events in order to manage permissions in this room. This
|
||||||
includes:
|
includes:
|
||||||
|
|
||||||
- ``m.room.power_levels`` : Sets the power levels of users and required power
|
- ``m.room.power_levels`` : Sets the power levels of users and required power
|
||||||
levels.
|
levels for various actions within the room such as sending events.
|
||||||
- ``m.room.join_rules`` : Whether the room is "invite-only" or not.
|
- ``m.room.join_rules`` : Whether the room is "invite-only" or not.
|
||||||
|
|
||||||
See `Room Events`_ for more information on these events.
|
See `Room Events`_ for more information on these events. To create a room, a
|
||||||
|
client has to use the the following API.
|
||||||
|
|
||||||
|
{{create_room_http_api}}
|
||||||
|
|
||||||
Room aliases
|
Room aliases
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
@ -921,7 +895,7 @@ certain operations such as kicking, banning and sending state events. See
|
||||||
`m.room.power_levels`_ for more information.
|
`m.room.power_levels`_ for more information.
|
||||||
|
|
||||||
Joining rooms
|
Joining rooms
|
||||||
-------------
|
~~~~~~~~~~~~~
|
||||||
Users need to be a member of a room in order to send and receive events in that
|
Users need to be a member of a room in order to send and receive events in that
|
||||||
room. There are several states in which a user may be, in relation to a room:
|
room. There are several states in which a user may be, in relation to a room:
|
||||||
|
|
||||||
|
@ -931,6 +905,11 @@ room. There are several states in which a user may be, in relation to a room:
|
||||||
- Joined (the user can send and receive events in the room)
|
- Joined (the user can send and receive events in the room)
|
||||||
- Banned (the user is not allowed to join the room)
|
- Banned (the user is not allowed to join the room)
|
||||||
|
|
||||||
|
There is an exception to the requirement that a user join a room before sending
|
||||||
|
events to it: users may send an ``m.room.member`` event to a room with
|
||||||
|
``content.membership`` set to ``leave`` to reject an invitation if they have
|
||||||
|
currently been invited to a room but have not joined it.
|
||||||
|
|
||||||
Some rooms require that users be invited to it before they can join; others
|
Some rooms require that users be invited to it before they can join; others
|
||||||
allow anyone to join. Whether a given room is an "invite-only" room is
|
allow anyone to join. Whether a given room is an "invite-only" room is
|
||||||
determined by the room config key ``m.room.join_rules``. It can have one of the
|
determined by the room config key ``m.room.join_rules``. It can have one of the
|
||||||
|
@ -957,8 +936,11 @@ Leaving rooms
|
||||||
|
|
||||||
|
|
||||||
A user can leave a room to stop receiving events for that room. A user must
|
A user can leave a room to stop receiving events for that room. A user must
|
||||||
have joined the room before they are eligible to leave the room. If the room is
|
have been invited to or have joined the room before they are eligible to leave
|
||||||
an "invite-only" room, they will need to be re-invited before they can re-join
|
the room. Leaving a room to which the user has been invited rejects the invite.
|
||||||
|
|
||||||
|
Whether or not they actually joined the room, if the room is
|
||||||
|
an "invite-only" room they will need to be re-invited before they can re-join
|
||||||
the room. To leave a room, a request should be made to
|
the room. To leave a room, a request should be made to
|
||||||
|/rooms/<room_id>/leave|_ with::
|
|/rooms/<room_id>/leave|_ with::
|
||||||
|
|
||||||
|
@ -1000,53 +982,17 @@ member's state, by making a request to
|
||||||
"membership": "ban"
|
"membership": "ban"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Account operations
|
||||||
|
------------------
|
||||||
|
|
||||||
Registration
|
Registration
|
||||||
------------
|
~~~~~~~~~~~~
|
||||||
This section refers to API Version 2. These API calls currently use the prefix
|
This API endpoint uses the `User-Interactive Authentication API`_.
|
||||||
``/_matrix/client/v2_alpha``.
|
|
||||||
|
|
||||||
Registering for a user account is done using the request::
|
{{v2_registration_http_api}}
|
||||||
|
|
||||||
POST $V2PREFIX/register
|
Login
|
||||||
|
~~~~~
|
||||||
This API endpoint uses the User-Interactive Authentication API.
|
|
||||||
This API endpoint does not require an access token.
|
|
||||||
|
|
||||||
The body of the POST request is a JSON object containing:
|
|
||||||
|
|
||||||
username
|
|
||||||
Optional. This is the local part of the desired Matrix ID. If omitted, the
|
|
||||||
Home Server must generate a Matrix ID local part.
|
|
||||||
password
|
|
||||||
Required. The desired password for the account.
|
|
||||||
bind_email
|
|
||||||
Optional. If ``true``, the server binds the email used for authentication to
|
|
||||||
the Matrix ID with the ID Server.
|
|
||||||
|
|
||||||
On success, this returns a JSON object with keys:
|
|
||||||
|
|
||||||
user_id
|
|
||||||
The fully-qualified Matrix ID that has been registered.
|
|
||||||
access_token
|
|
||||||
An access token for the new account.
|
|
||||||
home_server
|
|
||||||
The hostname of the Home Server on which the account has been registered.
|
|
||||||
|
|
||||||
This endpoint may also return the following error codes:
|
|
||||||
|
|
||||||
M_USER_IN_USE
|
|
||||||
If the Matrix ID is already in use
|
|
||||||
M_EXCLUSIVE
|
|
||||||
If the requested Matrix ID is in the exclusive namespace of an application
|
|
||||||
service.
|
|
||||||
|
|
||||||
Home Servers MUST perform the relevant checks and return these codes before
|
|
||||||
performing User-Interactive Authentication, although they may also return
|
|
||||||
them after authentication is completed if, for example, the requested user ID
|
|
||||||
was registered whilst the client was performing authentication.
|
|
||||||
|
|
||||||
Old V1 API docs: |register|_
|
|
||||||
|
|
||||||
{{login_http_api}}
|
{{login_http_api}}
|
||||||
|
|
|
@ -190,9 +190,64 @@ in the event JSON in a ``hash`` object under a ``sha256`` key.
|
||||||
event_json_object["unsigned"] = unsigned
|
event_json_object["unsigned"] = unsigned
|
||||||
return event_json_object
|
return event_json_object
|
||||||
|
|
||||||
Then all non-essential keys are stripped from the event object, and the
|
The event is then stripped of all non-essential keys both at the top level and
|
||||||
resulting object which included the ``hash`` key is signed using the JSON
|
within the ``content`` object. Any top-level keys not in the following list
|
||||||
signing algorithm
|
MUST be removed:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
auth_events
|
||||||
|
depth
|
||||||
|
event_id
|
||||||
|
hashes
|
||||||
|
membership
|
||||||
|
origin
|
||||||
|
origin_server_ts
|
||||||
|
prev_events
|
||||||
|
prev_state
|
||||||
|
room_id
|
||||||
|
sender
|
||||||
|
signatures
|
||||||
|
state_key
|
||||||
|
type
|
||||||
|
|
||||||
|
A new ``content`` object is constructed for the resulting event that contains
|
||||||
|
only the essential keys of the original ``content`` object. If the original
|
||||||
|
event lacked a ``content`` object at all, a new empty JSON object is created
|
||||||
|
for it.
|
||||||
|
|
||||||
|
The keys that are considered essential for the ``content`` object depend on the
|
||||||
|
the ``type`` of the event. These are:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
type is "m.room.aliases":
|
||||||
|
aliases
|
||||||
|
|
||||||
|
type is "m.room.create":
|
||||||
|
creator
|
||||||
|
|
||||||
|
type is "m.room.history_visibility":
|
||||||
|
history_visibility
|
||||||
|
|
||||||
|
type is "m.room.join_rules":
|
||||||
|
join_rule
|
||||||
|
|
||||||
|
type is "m.room.member":
|
||||||
|
membership
|
||||||
|
|
||||||
|
type is "m.room.power_levels":
|
||||||
|
ban
|
||||||
|
events
|
||||||
|
events_default
|
||||||
|
kick
|
||||||
|
redact
|
||||||
|
state_default
|
||||||
|
users
|
||||||
|
users_default
|
||||||
|
|
||||||
|
The resulting stripped object with the new ``content`` object and the original
|
||||||
|
``hashes`` key is then signed using the JSON signing algorithm outlined below:
|
||||||
|
|
||||||
.. code:: python
|
.. code:: python
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
Events
|
Event Structure
|
||||||
======
|
===============
|
||||||
|
|
||||||
All communication in Matrix is expressed in the form of data objects called
|
All communication in Matrix is expressed in the form of data objects called
|
||||||
Events. These are the fundamental building blocks common to the client-server,
|
Events. These are the fundamental building blocks common to the client-server,
|
|
@ -1,7 +1,7 @@
|
||||||
Feature Profiles
|
Feature Profiles
|
||||||
================
|
================
|
||||||
|
|
||||||
.. sect:feature-profiles:
|
.. _sect:feature-profiles:
|
||||||
|
|
||||||
Matrix supports many different kinds of clients: from embedded IoT devices to
|
Matrix supports many different kinds of clients: from embedded IoT devices to
|
||||||
desktop clients. Not all clients can provide the same feature sets as other
|
desktop clients. Not all clients can provide the same feature sets as other
|
|
@ -99,23 +99,23 @@ Architecture
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Matrix defines APIs for synchronising extensible JSON objects known as
|
Matrix defines APIs for synchronising extensible JSON objects known as
|
||||||
``events`` between compatible clients, servers and services. Clients are
|
"events" between compatible clients, servers and services. Clients are
|
||||||
typically messaging/VoIP applications or IoT devices/hubs and communicate by
|
typically messaging/VoIP applications or IoT devices/hubs and communicate by
|
||||||
synchronising communication history with their ``homeserver`` using the
|
synchronising communication history with their "homeserver" using the
|
||||||
``Client-Server API``. Each homeserver stores the communication history and
|
"Client-Server API". Each homeserver stores the communication history and
|
||||||
account information for all of its clients, and shares data with the wider
|
account information for all of its clients, and shares data with the wider
|
||||||
Matrix ecosystem by synchronising communication history with other homeservers
|
Matrix ecosystem by synchronising communication history with other homeservers
|
||||||
and their clients.
|
and their clients.
|
||||||
|
|
||||||
Clients typically communicate with each other by emitting events in the
|
Clients typically communicate with each other by emitting events in the
|
||||||
context of a virtual ``room``. Room data is replicated across *all of the
|
context of a virtual "room". Room data is replicated across *all of the
|
||||||
homeservers* whose users are participating in a given room. As such, *no
|
homeservers* whose users are participating in a given room. As such, *no
|
||||||
single homeserver has control or ownership over a given room*. Homeservers
|
single homeserver has control or ownership over a given room*. Homeservers
|
||||||
model communication history as a partially ordered graph of events known as
|
model communication history as a partially ordered graph of events known as
|
||||||
the room's ``event graph``, which is synchronised with eventual consistency
|
the room's "event graph", which is synchronised with eventual consistency
|
||||||
between the participating servers using the ``Server-Server API``. This process
|
between the participating servers using the "Server-Server API". This process
|
||||||
of synchronising shared conversation history between homeservers run by
|
of synchronising shared conversation history between homeservers run by
|
||||||
different parties is called ``Federation``. Matrix optimises for the the
|
different parties is called "Federation". Matrix optimises for the the
|
||||||
Availability and Partitioned properties of CAP theorem at
|
Availability and Partitioned properties of CAP theorem at
|
||||||
the expense of Consistency.
|
the expense of Consistency.
|
||||||
|
|
||||||
|
@ -151,13 +151,13 @@ Users
|
||||||
~~~~~
|
~~~~~
|
||||||
|
|
||||||
Each client is associated with a user account, which is identified in Matrix
|
Each client is associated with a user account, which is identified in Matrix
|
||||||
using a unique "User ID". This ID is namespaced to the home server which
|
using a unique "User ID". This ID is namespaced to the homeserver which
|
||||||
allocated the account and has the form::
|
allocated the account and has the form::
|
||||||
|
|
||||||
@localpart:domain
|
@localpart:domain
|
||||||
|
|
||||||
The ``localpart`` of a user ID may be a user name, or an opaque ID identifying
|
The ``localpart`` of a user ID may be a user name, or an opaque ID identifying
|
||||||
this user. They are case-insensitive.
|
this user. The ``domain`` of a user ID is the domain of the homeserver.
|
||||||
|
|
||||||
.. TODO-spec
|
.. TODO-spec
|
||||||
- Need to specify precise grammar for Matrix IDs
|
- Need to specify precise grammar for Matrix IDs
|
||||||
|
@ -183,9 +183,9 @@ Event Graphs
|
||||||
.. _sect:event-graph:
|
.. _sect:event-graph:
|
||||||
|
|
||||||
Events exchanged in the context of a room are stored in a directed acyclic graph
|
Events exchanged in the context of a room are stored in a directed acyclic graph
|
||||||
(DAG) called an ``event graph``. The partial ordering of this graph gives the
|
(DAG) called an "event graph". The partial ordering of this graph gives the
|
||||||
chronological ordering of events within the room. Each event in the graph has a
|
chronological ordering of events within the room. Each event in the graph has a
|
||||||
list of zero or more ``parent`` events, which refer to any preceding events
|
list of zero or more "parent" events, which refer to any preceding events
|
||||||
which have no chronological successor from the perspective of the homeserver
|
which have no chronological successor from the perspective of the homeserver
|
||||||
which created the event.
|
which created the event.
|
||||||
|
|
||||||
|
@ -292,11 +292,12 @@ Each room can also have multiple "Room Aliases", which look like::
|
||||||
|
|
||||||
A room alias "points" to a room ID and is the human-readable label by which
|
A room alias "points" to a room ID and is the human-readable label by which
|
||||||
rooms are publicised and discovered. The room ID the alias is pointing to can
|
rooms are publicised and discovered. The room ID the alias is pointing to can
|
||||||
be obtained by visiting the domain specified. They are case-insensitive. Note
|
be obtained by visiting the domain specified. Note that the mapping from a room
|
||||||
that the mapping from a room alias to a room ID is not fixed, and may change
|
alias to a room ID is not fixed, and may change over time to point to a
|
||||||
over time to point to a different room ID. For this reason, Clients SHOULD
|
different room ID. For this reason, Clients SHOULD resolve the room alias to a
|
||||||
resolve the room alias to a room ID once and then use that ID on subsequent
|
room ID once and then use that ID on subsequent requests. Room aliases MUST NOT
|
||||||
requests. Room aliases MUST NOT exceed 255 bytes (including the domain).
|
exceed 255 bytes (including the domain).
|
||||||
|
|
||||||
|
|
||||||
When resolving a room alias the server will also respond with a list of servers
|
When resolving a room alias the server will also respond with a list of servers
|
||||||
that are in the room that can be used to join via.
|
that are in the room that can be used to join via.
|
||||||
|
@ -339,12 +340,9 @@ Profiles
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
||||||
Users may publish arbitrary key/value data associated with their account - such
|
Users may publish arbitrary key/value data associated with their account - such
|
||||||
as a human readable ``display name``, a profile photo URL, contact information
|
as a human readable display name, a profile photo URL, contact information
|
||||||
(email address, phone numbers, website URLs etc).
|
(email address, phone numbers, website URLs etc).
|
||||||
|
|
||||||
In Client-Server API v2, profile data is typed using namespaced keys for
|
|
||||||
interoperability, much like events - e.g. ``m.profile.display_name``.
|
|
||||||
|
|
||||||
.. TODO
|
.. TODO
|
||||||
Actually specify the different types of data - e.g. what format are display
|
Actually specify the different types of data - e.g. what format are display
|
||||||
names allowed to be?
|
names allowed to be?
|
||||||
|
@ -431,15 +429,12 @@ Some requests have unique error codes:
|
||||||
:``M_BAD_PAGINATION``:
|
:``M_BAD_PAGINATION``:
|
||||||
Encountered when specifying bad pagination query parameters.
|
Encountered when specifying bad pagination query parameters.
|
||||||
|
|
||||||
:``M_LOGIN_EMAIL_URL_NOT_YET``:
|
|
||||||
Encountered when polling for an email link which has not been clicked yet.
|
|
||||||
|
|
||||||
.. _sect:txn_ids:
|
.. _sect:txn_ids:
|
||||||
|
|
||||||
The C-S API typically uses ``HTTP POST`` to submit requests. This means these
|
The Client-Server API typically uses ``HTTP POST`` to submit requests. This
|
||||||
requests are not idempotent. The C-S API also allows ``HTTP PUT`` to make
|
means these requests are not idempotent. The C-S API also allows ``HTTP PUT`` to
|
||||||
requests idempotent. In order to use a ``PUT``, paths should be suffixed with
|
make requests idempotent. In order to use a ``PUT``, paths should be suffixed
|
||||||
``/{txnId}``. ``{txnId}`` is a unique client-generated transaction ID which
|
with ``/{txnId}``. ``{txnId}`` is a unique client-generated transaction ID which
|
||||||
identifies the request, and is scoped to a given Client (identified by that
|
identifies the request, and is scoped to a given Client (identified by that
|
||||||
client's ``access_token``). Crucially, it **only** serves to identify new
|
client's ``access_token``). Crucially, it **only** serves to identify new
|
||||||
requests from retransmits. After the request has finished, the ``{txnId}``
|
requests from retransmits. After the request has finished, the ``{txnId}``
|
|
@ -30,6 +30,8 @@ Usage of this event is discouraged for several reasons:
|
||||||
|
|
||||||
{{m_room_topic_event}}
|
{{m_room_topic_event}}
|
||||||
|
|
||||||
|
{{m_room_avatar_event}}
|
||||||
|
|
||||||
m.room.message msgtypes
|
m.room.message msgtypes
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,8 @@ A client asks a server to invite a user by their third party identifier.
|
||||||
Server behaviour
|
Server behaviour
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
All homeservers MUST verify that sig(``token``, ``public_key``) = ``signature``.
|
All homeservers MUST verify the signature in the event's
|
||||||
|
``content.third_party_invite.signed`` object.
|
||||||
|
|
||||||
If a client of the current homeserver is joining by an
|
If a client of the current homeserver is joining by an
|
||||||
``m.room.third_party_invite``, that homesever MUST validate that the public
|
``m.room.third_party_invite``, that homesever MUST validate that the public
|
||||||
|
@ -93,11 +94,11 @@ For example:
|
||||||
When the third party user validates their identity, they are told about the
|
When the third party user validates their identity, they are told about the
|
||||||
invite, and ask their homeserver, H3, to join the room.
|
invite, and ask their homeserver, H3, to join the room.
|
||||||
|
|
||||||
H3 validates that sign(``token``, ``public_key``) = ``signature``, and may check
|
H3 validates the signature in the event's
|
||||||
``key_validity_url``.
|
``content.third_party_invite.signed`` object.
|
||||||
|
|
||||||
H3 then asks H1 to join it to the room. H1 *must* validate that
|
H3 then asks H1 to join it to the room. H1 *must* validate the ``signed``
|
||||||
sign(``token``, ``public_key``) = ``signature`` *and* check ``key_validity_url``.
|
property *and* check ``key_validity_url``.
|
||||||
|
|
||||||
Having validated these things, H1 writes the join event to the room, and H3
|
Having validated these things, H1 writes the join event to the room, and H3
|
||||||
begins participating in the room. H2 *must* accept this event.
|
begins participating in the room. H2 *must* accept this event.
|
||||||
|
|
|
@ -630,7 +630,7 @@ because HTTP services like Matrix are often deployed behind load balancers that
|
||||||
handle the TLS and these load balancers make it difficult to check TLS client
|
handle the TLS and these load balancers make it difficult to check TLS client
|
||||||
certificates.
|
certificates.
|
||||||
|
|
||||||
A home server may provide a TLS client certficate and the receiving home server
|
A home server may provide a TLS client certificate and the receiving home server
|
||||||
may check that the client certificate matches the certificate of the origin
|
may check that the client certificate matches the certificate of the origin
|
||||||
home server.
|
home server.
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
targets:
|
targets:
|
||||||
main: # arbitrary name to identify this build target
|
main: # arbitrary name to identify this build target
|
||||||
files: # the sort order of files to cat
|
files: # the sort order of files to cat
|
||||||
- 0-intro.rst
|
- intro.rst
|
||||||
- 1-client_server_api.rst
|
- client_server_api.rst
|
||||||
- { 1: 0-events.rst }
|
- { 1: events.rst }
|
||||||
- { 1: 0-event_signing.rst }
|
- { 1: event_signing.rst }
|
||||||
- 2-modules.rst
|
- modules.rst
|
||||||
- { 1: 0-feature_profiles.rst }
|
- { 1: feature_profiles.rst }
|
||||||
- { 1: "group:modules" } # reference a group of files
|
- { 1: "group:modules" } # reference a group of files
|
||||||
- 3-application_service_api.rst
|
- application_service_api.rst
|
||||||
- 4-server_server_api.rst
|
- server_server_api.rst
|
||||||
- 5-identity_servers.rst
|
- identity_servers.rst
|
||||||
- 6-appendices.rst
|
- appendices.rst
|
||||||
groups: # reusable blobs of files when prefixed with 'group:'
|
groups: # reusable blobs of files when prefixed with 'group:'
|
||||||
modules:
|
modules:
|
||||||
- modules/instant_messaging.rst
|
- modules/instant_messaging.rst
|
||||||
|
|
|
@ -7,18 +7,18 @@
|
||||||
{% for table in event.content_fields -%}
|
{% for table in event.content_fields -%}
|
||||||
{{"``"+table.title+"``" if table.title else "" }}
|
{{"``"+table.title+"``" if table.title else "" }}
|
||||||
|
|
||||||
================== ================= ===========================================
|
======================= ================= ===========================================
|
||||||
{{table.title or "Content"}} Key Type Description
|
{{table.title or "Content"}} Key Type Description
|
||||||
================== ================= ===========================================
|
======================= ================= ===========================================
|
||||||
{% for row in table.rows -%}
|
{% for row in table.rows -%}
|
||||||
{# -#}
|
{# -#}
|
||||||
{# Row type needs to prepend spaces to line up with the type column (19 ch) -#}
|
{# Row type needs to prepend spaces to line up with the type column (19 ch) -#}
|
||||||
{# Desc needs to prepend the required text (maybe) and prepend spaces too -#}
|
{# Desc needs to prepend the required text (maybe) and prepend spaces too -#}
|
||||||
{# It also needs to then wrap inside the desc col (43 ch width) -#}
|
{# It also needs to then wrap inside the desc col (43 ch width) -#}
|
||||||
{# -#}
|
{# -#}
|
||||||
{{row.key}}{{row.type|indent(19-row.key|length)}}{{row.desc|wrap(43,row.req_str | indent(18 - (row.type|length))) |indent_block(37)}}
|
{{row.key}}{{row.type|indent(24-row.key|length)}}{{row.desc|wrap(43,row.req_str | indent(18 - (row.type|length))) |indent_block(42)}}
|
||||||
{% endfor -%}
|
{% endfor -%}
|
||||||
================== ================= ===========================================
|
======================= ================= ===========================================
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
Example::
|
Example::
|
||||||
|
|
|
@ -532,6 +532,15 @@ class MatrixUnits(Units):
|
||||||
Units.prop(json_schema, "properties/content")
|
Units.prop(json_schema, "properties/content")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# This is horrible because we're special casing a key on m.room.member.
|
||||||
|
# We need to do this because we want to document a non-content object.
|
||||||
|
if schema["type"] == "m.room.member":
|
||||||
|
invite_room_state = get_json_schema_object_fields(
|
||||||
|
json_schema["properties"]["invite_room_state"]["items"]
|
||||||
|
)
|
||||||
|
schema["content_fields"].extend(invite_room_state)
|
||||||
|
|
||||||
|
|
||||||
# grab msgtype if it is the right kind of event
|
# grab msgtype if it is the right kind of event
|
||||||
msgtype = Units.prop(
|
msgtype = Units.prop(
|
||||||
json_schema, "properties/content/properties/msgtype/enum"
|
json_schema, "properties/content/properties/msgtype/enum"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue