Merge remote matrix-org/master

pull/1555/head
Travis Ralston 6 years ago
commit a5c3924492

@ -29,6 +29,8 @@ checkexamples: &checkexamples
source /env/bin/activate
cd event-schemas
./check_examples.py
cd ../api
./check_examples.py
genmatrixassets: &genmatrixassets
name: Generate/Verify matrix.org assets
@ -36,9 +38,33 @@ genmatrixassets: &genmatrixassets
source /env/bin/activate
./scripts/generate-matrix-org-assets
validateapi: &validateapi
name: Validate OpenAPI specifications
command: |
cd api
npm install
node validator.js -s "client-server"
buildspeculator: &buildspeculator
name: Build Speculator
command: |
cd scripts/speculator
go build -v
buildcontinuserv: &buildcontinuserv
name: Build Continuserv
command: |
cd scripts/continuserv
go build -v
version: 2
jobs:
validate-docs:
docker:
- image: node:alpine
steps:
- checkout
- run: *validateapi
check-docs:
docker:
- image: uhoreg/matrix-doc-build
@ -57,7 +83,6 @@ jobs:
- run:
name: "Doc build is available at:"
command: DOCS_URL="${CIRCLE_BUILD_URL}/artifacts/${CIRCLE_NODE_INDEX}/${CIRCLE_WORKING_DIRECTORY/#\~/$HOME}/scripts/gen/index.html"; echo $DOCS_URL
build-swagger:
docker:
- image: uhoreg/matrix-doc-build
@ -70,6 +95,18 @@ jobs:
- run:
name: "Swagger UI is available at:"
command: DOCS_URL="${CIRCLE_BUILD_URL}/artifacts/${CIRCLE_NODE_INDEX}/${CIRCLE_WORKING_DIRECTORY/#\~/$HOME}/api/client-server/index.html"; echo $DOCS_URL
build-dev-scripts:
docker:
- image: golang:1.8
steps:
- checkout
- run:
name: Install Dependencies
command: |
go get -v github.com/hashicorp/golang-lru
go get -v gopkg.in/fsnotify/fsnotify.v1
- run: *buildcontinuserv
- run: *buildspeculator
workflows:
version: 2
@ -78,6 +115,9 @@ workflows:
jobs:
- build-docs
- build-swagger
- check-docs
- validate-docs
- build-dev-scripts
notify:
webhooks:

@ -105,7 +105,8 @@ paths:
type: string
description: Most recently seen IP address of the session.
last_seen:
type: number
type: integer
format: int64
description: Unix timestamp that the session was last active.
user_agent:
type: string

@ -62,11 +62,12 @@ paths:
x-example: "!somewhere:domain.com"
- in: body
name: body
required: true
schema:
type: object
properties:
visibility:
type: enum
type: string
enum: ["public", "private"]
description: |-
Whether the room should be visible (public) in the directory

@ -259,7 +259,8 @@ paths:
description: "The URL to get a preview of"
required: true
- in: query
type: number
type: integer
format: int64
x-example: 1510610716656
name: ts
description: |-
@ -276,7 +277,8 @@ paths:
type: object
properties:
"matrix:image:size":
type: number
type: integer
format: int64
description: |-
The byte-size of the image. Omitted if there is no image attached.
"og:image":
@ -324,7 +326,8 @@ paths:
type: object
properties:
m.upload.size:
type: number
type: integer
format: int64
description: |-
The maximum size an upload can be in bytes.
Clients SHOULD use this as a guide when uploading content.

@ -11,7 +11,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
title: Filter
title: EventFilter
properties:
limit:
description: The maximum number of events to return.

@ -45,7 +45,7 @@ properties:
description: |-
The name of the room, if any.
num_joined_members:
type: number
type: integer
description: |-
The number of members joined to the room.
room_id:
@ -82,7 +82,7 @@ properties:
absence of this token means there are no results before this
batch, i.e. this is the first batch.
total_room_count_estimate:
type: number
type: integer
description: |-
An estimate on the total number of public rooms, if the
server has an estimate.

@ -13,23 +13,23 @@
# limitations under the License.
allOf:
- $ref: event_filter.yaml
title: RoomEventFilter
properties:
not_rooms:
description: A list of room IDs to exclude. If this list is absent then no rooms
are excluded. A matching room will be excluded even if it is listed in the ``'rooms'``
filter.
items:
type: string
type: array
rooms:
description: A list of room IDs to include. If this list is absent then all rooms
are included.
items:
type: string
type: array
contains_url:
type: boolean
description: If ``true``, includes only events with a url key in their content. If
``false``, excludes those events.
type: object
- type: object
title: RoomEventFilter
properties:
not_rooms:
description: A list of room IDs to exclude. If this list is absent then no rooms
are excluded. A matching room will be excluded even if it is listed in the ``'rooms'``
filter.
items:
type: string
type: array
rooms:
description: A list of room IDs to include. If this list is absent then all rooms
are included.
items:
type: string
type: array
contains_url:
type: boolean
description: If ``true``, includes only events with a ``url`` key in their content. If
``false``, excludes those events. Defaults to ``false``.

@ -11,6 +11,8 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
type: object
title: Filter
properties:
event_fields:
description: List of event fields to include. If this list is absent then all
@ -40,6 +42,7 @@ properties:
room:
title: RoomFilter
description: Filters to be applied to room data.
type: object
properties:
not_rooms:
description: A list of room IDs to exclude. If this list is absent then no rooms
@ -76,5 +79,3 @@ properties:
allOf:
- $ref: room_event_filter.yaml
description: The per user account data to include for rooms.
type: object
type: object

@ -0,0 +1,24 @@
# Copyright 2018 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
title: Homeserver Information
description: |-
Used by clients to discover homeserver information.
type: object
properties:
base_url:
type: string
description: The base URL for the homeserver for client-server connections.
example: https://matrix.example.com
required:
- base_url

@ -0,0 +1,24 @@
# Copyright 2018 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
title: Identity Server Information
description: |-
Used by clients to discover identity server information.
type: object
properties:
base_url:
type: string
description: The base URL for the identity server for client-server connections.
example: https://identity.example.com
required:
- base_url

@ -54,44 +54,45 @@ paths:
allOf:
- $ref: "definitions/sync_filter.yaml"
example: {
"room": {
"state": {
"types": ["m.room.*"],
"not_rooms": ["!726s6s6q:example.com"]
},
"timeline": {
"limit": 10,
"types": ["m.room.message"],
"not_rooms": ["!726s6s6q:example.com"],
"not_senders": ["@spam:example.com"]
},
"ephemeral": {
"types": ["m.receipt", "m.typing"],
"not_rooms": ["!726s6s6q:example.com"],
"not_senders": ["@spam:example.com"]
}
"room": {
"state": {
"types": ["m.room.*"],
"not_rooms": ["!726s6s6q:example.com"]
},
"presence": {
"types": ["m.presence"],
"not_senders": ["@alice:example.com"]
"timeline": {
"limit": 10,
"types": ["m.room.message"],
"not_rooms": ["!726s6s6q:example.com"],
"not_senders": ["@spam:example.com"]
},
"event_format": "client",
"event_fields": ["type", "content", "sender"]
}
"ephemeral": {
"types": ["m.receipt", "m.typing"],
"not_rooms": ["!726s6s6q:example.com"],
"not_senders": ["@spam:example.com"]
}
},
"presence": {
"types": ["m.presence"],
"not_senders": ["@alice:example.com"]
},
"event_format": "client",
"event_fields": ["type", "content", "sender"]
}
responses:
200:
description: The filter was created.
examples:
application/json: {
"filter_id": "66696p746572"
}
schema:
type: object
properties:
filter_id:
type: string
description: |-
The ID of the filter that was created.
The ID of the filter that was created. Cannot start
with a ``{`` as this character is used to determine
if the filter provided is inline JSON or a previously
declared filter by homeservers on some APIs.
example: "66696p746572"
required: ['filter_id']
tags:
- Room participation
"/user/{userId}/filter/{filterId}":

@ -123,7 +123,7 @@ paths:
parameters:
- in: query
name: limit
type: number
type: integer
description: |-
Limit the number of results returned.
- in: query
@ -173,7 +173,7 @@ paths:
type: object
properties:
limit:
type: number
type: integer
description: |-
Limit the number of results returned.
since:
@ -251,7 +251,7 @@ paths:
description: |-
The name of the room, if any.
num_joined_members:
type: number
type: integer
description: |-
The number of members joined to the room.
room_id:
@ -288,7 +288,7 @@ paths:
absence of this token means there are no results before this
batch, i.e. this is the first batch.
total_room_count_estimate:
type: number
type: integer
description: |-
An estimate on the total number of public rooms, if the
server has an estimate.

@ -45,7 +45,7 @@ paths:
required: false
x-example: "xxxxx"
- in: query
type: number
type: integer
name: limit
description: Limit on the number of events to return in this request.
required: false

@ -218,7 +218,7 @@ paths:
description: The email address
example: "example@example.com"
send_attempt:
type: number
type: integer
description: Used to distinguish protocol level retries from requests to re-send the email.
example: 1
required: ["client_secret", "email", "send_attempt"]
@ -283,7 +283,7 @@ paths:
description: The phone number.
example: "example@example.com"
send_attempt:
type: number
type: integer
description: Used to distinguish protocol level retries from requests to re-send the SMS message.
example: 1
required: ["client_secret", "country", "phone_number", "send_attempt"]

@ -41,7 +41,7 @@ paths:
type: string
description: |-
The point to return events from. If given, this should be a
`next_batch` result from a previous call to this endpoint.
``next_batch`` result from a previous call to this endpoint.
x-example: "YWxsCgpOb25lLDM1ODcwOA"
- in: body
name: body
@ -95,6 +95,7 @@ paths:
# for now :/
description: |-
This takes a `filter`_.
$ref: "definitions/room_event_filter.yaml"
order_by:
title: "Ordering"
type: string
@ -179,7 +180,7 @@ paths:
description: Mapping of category name to search criteria.
properties:
count:
type: number
type: integer
description: An approximate count of the total number of results found.
highlights:
type: array

@ -227,6 +227,14 @@ paths:
room up to the point when the user left.
allOf:
- $ref: "definitions/timeline_batch.yaml"
account_data:
title: Account Data
type: object
description: |-
The private data that this user has attached to
this room.
allOf:
- $ref: "definitions/event_batch.yaml"
presence:
title: Presence
type: object

@ -47,7 +47,7 @@ paths:
description: The term to search for
example: "foo"
limit:
type: number
type: integer
description: The maximum number of results to return (Defaults to 10).
example: 10
required: ["search_term"]

@ -0,0 +1,66 @@
# Copyright 2018 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
swagger: '2.0'
info:
title: "Matrix Client-Server Server Discovery API"
version: "1.0.0"
host: localhost:8008
schemes:
- https
basePath: /.well-known
produces:
- application/json
paths:
"/matrix/client":
get:
summary: Gets Matrix server discovery information about the domain.
description: |-
Gets discovery information about the domain. The file may include
additional keys, which MUST follow the Java package naming convention,
e.g. ``com.example.myapp.property``. This ensures property names are
suitably namespaced for each application and reduces the risk of
clashes.
Note that this endpoint is not necessarily handled by the homeserver,
but by another webserver, to be used for discovering the homeserver URL.
operationId: getWellknown
responses:
200:
description: Server discovery information.
examples:
application/json: {
"m.homeserver": {
"base_url": "https://matrix.example.com"
},
"m.identity_server": {
"base_url": "https://identity.example.com"
}
}
schema:
type: object
properties:
m.homeserver:
description: Information about the homeserver to connect to.
"$ref": "definitions/wellknown/homeserver.yaml"
m.identity_server:
description: Optional. Information about the identity server to connect to.
"$ref": "definitions/wellknown/identity_server.yaml"
additionalProperties:
description: Application-dependent keys using Java package naming convention.
required:
- m.homeserver
404:
description: No server discovery information available.
tags:
- Server administration

@ -46,10 +46,10 @@ paths:
description: Validation information for the session.
examples:
application/json: {
"medium": "email",
"validated_at": 1457622739026,
"address": "louise@bobs.burgers"
}
"medium": "email",
"validated_at": 1457622739026,
"address": "louise@bobs.burgers"
}
schema:
type: object
properties:
@ -62,6 +62,7 @@ paths:
validated_at:
type: integer
description: Timestamp indicating the time that the 3pid was validated.
required: ['medium', 'address', 'validated_at']
400:
description: |-
The session has not been validated.
@ -71,16 +72,20 @@ paths:
``errcode`` will be ``M_SESSION_EXPIRED``.
examples:
application/json: {
"errcode": "M_SESSION_NOT_VALIDATED",
"error": "This validation session has not yet been completed"
}
"errcode": "M_SESSION_NOT_VALIDATED",
"error": "This validation session has not yet been completed"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
404:
description: The Session ID or client secret were not found
examples:
application/json: {
"errcode": "M_NO_VALID_SESSION",
"error": "No valid session was found matching that sid and client secret"
}
"errcode": "M_NO_VALID_SESSION",
"error": "No valid session was found matching that sid and client secret"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
"/bind":
post:
summary: Publish an association between a session and a Matrix user ID.
@ -101,10 +106,10 @@ paths:
schema:
type: object
example: {
"sid": "1234",
"client_secret": "monkeys_are_GREAT",
"mxid": "@ears:matrix.org"
}
"sid": "1234",
"client_secret": "monkeys_are_GREAT",
"mxid": "@ears:matrix.org"
}
properties:
sid:
type: string
@ -121,19 +126,19 @@ paths:
description: The association was published.
examples:
application/json: {
"address": "louise@bobs.burgers",
"medium": "email",
"mxid": "@ears:matrix.org",
"not_before": 1428825849161,
"not_after": 4582425849161,
"ts": 1428825849161,
"address": "louise@bobs.burgers",
"medium": "email",
"mxid": "@ears:matrix.org",
"not_before": 1428825849161,
"not_after": 4582425849161,
"ts": 1428825849161,
"signatures": {
"matrix.org": {
"ed25519:0": "ENiU2YORYUJgE6WBMitU0mppbQjidDLanAusj8XS2nVRHPu+0t42OKA/r6zV6i2MzUbNQ3c3MiLScJuSsOiVDQ"
}
"signatures": {
"matrix.org": {
"ed25519:0": "ENiU2YORYUJgE6WBMitU0mppbQjidDLanAusj8XS2nVRHPu+0t42OKA/r6zV6i2MzUbNQ3c3MiLScJuSsOiVDQ"
}
}
}
schema:
type: object
properties:
@ -158,6 +163,15 @@ paths:
signatures:
type: object
description: The signatures of the verifying identity services which show that the association should be trusted, if you trust the verifying identity services.
$ref: "../../schemas/server-signatures.yaml"
required:
- address
- medium
- mxid
- not_before
- not_after
- ts
- signatures
400:
description: |-
The association was not published.
@ -167,13 +181,17 @@ paths:
``errcode`` will be ``M_SESSION_EXPIRED``.
examples:
application/json: {
"errcode": "M_SESSION_NOT_VALIDATED",
"error": "This validation session has not yet been completed"
}
"errcode": "M_SESSION_NOT_VALIDATED",
"error": "This validation session has not yet been completed"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
404:
description: The Session ID or client secret were not found
examples:
application/json: {
"errcode": "M_NO_VALID_SESSION",
"error": "No valid session was found matching that sid and client secret"
}
"errcode": "M_NO_VALID_SESSION",
"error": "No valid session was found matching that sid and client secret"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"

@ -51,10 +51,10 @@ paths:
schema:
type: object
example: {
"client_secret": "monkeys_are_GREAT",
"email": "foo@example.com",
"send_attempt": 1
}
"client_secret": "monkeys_are_GREAT",
"email": "foo@example.com",
"send_attempt": 1
}
properties:
client_secret:
type: string
@ -85,20 +85,28 @@ paths:
Session created.
examples:
application/json: {
"sid": "1234"
}
"sid": "1234"
}
schema:
type: object
properties:
sid:
type: string
description: The session ID.
required: ['sid']
400:
description: |
An error ocurred. Some possible errors are:
- ``M_INVALID_EMAIL``: The email address provided was invalid.
- ``M_EMAIL_SEND_ERROR``: The validation email could not be sent.
examples:
application/json: {
"errcode": "M_INVALID_EMAIL",
"error": "The email address is not valid"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
"/validate/email/submitToken":
post:
summary: Validate ownership of an email address.
@ -122,10 +130,10 @@ paths:
schema:
type: object
example: {
"sid": "1234",
"client_secret": "monkeys_are_GREAT",
"token": "atoken"
}
"sid": "1234",
"client_secret": "monkeys_are_GREAT",
"token": "atoken"
}
properties:
sid:
type: string
@ -143,14 +151,15 @@ paths:
The success of the validation.
examples:
application/json: {
"success": true
}
"success": true
}
schema:
type: object
properties:
success:
type: boolean
description: Whether the validation was successful or not.
required: ['success']
get:
summary: Validate ownership of an email address.
description: |-

@ -68,9 +68,11 @@ paths:
signatures:
type: object
description: The signature of the mxid, sender, and token.
$ref: "../../schemas/server-signatures.yaml"
token:
type: string
description: The token for the invitation.
required: ['mxid', 'sender', 'signatures', 'token']
examples:
application/json: {
"mxid": "@foo:bar.com",
@ -84,7 +86,10 @@ paths:
}
404:
description: Token was not found.
example: {
examples:
application/json: {
"errcode": "M_UNRECOGNIZED",
"error": "Didn't recognize token"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"

@ -49,19 +49,18 @@ paths:
The association for that 3pid, or the empty object if no association is known.
examples:
application/json: {
"address": "louise@bobs.burgers",
"medium": "email",
"mxid": "@ears:matrix.org",
"not_before": 1428825849161,
"not_after": 4582425849161,
"ts": 1428825849161,
"signatures": {
"matrix.org": {
"ed25519:0": "ENiU2YORYUJgE6WBMitU0mppbQjidDLanAusj8XS2nVRHPu+0t42OKA/r6zV6i2MzUbNQ3c3MiLScJuSsOiVDQ"
}
"address": "louise@bobs.burgers",
"medium": "email",
"mxid": "@ears:matrix.org",
"not_before": 1428825849161,
"not_after": 4582425849161,
"ts": 1428825849161,
"signatures": {
"matrix.org": {
"ed25519:0": "ENiU2YORYUJgE6WBMitU0mppbQjidDLanAusj8XS2nVRHPu+0t42OKA/r6zV6i2MzUbNQ3c3MiLScJuSsOiVDQ"
}
}
}
schema:
type: object
properties:
@ -86,6 +85,15 @@ paths:
signatures:
type: object
description: The signatures of the verifying identity services which show that the association should be trusted, if you trust the verifying identity services.
$ref: "../../schemas/server-signatures.yaml"
required:
- address
- medium
- mxid
- not_before
- not_after
- ts
- signatures
"/bulk_lookup":
post:
summary: Lookup Matrix user IDs for a list of 3pids.
@ -110,9 +118,14 @@ paths:
items:
type: array
title: 3PID mappings
minItems: 2
maxItems: 2
items:
type: string
title: 3PID medium or address
# TODO: Give real names to these values. Adding a `title` does not work.
#- type: 3PID Medium
#- type: 3PID Address
- type: string
- type: string
description: an array of arrays containing the `3PID Types`_ with the ``medium`` in first position and the ``address`` in second position.
required:
- "threepids"
@ -134,9 +147,16 @@ paths:
items:
type: array
title: 3PID mappings
minItems: 3
maxItems: 3
items:
type: string
title: 3PID medium or address or the Matrix ID
# TODO: Give real names to these values. Adding a `title` does not work.
#- type: 3PID Medium
#- type: 3PID Address
#- type: Matrix User ID
- type: string
- type: string
- type: string
description: an array of array containing the `3PID Types`_ with the ``medium`` in first position, the ``address`` in second position and Matrix ID in third position.
required:
- "threepids"

@ -51,11 +51,11 @@ paths:
schema:
type: object
example: {
"client_secret": "monkeys_are_GREAT",
"country": "GB",
"phone_number": "07700900001",
"send_attempt": 1
}
"client_secret": "monkeys_are_GREAT",
"country": "GB",
"phone_number": "07700900001",
"send_attempt": 1
}
properties:
client_secret:
type: string
@ -91,20 +91,28 @@ paths:
Session created.
examples:
application/json: {
"sid": "1234"
}
"sid": "1234"
}
schema:
type: object
properties:
sid:
type: string
description: The session ID.
required: ['sid']
400:
description: |
An error ocurred. Some possible errors are:
- ``M_INVALID_ADDRESS``: The phone number provided was invalid.
- ``M_SEND_ERROR``: The validation SMS could not be sent.
examples:
application/json: {
"errcode": "M_INVALID_ADDRESS",
"error": "The phone number is not valid"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
"/validate/msisdn/submitToken":
post:
summary: Validate ownership of a phone number.
@ -128,10 +136,10 @@ paths:
schema:
type: object
example: {
"sid": "1234",
"client_secret": "monkeys_are_GREAT",
"token": "atoken"
}
"sid": "1234",
"client_secret": "monkeys_are_GREAT",
"token": "atoken"
}
properties:
sid:
type: string
@ -149,14 +157,15 @@ paths:
The success of the validation.
examples:
application/json: {
"success": true
}
"success": true
}
schema:
type: object
properties:
success:
type: boolean
description: Whether the validation was successful or not.
required: ['success']
get:
summary: Validate ownership of a phone number.
description: |-

@ -45,13 +45,25 @@ paths:
The public key exists.
examples:
application/json: {
"public_key": "VXuGitF39UH5iRfvbIknlvlAVKgD1BsLDMvBf0pmp7c"
}
"public_key": "VXuGitF39UH5iRfvbIknlvlAVKgD1BsLDMvBf0pmp7c"
}
schema:
type: object
properties:
public_key:
type: string
description: Unpadded Base64 encoded public key.
required: ['public_key']
404:
description:
The public key was not found.
examples:
application/json: {
"errcode": "M_NOT_FOUND",
"error": "The public key was not found"
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
"/pubkey/isvalid":
get:
summary: Check whether a long-term public key is valid.
@ -72,14 +84,15 @@ paths:
The validity of the public key.
examples:
application/json: {
"valid": true
}
"valid": true
}
schema:
type: object
properties:
valid:
type: boolean
description: Whether the public key is recognised and is currently valid.
required: ['valid']
"/pubkey/ephemeral/isvalid":
get:
summary: Check whether a short-term public key is valid.
@ -108,3 +121,4 @@ paths:
valid:
type: boolean
description: Whether the public key is recognised and is currently valid.
required: ['valid']

@ -54,11 +54,11 @@ paths:
schema:
type: object
example: {
"medium": "email",
"address": "foo@bar.baz",
"room_id": "!something:example.tld",
"sender": "@bob:example.com"
}
"medium": "email",
"address": "foo@bar.baz",
"room_id": "!something:example.tld",
"sender": "@bob:example.com"
}
properties:
medium:
type: string
@ -90,15 +90,16 @@ paths:
display_name:
type: string
description: The generated (redacted) display_name.
required: ['token', 'public_keys', 'display_name']
example:
application/json: {
"token": "sometoken",
"public_keys": [
"serverpublickey",
"ephemeralpublickey"
],
"display_name": "f...@b..."
}
"token": "sometoken",
"public_keys": [
"serverpublickey",
"ephemeralpublickey"
],
"display_name": "f...@b..."
}
400:
description: |
An error has occured.
@ -108,7 +109,9 @@ paths:
error code will be ``M_UNRECOGNIZED``.
examples:
application/json: {
"errcode": "M_THREEPID_IN_USE",
"error": "Binding already known",
"mxid": mxid
}
"errcode": "M_THREEPID_IN_USE",
"error": "Binding already known",
"mxid": mxid
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"

@ -31,7 +31,7 @@ properties:
example: 1532991320875
pdus:
type: array
description: List of persistent updates to rooms.
description: List of persistent updates to rooms. Must not include more than 50 PDUs.
items:
$ref: "pdu.yaml"
required: ['origin', 'origin_server_ts', 'pdus']

@ -60,8 +60,8 @@ paths:
edus:
type: array
description: |-
List of ephemeral messages. May be omitted if there are no ephemeral
messages to be sent.
List of ephemeral messages. May be omitted if there are no ephemeral
messages to be sent. Must not include more than 100 EDUs.
items:
$ref: "definitions/edu.yaml"
example: {

@ -0,0 +1 @@
Specify how to control the power level required for ``@room``

@ -0,0 +1 @@
Add ``.well-known`` server discovery method

@ -0,0 +1 @@
Share room decryption keys between devices

@ -0,0 +1 @@
Add a common standard for user, room, and group mentions in messages.

@ -0,0 +1 @@
Clarify the supported HTML features for room messages.

@ -0,0 +1 @@
Move the ``invite_room_state`` definition under ``unsigned`` where it actually resides.

@ -0,0 +1 @@
Clarify the object structures and defaults for Filters.

@ -0,0 +1 @@
Clarify instances of ``type: number`` in the swagger/OpenAPI schema definitions.

@ -0,0 +1 @@
Clarify that left rooms also have account data in ``/sync``.

@ -0,0 +1 @@
Clarify the filter object schema used in room searching.

@ -0,0 +1 @@
specify how to handle multiple olm sessions with the same device

@ -0,0 +1,6 @@
r0.1.0
======
The first release of the Push Gateway specification. This release contains
a single endpoint, ``/notify``, that pushers may use to send push notifications
to clients.

@ -0,0 +1,30 @@
[tool.towncrier]
filename = "../push_gateway.rst"
directory = "newsfragments"
issue_format = "`#{issue} <https://github.com/matrix-org/matrix-doc/issues/{issue}>`_"
title_format = "{version}"
[[tool.towncrier.type]]
directory = "breaking"
name = "Breaking Changes"
showcontent = true
[[tool.towncrier.type]]
directory = "deprecation"
name = "Deprecations"
showcontent = true
[[tool.towncrier.type]]
directory = "new"
name = "New Endpoints"
showcontent = true
[[tool.towncrier.type]]
directory = "feature"
name = "Backwards Compatible Changes"
showcontent = true
[[tool.towncrier.type]]
directory = "clarification"
name = "Spec Clarifications"
showcontent = true

@ -0,0 +1,14 @@
{
"content": {
"algorithm": "m.megolm.v1.aes-sha2",
"room_id": "!Cuyf34gef24t:localhost",
"session_id": "X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ",
"session_key": "AgAAAADxKHa9uFxcXzwYoNueL5Xqi69IkD4sni8Llf...",
"sender_key": "RF3s+E7RkTQTGF2d8Deol0FkQvgII2aJDf3/Jp5mxVU",
"sender_claimed_ed25519_key": "aj40p+aw64yPIdsxoog8jhPu9i7l7NcFRecuOQblE3Y",
"forwarding_curve25519_key_chain": [
"hPQNcabIABgGnx3/ACv/jmMmiQHoeFfuLB17tzWp6Hw"
]
},
"type": "m.forwarded_room_key"
}

@ -5,22 +5,24 @@
"avatar_url": "mxc://localhost/SEsfnsuifSDFSSEF#auto",
"displayname": "Alice Margatroid"
},
"invite_room_state": [
{
"type": "m.room.name",
"state_key": "",
"content": {
"name": "Forest of Magic"
"unsigned": {
"invite_room_state": [
{
"type": "m.room.name",
"state_key": "",
"content": {
"name": "Forest of Magic"
}
},
{
"type": "m.room.join_rules",
"state_key": "",
"content": {
"join_rule": "invite"
}
}
},
{
"type": "m.room.join_rules",
"state_key": "",
"content": {
"join_rule": "invite"
}
}
],
]
},
"state_key": "@alice:localhost",
"origin_server_ts": 1431961217939,
"event_id": "$WLGTSEFSEF:localhost",

@ -2,7 +2,9 @@
"age": 242352,
"content": {
"body": "This is an example notice",
"msgtype": "m.notice"
"msgtype": "m.notice",
"format": "org.matrix.custom.html",
"formatted_body": "This is an <strong>example</strong> notice"
},
"origin_server_ts": 1431961217939,
"event_id": "$WLGTSEFSEF:localhost",

@ -14,7 +14,10 @@
"users": {
"@example:localhost": 100
},
"users_default": 0
"users_default": 0,
"notifications": {
"room": 20
}
},
"state_key": "",
"origin_server_ts": 1431961217939,

@ -0,0 +1,8 @@
{
"content": {
"action": "cancel_request",
"requesting_device_id": "RJYKSTBOIE",
"request_id": "1495474790150.19"
},
"type": "m.room_key_request"
}

@ -0,0 +1,14 @@
{
"content": {
"body": {
"algorithm": "m.megolm.v1.aes-sha2",
"room_id": "!Cuyf34gef24t:localhost",
"session_id": "X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ",
"sender_key": "RF3s+E7RkTQTGF2d8Deol0FkQvgII2aJDf3/Jp5mxVU"
},
"action": "request",
"requesting_device_id": "RJYKSTBOIE",
"request_id": "1495474790150.19"
},
"type": "m.room_key_request"
}

@ -16,7 +16,8 @@ properties:
origin_server_ts:
description: Timestamp in milliseconds on originating homeserver
when this event was sent.
type: number
type: integer
format: int64
unsigned:
description: Contains optional extra information about the event.
properties:

@ -11,7 +11,11 @@ properties:
state_key:
description: A unique key which defines the overwriting semantics for this piece
of room state. This value is often a zero-length string. The presence of this
key makes this event a State Event. The key MUST NOT start with '_'.
key makes this event a State Event.
State keys starting with an ``@`` are reserved for referencing user IDs, such
as room members. With the exception of a few events, state events set with a
given user's ID as the state key MUST only be set by that user.
type: string
required:
- state_key

@ -0,0 +1,59 @@
---
allOf:
- $ref: core-event-schema/event.yaml
description: |-
This event type is used to forward keys for end-to-end encryption. Typically
it is encrypted as an ``m.room.encrypted`` event, then sent as a `to-device`_
event.
properties:
content:
properties:
algorithm:
type: string
description: |-
The encryption algorithm the key in this event is to be used with.
room_id:
type: string
description: The room where the key is used.
sender_key:
type: string
description: |-
The Curve25519 key of the device which initiated the session originally.
session_id:
type: string
description: The ID of the session that the key is for.
session_key:
type: string
description: The key to be exchanged.
sender_claimed_ed25519_key:
type: string
description: |-
The Ed25519 key of the device which initiated the session originally.
It is 'claimed' because the receiving device has no way to tell that the
original room_key actually came from a device which owns the private part of
this key unless they have done device verification.
forwarding_curve25519_key_chain:
type: array
items:
type: string
description: |-
Chain of Curve25519 keys. It starts out empty, but each time the
key is forwarded to another device, the previous sender in the chain is added
to the end of the list. For example, if the key is forwarded from A to B to
C, this field is empty between A and B, and contains A's Curve25519 key between
B and C.
required:
- algorithm
- room_id
- session_id
- session_key
- sender_claimed_ed25519_key
- forwarding_curve25519_key_chain
- sender_key
type: object
type:
enum:
- m.forwarded_room_key
type: string
type: object

@ -18,7 +18,9 @@ description: |-
The ``third_party_invite`` property will be set if this invite is an ``invite`` event and is the successor of an ``m.room.third_party_invite`` event, and absent otherwise.
This event may also include an ``invite_room_state`` key **outside the** ``content`` **key**. If present, this contains an array of ``StrippedState`` Events. These events provide information on a subset of state events such as the room name.
This event may also include an ``invite_room_state`` key inside the event's ``unsigned`` data.
If present, this contains an array of ``StrippedState`` Events. These events provide information
on a subset of state events such as the room name.
properties:
content:
properties:
@ -71,34 +73,42 @@ properties:
- signed
title: Invite
type: object
unsigned:
type: object
title: UnsignedData
description: Contains optional extra information about the event.
properties:
invite_room_state:
description: 'A subset of the state of the room at the time of the invite, if ``membership`` is ``invite``. Note that this state is informational, and SHOULD NOT be trusted; once the client has joined the room, it SHOULD fetch the live state from the server and discard the invite_room_state. Also, clients must not rely on any particular state being present here; they SHOULD behave properly (with possibly a degraded but not a broken experience) in the absence of any particular events here. If they are set on the room, at least the state for ``m.room.avatar``, ``m.room.canonical_alias``, ``m.room.join_rules``, and ``m.room.name`` SHOULD be included.'
items:
description: 'A stripped down state event, with only the ``type``, ``state_key`` and ``content`` keys.'
properties:
content:
description: The ``content`` for the event.
title: EventContent
type: object
state_key:
description: The ``state_key`` for the event.
type: string
type:
description: The ``type`` for the event.
type: string
required:
- type
- state_key
- content
title: StrippedState
type: object
type: array
required:
- membership
title: EventContent
type: object
invite_room_state:
description: 'A subset of the state of the room at the time of the invite, if ``membership`` is ``invite``. Note that this state is informational, and SHOULD NOT be trusted; once the client has joined the room, it SHOULD fetch the live state from the server and discard the invite_room_state. Also, clients must not rely on any particular state being present here; they SHOULD behave properly (with possibly a degraded but not a broken experience) in the absence of any particular events here. If they are set on the room, at least the state for ``m.room.avatar``, ``m.room.canonical_alias``, ``m.room.join_rules``, and ``m.room.name`` SHOULD be included.'
items:
description: 'A stripped down state event, with only the ``type``, ``state_key`` and ``content`` keys.'
properties:
content:
description: The ``content`` for the event.
title: EventContent
type: object
state_key:
description: The ``state_key`` for the event.
type: string
type:
description: The ``type`` for the event.
type: string
required:
- type
- state_key
- content
title: StrippedState
type: object
type: array
state_key:
description: The ``user_id`` this membership event relates to.
description: |-
The ``user_id`` this membership event relates to. In all cases except for when ``membership`` is
``join``, the user ID sending the event does not need to match the user ID in the ``state_key``,
unlike other events. Regular authorisation rules still apply.
type: string
type:
enum:

@ -46,10 +46,10 @@ properties:
properties:
ban:
description: The level required to ban a user. Defaults to 50 if unspecified.
type: number
type: integer
events:
additionalProperties:
type: number
type: integer
description: The level required to send specific event types. This is a mapping from event type to power level required.
title: Event power levels
type: object
@ -57,25 +57,25 @@ properties:
description: |-
The default level required to send message events. Can be
overridden by the ``events`` key. Defaults to 0 if unspecified.
type: number
type: integer
invite:
description: The level required to invite a user. Defaults to 50 if unspecified.
type: number
type: integer
kick:
description: The level required to kick a user. Defaults to 50 if unspecified.
type: number
type: integer
redact:
description: The level required to redact an event. Defaults to 50 if unspecified.
type: number
type: integer
state_default:
description: |-
The default level required to send state events. Can be overridden
by the ``events`` key. Defaults to 50 if unspecified, but 0 if
there is no ``m.room.power_levels`` event at all.
type: number
type: integer
users:
additionalProperties:
type: number
type: integer
description: The power levels for specific users. This is a mapping from ``user_id`` to power level for that user.
title: User power levels
type: object
@ -84,7 +84,19 @@ properties:
The default power level for every user in the room, unless their
``user_id`` is mentioned in the ``users`` key. Defaults to 0 if
unspecified.
type: number
type: integer
notifications:
properties:
room:
type: integer
description: The level required to trigger an ``@room`` notification. Defaults to 50 if unspecified.
additionalProperties:
type: integer
description: |-
The power level requirements for specific notification types.
This is a mapping from ``key`` to power level for that notifications key.
title: Notifications
type: object
type: object
state_key:
description: A zero-length string.

@ -85,4 +85,4 @@ properties:
type: string
type:
enum: ['m.room.server_acl']
type: enum
type: string

@ -0,0 +1,61 @@
---
allOf:
- $ref: core-event-schema/event.yaml
description: |-
This event type is used to request keys for end-to-end encryption. It is sent as an
unencrypted `to-device`_ event.
properties:
content:
properties:
body:
description: |-
Information about the requested key. Required when ``action`` is
``request``.
properties:
algorithm:
type: string
description: |-
The encryption algorithm the requested key in this event is to be used
with.
room_id:
type: string
description: The room where the key is used.
sender_key:
type: string
description: |-
The Curve25519 key of the device which initiated the session originally.
session_id:
type: string
description: The ID of the session that the key is for.
required:
- algorithm
- room_id
- session_id
- sender_key
type: object
title: RequestedKeyInfo
action:
enum:
- request
- cancel_request
type: string
requesting_device_id:
description: ID of the device requesting the key.
type: string
request_id:
description: |-
A random string uniquely identifying the request for a key. If the key is
requested multiple times, it should be reused. It should also reused in order
to cancel a request.
type: string
required:
- action
- requesting_device_id
- request_id
type: object
type:
enum:
- m.room_key_request
type: string
type: object

@ -0,0 +1,48 @@
# How to release a specification
There are several specifications that belong to matrix, such as the client-server
specification, server-server specification, and identity server specification. Each
of these gets released independently of each other with their own version numbers.
Once a specification is ready for release, a branch should be created to track the
changes in and to hold potential future hotfixes. This should be the name of the
specification (as it appears in the directory structure of this project) followed
by "release-" and the release version. For example, if the Client-Server Specification
was getting an r0.4.0 release, the branch name would be `client_server/release-r0.4.0`.
*Note*: Historical releases prior to this process may or may not have an appropriate
release branch. Releases after this document came into place will have an appropriate
branch.
The remainder of the process is as follows:
1. Activate your Python 3 virtual environment.
1. Having checked out the new release branch, navigate your way over to `./changelogs`.
1. Follow the release instructions provided in the README.md located there.
1. Update the changelog section of the specification you're releasing to make a reference
to the new version.
1. Update any version/link references across all specifications.
1. Ensure the `targets.yml` file lists the version correctly.
1. Commit the changes and PR them to master.
1. Tag the release with the format `client_server/r0.4.0`.
1. Add the changes to the matrix-org/matrix.org repository (for historic tracking).
* This is done by making a PR to the `unstyled_docs/spec` folder for the version and
specification you're releasing.
* Don't forget to symlink the new release as `latest`.
1. Perform a release on GitHub to tag the release.
1. Yell from the mountaintop to the world about the new release.
### Creating a release for a brand-new specification
Some specifications may not have ever had a release, and therefore need a bit more work
to become ready.
1. Activate your Python 3 virtual environment.
1. Having checked out the new release branch, navigate your way over to `./changelogs`.
1. Follow the "new changelog" instructions provided in the README.md located there.
1. Open the specification RST file and make some changes:
* Using a released specification as a template, update the changelog section.
* Use the appropriate changelog variable in the RST.
1. Create/define the appropriate variables in `gendoc.py`.
1. Update `targets.yml`.
1. Update any version/link references across all specifications.
1. Follow the regular release process.

@ -0,0 +1,24 @@
# Copyright 2018 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
type: object
example: {
"example.com": {
"ed25519:0": "these86bytesofbase64signaturecoveressentialfieldsincludinghashessocancheckredactedpdus"
}
}
additionalProperties:
type: object
title: Server Signatures
additionalProperties:
type: string

@ -522,6 +522,10 @@ if __name__ == '__main__':
"--appservice_release", "-a", action="store", default="unstable",
help="The appservice release tag to generate, e.g. r1.2"
)
parser.add_argument(
"--push_gateway_release", "-p", action="store", default="unstable",
help="The push gateway release tag to generate, e.g. r1.2"
)
parser.add_argument(
"--list_targets", action="store_true",
help="Do not update the specification. Instead print a list of targets.",
@ -548,6 +552,7 @@ if __name__ == '__main__':
"%SERVER_MAJOR_VERSION%": extract_major(args.server_release),
"%APPSERVICE_MAJOR_VERSION%": "unstable",
"%APPSERVICE_RELEASE_LABEL%": args.appservice_release,
"%PUSH_GATEWAY_RELEASE_LABEL%": args.push_gateway_release,
}
exit (main(args.target or ["all"], args.dest, args.nodelete, substitutions))

@ -31,6 +31,11 @@ class MatrixSections(Sections):
def render_client_server_changelog(self):
changelogs = self.units.get("changelogs")
return changelogs["client_server"]
# TODO: We should make this a generic variable instead of having to add functions all the time.
def render_push_gateway_changelog(self):
changelogs = self.units.get("changelogs")
return changelogs["push_gateway"]
def render_application_service_changelog(self):
changelogs = self.units.get("changelogs")

@ -755,6 +755,7 @@ class MatrixUnits(Units):
cs_ver = substitutions.get("%CLIENT_RELEASE_LABEL%", "unstable")
fed_ver = substitutions.get("%SERVER_RELEASE_LABEL%", "unstable")
as_ver = substitutions.get("%APPSERVICE_RELEASE_LABEL%", "unstable")
push_gw_ver = substitutions.get("%PUSH_GATEWAY_RELEASE_LABEL%", "unstable")
# we abuse the typetable to return this info to the templates
return TypeTable(rows=[
@ -775,8 +776,8 @@ class MatrixUnits(Units):
"unstable",
"Mapping of third party IDs to Matrix IDs",
), TypeTableRow(
"`Push Gateway API <push_gateway/unstable.html>`_",
"unstable",
"`Push Gateway API <push_gateway/"+push_gw_ver+".html>`_",
push_gw_ver,
"Push notifications for Matrix events",
),
])
@ -876,15 +877,6 @@ 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_tables_for_schema(
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"

@ -1,5 +1,5 @@
.. Copyright 2016 Openmarket Ltd.
.. Copyright 2017 New Vector Ltd.
.. Copyright 2017, 2018 New Vector Ltd.
..
.. Licensed under the Apache License, Version 2.0 (the "License");
.. you may not use this file except in compliance with the License.
@ -283,3 +283,45 @@ domain).
.. TODO-spec
- Need to specify precise grammar for Room Aliases. https://matrix.org/jira/browse/SPEC-391
matrix.to navigation
++++++++++++++++++++
.. NOTE::
This namespacing is in place pending a ``matrix://`` (or similar) URI scheme.
This is **not** meant to be interpreted as an available web service - see
below for more details.
Rooms, users, aliases, and groups may be represented as a "matrix.to" URI.
This URI can be used to reference particular objects in a given context, such
as mentioning a user in a message or linking someone to a particular point
in the room's history (a permalink).
A matrix.to URI has the following format, based upon the specification defined
in RFC 3986:
https://matrix.to/#/<identifier>/<extra parameter>
The identifier may be a room ID, room alias, user ID, or group ID. The extra
parameter is only used in the case of permalinks where an event ID is referenced.
The matrix.to URI, when referenced, must always start with ``https://matrix.to/#/``
followed by the identifier.
Clients should not rely on matrix.to URIs falling back to a web server if accessed
and instead should perform some sort of action within the client. For example, if
the user were to click on a matrix.to URI for a room alias, the client may open
a view for the user to participate in the room.
Examples of matrix.to URIs are:
* Room alias: ``https://matrix.to/#/#somewhere:domain.com``
* Room: ``https://matrix.to/#/!somewhere:domain.com``
* Permalink by room: ``https://matrix.to/#/!somewhere:domain.com/$event:example.org``
* Permalink by room alias: ``https://matrix.to/#/#somewhere:domain.com/$event:example.org``
* User: ``https://matrix.to/#/@alice:example.org``
* Group: ``https://matrix.to/#/+example:domain.com``
.. Note::
Room ID permalinks are unroutable as there is no reliable domain to send requests
to upon receipt of the permalink. Clients should do their best route Room IDs to
where they need to go, however they should also be aware of `issue #1579 <https://github.com/matrix-org/matrix-doc/issues/1579>`_.

@ -304,26 +304,37 @@ An example request would be::
GET /_matrix/client/%CLIENT_MAJOR_VERSION%/account/whoami?user_id=@_irc_user:example.org
Authorization: Bearer YourApplicationServiceTokenHere
.. TODO-TravisR: Temporarily take out timestamp massaging while we're releasing r0.
See https://github.com/matrix-org/matrix-doc/issues/1585
.. Timestamp massaging
+++++++++++++++++++
The application service may want to inject events at a certain time (reflecting
the time on the network they are tracking e.g. irc, xmpp). Application services
need to be able to adjust the ``origin_server_ts`` value to do this.
Timestamp massaging
+++++++++++++++++++
The application service may want to inject events at a certain time (reflecting
the time on the network they are tracking e.g. irc, xmpp). Application services
need to be able to adjust the ``origin_server_ts`` value to do this.
Inputs:
- Application service token (``as_token``)
- Desired timestamp (in milliseconds since the unix epoch)
Inputs:
- Application service token (``as_token``)
- Desired timestamp (in milliseconds since the unix epoch)
Notes:
- This will only apply when sending events.
Notes:
- This will only apply when sending events.
::
::
PUT /_matrix/client/r0/rooms/!somewhere:domain.com/send/m.room.message/txnId?ts=1534535223283
Authorization: Bearer YourApplicationServiceTokenHere
PUT /_matrix/client/r0/rooms/!somewhere:domain.com/send/m.room.message/txnId?ts=1534535223283
Authorization: Bearer YourApplicationServiceTokenHere
Content: The event to send, as per the Client-Server API.
Timestamp massaging
+++++++++++++++++++
Content: The event to send, as per the Client-Server API.
Previous drafts of the Application Service API permitted application services
to alter the timestamp of their sent events by providing a ``ts`` query parameter
when sending an event. This API has been excluded from the first release due to
design concerns, however some servers may still support the feature. Please visit
`issue #1585 <https://github.com/matrix-org/matrix-doc/issues/1585>`_ for more
information.
Server admin style permissions
++++++++++++++++++++++++++++++

@ -189,6 +189,82 @@ headers to be returned by servers on all requests are:
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization
Server Discovery
----------------
In order to allow users to connect to a Matrix server without needing to
explicitly specify the homeserver's URL or other parameters, clients SHOULD use
an auto-discovery mechanism to determine the server's URL based on a user's
Matrix ID. Auto-discovery should only be done at login time.
In this section, the following terms are used with specific meanings:
``PROMPT``
Retrieve the specific piece of information from the user in a way which
fits within the existing client user experience, if the client is inclined to
do so. Failure can take place instead if no good user experience for this is
possible at this point.
``IGNORE``
Stop the current auto-discovery mechanism. If no more auto-discovery
mechanisms are available, then the client may use other methods of
determining the required parameters, such as prompting the user, or using
default values.
``FAIL_PROMPT``
Inform the user that auto-discovery failed due to invalid/empty data and
``PROMPT`` for the parameter.
``FAIL_ERROR``
Inform the user that auto-discovery did not return any usable URLs. Do not
continue further with the current login process. At this point, valid data
was obtained, but no homeserver is available to serve the client. No further
guess should be attempted and the user should make a conscientious decision
what to do next.
Well-known URI
~~~~~~~~~~~~~~
The ``.well-known`` method uses a JSON file at a predetermined location to
specify parameter values. The flow for this method is as follows:
1. Extract the server name from the user's Matrix ID by splitting the Matrix ID
at the first colon.
2. Extract the hostname from the server name.
3. Make a GET request to ``https://hostname/.well-known/matrix/client``.
a. If the returned status code is 404, then ``IGNORE``.
b. If the returned status code is not 200, or the response body is empty,
then ``FAIL_PROMPT``.
c. Parse the response body as a JSON object
i. If the content cannot be parsed, then ``FAIL_PROMPT``.
d. Extract the ``base_url`` value from the ``m.homeserver`` property. This
value is to be used as the base URL of the homeserver.
i. If this value is not provided, then ``FAIL_PROMPT``.
e. Validate the homeserver base URL:
i. Parse it as a URL. If it is not a URL, then ``FAIL_ERROR``.
ii. Clients SHOULD validate that the URL points to a valid homeserver
before accepting it by connecting to the |/_matrix/client/versions|_
endpoint, ensuring that it does not return an error, and parsing and
validating that the data conforms with the expected response
format. If any step in the validation fails, then
``FAIL_ERROR``. Validation is done as a simple check against
configuration errors, in order to ensure that the discovered address
points to a valid homeserver.
f. If the ``m.identity_server`` property is present, extract the
``base_url`` value for use as the base URL of the identity server.
Validation for this URL is done as in the step above, but using
``/_matrix/identity/api/v1`` as the endpoint to connect to. If the
``m.identity_server`` property is present, but does not have a
``base_url`` value, then ``FAIL_ERROR``.
{{wellknown_cs_http_api}}
Client Authentication
---------------------
@ -1596,5 +1672,8 @@ have to wait in milliseconds before they can try again.
.. |/user/<user_id>/account_data/<type>| replace:: ``/user/<user_id>/account_data/<type>``
.. _/user/<user_id>/account_data/<type>: #put-matrix-client-%CLIENT_MAJOR_VERSION%-user-userid-account-data-type
.. |/_matrix/client/versions| replace:: ``/_matrix/client/versions``
.. _/_matrix/client/versions: #get-matrix-client-versions
.. _`Unpadded Base64`: ../appendices.html#unpadded-base64
.. _`3PID Types`: ../appendices.html#pid-types

@ -23,7 +23,7 @@ user identifiers. From time to time, it is useful to refer to users by other
number. This identity service specification describes how mappings between
third-party identifiers and Matrix user identifiers can be established,
validated, and used. This description technically may apply to any 3pid, but in
practice has only been applied specifically to email addresses.
practice has only been applied specifically to email addresses and phone numbers.
.. contents:: Table of Contents
.. sectnum::
@ -56,6 +56,75 @@ is left as an exercise for the client.
3PID types are described in `3PID Types`_ Appendix.
API Standards
-------------
The mandatory baseline for identity service communication in Matrix is exchanging
JSON objects over HTTP APIs. HTTPS is required for communication, and all API calls
use a Content-Type of ``application/json``. In addition, strings MUST be encoded as
UTF-8.
Any errors which occur at the Matrix API level MUST return a "standard error response".
This is a JSON object which looks like:
.. code:: json
{
"errcode": "<error code>",
"error": "<error message>"
}
The ``error`` string will be a human-readable error message, usually a sentence
explaining what went wrong. The ``errcode`` string will be a unique string
which can be used to handle an error message e.g. ``M_FORBIDDEN``. There may be
additional keys depending on the error, but the keys ``error`` and ``errcode``
MUST always be present.
Some standard error codes are below:
:``M_NOT_FOUND``:
The resource requested could not be located.
:``M_MISSING_PARAMS``:
The request was missing one or more parameters.
:``M_INVALID_PARAM``:
The request contained one or more invalid parameters.
:``M_SESSION_NOT_VALIDATED``:
The session has not been validated.
:``M_NO_VALID_SESSION``:
A session could not be located for the given parameters.
:``M_SESSION_EXPIRED``:
The session has expired and must be renewed.
:``M_INVALID_EMAIL``:
The email address provided was not valid.
:``M_EMAIL_SEND_ERROR``:
There was an error sending an email. Typically seen when attempting to verify
ownership of a given email address.
:``M_INVALID_ADDRESS``:
The provided third party address was not valid.
:``M_SEND_ERROR``:
There was an error sending a notification. Typically seen when attempting to
verify ownership of a given third party address.
:``M_UNRECOGNIZED``:
The request contained an unrecognised value, such as an unknown token or medium.
:``M_THREEPID_IN_USE``:
The third party identifier is already in use by another user. Typically this
error will have an additional ``mxid`` property to indicate who owns the
third party identifier.
:``M_UNKNOWN``:
An unknown error has occurred.
Privacy
-------

@ -283,6 +283,31 @@ Device verification may reach one of several conclusions. For example:
decrypted by such a device. For the Olm protocol, this is documented at
https://matrix.org/git/olm/about/docs/signing.rst.
Key sharing
-----------
If Bob has an encrypted conversation with Alice on his computer, and then logs in
through his phone for the first time, he may want to have access to the previously
exchanged messages. To address this issue, events exist for requesting and sending
keys from device to device.
When a device is missing keys to decrypt messages, it can request the keys by
sending `m.room_key_request`_ to-device messages to other devices with
``action`` set to ``request``. If a device wishes to share the keys with that
device, it can forward the keys to the first device by sending an encrypted
`m.forwarded_room_key`_ to-device message. The first device should then send an
`m.room_key_request`_ to-device message with ``action`` set to
``cancel_request`` to the other devices that it had originally sent the key
request to; a device that receives a ``cancel_request`` should disregard any
previously-received ``request`` message with the same ``request_id`` and
``requesting_device_id``.
.. NOTE::
Key sharing can be a big attack vector, thus it must be done very carefully.
A reasonable stategy is for a user's client to only send keys requested by the
verified devices of the same user.
Messaging Algorithms
--------------------
@ -391,6 +416,12 @@ this check, a client cannot be sure that the sender device owns the private
part of the ed25519 key it claims to have in the Olm payload.
This is crucial when the ed25519 key corresponds to a verified device.
If a client has multiple sessions established with another device, it should
use the session from which it last received a message. A client may expire old
sessions by defining a maximum number of olm sessions that it will maintain for
each device, and expiring sessions on a Least Recently Used basis. The maximum
number of olm sessions maintained per device should be at least 4.
``m.megolm.v1.aes-sha2``
~~~~~~~~~~~~~~~~~~~~~~~~
@ -464,6 +495,10 @@ Events
{{m_room_key_event}}
{{m_room_key_request_event}}
{{m_forwarded_room_key_event}}
Key management API
~~~~~~~~~~~~~~~~~~

@ -56,6 +56,60 @@ of message being sent. Each type has their own required and optional keys, as
outlined below. If a client cannot display the given ``msgtype`` then it SHOULD
display the fallback plain text ``body`` key instead.
Some message types support HTML in the event content that clients should prefer
to display if available. Currently ``m.text``, ``m.emote``, and ``m.notice``
support an additional ``format`` parameter of ``org.matrix.custom.html``. When
this field is present, a ``formatted_body`` with the HTML must be provided. The
plain text version of the HTML should be provided in the ``body``.
Clients should limit the HTML they render to avoid Cross-Site Scripting, HTML
injection, and similar attacks. The strongly suggested set of HTML tags to permit,
denying the use and rendering of anything else, is: ``font``, ``del``, ``h1``,
``h2``, ``h3``, ``h4``, ``h5``, ``h6``, ``blockquote``, ``p``, ``a``, ``ul``,
``ol``, ``sup``, ``sub``, ``li``, ``b``, ``i``, ``u``, ``strong``, ``em``,
``strike``, ``code``, ``hr``, ``br``, ``div``, ``table``, ``thead``, ``tbody``,
``tr``, ``th``, ``td``, ``caption``, ``pre``, ``span``, ``img``.
Not all attributes on those tags should be permitted as they may be avenues for
other disruption attempts, such as adding ``onclick`` handlers or excessively
large text. Clients should only permit the attributes listed for the tags below.
Where ``data-mx-bg-color`` and ``data-mx-color`` are listed, clients should
translate the value (a 6-character hex color code) to the appropriate CSS/attributes
for the tag.
:``font``:
``data-mx-bg-color``, ``data-mx-color``
:``span``:
``data-mx-bg-color``, ``data-mx-color``
:``a``:
``name``, ``target``, ``href`` (provided the value is not relative and has a scheme
matching one of: ``https``, ``http``, ``ftp``, ``mailto``, ``magnet``)
:``img``:
``width``, ``height``, ``alt``, ``title``, ``src`` (provided it is a `Matrix Content (MXC) URI`_)
:``ol``:
``start``
:``code``:
``class`` (only classes which start with ``language-`` for syntax highlighting)
Additionally, web clients should ensure that *all* ``a`` tags get a ``rel="noopener"``
to prevent the target page from referencing the client's tab/window.
Tags must not be nested more than 100 levels deep. Clients should only support the subset
of tags they can render, falling back to other representations of the tags where possible.
For example, a client may not be able to render tables correctly and instead could fall
back to rendering tab-delimited text.
.. Note::
A future iteration of the specification will support more powerful and extensible
message formatting options, such as the proposal `MSC1225 <https://github.com/matrix-org/matrix-doc/issues/1225>`_.
{{msgtype_events}}
@ -297,3 +351,4 @@ Clients should sanitise **all displayed keys** for unsafe HTML to prevent Cross-
Scripting (XSS) attacks. This includes room names and topics.
.. _`E2E module`: `module:e2e`_
.. _`Matrix Content (MXC) URI`: `module:content`_

@ -0,0 +1,74 @@
.. Copyright 2018 New Vector Ltd.
..
.. Licensed under the Apache License, Version 2.0 (the "License");
.. you may not use this file except in compliance with the License.
.. You may obtain a copy of the License at
..
.. http://www.apache.org/licenses/LICENSE-2.0
..
.. Unless required by applicable law or agreed to in writing, software
.. distributed under the License is distributed on an "AS IS" BASIS,
.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
.. See the License for the specific language governing permissions and
.. limitations under the License.
User, room, and group mentions
==============================
.. _module:mentions:
This module allows users to mention other users, rooms, and groups within
a room message. This is achieved by including a `matrix.to URI`_ in the HTML
body of an `m.room.message`_ event. This module does not have any server-specific
behaviour to it.
Mentions apply only to `m.room.message`_ events where the ``msgtype`` is ``m.text``,
``m.emote``, or ``m.notice``. The ``format`` for the event must be ``org.matrix.custom.html``
and therefore requires a ``formatted_body``.
To make a mention, reference the entity being mentioned in the ``formatted_body``
using an anchor, like so::
{
"body": "Hello Alice!",
"msgtype": "m.text",
"format": "org.matrix.custom.html",
"formatted_body": "Hello <a href='https://matrix.to/#/@alice:example.org'>Alice</a>!"
}
Client behaviour
----------------
In addition to using the appropriate ``matrix.to URI`` for the mention,
clients should use the following guidelines when making mentions in events
to be sent:
* When mentioning users, use the user's potentially ambigious display name for
the anchor's text. If the user does not have a display name, use the user's
ID.
* When mentioning rooms, use the canonical alias for the room. If the room
does not have a canonical alias, prefer one of the aliases listed on the
room. If no alias can be found, fall back to the room ID. In all cases,
use the alias/room ID being linked to as the anchor's text.
* When referencing groups, use the group ID as the anchor's text.
The text component of the anchor should be used in the event's ``body`` where
the mention would normally be represented, as shown in the example above.
Clients should display mentions differently from other elements. For example,
this may be done by changing the background color of the mention to indicate
that it is different from a normal link.
If the current user is mentioned in a message (either by a mention as defined
in this module or by a push rule), the client should show that mention differently
from other mentions, such as by using a red background color to signify to the
user that they were mentioned.
When clicked, the mention should navigate the user to the appropriate room, group,
or user information.
.. _`matrix.to URI`: ../appendices.html#matrix-to-navigation

@ -744,4 +744,4 @@ should send a "sync" command to instruct the client to get new events from the
homeserver directly.
.. _`Push Gateway Specification`: ../push_gateway/unstable.html
.. _`Push Gateway Specification`: ../push_gateway/%PUSH_GATEWAY_RELEASE_LABEL%.html

@ -63,7 +63,7 @@ If the client sends messages to users on remote domains, those messages should
be sent on to the remote servers via
`federation`_.
.. _`federation`: ../server_server/latest.html#send-to-device-messages
.. _`federation`: ../server_server/latest.html#send-to-device-messaging
.. TODO-spec:

@ -1,4 +1,5 @@
.. Copyright 2016 OpenMarket Ltd
.. Copyright 2018 New Vector Ltd
..
.. Licensed under the Apache License, Version 2.0 (the "License");
.. you may not use this file except in compliance with the License.
@ -21,13 +22,27 @@ the homeserver. This is managed by a distinct entity called the Push Gateway.
.. contents:: Table of Contents
.. sectnum::
Specification version
---------------------
Changelog
---------
.. topic:: Version: %PUSH_GATEWAY_RELEASE_LABEL%
{{push_gateway_changelog}}
This version of the specification is generated from
`matrix-doc <https://github.com/matrix-org/matrix-doc>`_ as of Git commit
`{{git_version}} <https://github.com/matrix-org/matrix-doc/tree/{{git_rev}}>`_.
For the full historical changelog, see
https://github.com/matrix-org/matrix-doc/blob/master/changelogs/push_gateway.rst
Other versions of this specification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The following other versions are also available, in reverse chronological order:
- `HEAD <https://matrix.org/docs/spec/push_gateway/unstable.html>`_: Includes all changes since the latest versioned release.
- `r0.1.0 <https://matrix.org/docs/spec/push_gateway/r0.1.0.html>`_
Overview
--------

@ -26,9 +26,9 @@ to communicate with each other. Homeservers use these APIs to push messages to
each other in real-time, to retrieve historic messages from each other, and to
query profile and presence information about users on each other's servers.
The APIs are implemented using HTTPS requests between each of the servers.
These HTTPS requests are strongly authenticated using public key signatures
at the TLS transport layer and using public key signatures in HTTP
The APIs are implemented using HTTPS requests between each of the servers.
These HTTPS requests are strongly authenticated using public key signatures
at the TLS transport layer and using public key signatures in HTTP
Authorization headers at the HTTP layer.
There are three main kinds of communication that occur between homeservers:
@ -121,7 +121,7 @@ Retrieving Server Keys
Each homeserver publishes its public keys under ``/_matrix/key/v2/server/{keyId}``.
Homeservers query for keys by either getting ``/_matrix/key/v2/server/{keyId}``
directly or by querying an intermediate notary server using a
``/_matrix/key/v2/query/{serverName}/{keyId}`` API. Intermediate notary servers
``/_matrix/key/v2/query/{serverName}/{keyId}`` API. Intermediate notary servers
query the ``/_matrix/key/v2/server/{keyId}`` API on behalf of another server and
sign the response with their own key. A server may query multiple notary servers to
ensure that they all report the same public keys.
@ -262,6 +262,8 @@ of Transaction messages, which are encoded as JSON objects, passed over an HTTP
PUT request. A Transaction is meaningful only to the pair of homeservers that
exchanged it; they are not globally-meaningful.
Transactions are limited in size; they can have at most 50 PDUs and 100 EDUs.
{{transactions_ss_http_api}}
PDUs
@ -590,9 +592,9 @@ To cover this case, the federation API provides a server-to-server analog of
the ``/messages`` client API, allowing one homeserver to fetch history from
another. This is the ``/backfill`` API.
To request more history, the requesting homeserver picks another homeserver
that it thinks may have more (most likely this should be a homeserver for
some of the existing users in the room at the earliest point in history it
To request more history, the requesting homeserver picks another homeserver
that it thinks may have more (most likely this should be a homeserver for
some of the existing users in the room at the earliest point in history it
has currently), and makes a ``/backfill`` request.
Similar to backfilling a room's history, a server may not have all the events
@ -669,10 +671,10 @@ homeservers, though most in practice will use just two.
The first part of the handshake usually involves using the directory server to
request the room ID and join candidates through the |/query/directory|_
API endpoint. In the case of a new user joining a room as a result of a received
invite, the joining user's homeserver could optimise this step away by picking
the origin server of that invite message as the join candidate. However, the
invite, the joining user's homeserver could optimise this step away by picking
the origin server of that invite message as the join candidate. However, the
joining server should be aware that the origin server of the invite might since
have left the room, so should be prepared to fall back on the regular join flow
have left the room, so should be prepared to fall back on the regular join flow
if this optimisation fails.
Once the joining server has the room ID and the join candidates, it then needs
@ -692,7 +694,7 @@ event to a resident homeserver, by using the ``PUT /send_join`` endpoint.
The resident homeserver then accepts this event into the room's event graph,
and responds to the joining server with the full set of state for the
newly-joined room. The resident server must also send the event to other servers
participating in the room.
participating in the room.
{{joins_ss_http_api}}
@ -716,8 +718,8 @@ Leaving Rooms (Rejecting Invites)
Normally homeservers can send appropriate ``m.room.member`` events to have users
leave the room, or to reject local invites. Remote invites from other homeservers
do not involve the server in the graph and therefore need another approach to
reject the invite. Joining the room and promptly leaving is not recommended as
do not involve the server in the graph and therefore need another approach to
reject the invite. Joining the room and promptly leaving is not recommended as
clients and servers will interpret that as accepting the invite, then leaving the
room rather than rejecting the invite.
@ -829,7 +831,7 @@ EDUs. There are no PDUs or Federation Queries involved.
Servers should only send presence updates for users that the receiving server
would be interested in. This can include the receiving server sharing a room
with a given user, or a user on the receiving server has added one of the
with a given user, or a user on the receiving server has added one of the
sending server's users to their presence list.
Clients may define lists of users that they are interested in via "Presence
@ -848,7 +850,7 @@ or ``m.presence_deny`` EDU back.
{{definition_ss_event_schemas_m_presence_invite}}
{{definition_ss_event_schemas_m_presence_accept}}
{{definition_ss_event_schemas_m_presence_accept}}
{{definition_ss_event_schemas_m_presence_deny}}
@ -881,11 +883,11 @@ that can be made.
OpenID
------
Third party services can exchange an access token previously generated by the
Third party services can exchange an access token previously generated by the
`Client-Server API` for information about a user. This can help verify that a
user is who they say they are without granting full access to the user's account.
Access tokens generated by the OpenID API are only good for the OpenID API and
Access tokens generated by the OpenID API are only good for the OpenID API and
nothing else.
{{openid_ss_http_api}}

@ -25,7 +25,7 @@ targets:
push_gateway:
files:
- push_gateway.rst
version_label: unstable
version_label: "%PUSH_GATEWAY_RELEASE_LABEL%"
appendices:
files:
- appendices.rst
@ -68,6 +68,7 @@ groups: # reusable blobs of files when prefixed with 'group:'
- modules/third_party_networks.rst
- modules/openid.rst
- modules/server_acls.rst
- modules/mentions.rst
title_styles: ["=", "-", "~", "+", "^", "`", "@", ":"]

Loading…
Cancel
Save