Merge branch 'master' into babolivier/standardised-federation-response-format
commit
c1721cb6f7
@ -0,0 +1,11 @@
|
||||
steps:
|
||||
- label: ":books: Build spec"
|
||||
command:
|
||||
- python3 -m venv env
|
||||
- env/bin/pip install -r scripts/requirements.txt
|
||||
- ". env/bin/activate; scripts/generate-matrix-org-assets"
|
||||
artifact_paths:
|
||||
- assets.tar.gz
|
||||
plugins:
|
||||
- docker#v3.0.1:
|
||||
image: "python:3.6"
|
@ -0,0 +1,112 @@
|
||||
# Copyright 2019 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 Capabiltiies API"
|
||||
version: "1.0.0"
|
||||
host: localhost:8008
|
||||
schemes:
|
||||
- https
|
||||
- http
|
||||
basePath: /_matrix/client/%CLIENT_MAJOR_VERSION%
|
||||
produces:
|
||||
- application/json
|
||||
securityDefinitions:
|
||||
$ref: definitions/security.yaml
|
||||
paths:
|
||||
"/capabilities":
|
||||
get:
|
||||
summary: Gets information about the server's capabilities.
|
||||
description: |-
|
||||
Gets information about the server's supported feature set
|
||||
and other relevant capabilities.
|
||||
operationId: getCapabilities
|
||||
security:
|
||||
- accessToken: []
|
||||
parameters: []
|
||||
responses:
|
||||
200:
|
||||
description:
|
||||
The capabilities of the server.
|
||||
examples:
|
||||
application/json: {
|
||||
"capabilities": {
|
||||
"m.change_password": {
|
||||
"enabled": false
|
||||
},
|
||||
"m.room_versions": {
|
||||
"default": "1",
|
||||
"available": {
|
||||
"1": "stable",
|
||||
"2": "stable",
|
||||
"3": "unstable",
|
||||
"test-version": "unstable"
|
||||
}
|
||||
},
|
||||
"com.example.custom.ratelimit": {
|
||||
"max_requests_per_hour": 600
|
||||
}
|
||||
}
|
||||
}
|
||||
schema:
|
||||
type: object
|
||||
required: ["capabilities"]
|
||||
properties:
|
||||
capabilities:
|
||||
type: object
|
||||
title: Capabilities
|
||||
description: |-
|
||||
The custom capabilities the server supports, using the
|
||||
Java package naming convention.
|
||||
additionalProperties:
|
||||
type: object
|
||||
properties:
|
||||
"m.change_password":
|
||||
type: object
|
||||
description: |-
|
||||
Capability to indicate if the user can change their password.
|
||||
title: ChangePasswordCapability
|
||||
properties:
|
||||
enabled:
|
||||
type: boolean
|
||||
description: |-
|
||||
True if the user can change their password, false otherwise.
|
||||
example: false
|
||||
required: ['enabled']
|
||||
"m.room_versions":
|
||||
type: object
|
||||
description: The room versions the server supports.
|
||||
title: RoomVersionsCapability
|
||||
properties:
|
||||
default:
|
||||
type: string
|
||||
description: |-
|
||||
The default room version the server is using for new rooms.
|
||||
example: "1"
|
||||
available:
|
||||
type: object
|
||||
description: |-
|
||||
A detailed description of the room versions the server supports.
|
||||
additionalProperties:
|
||||
type: string
|
||||
title: RoomVersionStability
|
||||
enum: [stable, unstable]
|
||||
description: The stability of the room version.
|
||||
required: ['default', 'available']
|
||||
429:
|
||||
description: This request was rate-limited.
|
||||
schema:
|
||||
"$ref": "definitions/errors/rate_limited.yaml"
|
||||
tags:
|
||||
- Capabilities
|
@ -1,66 +0,0 @@
|
||||
# Copyright 2016 OpenMarket Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
swagger: '2.0'
|
||||
info:
|
||||
title: "Matrix Client-Server CAS Login API"
|
||||
version: "1.0.0"
|
||||
host: localhost:8008
|
||||
schemes:
|
||||
- https
|
||||
- http
|
||||
basePath: /_matrix/client/%CLIENT_MAJOR_VERSION%
|
||||
paths:
|
||||
"/login/cas/ticket":
|
||||
get:
|
||||
summary: Receive and validate a CAS login ticket.
|
||||
description: |-
|
||||
Once the CAS server has authenticated the user, it will redirect the
|
||||
browser to this endpoint (assuming |/login/cas/redirect|_ gave it the
|
||||
correct ``service`` parameter).
|
||||
|
||||
The server MUST call ``/proxyValidate`` on the CAS server, to validate
|
||||
the ticket supplied by the browser.
|
||||
|
||||
If validation is successful, the server must generate a Matrix login
|
||||
token. It must then respond with an HTTP redirect to the URI given in
|
||||
the ``redirectUrl`` parameter, adding a ``loginToken`` query parameter
|
||||
giving the generated token.
|
||||
|
||||
If validation is unsuccessful, the server should respond with a ``401
|
||||
Unauthorized`` error, the body of which will be displayed to the user.
|
||||
operationId: loginByCASTicket
|
||||
parameters:
|
||||
- in: query
|
||||
type: string
|
||||
name: redirectUrl
|
||||
description: |-
|
||||
The ``redirectUrl`` originally provided by the client to
|
||||
|/login/cas/redirect|_.
|
||||
required: true
|
||||
- in: query
|
||||
type: string
|
||||
name: ticket
|
||||
description: |-
|
||||
CAS authentication ticket.
|
||||
required: true
|
||||
responses:
|
||||
302:
|
||||
description: A redirect to the Matrix client.
|
||||
headers:
|
||||
Location:
|
||||
type: "string"
|
||||
x-example: |-
|
||||
https://client.example.com/?q=p&loginToken=secrettoken
|
||||
401:
|
||||
description: The server was unable to validate the CAS ticket.
|
@ -0,0 +1,39 @@
|
||||
# Copyright 2019 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: Discovery Information
|
||||
description: |-
|
||||
Used by clients to determine the homeserver, identity server, and other
|
||||
optional components they should be interacting with.
|
||||
type: object
|
||||
properties:
|
||||
"m.homeserver":
|
||||
$ref: "homeserver.yaml"
|
||||
"m.identity_server":
|
||||
$ref: "identity_server.yaml"
|
||||
additionalProperties:
|
||||
type: object
|
||||
description: Application-dependent keys using Java package naming convention.
|
||||
required:
|
||||
- m.homeserver
|
||||
example: {
|
||||
"m.homeserver": {
|
||||
"base_url": "https://matrix.example.com"
|
||||
},
|
||||
"m.identity_server": {
|
||||
"base_url": "https://identity.example.com"
|
||||
},
|
||||
"org.example.custom.property": {
|
||||
"app_url": "https://custom.app.example.org"
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
# Copyright 2019 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 Room Upgrades API"
|
||||
version: "1.0.0"
|
||||
host: localhost:8008
|
||||
schemes:
|
||||
- https
|
||||
- http
|
||||
basePath: /_matrix/client/%CLIENT_MAJOR_VERSION%
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
securityDefinitions:
|
||||
$ref: definitions/security.yaml
|
||||
paths:
|
||||
"/rooms/{roomId}/upgrade":
|
||||
post:
|
||||
summary: Upgrades a room to a new room version.
|
||||
description: |-
|
||||
Upgrades the given room to a particular room version.
|
||||
operationId: upgradeRoom
|
||||
security:
|
||||
- accessToken: []
|
||||
parameters:
|
||||
- in: path
|
||||
type: string
|
||||
name: roomId
|
||||
required: true
|
||||
description: The ID of the room to upgrade.
|
||||
x-example: "!oldroom:example.org"
|
||||
- in: body
|
||||
name: body
|
||||
required: true
|
||||
description: The request body
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
new_version:
|
||||
type: string
|
||||
description: The new version for the room.
|
||||
example: {"new_version": "2"}
|
||||
required: [new_version]
|
||||
responses:
|
||||
200:
|
||||
description: The room was successfully upgraded.
|
||||
examples:
|
||||
application/json: {
|
||||
"replacement_room": "!newroom:example.org"
|
||||
}
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
replacement_room:
|
||||
type: string
|
||||
description: The ID of the new room.
|
||||
required: [replacement_room]
|
||||
400:
|
||||
description: |-
|
||||
The request was invalid. One way this can happen is if the room version
|
||||
requested is not supported by the homeserver.
|
||||
examples:
|
||||
application/json: {
|
||||
"errcode": "M_UNSUPPORTED_ROOM_VERSION",
|
||||
"error": "This server does not support that room version"
|
||||
}
|
||||
schema:
|
||||
"$ref": "definitions/errors/error.yaml"
|
||||
403:
|
||||
description: |-
|
||||
The user is not permitted to upgrade the room.
|
||||
examples:
|
||||
application/json: {
|
||||
"errcode": "M_FORBIDDEN",
|
||||
"error": "You cannot upgrade this room"
|
||||
}
|
||||
schema:
|
||||
"$ref": "definitions/errors/error.yaml"
|
||||
tags:
|
||||
- Room ugprades
|
@ -1,46 +0,0 @@
|
||||
# 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
|
||||
title: m.presence_accept
|
||||
description: |-
|
||||
An EDU representing approval for the observing user to subscribe to the
|
||||
presence of the the observed user.
|
||||
allOf:
|
||||
- $ref: ../edu.yaml
|
||||
- type: object
|
||||
properties:
|
||||
edu_type:
|
||||
type: enum
|
||||
enum: ['m.presence_accept']
|
||||
description: The string ``m.presence_accept``
|
||||
example: "m.presence_accept"
|
||||
content:
|
||||
type: object
|
||||
description: The invite information.
|
||||
title: Invite Information
|
||||
properties:
|
||||
observed_user:
|
||||
type: string
|
||||
description: |-
|
||||
The user ID that has approved the ``observer_user`` to
|
||||
subscribe to their presence.
|
||||
example: "@alice:elsewhere.com"
|
||||
observer_user:
|
||||
type: string
|
||||
description: |-
|
||||
The user ID that requested to subscribe to the presence of
|
||||
the ``observed_user``.
|
||||
example: "@john:matrix.org"
|
||||
required: ['observer_user', 'observed_user']
|
@ -1,55 +0,0 @@
|
||||
# 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
|
||||
title: m.presence_deny
|
||||
description: |-
|
||||
An EDU representing a declination or revocation for the observing user
|
||||
to subscribe to the presence of the observed user.
|
||||
example: {
|
||||
"origin": "example.org",
|
||||
"destination": "elsewhere.org",
|
||||
"edu_type": "m.presence_deny",
|
||||
"content": {
|
||||
"observed_user": "@alice:elsewhere.org",
|
||||
"observer_user": "@john:example.org"
|
||||
}
|
||||
}
|
||||
allOf:
|
||||
- $ref: ../edu.yaml
|
||||
- type: object
|
||||
properties:
|
||||
edu_type:
|
||||
type: enum
|
||||
enum: ['m.presence_deny']
|
||||
description: The string ``m.presence_deny``
|
||||
example: "m.presence_deny"
|
||||
content:
|
||||
type: object
|
||||
description: The invite information.
|
||||
title: Invite Information
|
||||
properties:
|
||||
observed_user:
|
||||
type: string
|
||||
description: |-
|
||||
The user ID that has declined or revoked the ``observer_user`` from
|
||||
subscribing to their presence.
|
||||
example: "@alice:elsewhere.com"
|
||||
observer_user:
|
||||
type: string
|
||||
description: |-
|
||||
The user ID that requested to subscribe to the presence of
|
||||
the ``observed_user``.
|
||||
example: "@john:matrix.org"
|
||||
required: ['observer_user', 'observed_user']
|
@ -1,45 +0,0 @@
|
||||
# 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
|
||||
title: m.presence_invite
|
||||
description: |-
|
||||
An EDU representing a request to subscribe to a user's presence.
|
||||
allOf:
|
||||
- $ref: ../edu.yaml
|
||||
- type: object
|
||||
properties:
|
||||
edu_type:
|
||||
type: enum
|
||||
enum: ['m.presence_invite']
|
||||
description: The string ``m.presence_invite``
|
||||
example: "m.presence_invite"
|
||||
content:
|
||||
type: object
|
||||
description: The invite information.
|
||||
title: Invite Information
|
||||
properties:
|
||||
observed_user:
|
||||
type: string
|
||||
description: |-
|
||||
The user ID the ``observer_user`` would like to subscribe
|
||||
to the presence of.
|
||||
example: "@alice:elsewhere.com"
|
||||
observer_user:
|
||||
type: string
|
||||
description: |-
|
||||
The user ID that is wishing to subscribe to the presence of
|
||||
the ``observed_user``.
|
||||
example: "@john:matrix.org"
|
||||
required: ['observer_user', 'observed_user']
|
@ -0,0 +1,73 @@
|
||||
# Copyright 2019 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
|
||||
title: Persistent Data Unit
|
||||
description: A persistent data unit (event) for room version 3 and beyond.
|
||||
example:
|
||||
$ref: "../examples/pdu_v3.json"
|
||||
allOf:
|
||||
- $ref: "unsigned_pdu_base.yaml"
|
||||
- type: object
|
||||
properties:
|
||||
auth_events:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Event ID.
|
||||
description: |-
|
||||
Event IDs for the authorization events that would
|
||||
allow this event to be in the room.
|
||||
example: ["$base64EncodedHash", "$AnotherEvent"]
|
||||
prev_events:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Event ID.
|
||||
description: |-
|
||||
Event IDs for the most recent events in the room
|
||||
that the homeserver was aware of when it made this event.
|
||||
example: ["$base64EncodedHash", "$AnotherEvent"]
|
||||
hashes:
|
||||
type: object
|
||||
title: Event Hash
|
||||
description: |-
|
||||
Content hashes of the PDU, following the algorithm specified in `Signing Events`_.
|
||||
example: {
|
||||
"sha256": "ThisHashCoversAllFieldsInCaseThisIsRedacted"
|
||||
}
|
||||
properties:
|
||||
sha256:
|
||||
type: string
|
||||
description: The hash.
|
||||
example: ThisHashCoversAllFieldsInCaseThisIsRedacted
|
||||
required: ['sha256']
|
||||
signatures:
|
||||
type: object
|
||||
description: |-
|
||||
Signatures for the PDU, following the algorithm specified in `Signing Events`_.
|
||||
example: {
|
||||
"example.com": {
|
||||
"ed25519:key_version:": "86BytesOfSignatureOfTheRedactedEvent"
|
||||
}
|
||||
}
|
||||
additionalProperties:
|
||||
type: object
|
||||
title: Server Signatures
|
||||
additionalProperties:
|
||||
type: string
|
||||
required:
|
||||
- auth_events
|
||||
- prev_events
|
||||
- hashes
|
||||
- signatures
|
@ -0,0 +1,151 @@
|
||||
# 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
|
||||
title: Unsigned Persistent Data Unit
|
||||
description: An unsigned persistent data unit (event)
|
||||
example:
|
||||
$ref: "../examples/unsigned_pdu_base.json"
|
||||
properties:
|
||||
room_id:
|
||||
type: string
|
||||
description: Room identifier.
|
||||
example: "!abc123:matrix.org"
|
||||
sender:
|
||||
type: string
|
||||
description: The ID of the user sending the event.
|
||||
example: "@someone:matrix.org"
|
||||
origin:
|
||||
type: string
|
||||
description: The ``server_name`` of the homeserver that created this event.
|
||||
example: "matrix.org"
|
||||
origin_server_ts:
|
||||
type: integer
|
||||
format: int64
|
||||
description: Timestamp in milliseconds on origin homeserver when this event was created.
|
||||
example: 1234567890
|
||||
type:
|
||||
type: string
|
||||
description: Event type
|
||||
example: "m.room.message"
|
||||
state_key:
|
||||
type: string
|
||||
description: |-
|
||||
If this key is present, the event is a state event, and it will replace previous events
|
||||
with the same ``type`` and ``state_key`` in the room state.
|
||||
example: "my_key"
|
||||
content:
|
||||
type: object
|
||||
description: The content of the event.
|
||||
example: {"key": "value"}
|
||||
prev_events:
|
||||
type: array
|
||||
description: |-
|
||||
Event IDs and reference hashes for the most recent events in the room
|
||||
that the homeserver was aware of when it made this event.
|
||||
items:
|
||||
type: array
|
||||
maxItems: 2
|
||||
minItems: 2
|
||||
items:
|
||||
- type: string
|
||||
title: Event ID
|
||||
example: "$abc123:matrix.org"
|
||||
- type: object
|
||||
title: Event Hash
|
||||
example: {
|
||||
"sha256": "Base64EncodedSha256HashesShouldBe43BytesLong"
|
||||
}
|
||||
properties:
|
||||
sha256:
|
||||
type: string
|
||||
description: The event hash.
|
||||
example: Base64EncodedSha256HashesShouldBe43BytesLong
|
||||
required: ['sha256']
|
||||
depth:
|
||||
type: integer
|
||||
description: |-
|
||||
The maximum depth of the ``prev_events``, plus one. Must be less than the
|
||||
maximum value for an integer (2^63 - 1). If the room's depth is already at
|
||||
the limit, the depth must be set to the limit.
|
||||
example: 12
|
||||
auth_events:
|
||||
type: array
|
||||
description: |-
|
||||
Event IDs and reference hashes for the authorization events that would
|
||||
allow this event to be in the room.
|
||||
items:
|
||||
type: array
|
||||
maxItems: 2
|
||||
minItems: 2
|
||||
items:
|
||||
- type: string
|
||||
title: Event ID
|
||||
example: "$abc123:matrix.org"
|
||||
- type: object
|
||||
title: Event Hash
|
||||
example: {
|
||||
"sha256": "Base64EncodedSha256HashesShouldBe43BytesLong"
|
||||
}
|
||||
properties:
|
||||
sha256:
|
||||
type: string
|
||||
description: The event hash.
|
||||
example: Base64EncodedSha256HashesShouldBe43BytesLong
|
||||
required: ['sha256']
|
||||
redacts:
|
||||
type: string
|
||||
description: For redaction events, the ID of the event being redacted.
|
||||
example: "$def456:matrix.org"
|
||||
unsigned:
|
||||
type: object
|
||||
title: Example Unsigned Data
|
||||
description: |-
|
||||
Additional data added by the origin server but not covered by the ``signatures``. More
|
||||
keys than those defined here may be used.
|
||||
example: {"key": "value"}
|
||||
properties:
|
||||
age:
|
||||
type: integer
|
||||
description: The number of milliseconds that have passed since this message was sent.
|
||||
example: 4612
|
||||
replaces_state:
|
||||
type: string
|
||||
description: The event ID of the state event this event replaces.
|
||||
example: "$state_event:example.org"
|
||||
prev_sender:
|
||||
type: string
|
||||
description: The sender of the replaced state event.
|
||||
example: "@someone:example.org"
|
||||
prev_content:
|
||||
type: object
|
||||
description: The content of the replaced state event.
|
||||
example: {
|
||||
"membership": "join",
|
||||
"displayname": "Bob"
|
||||
}
|
||||
redacted_because:
|
||||
type: string
|
||||
description: A reason for why the event was redacted.
|
||||
example: "Inappropriate content"
|
||||
required:
|
||||
- event_id
|
||||
- room_id
|
||||
- sender
|
||||
- origin
|
||||
- origin_server_ts
|
||||
- type
|
||||
- content
|
||||
- prev_events
|
||||
- depth
|
||||
- auth_events
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "m.room.minimal_pdu",
|
||||
"room_id": "!somewhere:example.org",
|
||||
"content": {
|
||||
"see_room_version_spec": "The event format changes depending on the room version."
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"$ref": "unsigned_pdu_base.json",
|
||||
"hashes": {
|
||||
"sha256": "thishashcoversallfieldsincasethisisredacted"
|
||||
},
|
||||
"signatures": {
|
||||
"example.com": {
|
||||
"ed25519:key_version:": "these86bytesofbase64signaturecoveressentialfieldsincludinghashessocancheckredactedpdus"
|
||||
}
|
||||
},
|
||||
"auth_events": [
|
||||
"$base64encodedeventid",
|
||||
"$adifferenteventid"
|
||||
],
|
||||
"prev_events": [
|
||||
"$base64encodedeventid",
|
||||
"$adifferenteventid"
|
||||
]
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
{
|
||||
"origin": "matrix.org",
|
||||
"origin_server_ts": 1234567890,
|
||||
"pdus": [{"$ref": "pdu.json"}]
|
||||
}
|
||||
"pdus": [{
|
||||
"$ref": "minimal_pdu.json"
|
||||
}]
|
||||
}
|
||||
|
@ -1,27 +1,4 @@
|
||||
{
|
||||
"room_id": "!UcYsUzyxTGDxLBEvLy:example.org",
|
||||
"sender": "@alice:example.com",
|
||||
"origin": "example.com",
|
||||
"event_id": "$a4ecee13e2accdadf56c1025:example.com",
|
||||
"origin_server_ts": 1404838188000,
|
||||
"depth": 12,
|
||||
"auth_events": [
|
||||
[
|
||||
"$af232176:example.org",
|
||||
{"sha256": "abase64encodedsha256hashshouldbe43byteslong"}
|
||||
]
|
||||
],
|
||||
"type": "m.room.message",
|
||||
"prev_events": [
|
||||
[
|
||||
"$af232176:example.org",
|
||||
{"sha256": "abase64encodedsha256hashshouldbe43byteslong"}
|
||||
]
|
||||
],
|
||||
"content": {
|
||||
"key": "value"
|
||||
},
|
||||
"unsigned": {
|
||||
"age": 4612
|
||||
}
|
||||
}
|
||||
"$ref": "unsigned_pdu_base.json",
|
||||
"event_id": "$a4ecee13e2accdadf56c1025:example.com"
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"room_id": "!UcYsUzyxTGDxLBEvLy:example.org",
|
||||
"sender": "@alice:example.com",
|
||||
"origin": "example.com",
|
||||
"origin_server_ts": 1404838188000,
|
||||
"depth": 12,
|
||||
"auth_events": [
|
||||
[
|
||||
"$af232176:example.org",
|
||||
{"sha256": "abase64encodedsha256hashshouldbe43byteslong"}
|
||||
]
|
||||
],
|
||||
"type": "m.room.message",
|
||||
"prev_events": [
|
||||
[
|
||||
"$af232176:example.org",
|
||||
{"sha256": "abase64encodedsha256hashshouldbe43byteslong"}
|
||||
]
|
||||
],
|
||||
"content": {
|
||||
"key": "value"
|
||||
},
|
||||
"unsigned": {
|
||||
"age": 4612
|
||||
}
|
||||
}
|
@ -0,0 +1,246 @@
|
||||
# Copyright 2018-2019 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 Federation Invite User To Room API"
|
||||
version: "1.0.0"
|
||||
host: localhost:8448
|
||||
schemes:
|
||||
- https
|
||||
basePath: /_matrix/federation/v2
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
securityDefinitions:
|
||||
$ref: definitions/security.yaml
|
||||
paths:
|
||||
"/invite/{roomId}/{eventId}":
|
||||
put:
|
||||
summary: Invites a remote user to a room
|
||||
description: |-
|
||||
.. Note::
|
||||
This API is nearly identical to the v1 API with the exception of the request
|
||||
body being different, and the response format fixed.
|
||||
|
||||
Invites a remote user to a room. Once the event has been signed by both the inviting
|
||||
homeserver and the invited homeserver, it can be sent to all of the servers in the
|
||||
room by the inviting homeserver.
|
||||
|
||||
This endpoint is preferred over the v1 API as it is more useful for servers. Senders
|
||||
which receive a 400 or 404 response to this endpoint should retry using the v1
|
||||
API as the server may be older, if the room version is "1" or "2".
|
||||
|
||||
Note that events have a different format depending on the room version - check the
|
||||
`room version specification`_ for precise event formats. **The request and response
|
||||
bodies here describe the common event fields in more detail and may be missing other
|
||||
required fields for a PDU.**
|
||||
operationId: sendInviteV2
|
||||
security:
|
||||
- signedRequest: []
|
||||
parameters:
|
||||
- in: path
|
||||
name: roomId
|
||||
type: string
|
||||
description: The room ID that the user is being invited to.
|
||||
required: true
|
||||
x-example: "!abc123:matrix.org"
|
||||
- in: path
|
||||
name: eventId
|
||||
type: string
|
||||
description: The event ID for the invite event, generated by the inviting server.
|
||||
required: true
|
||||
x-example: "$abc123:example.org"
|
||||
- in: body
|
||||
name: body
|
||||
type: object
|
||||
required: true
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
room_version:
|
||||
type: string
|
||||
description: The version of the room where the user is being invited to.
|
||||
example: "2"
|
||||
event:
|
||||
$ref: "definitions/invite_event.yaml"
|
||||
invite_room_state:
|
||||
type: array
|
||||
description: |-
|
||||
An optional list of simplified events to help the receiver of the invite
|
||||
identify the room. The recommended events to include are the join rules,
|
||||
canonical alias, avatar, and name of the room.
|
||||
items:
|
||||
type: object
|
||||
title: Invite Room State Event
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
description: The type of event.
|
||||
example: "m.room.join_rules"
|
||||
state_key:
|
||||
type: string
|
||||
description: The state key for the event. May be an empty string.
|
||||
example: ""
|
||||
content:
|
||||
type: object
|
||||
description: The content for the event.
|
||||
sender:
|
||||
type: string
|
||||
description: The sender of the event.
|
||||
example: "@someone:matrix.org"
|
||||
required: ['type', 'state_key', 'content', 'sender']
|
||||
example: [
|
||||
{
|
||||
"type": "m.room.join_rules",
|
||||
"sender": "@someone:matrix.org",
|
||||
"state_key": "",
|
||||
"content": {
|
||||
"join_rule": "public"
|
||||
}
|
||||
}
|
||||
]
|
||||
required: ['room_version', 'event']
|
||||
example: {
|
||||
"room_version": "2",
|
||||
"event": {
|
||||
"$ref": "examples/minimal_pdu.json",
|
||||
"type": "m.room.member",
|
||||
"state_key": "@joe:elsewhere.com",
|
||||
"origin": "example.org",
|
||||
"origin_server_ts": 1549041175876,
|
||||
"sender": "@someone:example.org",
|
||||
"content": {
|
||||
"membership": "invite"
|
||||
},
|
||||
"signatures": {
|
||||
"example.com": {
|
||||
"ed25519:key_version": "SomeSignatureHere"
|
||||
},
|
||||
}
|
||||
},
|
||||
"invite_room_state": [
|
||||
{
|
||||
"type": "m.room.join_rules",
|
||||
"sender": "@someone:matrix.org",
|
||||
"state_key": "",
|
||||
"content": {
|
||||
"join_rule": "public"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "m.room.name",
|
||||
"sender": "@someone:matrix.org",
|
||||
"state_key": "",
|
||||
"content": {
|
||||
"name": "Cool New Room"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
responses:
|
||||
200:
|
||||
description: |-
|
||||
The event with the invited server's signature added. All other fields of the events
|
||||
should remain untouched. Note that events have a different format depending on the
|
||||
room version - check the `room version specification`_ for precise event formats.
|
||||
schema:
|
||||
type: object
|
||||
description: An object containing the signed invite event.
|
||||
title: Event Container
|
||||
properties:
|
||||
event:
|
||||
$ref: "definitions/invite_event.yaml"
|
||||
required: ['event']
|
||||
examples:
|
||||
application/json: {
|
||||
"event": {
|
||||
"$ref": "examples/minimal_pdu.json",
|
||||
"type": "m.room.member",
|
||||
"state_key": "@someone:example.org",
|
||||
"origin": "example.org",
|
||||
"origin_server_ts": 1549041175876,
|
||||
"sender": "@someone:example.org",
|
||||
"unsigned": {
|
||||
"invite_room_state": [
|
||||
{
|
||||
"type": "m.room.join_rules",
|
||||
"sender": "@someone:matrix.org",
|
||||
"state_key": "",
|
||||
"content": {
|
||||
"join_rule": "public"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "m.room.name",
|
||||
"sender": "@someone:matrix.org",
|
||||
"state_key": "",
|
||||
"content": {
|
||||
"name": "Cool New Room"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"membership": "invite"
|
||||
},
|
||||
"signatures": {
|
||||
"example.com": {
|
||||
"ed25519:key_version": "SomeSignatureHere"
|
||||
},
|
||||
"elsewhere.com": {
|
||||
"ed25519:k3y_versi0n": "SomeOtherSignatureHere"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
403:
|
||||
description: |-
|
||||
The invite is not allowed. This could be for a number of reasons, including:
|
||||
|
||||
* The sender is not allowed to send invites to the target user/homeserver.
|
||||
* The homeserver does not permit anyone to invite its users.
|
||||
* The homeserver refuses to participate in the room.
|
||||
schema:
|
||||
$ref: "../client-server/definitions/errors/error.yaml"
|
||||
examples:
|
||||
application/json: {
|
||||
"errcode": "M_FORBIDDEN",
|
||||
"error": "User cannot invite the target user."
|
||||
}
|
||||
400:
|
||||
description: |-
|
||||
The request is invalid or the room the server is attempting
|
||||
to join has a version that is not listed in the ``ver``
|
||||
parameters.
|
||||
|
||||
The error should be passed through to clients so that they
|
||||
may give better feedback to users.
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: "../client-server/definitions/errors/error.yaml"
|
||||
- type: object
|
||||
properties:
|
||||
room_version:
|
||||
type: string
|
||||
description: |-
|
||||
The version of the room. Required if the ``errcode``
|
||||
is ``M_INCOMPATIBLE_ROOM_VERSION``.
|
||||
examples:
|
||||
application/json: {
|
||||
"errcode": "M_INCOMPATIBLE_ROOM_VERSION",
|
||||
"error": "Your homeserver does not support the features required to join this room",
|
||||
"room_version": "3"
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
# Copyright 2019 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 Federation Server Discovery API"
|
||||
version: "1.0.0"
|
||||
host: localhost:443
|
||||
schemes:
|
||||
- https
|
||||
basePath: /.well-known
|
||||
produces:
|
||||
- application/json
|
||||
paths:
|
||||
"/matrix/server":
|
||||
get:
|
||||
summary: Gets information about the delegated server for server-server communication.
|
||||
description: |-
|
||||
Gets information about the delegated server for server-server communication
|
||||
between Matrix homeservers. Servers should follow 30x redirects, carefully
|
||||
avoiding redirect loops, and use normal X.509 certificate validation.
|
||||
responses:
|
||||
200:
|
||||
description:
|
||||
The delegated server information. The ``Content-Type`` for this response SHOULD
|
||||
be ``application/json``, however servers parsing the response should assume that
|
||||
the body is JSON regardless of type. Failures parsing the JSON or invalid data
|
||||
provided in the resulting parsed JSON should not result in discovery failure -
|
||||
consult the server discovery process for information on how to continue.
|
||||
examples:
|
||||
application/json: {
|
||||
"m.server": "delegated.example.com:1234"
|
||||
}
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
"m.server":
|
||||
type: string
|
||||
description: |-
|
||||
The server name to delegate server-server communciations to, with optional
|
||||
port. The delegated server name uses the same grammar as
|
||||
`server names in the appendices <../appendices.html#server-name>`_.
|
@ -1 +1 @@
|
||||
Add missing status_msg to m.presence schema
|
||||
Add missing status_msg to m.presence schema.
|
||||
|
@ -0,0 +1 @@
|
||||
Add support for advertising experimental features to clients.
|
@ -0,0 +1 @@
|
||||
Add a generic SSO login API.
|
@ -0,0 +1 @@
|
||||
Add a mechanism for servers to redirect clients to an alternative homeserver after logging in.
|
@ -0,0 +1 @@
|
||||
Add room version upgrades.
|
@ -0,0 +1 @@
|
||||
Remove references to presence lists.
|
@ -0,0 +1 @@
|
||||
Support optional features by having clients query for capabilities.
|
@ -0,0 +1 @@
|
||||
Fix various spelling mistakes throughout the specification.
|
@ -0,0 +1 @@
|
||||
Fix various spelling mistakes throughout the specification.
|
@ -0,0 +1 @@
|
||||
Fix various spelling mistakes throughout the specification.
|
@ -0,0 +1 @@
|
||||
``GET /account_data`` routes.
|
@ -0,0 +1 @@
|
||||
Add ``M_RESOURCE_LIMIT_EXCEEDED`` as an error code for when homeservers exceed limits imposed on them.
|
@ -0,0 +1 @@
|
||||
Add room version upgrades.
|
@ -0,0 +1 @@
|
||||
Support optional features by having clients query for capabilities.
|
@ -0,0 +1 @@
|
||||
Add the missing `m.push_rules` event schema.
|
@ -0,0 +1 @@
|
||||
Emit ``M_UNSUPPORTED_ROOM_VERSION`` error codes where applicable on ``/createRoom`` and ``/invite`` APIs.
|
@ -0,0 +1 @@
|
||||
Fix various spelling mistakes throughout the specification.
|
@ -0,0 +1 @@
|
||||
Fix various spelling mistakes throughout the specification.
|
@ -0,0 +1,16 @@
|
||||
r0.1.1
|
||||
======
|
||||
|
||||
Spec Clarifications
|
||||
-------------------
|
||||
|
||||
- Remove legacy references to TLS fingerprints. (`#1844 <https://github.com/matrix-org/matrix-doc/issues/1844>`_)
|
||||
- Clarify that servers should not fail to contact servers if ``/.well-known`` fails. (`#1855 <https://github.com/matrix-org/matrix-doc/issues/1855>`_)
|
||||
|
||||
|
||||
r0.1.0
|
||||
======
|
||||
|
||||
This is the first release of the Server Server (Federation) specification.
|
||||
It includes support for homeservers being able to interact with other
|
||||
homeservers in a decentralized and standard way.
|
@ -0,0 +1 @@
|
||||
Fix the `access_token` parameter in the open_id endpoint.
|
@ -0,0 +1,192 @@
|
||||
{
|
||||
"$ref": "core/event.json",
|
||||
"type": "m.push_rules",
|
||||
"content": {
|
||||
"global": {
|
||||
"content": [
|
||||
{
|
||||
"actions": [
|
||||
"notify",
|
||||
{
|
||||
"set_tweak": "sound",
|
||||
"value": "default"
|
||||
},
|
||||
{
|
||||
"set_tweak": "highlight"
|
||||
}
|
||||
],
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"pattern": "alice",
|
||||
"rule_id": ".m.rule.contains_user_name"
|
||||
}
|
||||
],
|
||||
"override": [
|
||||
{
|
||||
"actions": [
|
||||
"dont_notify"
|
||||
],
|
||||
"conditions": [],
|
||||
"default": true,
|
||||
"enabled": false,
|
||||
"rule_id": ".m.rule.master"
|
||||
},
|
||||
{
|
||||
"actions": [
|
||||
"dont_notify"
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"key": "content.msgtype",
|
||||
"kind": "event_match",
|
||||
"pattern": "m.notice"
|
||||
}
|
||||
],
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"rule_id": ".m.rule.suppress_notices"
|
||||
}
|
||||
],
|
||||
"room": [],
|
||||
"sender": [],
|
||||
"underride": [
|
||||
{
|
||||
"actions": [
|
||||
"notify",
|
||||
{
|
||||
"set_tweak": "sound",
|
||||
"value": "ring"
|
||||
},
|
||||
{
|
||||
"set_tweak": "highlight",
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"key": "type",
|
||||
"kind": "event_match",
|
||||
"pattern": "m.call.invite"
|
||||
}
|
||||
],
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"rule_id": ".m.rule.call"
|
||||
},
|
||||
{
|
||||
"actions": [
|
||||
"notify",
|
||||
{
|
||||
"set_tweak": "sound",
|
||||
"value": "default"
|
||||
},
|
||||
{
|
||||
"set_tweak": "highlight"
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"kind": "contains_display_name"
|
||||
}
|
||||
],
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"rule_id": ".m.rule.contains_display_name"
|
||||
},
|
||||
{
|
||||
"actions": [
|
||||
"notify",
|
||||
{
|
||||
"set_tweak": "sound",
|
||||
"value": "default"
|
||||
},
|
||||
{
|
||||
"set_tweak": "highlight",
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"is": "2",
|
||||
"kind": "room_member_count"
|
||||
}
|
||||
],
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"rule_id": ".m.rule.room_one_to_one"
|
||||
},
|
||||
{
|
||||
"actions": [
|
||||
"notify",
|
||||
{
|
||||
"set_tweak": "sound",
|
||||
"value": "default"
|
||||
},
|
||||
{
|
||||
"set_tweak": "highlight",
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"key": "type",
|
||||
"kind": "event_match",
|
||||
"pattern": "m.room.member"
|
||||
},
|
||||
{
|
||||
"key": "content.membership",
|
||||
"kind": "event_match",
|
||||
"pattern": "invite"
|
||||
},
|
||||
{
|
||||
"key": "state_key",
|
||||
"kind": "event_match",
|
||||
"pattern": "@alice:example.com"
|
||||
}
|
||||
],
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"rule_id": ".m.rule.invite_for_me"
|
||||
},
|
||||
{
|
||||
"actions": [
|
||||
"notify",
|
||||
{
|
||||
"set_tweak": "highlight",
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"key": "type",
|
||||
"kind": "event_match",
|
||||
"pattern": "m.room.member"
|
||||
}
|
||||
],
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"rule_id": ".m.rule.member_event"
|
||||
},
|
||||
{
|
||||
"actions": [
|
||||
"notify",
|
||||
{
|
||||
"set_tweak": "highlight",
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"key": "type",
|
||||
"kind": "event_match",
|
||||
"pattern": "m.room.message"
|
||||
}
|
||||
],
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"rule_id": ".m.rule.message"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"$ref": "core/state_event.json",
|
||||
"type": "m.room.tombstone",
|
||||
"state_key": "",
|
||||
"content": {
|
||||
"body": "This room has been replaced",
|
||||
"replacement_room": "!newroom:example.org"
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
---
|
||||
allOf:
|
||||
- $ref: core-event-schema/event.yaml
|
||||
description: Describes all push rules for this user.
|
||||
properties:
|
||||
content:
|
||||
properties:
|
||||
global:
|
||||
type: object
|
||||
title: Ruleset
|
||||
description: The global ruleset
|
||||
allOf:
|
||||
- $ref: ../../api/client-server/definitions/push_ruleset.yaml
|
||||
type: object
|
||||
type:
|
||||
enum:
|
||||
- m.push_rules
|
||||
type: string
|
||||
title: Push rules
|
||||
type: object
|
||||
|
@ -0,0 +1,27 @@
|
||||
---
|
||||
allOf:
|
||||
- $ref: core-event-schema/state_event.yaml
|
||||
description: 'A state event signifying that a room has been upgraded to a different room version, and that clients should go there.'
|
||||
properties:
|
||||
content:
|
||||
properties:
|
||||
body:
|
||||
type: string
|
||||
description: A server-defined message.
|
||||
replacement_room:
|
||||
type: string
|
||||
description: The new room the client should be visiting.
|
||||
required:
|
||||
- replacement_room
|
||||
- body
|
||||
type: object
|
||||
state_key:
|
||||
description: A zero-length string.
|
||||
pattern: '^$'
|
||||
type: string
|
||||
type:
|
||||
enum:
|
||||
- m.room.tombstone
|
||||
type: string
|
||||
title: Indication that the room has been upgraded.
|
||||
type: object
|
@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec ./scripts/test-and-build.sh
|
@ -0,0 +1,203 @@
|
||||
# MSC1708: .well-known support for server name resolution
|
||||
|
||||
Currently, mapping from a server name to a hostname for federation is done via
|
||||
`SRV` records. However,
|
||||
[MSC1711](https://github.com/matrix-org/matrix-doc/pull/1711) proposes
|
||||
requiring valid X.509 certificates on the federation endpoint. It will then be
|
||||
necessary for the homeserver to present a certificate which is valid for the
|
||||
server name. This presents difficulties for hosted server offerings: BigCorp
|
||||
may want to delegate responsibility for running its Matrix homeserver to an
|
||||
outside supplier, but it may be difficult for that supplier to obtain a TLS
|
||||
certificate for `bigcorp.com` (and BigCorp may be reluctant to let them have
|
||||
one).
|
||||
|
||||
This MSC proposes to solve this problem by augmenting the current `SRV` record
|
||||
with a `.well-known` lookup.
|
||||
|
||||
## Proposal
|
||||
|
||||
For reference, the current [specification for resolving server
|
||||
names](https://matrix.org/docs/spec/server_server/unstable.html#resolving-server-names)
|
||||
is as follows:
|
||||
|
||||
1. If the hostname is an IP literal, then that IP address should be used,
|
||||
together with the given port number, or 8448 if no port is given.
|
||||
|
||||
2. Otherwise, if the port is present, then an IP address is discovered by
|
||||
looking up an AAAA or A record for the hostname, and the specified port is
|
||||
used.
|
||||
|
||||
3. If the hostname is not an IP literal and no port is given, the server is
|
||||
discovered by first looking up a `_matrix._tcp` SRV record for the
|
||||
hostname, which may give a hostname (to be looked up using AAAA or A queries)
|
||||
and port.
|
||||
|
||||
4. Finally, the server is discovered by looking up an AAAA or A record on the
|
||||
hostname, and taking the default fallback port number of 8448.
|
||||
|
||||
We insert the following between Steps 3 and 4.
|
||||
|
||||
If the SRV record does not exist, the requesting server should make a `GET`
|
||||
request to `https://<server_name>/.well-known/matrix/server`, with normal X.509
|
||||
certificate validation, and following 30x redirects (being careful to avoid
|
||||
redirect loops). If the request does not return a 200, continue to step 4,
|
||||
otherwise:
|
||||
|
||||
The response must be valid JSON which follows the structure documented
|
||||
below. Otherwise, continue to the next step in the discovery process. It is
|
||||
NOT necessary for the response to have a `Content-Type` of `application/json`.
|
||||
|
||||
If the response is valid, the `m.server` property is parsed as
|
||||
`<delegated_server_name>[:<delegated_port>]`, and processed as follows:
|
||||
|
||||
* If `<delegated_server_name>` is an IP literal, then that IP address should be
|
||||
used, together with `<delegated_port>`, or 8448 if no port is given. The
|
||||
server should present a valid TLS certificate for `<delegated_server_name>`.
|
||||
|
||||
* If `<delegated_server_name>` is not an IP literal, and `<delegated_port>` is
|
||||
present, then an IP address is discovered by looking up an AAAA or A record
|
||||
for `<delegated_server_name>`, and the specified port is used. The server
|
||||
should present a valid TLS certificate for `<delegated_server_name>`.
|
||||
|
||||
(In other words, the federation connection is made to
|
||||
`https://<delegated_server_name>:<delegated_port>`).
|
||||
|
||||
* If the hostname is not an IP literal and no port is given, a second SRV
|
||||
record is looked up; this time for `_matrix._tcp.<delegated_server_name>`,
|
||||
which may give yet another hostname (to be looked up using A/AAAA queries)
|
||||
and port. The server must present a TLS cert for the
|
||||
`<delegated_server_name>` from the .well-known.
|
||||
|
||||
* If no SRV record is found, the server is discovered by looking up an AAAA
|
||||
or A record on `<delegated_server_name>`, and taking the default fallback
|
||||
port number of 8448.
|
||||
|
||||
(In other words, the federation connection is made to
|
||||
`https://<delegated_server_name>:8448`).
|
||||
|
||||
### Structure of the `.well-known` response
|
||||
|
||||
The contents of the `.well-known` response should be structured as shown:
|
||||
|
||||
```json
|
||||
{
|
||||
"m.server": "<server>[:<port>]"
|
||||
}
|
||||
```
|
||||
|
||||
If the response cannot be parsed as JSON, or lacks a valid `m.server` property,
|
||||
the request is considered to have failed, and no fallback to port 8448 takes
|
||||
place.
|
||||
|
||||
The formal grammar for the `m.server` property is the same as that of a [server
|
||||
name](https://matrix.org/docs/spec/appendices.html#server-name): it is a
|
||||
hostname or IP address, followed by an optional port.
|
||||
|
||||
### Caching
|
||||
|
||||
Servers should not look up the `.well-known` file for every request, as this
|
||||
would impose an unacceptable overhead on both sides. Instead, the results of
|
||||
the `.well-known` request should be cached according to the HTTP response
|
||||
headers, as per [RFC7234](https://tools.ietf.org/html/rfc7234). If the response
|
||||
does not include an explicit expiry time, the requesting server should use a
|
||||
sensible default: 24 hours is suggested.
|
||||
|
||||
Because there is no way to request a revalidation, it is also recommended that
|
||||
requesting servers cap the expiry time. 48 hours is suggested.
|
||||
|
||||
A failure to retrieve the `.well-known` file should also be cached, though care
|
||||
must be taken that a single 500 error or connection failure should not break
|
||||
federation for an extended period. A short cache time of about an hour might be
|
||||
appropriate; alternatively, servers might use an exponential backoff.
|
||||
|
||||
## Problems
|
||||
|
||||
It will take a while for `.well-known` to be supported across the ecosystem;
|
||||
until it is, it will be difficult to deploy homeservers which rely on it for
|
||||
their routing: if Alice is using a current homeserver implementation, and Bob
|
||||
deploys a new implementation which relies on `.well-known` for routing, then
|
||||
Alice will be unable to send messages to Bob. (This is the same problem we have with
|
||||
[SNI](https://github.com/matrix-org/synapse/issues/1491#issuecomment-415153428).)
|
||||
|
||||
The main defence against this seems to be to release support for `.well-known`
|
||||
as soon as possible, to maximise uptake in the ecosystem. It is likely that, as
|
||||
we approach Matrix 1.0, there will be sufficient other new features (such as
|
||||
new Room versions) that upgrading will be necessary anyway.
|
||||
|
||||
## Security considerations
|
||||
|
||||
The `.well-known` file potentially broadens the attack surface for an attacker
|
||||
wishing to intercept federation traffic to a particular server.
|
||||
|
||||
## Dismissed alternatives
|
||||
|
||||
For future reference, here are the alternative solutions which have been
|
||||
considered and dismissed.
|
||||
|
||||
### Look up the `.well-known` file before the SRV record
|
||||
|
||||
We could make the request for `.well-known` before looking up the `SRV`
|
||||
record. On the one hand this is maybe marginally simpler (and avoids the
|
||||
overhead of having to make *two* `SRV` lookups in the case that a `.well-known`
|
||||
is found. It might also open a future path for using `.well-known` for
|
||||
information other than delegation.
|
||||
|
||||
Ultimately we decided to include the initial `SRV` lookup so that deployments
|
||||
have a mechanism to avoid the `.well-known` overhead in the common case that it
|
||||
is not required.
|
||||
|
||||
### Subdomain hack
|
||||
|
||||
As well as accepting TLS certs for `example.com`, we could also accept them for
|
||||
`delegated--matrix.example.com`. This would allow `example.com` to delegate its
|
||||
matrix hosting by (a) setting up the SRV record at `_matrix._tcp.example.com`
|
||||
and (b) setting up a CNAME at `delegated--matrix.example.com`. The latter would
|
||||
enable the delegatee to obtain an acceptable TLS certificate.
|
||||
|
||||
This was certainly an interesting idea, but we dismissed it for the following
|
||||
reasons:
|
||||
|
||||
* There's a security trap for anybody who lets people sign up for subdomains
|
||||
(which is certainly not an uncommon business model): if you can register for
|
||||
delegated--matrix.example.com, you get to intercept all the matrix traffic
|
||||
for example.com.
|
||||
|
||||
* Generally it feels quite unintuitive and violates the principle of least
|
||||
surprise.
|
||||
|
||||
* The fact that we can't find any prior art for this sets off alarm bells too.
|
||||
|
||||
### Rely on DNS/DNSSEC
|
||||
|
||||
If we could trust SRV records, we would be able to accept TLS certs for the
|
||||
*target* of the SRV record, which avoids this whole problem.
|
||||
|
||||
Such trust could come from assuming that plain DNS is "good enough". However,
|
||||
DNS cache poisoning attacks are a real thing, and the fact that the designers
|
||||
of TLS chose to implement a server-name check specifically to deal with this
|
||||
case suggests we would be foolish to make this assumption.
|
||||
|
||||
The alternative is to rely on DNSSEC to provide security for SRV records. The
|
||||
problem here is simply that DNSSEC is not that widely deployed currently. A
|
||||
number of large organisations are actively avoiding enabling it on their
|
||||
domains, so requiring DNSSEC would be a direct impediment to the uptake of
|
||||
Matrix. Furthermore, if we required DNSSEC-authenticated SRV records for
|
||||
domains doing delegation, we would end up with a significant number of
|
||||
homeservers unable to talk to such domains, because their local DNS
|
||||
infrastructure may not implement DNSSEC.
|
||||
|
||||
Finally, if we're expecting servers to present the cert for the *target* of the
|
||||
SRV record, then we'll have to change the Host and SNI fields, and that will
|
||||
break backwards compat everywhere (and it's hard to see how to mitigate that).
|
||||
|
||||
### Stick with perspectives
|
||||
|
||||
The final option is to double-down on the Perspectives approach, ie to skip
|
||||
[MSC1711](https://github.com/matrix-org/matrix-doc/pull/1711). MSC1711
|
||||
discusses the reasons we do not believe this to be a viable option.
|
||||
|
||||
## Conclusion
|
||||
|
||||
This proposal adds a new mechanism, alongside the existing `SRV` record lookup
|
||||
for finding the server responsible for a particular matrix server_name, which
|
||||
will allow greater flexibility in deploying homeservers.
|
@ -0,0 +1,78 @@
|
||||
# MSC 1794 - Federation v2 Invite API
|
||||
|
||||
This proposal adds a new `/invite` API to federation that supports different
|
||||
room versions.
|
||||
|
||||
## Motivation
|
||||
|
||||
It is planned for future room versions to be able to change the format of events
|
||||
in various ways. To support this, all servers must know the room version
|
||||
whenever they need to parse an event. Currently the `/invite` API does not
|
||||
include the room version, so the target server would be unable to parse the event included in the payload.
|
||||
|
||||
## Proposal
|
||||
|
||||
Add a new version of the invite API under the prefix `/_matrix/federation/v2`,
|
||||
which has a payload of:
|
||||
|
||||
```
|
||||
PUT /_matrix/federation/v2/invite/<room_id>/<event_id>
|
||||
|
||||
{
|
||||
"room_version": <room_version>,
|
||||
"event": { ... },
|
||||
"invite_room_state": [ ... ]
|
||||
}
|
||||
```
|
||||
|
||||
The differences between this and `v1` are:
|
||||
|
||||
1. The payload in `v1` is the event, while in `v2` the event is instead placed
|
||||
under an `"event"` key. This is for consistency with other APIs, and to allow
|
||||
extra data to be added to the request payload separately from the event.
|
||||
2. A required field called `"room_version"` is added that specifies the room
|
||||
version.
|
||||
3. The `"invite_room_state"` is moved from the `unsigned` section of the event
|
||||
to a top level key. The key `invite_room_state` being in the `event.unsigned`
|
||||
was a hack due to point 1. above.
|
||||
|
||||
|
||||
The response is identical to `v1`, except that:
|
||||
|
||||
1. If the receiving server does not support the given room version the
|
||||
appropriate incompatible-room-version error is returned, in the same way
|
||||
as e.g. for `/make_join` APIs.
|
||||
2. The response payload is no longer in the format of `[200, { ... }]`, and is
|
||||
instead simply the `{ ... }` portion. This fixes a historical accident to
|
||||
bring the invite API into line with the rest of the federation API.
|
||||
|
||||
|
||||
If a call to `v2` `/invite` results in an unrecognised request exception **AND**
|
||||
the room version is `1` or `2` then the sending server should retry the request
|
||||
with the `v1` API.
|
||||
|
||||
|
||||
## Alternatives
|
||||
|
||||
|
||||
### Reusing V1 API
|
||||
|
||||
One alternative is to add a `room_version` query string parameter to the `v1`
|
||||
`/invite` API in a similar way as for the `/make_join` APIs. However, older
|
||||
servers would ignore the query string parameter while processing an incoming
|
||||
`/invite` request, resulting in the server attempting to parse the event in the
|
||||
old `v1` format. This would likely result in either a `400` or `500` response,
|
||||
which the sending server could interpret as the receiving server not supporting
|
||||
the room version.
|
||||
|
||||
This method, however, is fragile and could easily mask legitimate `400` and
|
||||
`500` errors that are not due to not supporting the room version.
|
||||
|
||||
|
||||
### Using V1 API for V1 room versions
|
||||
|
||||
Instead of all servers attempting to use the new API and falling back if the API
|
||||
is not found, servers could instead always use the current API for V1 and V2
|
||||
rooms.
|
||||
|
||||
However, this would not allow us to deprecate the `v1` API.
|
@ -0,0 +1,50 @@
|
||||
# Proposal for advertising capable room versions to clients
|
||||
|
||||
Currently clients need to guess at which room versions the server supports, if any. This is particularly
|
||||
difficult to do as it generally requires knowing the state of the ecosystem and what versions are
|
||||
available and how keen users are to upgrade their servers and clients. The impossible judgement call
|
||||
for when to encourage people to upgrade shouldn't be impossible, or even a judgement call.
|
||||
|
||||
|
||||
## Proposal
|
||||
|
||||
Building off of [MSC1753](https://github.com/matrix-org/matrix-doc/pull/1753) (capabilities API) and
|
||||
the [recommendations laid out for room versions](https://github.com/matrix-org/matrix-doc/pull/1773/files#diff-1436075794bb304492ca6953a6692cd0R463),
|
||||
this proposal suggests a `m.room_versions` capability be introduced like the following:
|
||||
|
||||
```json
|
||||
{
|
||||
"capabilities": {
|
||||
"m.room_versions": {
|
||||
"default": "1",
|
||||
"available": {
|
||||
"1": "stable",
|
||||
"2": "stable",
|
||||
"state-res-v2-test": "unstable",
|
||||
"event-ids-as-hashes": "unstable",
|
||||
"3": "future-scifi-label"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Clients are encouraged to make use of this capability to determine if the server supports a given
|
||||
version, and at what level of stability. Anything not flagged explicitly as `stable` should be treated
|
||||
as `unstable` (ie: `future-scifi-label` is the same as `unstable`).
|
||||
|
||||
The default version is the version that the server is using to create new rooms with. Clients can
|
||||
make the assumption that the default version is a stable version.
|
||||
|
||||
Clients should encourage people with sufficient permissions to perform an upgrade to upgrade their
|
||||
rooms to the `default` room version when the room is using an `unstable` version.
|
||||
|
||||
|
||||
## Potential issues
|
||||
|
||||
Changes aren't pushed to the client, which means clients may want to poll this endpoint on some
|
||||
heuristic instead. For example, clients may want to poll the endpoint weekly or when the user relaunches
|
||||
the client. Clients may also wish to provide users a way to upgrade without considering the capabilities
|
||||
of the server, expecting that the server may not support the user-provided version - the intention
|
||||
being such a feature would be used by eager room administrators which do not want to relaunch their
|
||||
client, for example.
|
@ -0,0 +1,21 @@
|
||||
# MSC 1813 - Federation Make Membership Room Version
|
||||
|
||||
This proposal adds a new `room_version` field to the responses of `/make_leave`
|
||||
and `/make_join` APIs.
|
||||
|
||||
## Motivation
|
||||
|
||||
It is planned for future room versions to be able to change the format of events
|
||||
in various ways. To support this, all servers must know the room version
|
||||
whenever they need to parse an event. Currently the `/make_*` APIs do not
|
||||
include the room version in the response, so the requesting server is unable to
|
||||
parse the event included in the response body.
|
||||
|
||||
## Proposal
|
||||
|
||||
Add a new `room_version` field to the response body of the `v1` `/make_join` and
|
||||
`/make_leave` APIs, which describes the room version.
|
||||
|
||||
For backwards compatibility servers must correctly handle responses that do not
|
||||
include the new field. In which case the room version is assumed to be one of
|
||||
either `1` or `2`.
|
@ -0,0 +1,55 @@
|
||||
# Remove references to presence lists
|
||||
|
||||
[Presence](https://matrix.org/docs/spec/client_server/r0.4.0.html#id107) lists
|
||||
allow a given user the ability to subscribe to other users and be alerted to
|
||||
their current presence status.
|
||||
|
||||
While spec'd, no established client has implemented support and the only server
|
||||
side implementation raises privacy concerns.
|
||||
|
||||
The proposal is to simply remove references to presence lists with a view to
|
||||
revisiting the same ideas in the future.
|
||||
|
||||
This MSC addresses
|
||||
[#1810](https://github.com/matrix-org/matrix-doc/issues/1810)
|
||||
|
||||
## Proposal
|
||||
|
||||
Presence lists seem like a good fit for ['MSC1769: Extensible profiles as
|
||||
rooms'](https://github.com/matrix-org/matrix-doc/pull/1769) proposal, meaning
|
||||
that the current design will most likely be superceded.
|
||||
|
||||
Additionally, no major client has implemented the behaviour to date and the
|
||||
only server implementation of presence lists (Synapse) auto-accepts invites
|
||||
leading to privacy concerns in the wild.
|
||||
|
||||
With this in mind the most pragmatic solution is to remove presence lists ahead
|
||||
of the r0 release.
|
||||
|
||||
Specifically:-
|
||||
|
||||
CS API: Remove
|
||||
* [POST
|
||||
/_matrix/client/r0/presence/list/{userId}](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-presence-list-userid)
|
||||
* [GET
|
||||
/_matrix/client/r0/presence/list/{userId}](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-presence-list-userid)
|
||||
|
||||
SS API: Remove
|
||||
* [m.presence_invite](https://matrix.org/docs/spec/server_server/unstable.html#m-presence-invite-schema)
|
||||
* [m.presence_accept](https://matrix.org/docs/spec/server_server/unstable.html#m-presence-accept-schema)
|
||||
* [m.presence_deny](https://matrix.org/docs/spec/server_server/unstable.html#m-presence-deny-schema)
|
||||
|
||||
|
||||
## Tradeoffs
|
||||
|
||||
Ideally this proposal would also come with an alternative design for this
|
||||
functionality. Out of pragmatism the proposal only covers removal of what is
|
||||
there today.
|
||||
|
||||
|
||||
## Conclusions
|
||||
|
||||
This is a common sense attempt to remove unused portions of the spec ahead of
|
||||
an r0 release. It does not suggest that the ability to subscribe to the
|
||||
presence of others is undesirable and assumes that this behvaiour will return
|
||||
again in some form.
|
@ -0,0 +1,25 @@
|
||||
# Proposal to do SRV lookups after .well-known to discover homeservers
|
||||
|
||||
Currently there is a logistical error proposed by [MSC1708](https://github.com/matrix-org/matrix-doc/pull/1708)
|
||||
which results in some homeservers unable to migrate to the new functionality
|
||||
proposed by [MSC1711](https://github.com/matrix-org/matrix-doc/pull/1711). This
|
||||
can happen if the delegated homeserver cannot obtain a valid TLS certificate for
|
||||
the domain, and an SRV record is used for backwards compatibility reasons.
|
||||
|
||||
Specifically, in order to be compatible with requests from both Synapse 0.34 and 1.0,
|
||||
servers can have both a SRV and a .well-known file, with Synapse presenting a certificate
|
||||
corresponding to the target of the .well-known. Synapse 0.34 is then happy because it
|
||||
will follow the SRV (and won't care about the incorrect certificate); Synapse 1.0 is
|
||||
happy because it will follow the .well-known (and will see the correct cert).
|
||||
|
||||
## Proposal
|
||||
|
||||
We change the order of operations to perform a .well-known lookup before falling
|
||||
back to resolving the SRV record. This allows for domains to delegate to other
|
||||
hostnames and maintains backwards compatibility with older homeservers.
|
||||
|
||||
## Tradeoffs
|
||||
|
||||
More HTTP hits will be made due to the .well-known lookup being first. This is
|
||||
somewhat mitigated by servers caching the responses appropriately, and using
|
||||
connection pools where possible.
|
@ -0,0 +1,14 @@
|
||||
# MSC 1866 - Unsupported Room Version Error Code for Invites
|
||||
|
||||
It is currently unspecified what error code should be relayed to clients when
|
||||
they attempt to invite a user on a remote server that does not support the room
|
||||
version.
|
||||
|
||||
The proposal is to reuse the `M_UNSUPPORTED_ROOM_VERSION` error code that is
|
||||
currently returned by the create room API.
|
||||
|
||||
Strictly, the error returned by the create room API would mean the local server
|
||||
didn't support the room version, while for the invite API it would mean the
|
||||
remote server didn't. However, there is sufficient overlap that it makes sense
|
||||
to reuse the same error code and rely on the context to differentiate the two
|
||||
cases.
|
@ -0,0 +1,166 @@
|
||||
# MSC1884: Proposal to replace slashes in event IDs
|
||||
|
||||
[MSC1659](https://github.com/matrix-org/matrix-doc/pull/1659) mandated that,
|
||||
starting in version 3 rooms, event IDs must be calculated as a base64-encoding
|
||||
of a hash. This implies that event IDs may contain any character in the
|
||||
standard Base64 alphabet, which notably includes the slash character, `/`.
|
||||
|
||||
Event IDs are often embedded in URI paths, and since the slash character is
|
||||
used as a separator in URI paths, this presents a problem. The immediate
|
||||
solution is to ensure that event IDs are URL-encoded, so that `/` is instead
|
||||
represented as `%2F`. However, this is not entirely satisfactory for a number
|
||||
of reasons:
|
||||
|
||||
* The act of escaping and unescaping slash characters when manually calling
|
||||
the API during devops work becomes an constant and annoying chore which
|
||||
is entirely avoidable. Whenever using tools like `curl` and `grep` or
|
||||
manipulating SQL, developers will have to constantly keep in mind whether
|
||||
they are dealing with escaped or unescaped IDs, and manually convert between
|
||||
the two as needed. This will only get worse with further keys-as-IDs
|
||||
landing with MSC1228.
|
||||
|
||||
* There exist a number of client (and possibly server) implementations which
|
||||
do not currently URL-encode such parameters; these are therefore broken by
|
||||
such event IDs and must be updated. Furthermore, all future client
|
||||
implementers must remember to do the encoding correctly.
|
||||
|
||||
* Even if client implementations do remember to URL-encode their parameters,
|
||||
they may not do it correctly: many URL-encoding implementations may be
|
||||
intended to encode parameters in the query-string (which can of course
|
||||
contain literal slashes) rather than the path component.
|
||||
|
||||
* Some proxy software may treat `%2F` specially: for instance, Apache, when
|
||||
configured as a reverse-proxy, will reject requests for a path containing
|
||||
`%2F` unless it is also configured with `nocanon`. Again this means that
|
||||
existing setups will be broken by this change, and it is a trap for new
|
||||
users of the software.
|
||||
|
||||
* Cosmetically, URL-escaping base64 in otherwise-constant-length IDs results
|
||||
in variable length IDs, making it harder to visually scan lists of IDs and
|
||||
manipulate them in columnar form when doing devops work.
|
||||
|
||||
* Those developing against the CS API might reasonably expect us to use
|
||||
URL-safe identifiers in URLs where available, rather than deliberately
|
||||
choosing non-URL-safe IDs, which could be seen as developer-unfriendly.
|
||||
|
||||
## Proposal
|
||||
|
||||
This MSC proposes that we should introduce a new room version, in which event
|
||||
IDs are encoded using the [URL-safe Base64
|
||||
encoding](https://tools.ietf.org/html/rfc4648#section-5) (which uses `-` and
|
||||
`_` as the 62nd and 63rd characters instead of `+` and `/`).
|
||||
|
||||
We will then aim to use URL-safe Base64 encoding across Matrix in future,
|
||||
such that typical CS API developers should be able to safely assume
|
||||
that for all common cases (including upcoming MSC1228 identifiers) they should
|
||||
use URL-safe Base64 when decoding base64 strings.
|
||||
|
||||
The exception would be for E2EE data (device keys and signatures etc) which
|
||||
currently use normal Base64 with no easy mechanism to migrate to a new encoding.
|
||||
Given E2EE development is rare and requires expert skills, it seems acceptable
|
||||
to expect E2EE developers to be able to use the right encoding without tripping
|
||||
up significantly.
|
||||
|
||||
Similarly, the S2S API could continue to use standard base64-encoded hashes and
|
||||
signatures in the places it does today, given they are only exposed to S2S API
|
||||
developers who are necessarily expert and should be able to correctly pick the
|
||||
right encoding.
|
||||
|
||||
## Counterarguments
|
||||
|
||||
1. Inconsistency. Base64 encoding is used heavily elsewhere in the matrix
|
||||
protocol and in all cases the standard encoding is used (though with some
|
||||
variation as to the inclusion of padding characters). Further, SHA256 hashes
|
||||
are used in a number of places and are universally included with standard,
|
||||
unpadded Base64.
|
||||
|
||||
Changing event IDs alone would therefore leave us with a confusing mix of
|
||||
encodings.
|
||||
|
||||
However, the current uses of standard Base64 encodings are not exposed to
|
||||
common CS API developers, and so whilst this might be slightly confusing
|
||||
for the minority of expert homeserver developers, the confusion does not
|
||||
exist today for client developers (except those implementing E2EE).
|
||||
Therefore it seems safe to standardise on URL-safe Base64 for identifiers
|
||||
exposed to the client developers, who form by far the majority of the
|
||||
Matrix ecosystem today, and expect as simple an API as possible.
|
||||
|
||||
A potential extension would be to change *all* Base64 encodings to be
|
||||
URL-safe. This would address the inconsistency. However, it feels like a
|
||||
large job which would span the entire matrix ecosystem (far larger than
|
||||
updating clients to URL-encode their URL prarameters), and again the
|
||||
situation would be confusing while the transition was in progress.
|
||||
|
||||
2. Incompleteness. Event IDs are certainly not the only identifier which can
|
||||
contain slashes - Room aliases, Room IDs, Group IDs, User IDs [1], and state
|
||||
keys can all contain slashes, as well as a number of identifiers whose
|
||||
grammars are currently underspecified (eg transaction ids, event types,
|
||||
device IDs). (Indeed, there was nothing preventing Event IDs from containing
|
||||
slashes before room v3 - it just happened that Synapse used an algorithm
|
||||
which didn't generate them).
|
||||
|
||||
All of these other identifiers can appear in URLs in either or both the
|
||||
client-server or server-server APIs, and all have the potential to cause
|
||||
misbehaviour if software does not correctly URL-encode them.
|
||||
|
||||
It can be argued that it is better for software to fail 50% of the time [2]
|
||||
so that it can be fixed than it is to fail only on edge-cases or, worse,
|
||||
when deliberately provoked by a malicious or "curious" actor.
|
||||
|
||||
Of course, an alternative is to modify the grammars of all of these
|
||||
identifiers to forbid slashes.
|
||||
|
||||
The counter-counterargument to this is that it is of course best practice
|
||||
for implementations is to URL-escape any IDs used in URLs, and human-selected
|
||||
IDs such as Room aliases, Group IDs, Matrix user IDs etc apply an adequate
|
||||
forcing function already to remind developers to do this. However,
|
||||
it doesn't follow that we should then also deliberately pick URL-unsafe
|
||||
encodings for machine-selected IDs - the argument that it is better for software
|
||||
to fail 50% of the time to force a fix is irrelevant when the possibility
|
||||
exists for the software to fail 0% of the time in the first place by picking
|
||||
an identifier format which cannot fail.
|
||||
|
||||
[1] Discussion remains open as to whether allowing slashes in User IDs was a
|
||||
good idea.
|
||||
|
||||
[2] 48% of random 32-byte sequences will contain a slash when Base64-encoded.
|
||||
|
||||
## Alternatives
|
||||
|
||||
An alternative would be to modify all REST endpoints to use query or body
|
||||
parameters instead of path parameters. This would of course be a significant
|
||||
and incompatible change, but it would also bring the benefit of solving a
|
||||
common problem where forgetting to use `nocanon` in a reverse-proxy
|
||||
configuration [breaks
|
||||
federation](https://github.com/matrix-org/synapse/issues/3294) (though other
|
||||
solutions to that are also possible).
|
||||
|
||||
## Conclusion
|
||||
|
||||
There are two main questions here:
|
||||
|
||||
1. Whether it's worth forcing CS API developers to juggle escaping of
|
||||
machine-selected IDs during manual use of the API in order to remind them
|
||||
to escape all variables in their URIs correctly when writing code.
|
||||
|
||||
2. Whether it's a significant problem for E2EE & SS API developers to have to
|
||||
handle strings which are a mix of standard Base64 and URL-safe Base64
|
||||
encodings.
|
||||
|
||||
Both of these are a subjective judgement call.
|
||||
|
||||
Given we wish the CS API particularly to be as easy as possible for manual
|
||||
use, it feels that we should find another way to encourage developers to
|
||||
escape variables in their URLs in general - e.g. by recommending that
|
||||
developers test their clients against a 'torture room' full of exotic IDs and
|
||||
data, or by improving warnings in the spec... rather than (ab)using
|
||||
machine-selected IDs as a reminder.
|
||||
|
||||
Meanwhile, given we have many more people manually invoking the CS API than
|
||||
developing on the SS or E2EE APIs, and we wish to make the CS API particularly
|
||||
easy for developers to manually invoke, it feels we should not prioritise
|
||||
consistency of encodings for SS/E2EE developers over the usability of the CS
|
||||
API.
|
||||
|
||||
Therefore, on balance, it seems plausible that changing the format of event IDs
|
||||
does solve sufficient problems to make it desirable.
|
@ -0,0 +1,107 @@
|
||||
# MSC 1915 - Add unbind 3PID APIs
|
||||
|
||||
Note that this is a simplified version of MSC1194.
|
||||
|
||||
|
||||
## Motivation
|
||||
|
||||
Currently we do not have a reasonable route for a user to unbind/remove a 3PID
|
||||
from their account, particularly when deactivating their account. Users have an
|
||||
expectation to be able to do this, and thus we should have an API to provide it.
|
||||
|
||||
This is meant as a simple extension to the current APIs, and so this explicitly
|
||||
does not try and solve any existing usability concerns.
|
||||
|
||||
|
||||
## API Changes
|
||||
|
||||
### Client-Server 3PID Delete API
|
||||
|
||||
Add an `id_server` param to `POST /_matrix/client/r0/account/3pid/delete` API,
|
||||
which matches the 3PID creation APIs.
|
||||
|
||||
The new `id_server` parameter is optional and if missing the server will attempt
|
||||
to unbind from the identity server used when originally binding the 3pid (if
|
||||
known by the homeserver).
|
||||
|
||||
The 200 response is a JSON object with an `id_server_unbind_result` field whose
|
||||
value is either `success` or `no-support`, where the latter indicates that the
|
||||
identity server (IS) does not support unbinding 3PIDs directly. If the identity
|
||||
server returns an error then that should be returned to the client.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
POST /_matrix/client/r0/account/3pid/delete HTTP/1.1
|
||||
|
||||
{
|
||||
"medium": "email",
|
||||
"address": "foobar@example.com",
|
||||
"id_server": "https://matrix.org
|
||||
}
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
{
|
||||
"id_server_unbind_result": "success"
|
||||
}
|
||||
```
|
||||
|
||||
### Client-Server Deactivate account API
|
||||
|
||||
Add an `id_server` param to `POST /_matrix/client/r0/account/deactivate` API,
|
||||
with the same semantics as above. This is used to unbind any bound threepids
|
||||
from the given identity server.
|
||||
|
||||
|
||||
### Identity Server 3PID Unbind API
|
||||
|
||||
Add `POST /_matrix/identity/api/v1/3pid/unbind` with `mxid` and `threepid` fields.
|
||||
The `mxid` is the user's `user_id` and `threepid` is a dict with the usual
|
||||
`medium` and `address` fields.
|
||||
|
||||
If the server returns a 400, 404 or 501 HTTP error code then the homeserver
|
||||
should assume that the identity server doesn't support the `/3pid/unbind` API, unless
|
||||
it returns a specific matrix error response (i.e. the body is a JSON object with
|
||||
`error` and `errcode` fields).
|
||||
|
||||
The identity server should authenticate the request in one of two ways:
|
||||
|
||||
1. The request is signed by the homeserver which controls the `user_id`.
|
||||
2. The request includes the `sid` and `client_secret` params (as per `/bind`),
|
||||
which proves ownership of the given 3PID.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
POST /_matrix/identity/api/v1/3pid/unbind HTTP/1.1
|
||||
|
||||
{
|
||||
"mxid": "@foobar:example.com",
|
||||
"threepid": {
|
||||
"medium": "email",
|
||||
"address": "foobar@example.com"
|
||||
}
|
||||
}
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
|
||||
{}
|
||||
```
|
||||
|
||||
# Trade-offs
|
||||
|
||||
A homeserver can unbind any 3PID associated with one of its users, and
|
||||
specifically does not require a re-validation of control of the 3PID. This means
|
||||
that users have to trust that their homeserver will not arbitrarily remove valid
|
||||
3PIDs, however users must already trust their homeserver to a large extent. The
|
||||
flip side is that this provides a mechanism for homeservers and users to remove
|
||||
3PIDs directed at their user IDs that they no longer (or never did) have control
|
||||
over.
|
||||
|
||||
Removing a 3PID does not require user interactive auth (UIA), which opens a
|
||||
potential attack whereby a logged in device can remove all associated 3PIDs and
|
||||
then log out all devices. If the user has forgotten their password they would no
|
||||
longer be able to reset their password via a 3PID (e.g. email), resulting in
|
||||
losing access to their account. However, given that clients and servers have
|
||||
implemented these APIs in the wild this is considered a sufficient edge case
|
||||
that adding UIA is unlikely to be worthwhile.
|
@ -0,0 +1,40 @@
|
||||
# Proposal to add a default push rule for m.room.tombstone events
|
||||
|
||||
Currently users are unaware of when a room becomes upgraded, leaving them potentially in the old room
|
||||
without knowing until they visit the room again. By having a notification for when the room is upgraded,
|
||||
users are able to ensure they are able to stay relevant in rooms by joining the upgraded room.
|
||||
|
||||
|
||||
## Proposal
|
||||
|
||||
A new default override rule is to be added which is similar to `@room` notifications:
|
||||
|
||||
```json
|
||||
{
|
||||
"rule_id": ".m.rule.tombstone",
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"conditions": [
|
||||
{
|
||||
"kind": "event_match",
|
||||
"key": "type",
|
||||
"pattern": "m.room.tombstone"
|
||||
}
|
||||
],
|
||||
"actions": [
|
||||
"notify",
|
||||
{
|
||||
"set_tweak": "highlight",
|
||||
"value": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Tradeoffs
|
||||
|
||||
Clients could calculate this on their own and show some sort of "room upgraded" notification instead,
|
||||
however by doing it this way it means that all clients would need to be aware of room upgrades. Having
|
||||
a default push rule means that clients get this notification for free. Clients which want a more diverse
|
||||
UX can still do so by ignoring this push rule locally.
|
@ -0,0 +1,77 @@
|
||||
# Remove prev_content from the essential keys list
|
||||
|
||||
Matrix supports the concept of event redaction. The ability to redact rather
|
||||
than delete is necessary because some events e.g. membership events are
|
||||
essential to the protocol and _cannot_ be deleted. Therefore we do not delete
|
||||
events outright and instead redact them. This involves removing all keys from
|
||||
an event that are not required by the protocol. The stripped down event is
|
||||
thereafter returned anytime a client or remote server requests it.
|
||||
|
||||
|
||||
## Proposal
|
||||
|
||||
[The redaction algorithm](https://matrix.org/docs/spec/client_server/r0.4.0.html#redactions)
|
||||
defines which keys must be retained through a redaction. Currently it lists
|
||||
```prev_content``` as a key to retain, though in practice there is no need to
|
||||
do so at the protocol level.
|
||||
|
||||
The proposal is simply to remove ```prev_content``` from the essential keys
|
||||
list.
|
||||
|
||||
Note: the inclusion of ```prev_content``` in the essential keys list was
|
||||
unintentional and should be considered a spec bug. Synapse (and other server
|
||||
implementations) have not implemented the bug and already omit
|
||||
```prev_content``` from redacted events.
|
||||
|
||||
|
||||
## Tradeoffs
|
||||
|
||||
When sending events over federation the events are [hashed and
|
||||
signed](https://matrix.org/docs/spec/server_server/unstable.html#adding-hashes-and-signatures-to-outgoing-events),
|
||||
this involves operating not only on the original event but also the redacted
|
||||
form of the event. The redacted hash and redacted signed event are necessary if
|
||||
the event is ever redacted in future. As a result, any change of the essential
|
||||
keys list must be managed carefully. If disparate servers implement different
|
||||
versions of the redaction algorithm (for a given event) attempts to send the
|
||||
event over federation will fail.
|
||||
|
||||
We _could_ manage this change via room versioning and create a new room
|
||||
version that implements this MSC. However, because the federation already
|
||||
omits the ```prev_content``` key by convention, implementing this MSC only in
|
||||
the new room version would mean that the entire existing federation would not
|
||||
be spec compliant.
|
||||
|
||||
As a result it seems pragmatic to have the spec reflect reality, acknowledge
|
||||
that the spec and federation have deviated and instead update the spec
|
||||
retrospectively to describe the de-facto redaction algorithm.
|
||||
|
||||
## Potential issues
|
||||
|
||||
It is theoretically possible that a closed federation could exist whose servers
|
||||
do follow the spec as is. This MSC would render those servers non-compliant with
|
||||
the spec. On balance this seems unlikely and in the worst case those
|
||||
implementors could add the change to a subsequent room version, eventually
|
||||
reaching spec consistency as older room versions are deprecated.
|
||||
|
||||
Another scenario is that a client may redact events according to the spec as is
|
||||
and persist prev_content through the redaction, thereby diverting from that on
|
||||
the server(s). Client authors will have to update their code to drop
|
||||
```prev_content``` - however, given that prev_content should not be used in
|
||||
important calculations and/or visualisations, this ought to be a relatively
|
||||
non-invasive change.
|
||||
|
||||
|
||||
## Security considerations
|
||||
|
||||
A further reason to support removal of ```prev_content``` is the case where a
|
||||
malicious user adds illegal or abusive content into a state event and then
|
||||
overwrites that state event. The content would then be preserved through the
|
||||
redaction.
|
||||
|
||||
Additionally, there are plenty of reasons to have security concerns over a
|
||||
precedent that the federation can deviate from the spec.
|
||||
|
||||
## Conclusions
|
||||
Removing ```prev_content``` is pragmatic response to the current situation. It
|
||||
alligns the federation and the spec, and does so in a way that removes
|
||||
unecessary overhead.
|
@ -1,119 +0,0 @@
|
||||
.. Copyright 2016 OpenMarket Ltd
|
||||
..
|
||||
.. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
.. you may not use this file except in compliance with the License.
|
||||
.. You may obtain a copy of the License at
|
||||
..
|
||||
.. http://www.apache.org/licenses/LICENSE-2.0
|
||||
..
|
||||
.. Unless required by applicable law or agreed to in writing, software
|
||||
.. distributed under the License is distributed on an "AS IS" BASIS,
|
||||
.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
.. See the License for the specific language governing permissions and
|
||||
.. limitations under the License.
|
||||
|
||||
CAS-based client login
|
||||
======================
|
||||
|
||||
.. _module:cas_login:
|
||||
|
||||
`Central Authentication Service
|
||||
<https://github.com/apereo/cas/blob/master/docs/cas-server-documentation/protocol/CAS-Protocol-Specification.md>`_
|
||||
(CAS) is a web-based single sign-on protocol.
|
||||
|
||||
An overview of the process, as used in Matrix, is as follows:
|
||||
|
||||
1. The Matrix client instructs the user's browser to navigate to the
|
||||
|/login/cas/redirect|_ endpoint on the user's homeserver.
|
||||
|
||||
2. The homeserver responds with an HTTP redirect to the CAS user interface,
|
||||
which the browser follows.
|
||||
|
||||
3. The CAS system authenticates the user.
|
||||
|
||||
4. The CAS server responds to the user's browser with a redirect back to the
|
||||
|/login/cas/ticket|_ endpoint on the homeserver, which the browser
|
||||
follows. A 'ticket' identifier is passed as a query parameter in the
|
||||
redirect.
|
||||
|
||||
5. The homeserver receives the ticket ID from the user's browser, and makes a
|
||||
request to the CAS server to validate the ticket.
|
||||
|
||||
6. Having validated the ticket, the homeserver responds to the browser with a
|
||||
third HTTP redirect, back to the Matrix client application. A login token
|
||||
is passed as a query parameter in the redirect.
|
||||
|
||||
7. The Matrix client receives the login token and passes it to the |/login|_
|
||||
API.
|
||||
|
||||
Client behaviour
|
||||
----------------
|
||||
|
||||
The client starts the process by instructing the browser to navigate to
|
||||
|/login/cas/redirect|_ with an appropriate ``redirectUrl``. Once authentication
|
||||
is successful, the browser will be redirected to that ``redirectUrl``.
|
||||
|
||||
.. TODO-spec
|
||||
|
||||
Should we recommend some sort of CSRF protection here (specifically, we
|
||||
should guard against people accidentally logging in by sending them a link
|
||||
to ``/login/cas/redirect``.
|
||||
|
||||
Maybe we should recommend that the ``redirectUrl`` should contain a CSRF
|
||||
token which the client should then check before sending the login token to
|
||||
``/login``?
|
||||
|
||||
{{cas_login_redirect_cs_http_api}}
|
||||
{{cas_login_ticket_cs_http_api}}
|
||||
|
||||
Server behaviour
|
||||
----------------
|
||||
|
||||
The URI for the CAS system to be used should be configured on the server by the
|
||||
server administrator.
|
||||
|
||||
Handling the redirect endpoint
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When responding to the ``/login/cas/redirect`` endpoint, the server must
|
||||
generate a URI for the CAS login page. The server should take the base CAS URI
|
||||
described above, and add a ``service`` query parameter. This parameter MUST be
|
||||
the URI of the ``/login/cas/ticket`` endpoint, including the ``redirectUrl``
|
||||
query parameter. Because the homeserver may not know its base URI, this may
|
||||
also require manual configuration.
|
||||
|
||||
.. TODO-spec:
|
||||
|
||||
It might be nice if the server did some validation of the ``redirectUrl``
|
||||
parameter, so that we could check that aren't going to redirect to a non-TLS
|
||||
endpoint, and to give more meaningful errors in the case of
|
||||
faulty/poorly-configured clients.
|
||||
|
||||
Handling the authentication endpoint
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When responding to the ``/login/cas/ticket`` endpoint, the server MUST make a
|
||||
request to the CAS server to validate the provided ticket. The server MAY also
|
||||
check for certain user attributes in the response. Any required attributes
|
||||
should be configured by the server administrator.
|
||||
|
||||
Once the ticket has been validated, the server MUST map the CAS ``user_id``
|
||||
to a valid `Matrix user identifier <../index.html#user-identifiers>`_. The
|
||||
guidance in `Mapping from other character sets
|
||||
<../index.html#mapping-from-other-character-sets>`_ may be useful.
|
||||
|
||||
If the generated user identifier represents a new user, it should be registered
|
||||
as a new user.
|
||||
|
||||
Finally, the server should generate a short-term login token. The generated
|
||||
token should be a macaroon, suitable for use with the ``m.login.token`` type of
|
||||
the |/login|_ API, and `token-based interactive login <#token-based>`_. The
|
||||
lifetime of this token SHOULD be limited to around five seconds.
|
||||
|
||||
|
||||
.. |/login| replace:: ``/login``
|
||||
.. _/login: #post-matrix-client-%CLIENT_MAJOR_VERSION%-login
|
||||
.. |/login/cas/redirect| replace:: ``/login/cas/redirect``
|
||||
.. _/login/cas/redirect: #get-matrix-client-%CLIENT_MAJOR_VERSION%-login-cas-redirect
|
||||
.. |/login/cas/ticket| replace:: ``/login/cas/ticket``
|
||||
.. _/login/cas/ticket: #get-matrix-client-%CLIENT_MAJOR_VERSION%-login-cas-ticket
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue