Merge branch 'master' into appservice-swagger

Conflicts:
	specification/application_service_api.rst
pull/977/head
Kegan Dougal 9 years ago
commit f95d19cecd

@ -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.

@ -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
type: string
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
x-example: "s3456_9_0"
- in: query
@ -39,16 +41,6 @@ paths:
description: The maximum time in milliseconds to wait for an event.
required: false
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:
200:
description: "The events received, which may be none."
@ -78,19 +70,19 @@ paths:
start:
type: string
description: |-
A token which correlates to the first value in ``chunk``. Used
for pagination.
A token which correlates to the first value in ``chunk``. This
is usually the same token supplied to ``from=``.
end:
type: string
description: |-
A token which correlates to the last value in ``chunk``. Used
for pagination.
A token which correlates to the last value in ``chunk``. This
token should be used in the next request to ``/events``.
chunk:
type: array
description: "An array of events."
items:
type: object
title: RoomEvent
title: Event
allOf:
- "$ref": "core-event-schema/room_event.json"
400:
@ -110,6 +102,16 @@ paths:
description: The maximum number of messages to return for each room.
required: false
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:
200:
description: The user's current state.

@ -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
# 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
do
split_path=(${line///// })

@ -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",
"public_key": "abc123",
"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"
}
},
"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",
"origin_server_ts": 1431961217939,
"event_id": "$WLGTSEFSEF:localhost",

@ -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",
"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": [{
"$ref": "core-event-schema/state_event.json"
}],
@ -24,7 +24,7 @@
},
"third_party_invite": {
"type": "object",
"title": "invite",
"title": "Invite",
"properties": {
"token": {
"type": "string",
@ -38,16 +38,32 @@
"type": "string",
"description": "A base64-encoded ed25519 key with which token must be signed."
},
"signature": {
"type": "string",
"description": "A base64-encoded signature of token with public_key."
"signed": {
"type": "object",
"title": "signed",
"properties": {
"mxid": {
"type": "string",
"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": {
"type": "string",
"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"]
@ -65,17 +81,23 @@
"description": "A subset of the state of the room at the time of the invite, if ``membership`` is ``invite``",
"items": {
"type": "object",
"title": "StateEvent",
"title": "StrippedState",
"description": "A stripped down state event, with only the ``type``, ``state_key`` and ``content`` keys.",
"required": ["type", "state_key", "content"],
"properties": {
"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": {
"type": "string"
"type": "string",
"description": "The ``state_key`` for the event."
},
"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"
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.
Threat: Bad History
@ -63,7 +63,7 @@ Spoofing
An attacker could try to send a message claiming to be from the victim without
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.
Threat: Altering Message Contents
@ -81,7 +81,7 @@ with a phony "origin" field.
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:
* Find victims for scams.

@ -147,6 +147,9 @@ application services MUST implement these APIs. These APIs are defined below.
{{application_service_http_api}}
.. _create the user: `sect:asapi-permissions`_
Client-Server v2 API Extensions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -165,11 +168,8 @@ additional permissions granting the AS permission to masquerade as a matrix user
Inputs:
- Application service token (``access_token``)
- User ID in the AS namespace to act as.
Either:
- User ID in the AS namespace to act as.
Or:
- OAuth2 token of real user (which may end up being an access token)
Notes:
- 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
@ -184,12 +184,6 @@ Notes:
access_token: The application service token
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
+++++++++++++++++++
The application service may want to inject events at a certain time (reflecting
@ -212,6 +206,9 @@ Notes:
Server admin style permissions
++++++++++++++++++++++++++++++
.. _sect:asapi-permissions:
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
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
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,
but only if the application service has defined the namespace as ``exclusive``.
@ -291,9 +288,10 @@ an API is exposed.
Room Aliases
++++++++++++
We may want to expose some 3P network rooms so Matrix users can join them directly,
e.g. IRC rooms. We don't want to expose every 3P network room though, e.g. mailto,
tel. Rooms which are publicly accessible (e.g. IRC rooms) can be exposed as an alias by
the application service. Private rooms (e.g. sending an email to someone) should not
e.g. IRC rooms. We don't want to expose every 3P network room though, e.g.
``mailto``, ``tel``. Rooms which are publicly accessible (e.g. IRC rooms) can be
exposed as an alias by the application service. Private rooms
(e.g. sending an email to someone) should not
be exposed in this way, but should instead operate using normal invite/join semantics.
Therefore, the ID conventions discussed below are only valid for public rooms which
expose room aliases.
@ -313,9 +311,9 @@ SHOULD be mapped in the same way as "user" URIs.
Event fields
++++++++++++
We recommend that any gatewayed events should include an ``external_url`` field
in their content to provide a way for Matrix clients to link into the 'native'
client from which the event originated. For instance, this could contain the
message-ID for emails/nntp posts, or a link to a blog comment when gatewaying
blog comment traffic in & out of matrix
We recommend that any events that originated from a remote network should
include an ``external_url`` field in their content to provide a way for Matrix
clients to link into the 'native' client from which the event originated.
For instance, this could contain the message-ID for emails/nntp posts, or a link
to a blog comment when bridging blog comment traffic in & out of Matrix.

@ -1,9 +1,6 @@
Client-Server API
=================
Overview
--------
The client-server API provides a simple lightweight API to let clients send
messages, control rooms and synchronise conversation history. It is designed to
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.
User-Interactive Authentication API
-----------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. _sect:auth-api:
This section refers to API Version 2.
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.
Example
~~~~~~~
+++++++
At a high level, the requests made for an API call completing an auth flow with
three stages will resemble the following diagram::
@ -201,7 +201,7 @@ This specification defines the following login types:
- ``m.login.dummy``
Password-based
~~~~~~~~~~~~~~
++++++++++++++
:Type:
``m.login.password``
: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``.
Google ReCaptcha
~~~~~~~~~~~~~~~~
++++++++++++++++
:Type:
``m.login.recaptcha``
:Description:
@ -236,7 +236,7 @@ To respond to this type, reply with an auth dict as follows::
}
Token-based
~~~~~~~~~~~
+++++++++++
:Type:
``m.login.token``
:Description:
@ -267,7 +267,7 @@ newly provisioned access_token).
The ``token`` must be a macaroon.
OAuth2-based
~~~~~~~~~~~~
++++++++++++
:Type:
``m.login.oauth2``
:Description:
@ -291,7 +291,7 @@ the OAuth flow has completed, the client retries the request with the session
only, as above.
Email-based (identity server)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+++++++++++++++++++++++++++++
:Type:
``m.login.email.identity``
:Description:
@ -316,7 +316,7 @@ To respond to this type, reply with an auth dict as follows::
}
Dummy Auth
~~~~~~~~~~
++++++++++
:Type:
``m.login.dummy``
:Description:
@ -333,7 +333,7 @@ if provided::
Fallback
~~~~~~~~
++++++++
Clients cannot be expected to be able to know how to process every single login
type. If a client does not know how to handle a given login type, it can direct
the user to a web browser with the URL of a fallback page which will allow the
@ -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
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
----------
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
dataset. Requests pass in ``from``, ``to`` and ``limit`` parameters which describe
where to read from the stream. ``from`` and ``to`` are opaque textual 'stream
tokens' which describe positions in the dataset. The response returns new
``start`` and ``end`` stream token values which can then be passed to subsequent
requests to continue pagination.
dataset. Requests pass in ``from``, ``to``, ``dir`` and ``limit`` parameters
which describe where to read from the stream. ``from`` and ``to`` are opaque
textual 'stream tokens' which describe the current position in the dataset.
The ``dir`` parameter is an enum representing the direction of events to return:
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -373,24 +526,26 @@ Query parameters:
limit:
integer - An integer representing the maximum number of items to
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 of the dataset respectively.
Unless specified, the default pagination parameters are from=START, to=END,
without a limit set. This allows you to hit an API like
/events without any query parameters to get everything.
Unless specified, the default pagination parameters are ``from=START``,
``to=END``, without a limit set.
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::
S E
|-E1-E2-E3-E4-E5-E6-E7-E8-E9-E10-E11-E12-E13-E14-E15-|
| | |
| _____| |
|__________________ | ___________________|
| | |
GET /events?to=START&limit=5&from=END
| _____| <--backwards-- |
|__________________ | | ________|
| | | |
GET /somepath?to=START&limit=5&dir=b&from=END
Returns:
E15,E14,E13,E12,E11
@ -407,7 +562,7 @@ now show page 3 (rooms R11 -> 15)::
Currently |
viewing |
|
GET /rooms/list?from=9&to=END&limit=5
GET /roomslist?from=9&to=END&limit=5
Returns: R11,R12,R13,R14,R15
Note that tokens are treated in an *exclusive*, not inclusive, manner. The end
@ -435,9 +590,6 @@ Events
.. _sect:events:
Overview
~~~~~~~~
The model of conversation history exposed by the client-server API can be
considered as a list of events. The server 'linearises' the
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'
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
``end`` token returned by initial sync. The request blocks until new events are
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.
Receiving live updates on a client
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Syncing
~~~~~~~
Clients receive new events by long-polling the home server via the
$PREFIX/events API, specifying a timeout in milliseconds in the timeout
parameter. This will hold open the HTTP connection for a short period of time
waiting for new events, returning early if an event occurs. This is called the
`Event Stream`_. 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
Clients receive new events by "long-polling" the home server via the events API.
This involves specifying a timeout in the request which will hold
open the HTTP connection for a short period of time waiting for new events,
returning early if an event occurs. Only the events API supports long-polling.
All events which are visible to the client will appear 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
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.
.. TODO
is deduplication actually a hard requirement in CS v2?
.. Warning::
Events are ordered in this API according to the arrival time of the event on
the homeserver. This can conflict with other APIs which order events based on
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
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?
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
returns an ``end`` token which can be used with the event stream. See the 'Room Sync' section below.
their home server. This is achieved via the initial sync API described below.
This API also returns an ``end`` token which can be used with the event stream.
{{sync_http_api}}
Events in a room
~~~~~~~~~~~~~~~~
Types of room events
~~~~~~~~~~~~~~~~~~~~
Room events are split into two categories:
@ -534,7 +688,7 @@ Room events are split into two categories:
:Message events:
These are events which describe transient "once-off" activity in a room:
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
``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.
State events
~~~~~~~~~~~~
++++++++++++
State events can be sent by ``PUT`` ing to
|/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.
Message events
~~~~~~~~~~~~~~
++++++++++++++
Message events can be sent by sending a request to
|/rooms/<room_id>/send/<event_type>|_. These requests *can* use transaction
@ -603,69 +757,6 @@ example::
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
~~~~~~~~~~~~~~~~~~~~~~~~~
@ -673,6 +764,9 @@ There are several APIs provided to ``GET`` events for a room:
{{rooms_http_api}}
{{message_pagination_http_api}}
Redactions
~~~~~~~~~~
Since events are extensible it is possible for malicious users and/or servers
@ -723,140 +817,20 @@ Rooms
Creation
~~~~~~~~
To create a room, a client has to use the |createRoom|_ API. There are various
options which can be set when creating a room:
``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
The home server will create an ``m.room.create`` event when a room is created,
which serves as the root of the event graph for this room. This event also has a
``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
includes:
- ``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.
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
~~~~~~~~~~~~
@ -921,7 +895,7 @@ certain operations such as kicking, banning and sending state events. See
`m.room.power_levels`_ for more information.
Joining rooms
-------------
~~~~~~~~~~~~~
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:
@ -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)
- 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
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
@ -957,8 +936,11 @@ Leaving rooms
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
an "invite-only" room, they will need to be re-invited before they can re-join
have been invited to or have joined the room before they are eligible to leave
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
|/rooms/<room_id>/leave|_ with::
@ -1000,53 +982,17 @@ member's state, by making a request to
"membership": "ban"
}
Account operations
------------------
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.
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.
~~~~~~~~~~~~
This API endpoint uses the `User-Interactive Authentication API`_.
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.
{{v2_registration_http_api}}
Old V1 API docs: |register|_
Login
~~~~~
{{login_http_api}}

@ -190,9 +190,64 @@ in the event JSON in a ``hash`` object under a ``sha256`` key.
event_json_object["unsigned"] = unsigned
return event_json_object
Then all non-essential keys are stripped from the event object, and the
resulting object which included the ``hash`` key is signed using the JSON
signing algorithm
The event is then stripped of all non-essential keys both at the top level and
within the ``content`` object. Any top-level keys not in the following list
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

@ -1,5 +1,5 @@
Events
======
Event Structure
===============
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,

@ -1,7 +1,7 @@
Feature Profiles
================
.. sect:feature-profiles:
.. _sect:feature-profiles:
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

@ -99,23 +99,23 @@ Architecture
------------
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
synchronising communication history with their ``homeserver`` using the
``Client-Server API``. Each homeserver stores the communication history and
synchronising communication history with their "homeserver" using the
"Client-Server API". Each homeserver stores the communication history and
account information for all of its clients, and shares data with the wider
Matrix ecosystem by synchronising communication history with other homeservers
and their clients.
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
single homeserver has control or ownership over a given room*. Homeservers
model communication history as a partially ordered graph of events known as
the room's ``event graph``, which is synchronised with eventual consistency
between the participating servers using the ``Server-Server API``. This process
the room's "event graph", which is synchronised with eventual consistency
between the participating servers using the "Server-Server API". This process
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
the expense of Consistency.
@ -151,13 +151,13 @@ Users
~~~~~
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::
@localpart:domain
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
- Need to specify precise grammar for Matrix IDs
@ -183,9 +183,9 @@ Event Graphs
.. _sect:event-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
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 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
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
that the mapping from a room alias to a room ID is not fixed, and may change
over time to point to a different room ID. For this reason, Clients SHOULD
resolve the room alias to a room ID once and then use that ID on subsequent
requests. Room aliases MUST NOT exceed 255 bytes (including the domain).
be obtained by visiting the domain specified. Note that the mapping from a room
alias to a room ID is not fixed, and may change over time to point to a
different room ID. For this reason, Clients SHOULD resolve the room alias to a
room ID once and then use that ID on subsequent requests. Room aliases MUST NOT
exceed 255 bytes (including the domain).
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.
@ -339,12 +340,9 @@ Profiles
~~~~~~~~
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).
In Client-Server API v2, profile data is typed using namespaced keys for
interoperability, much like events - e.g. ``m.profile.display_name``.
.. TODO
Actually specify the different types of data - e.g. what format are display
names allowed to be?
@ -431,15 +429,12 @@ Some requests have unique error codes:
:``M_BAD_PAGINATION``:
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:
The C-S API typically uses ``HTTP POST`` to submit requests. This means these
requests are not idempotent. The C-S API also allows ``HTTP PUT`` to make
requests idempotent. In order to use a ``PUT``, paths should be suffixed with
``/{txnId}``. ``{txnId}`` is a unique client-generated transaction ID which
The Client-Server API typically uses ``HTTP POST`` to submit requests. This
means these requests are not idempotent. The C-S API also allows ``HTTP PUT`` to
make requests idempotent. In order to use a ``PUT``, paths should be suffixed
with ``/{txnId}``. ``{txnId}`` is a unique client-generated transaction ID which
identifies the request, and is scoped to a given Client (identified by that
client's ``access_token``). Crucially, it **only** serves to identify new
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_avatar_event}}
m.room.message msgtypes
~~~~~~~~~~~~~~~~~~~~~~~

@ -36,7 +36,8 @@ A client asks a server to invite a user by their third party identifier.
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
``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
invite, and ask their homeserver, H3, to join the room.
H3 validates that sign(``token``, ``public_key``) = ``signature``, and may check
``key_validity_url``.
H3 validates the signature in the event's
``content.third_party_invite.signed`` object.
H3 then asks H1 to join it to the room. H1 *must* validate that
sign(``token``, ``public_key``) = ``signature`` *and* check ``key_validity_url``.
H3 then asks H1 to join it to the room. H1 *must* validate the ``signed``
property *and* check ``key_validity_url``.
Having validated these things, H1 writes the join event to the room, and H3
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
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
home server.

@ -1,17 +1,17 @@
targets:
main: # arbitrary name to identify this build target
files: # the sort order of files to cat
- 0-intro.rst
- 1-client_server_api.rst
- { 1: 0-events.rst }
- { 1: 0-event_signing.rst }
- 2-modules.rst
- { 1: 0-feature_profiles.rst }
- intro.rst
- client_server_api.rst
- { 1: events.rst }
- { 1: event_signing.rst }
- modules.rst
- { 1: feature_profiles.rst }
- { 1: "group:modules" } # reference a group of files
- 3-application_service_api.rst
- 4-server_server_api.rst
- 5-identity_servers.rst
- 6-appendices.rst
- application_service_api.rst
- server_server_api.rst
- identity_servers.rst
- appendices.rst
groups: # reusable blobs of files when prefixed with 'group:'
modules:
- modules/instant_messaging.rst

@ -7,18 +7,18 @@
{% for table in event.content_fields -%}
{{"``"+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 -%}
{# -#}
{# 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 -#}
{# 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 %}
Example::

@ -532,6 +532,15 @@ class MatrixUnits(Units):
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
msgtype = Units.prop(
json_schema, "properties/content/properties/msgtype/enum"

Loading…
Cancel
Save