Merge branch 'master' into matthew/msc1779
commit
efcbf2f807
@ -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
|
@ -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": "matrix.org",
|
||||||
"origin_server_ts": 1234567890,
|
"origin_server_ts": 1234567890,
|
||||||
"pdus": [{"$ref": "pdu.json"}]
|
"pdus": [{
|
||||||
}
|
"$ref": "minimal_pdu.json"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
@ -1,27 +1,4 @@
|
|||||||
{
|
{
|
||||||
"room_id": "!UcYsUzyxTGDxLBEvLy:example.org",
|
"$ref": "unsigned_pdu_base.json",
|
||||||
"sender": "@alice:example.com",
|
"event_id": "$a4ecee13e2accdadf56c1025: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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -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>`_.
|
@ -0,0 +1 @@
|
|||||||
|
Add support for advertising experimental features to clients.
|
@ -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
|
@ -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,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/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 `/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/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,78 @@
|
|||||||
|
.. 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.
|
||||||
|
|
||||||
|
Room Upgrades
|
||||||
|
=============
|
||||||
|
|
||||||
|
.. _module:room-upgrades:
|
||||||
|
|
||||||
|
From time to time, a room may need to be upgraded to a different room version for a
|
||||||
|
variety for reasons. This module defines a way for rooms to upgrade to a different
|
||||||
|
room version when needed.
|
||||||
|
|
||||||
|
Events
|
||||||
|
------
|
||||||
|
|
||||||
|
{{m_room_tombstone_event}}
|
||||||
|
|
||||||
|
Client behaviour
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Clients which understand ``m.room.tombstone`` events and the ``predecessor`` field on
|
||||||
|
``m.room.create`` events should communicate to the user that the room was upgraded.
|
||||||
|
One way of accomplishing this would be hiding the old room from the user's room list
|
||||||
|
and showing banners linking between the old and new room - ensuring that permalinks
|
||||||
|
work when referencing the old room. Another approach may be to virtually merge the
|
||||||
|
rooms such that the old room's timeline seamlessly continues into the new timeline
|
||||||
|
without the user having to jump between the rooms.
|
||||||
|
|
||||||
|
{{room_upgrades_cs_http_api}}
|
||||||
|
|
||||||
|
Server behaviour
|
||||||
|
----------------
|
||||||
|
|
||||||
|
When the client requests to upgrade a known room to a known version, the server:
|
||||||
|
|
||||||
|
1. Checks that the user has permission to send ``m.room.tombstone`` events in the room.
|
||||||
|
2. Creates a replacement room with a ``m.room.create`` event containing a ``predecessor``
|
||||||
|
field and the applicable ``room_version``.
|
||||||
|
3. Replicates transferable state events to the new room. The exact details for what is
|
||||||
|
transferred is left as an implementation detail, however the recommended state events
|
||||||
|
to transfer are:
|
||||||
|
|
||||||
|
* ``m.room.server_acl``
|
||||||
|
* ``m.room.encryption``
|
||||||
|
* ``m.room.name``
|
||||||
|
* ``m.room.avatar``
|
||||||
|
* ``m.room.topic``
|
||||||
|
* ``m.room.guest_access``
|
||||||
|
* ``m.room.history_visibility``
|
||||||
|
* ``m.room.join_rules``
|
||||||
|
* ``m.room.power_levels``
|
||||||
|
|
||||||
|
Membership events should not be transferred to the new room due to technical limitations
|
||||||
|
of servers not being able to impersonate people from other homeservers. Additionally,
|
||||||
|
servers should not transfer state events which are sensitive to who sent them, such as
|
||||||
|
events outside of the Matrix namespace where clients may rely on the sender to match
|
||||||
|
certain criteria.
|
||||||
|
|
||||||
|
4. Moves any local aliases to the new room.
|
||||||
|
5. Sends a ``m.room.tombstone`` event to the old room to indicate that it is not intended
|
||||||
|
to be used any further.
|
||||||
|
6. If possible, the power levels in the old room should also be modified to prevent sending
|
||||||
|
of events and inviting new users. For example, setting ``events_default`` and ``invite``
|
||||||
|
to the greater of ``50`` and ``users_default + 1``.
|
||||||
|
|
||||||
|
When a user joins the new room, the server should automatically transfer/replicate some of
|
||||||
|
the user's personalized settings such as notifications, tags, etc.
|
@ -0,0 +1,297 @@
|
|||||||
|
.. Copyright 2017,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.
|
||||||
|
|
||||||
|
Room Version 1
|
||||||
|
==============
|
||||||
|
|
||||||
|
This room version is the first ever version for rooms, and contains the building
|
||||||
|
blocks for other room versions.
|
||||||
|
|
||||||
|
.. contents:: Table of Contents
|
||||||
|
.. sectnum::
|
||||||
|
|
||||||
|
Server implementation components
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
.. WARNING::
|
||||||
|
The information contained in this section is strictly for server implementors.
|
||||||
|
Applications which use the Client-Server API are generally unaffected by the
|
||||||
|
details contained here, and can safely ignore their presence.
|
||||||
|
|
||||||
|
|
||||||
|
The algorithms defined here should only apply to version 1 rooms. Other algorithms
|
||||||
|
may be used by other room versions, and as such servers should be aware of which
|
||||||
|
version room they are dealing with prior to executing a given algorithm.
|
||||||
|
|
||||||
|
.. WARNING::
|
||||||
|
Although room version 1 is the most popular room version, it is known to have
|
||||||
|
undesirable effects. Servers implementing support for room version 1 should be
|
||||||
|
aware that restrictions should be generally relaxed and that inconsistencies
|
||||||
|
may occur until room version 2 (or later) is ready and adopted.
|
||||||
|
|
||||||
|
State resolution
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. WARNING::
|
||||||
|
This section documents the state resolution algorithm as implemented by
|
||||||
|
Synapse as of December 2017 (and therefore the de-facto Matrix protocol).
|
||||||
|
However, this algorithm is known to have some problems.
|
||||||
|
|
||||||
|
The room state :math:`S'(E)` after an event :math:`E` is defined in terms of
|
||||||
|
the room state :math:`S(E)` before :math:`E`, and depends on whether
|
||||||
|
:math:`E` is a state event or a message event:
|
||||||
|
|
||||||
|
* If :math:`E` is a message event, then :math:`S'(E) = S(E)`.
|
||||||
|
|
||||||
|
* If :math:`E` is a state event, then :math:`S'(E)` is :math:`S(E)`, except
|
||||||
|
that its entry corresponding to :math:`E`'s ``event_type`` and ``state_key``
|
||||||
|
is replaced by :math:`E`'s ``event_id``.
|
||||||
|
|
||||||
|
The room state :math:`S(E)` before :math:`E` is the *resolution* of the set of
|
||||||
|
states :math:`\{ S'(E'), S'(E''), … \}` consisting of the states after each of
|
||||||
|
:math:`E`'s ``prev_event``\s :math:`\{ E', E'', … \}`.
|
||||||
|
|
||||||
|
The *resolution* of a set of states is defined as follows. The resolved state
|
||||||
|
is built up in a number of passes; here we use :math:`R` to refer to the
|
||||||
|
results of the resolution so far.
|
||||||
|
|
||||||
|
* Start by setting :math:`R` to the union of the states to be resolved,
|
||||||
|
excluding any *conflicting* events.
|
||||||
|
|
||||||
|
* First we resolve conflicts between ``m.room.power_levels`` events. If there
|
||||||
|
is no conflict, this step is skipped, otherwise:
|
||||||
|
|
||||||
|
* Assemble all the ``m.room.power_levels`` events from the states to
|
||||||
|
be resolved into a list.
|
||||||
|
|
||||||
|
* Sort the list by ascending ``depth`` then descending ``sha1(event_id)``.
|
||||||
|
|
||||||
|
* Add the first event in the list to :math:`R`.
|
||||||
|
|
||||||
|
* For each subsequent event in the list, check that the event would be
|
||||||
|
allowed by the authorization rules for a room in state :math:`R`. If the
|
||||||
|
event would be allowed, then update :math:`R` with the event and continue
|
||||||
|
with the next event in the list. If it would not be allowed, stop and
|
||||||
|
continue below with ``m.room.join_rules`` events.
|
||||||
|
|
||||||
|
* Repeat the above process for conflicts between ``m.room.join_rules`` events.
|
||||||
|
|
||||||
|
* Repeat the above process for conflicts between ``m.room.member`` events.
|
||||||
|
|
||||||
|
* No other events affect the authorization rules, so for all other conflicts,
|
||||||
|
just pick the event with the highest depth and lowest ``sha1(event_id)`` that
|
||||||
|
passes authentication in :math:`R` and add it to :math:`R`.
|
||||||
|
|
||||||
|
A *conflict* occurs between states where those states have different
|
||||||
|
``event_ids`` for the same ``(state_type, state_key)``. The events thus
|
||||||
|
affected are said to be *conflicting* events.
|
||||||
|
|
||||||
|
|
||||||
|
Authorization rules
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The types of state events that affect authorization are:
|
||||||
|
|
||||||
|
- ``m.room.create``
|
||||||
|
- ``m.room.member``
|
||||||
|
- ``m.room.join_rules``
|
||||||
|
- ``m.room.power_levels``
|
||||||
|
- ``m.room.third_party_invite``
|
||||||
|
|
||||||
|
The rules are as follows:
|
||||||
|
|
||||||
|
1. If type is ``m.room.create``:
|
||||||
|
|
||||||
|
a. If it has any previous events, reject.
|
||||||
|
b. If the domain of the ``room_id`` does not match the domain of the
|
||||||
|
``sender``, reject.
|
||||||
|
c. If ``content.room_version`` is present and is not a recognised version,
|
||||||
|
reject.
|
||||||
|
d. If ``content`` has no ``creator`` field, reject.
|
||||||
|
e. Otherwise, allow.
|
||||||
|
|
||||||
|
#. Reject if event has ``auth_events`` that:
|
||||||
|
|
||||||
|
a. have duplicate entries for a given ``type`` and ``state_key`` pair
|
||||||
|
#. have entries whose ``type`` and ``state_key`` don't match those
|
||||||
|
specified by the `auth events selection`_ algorithm described in the
|
||||||
|
server specification.
|
||||||
|
|
||||||
|
#. If event does not have a ``m.room.create`` in its ``auth_events``, reject.
|
||||||
|
|
||||||
|
#. If type is ``m.room.aliases``:
|
||||||
|
|
||||||
|
a. If event has no ``state_key``, reject.
|
||||||
|
b. If sender's domain doesn't matches ``state_key``, reject.
|
||||||
|
c. Otherwise, allow.
|
||||||
|
|
||||||
|
#. If type is ``m.room.member``:
|
||||||
|
|
||||||
|
a. If no ``state_key`` key or ``membership`` key in ``content``, reject.
|
||||||
|
|
||||||
|
#. If ``membership`` is ``join``:
|
||||||
|
|
||||||
|
i. If the only previous event is an ``m.room.create``
|
||||||
|
and the ``state_key`` is the creator, allow.
|
||||||
|
|
||||||
|
#. If the ``sender`` does not match ``state_key``, reject.
|
||||||
|
|
||||||
|
#. If the ``sender`` is banned, reject.
|
||||||
|
|
||||||
|
#. If the ``join_rule`` is ``invite`` then allow if membership state
|
||||||
|
is ``invite`` or ``join``.
|
||||||
|
|
||||||
|
#. If the ``join_rule`` is ``public``, allow.
|
||||||
|
|
||||||
|
#. Otherwise, reject.
|
||||||
|
|
||||||
|
#. If ``membership`` is ``invite``:
|
||||||
|
|
||||||
|
i. If ``content`` has ``third_party_invite`` key:
|
||||||
|
|
||||||
|
#. If *target user* is banned, reject.
|
||||||
|
|
||||||
|
#. If ``content.third_party_invite`` does not have a
|
||||||
|
``signed`` key, reject.
|
||||||
|
|
||||||
|
#. If ``signed`` does not have ``mxid`` and ``token`` keys, reject.
|
||||||
|
|
||||||
|
#. If ``mxid`` does not match ``state_key``, reject.
|
||||||
|
|
||||||
|
#. If there is no ``m.room.third_party_invite`` event in the
|
||||||
|
current room state with ``state_key`` matching ``token``, reject.
|
||||||
|
|
||||||
|
#. If ``sender`` does not match ``sender`` of the
|
||||||
|
``m.room.third_party_invite``, reject.
|
||||||
|
|
||||||
|
#. If any signature in ``signed`` matches any public key in the
|
||||||
|
``m.room.third_party_invite`` event, allow. The public keys are
|
||||||
|
in ``content`` of ``m.room.third_party_invite`` as:
|
||||||
|
|
||||||
|
#. A single public key in the ``public_key`` field.
|
||||||
|
#. A list of public keys in the ``public_keys`` field.
|
||||||
|
|
||||||
|
#. Otherwise, reject.
|
||||||
|
|
||||||
|
#. If the ``sender``'s current membership state is not ``join``, reject.
|
||||||
|
|
||||||
|
#. If *target user*'s current membership state is ``join`` or ``ban``,
|
||||||
|
reject.
|
||||||
|
|
||||||
|
#. If the ``sender``'s power level is greater than or equal to the *invite
|
||||||
|
level*, allow.
|
||||||
|
|
||||||
|
#. Otherwise, reject.
|
||||||
|
|
||||||
|
#. If ``membership`` is ``leave``:
|
||||||
|
|
||||||
|
i. If the ``sender`` matches ``state_key``, allow if and only if that user's
|
||||||
|
current membership state is ``invite`` or ``join``.
|
||||||
|
|
||||||
|
#. If the ``sender``'s current membership state is not ``join``, reject.
|
||||||
|
|
||||||
|
#. If the *target user*'s current membership state is ``ban``, and the
|
||||||
|
``sender``'s power level is less than the *ban level*, reject.
|
||||||
|
|
||||||
|
#. If the ``sender``'s power level is greater than or equal to the *kick
|
||||||
|
level*, and the *target user*'s power level is less than the
|
||||||
|
``sender``'s power level, allow.
|
||||||
|
|
||||||
|
#. Otherwise, reject.
|
||||||
|
|
||||||
|
#. If ``membership`` is ``ban``:
|
||||||
|
|
||||||
|
i. If the ``sender``'s current membership state is not ``join``, reject.
|
||||||
|
|
||||||
|
#. If the ``sender``'s power level is greater than or equal to the *ban
|
||||||
|
level*, and the *target user*'s power level is less than the
|
||||||
|
``sender``'s power level, allow.
|
||||||
|
|
||||||
|
#. Otherwise, reject.
|
||||||
|
|
||||||
|
#. Otherwise, the membership is unknown. Reject.
|
||||||
|
|
||||||
|
#. If the ``sender``'s current membership state is not ``join``, reject.
|
||||||
|
|
||||||
|
#. If type is ``m.room.third_party_invite``:
|
||||||
|
|
||||||
|
a. Allow if and only if ``sender``'s current power level is greater than
|
||||||
|
or equal to the *invite level*.
|
||||||
|
|
||||||
|
#. If the event type's *required power level* is greater than the ``sender``'s power
|
||||||
|
level, reject.
|
||||||
|
|
||||||
|
#. If the event has a ``state_key`` that starts with an ``@`` and does not match
|
||||||
|
the ``sender``, reject.
|
||||||
|
|
||||||
|
#. If type is ``m.room.power_levels``:
|
||||||
|
|
||||||
|
a. If ``users`` key in ``content`` is not a dictionary with keys that are
|
||||||
|
valid user IDs with values that are integers (or a string that is an
|
||||||
|
integer), reject.
|
||||||
|
|
||||||
|
#. If there is no previous ``m.room.power_levels`` event in the room, allow.
|
||||||
|
|
||||||
|
#. For each of the keys ``users_default``, ``events_default``,
|
||||||
|
``state_default``, ``ban``, ``redact``, ``kick``, ``invite``, as well as
|
||||||
|
each entry being changed under the ``events`` or ``users`` keys:
|
||||||
|
|
||||||
|
i. If the current value is higher than the ``sender``'s current power level,
|
||||||
|
reject.
|
||||||
|
|
||||||
|
#. If the new value is higher than the ``sender``'s current power level,
|
||||||
|
reject.
|
||||||
|
|
||||||
|
#. For each entry being changed under the ``users`` key, other than the
|
||||||
|
``sender``'s own entry:
|
||||||
|
|
||||||
|
i. If the current value is equal to the ``sender``'s current power level,
|
||||||
|
reject.
|
||||||
|
|
||||||
|
#. Otherwise, allow.
|
||||||
|
|
||||||
|
#. If type is ``m.room.redaction``:
|
||||||
|
|
||||||
|
a. If the ``sender``'s power level is greater than or equal to the *redact
|
||||||
|
level*, allow.
|
||||||
|
|
||||||
|
#. If the domain of the ``event_id`` of the event being redacted is the same
|
||||||
|
as the domain of the ``event_id`` of the ``m.room.redaction``, allow.
|
||||||
|
|
||||||
|
#. Otherwise, reject.
|
||||||
|
|
||||||
|
#. Otherwise, allow.
|
||||||
|
|
||||||
|
.. NOTE::
|
||||||
|
|
||||||
|
Some consequences of these rules:
|
||||||
|
|
||||||
|
* Unless you are a member of the room, the only permitted operations (apart
|
||||||
|
from the initial create/join) are: joining a public room; accepting or
|
||||||
|
rejecting an invitation to a room.
|
||||||
|
|
||||||
|
* To unban somebody, you must have power level greater than or equal to both
|
||||||
|
the kick *and* ban levels, *and* greater than the target user's power
|
||||||
|
level.
|
||||||
|
|
||||||
|
Event format
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Events in version 1 rooms have the following structure:
|
||||||
|
|
||||||
|
{{definition_ss_pdu}}
|
||||||
|
|
||||||
|
|
||||||
|
.. _`auth events selection`: ../../server_server/r0.1.1.html#auth-events-selection
|
||||||
|
.. _`Signing Events`: ../../server_server/r0.1.1.html#signing-events
|
@ -0,0 +1,204 @@
|
|||||||
|
.. 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.
|
||||||
|
|
||||||
|
Room Version 2
|
||||||
|
==============
|
||||||
|
|
||||||
|
This room version builds off of `version 1 <v1.html>`_ with an improved state
|
||||||
|
resolution algorithm.
|
||||||
|
|
||||||
|
.. contents:: Table of Contents
|
||||||
|
.. sectnum::
|
||||||
|
|
||||||
|
Server implementation components
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
.. WARNING::
|
||||||
|
The information contained in this section is strictly for server implementors.
|
||||||
|
Applications which use the Client-Server API are generally unaffected by the
|
||||||
|
details contained here, and can safely ignore their presence.
|
||||||
|
|
||||||
|
|
||||||
|
Room version 2 uses the base components of `room version 1 <v1.html>`_, changing
|
||||||
|
only the state resolution algorithm.
|
||||||
|
|
||||||
|
|
||||||
|
State resolution
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The room state :math:`S'(E)` after an event :math:`E` is defined in terms of
|
||||||
|
the room state :math:`S(E)` before :math:`E`, and depends on whether
|
||||||
|
:math:`E` is a state event or a message event:
|
||||||
|
|
||||||
|
* If :math:`E` is a message event, then :math:`S'(E) = S(E)`.
|
||||||
|
|
||||||
|
* If :math:`E` is a state event, then :math:`S'(E)` is :math:`S(E)`, except
|
||||||
|
that its entry corresponding to :math:`E`'s ``event_type`` and ``state_key``
|
||||||
|
is replaced by :math:`E`'s ``event_id``.
|
||||||
|
|
||||||
|
The room state :math:`S(E)` before :math:`E` is the *resolution* of the set of
|
||||||
|
states :math:`\{ S'(E_1), S'(E_2), … \}` consisting of the states after each of
|
||||||
|
:math:`E`'s ``prev_event``\s :math:`\{ E_1, E_2, … \}`, where the resolution of
|
||||||
|
a set of states is given in the algorithm below.
|
||||||
|
|
||||||
|
Definitions
|
||||||
|
+++++++++++
|
||||||
|
|
||||||
|
The state resolution algorithm for version 2 rooms uses the following
|
||||||
|
definitions, given the set of room states :math:`\{ S_1, S_2, \ldots \}`:
|
||||||
|
|
||||||
|
Power events
|
||||||
|
A *power event* is a state event with type ``m.room.power_levels`` or
|
||||||
|
``m.room.join_rules``, or a state event with type ``m.room.member`` where the
|
||||||
|
``membership`` is ``leave`` or ``ban`` and the ``sender`` does not match the
|
||||||
|
``state_key``. The idea behind this is that power events are events that might
|
||||||
|
remove someone's ability to do something in the room.
|
||||||
|
|
||||||
|
Unconflicted state map and conflicted state set
|
||||||
|
The *unconflicted state map* is the state where the value of each key exists
|
||||||
|
and is the same in each state :math:`S_i`. The *conflicted state set* is the
|
||||||
|
set of all other state events. Note that the unconflicted state map only has
|
||||||
|
one event per ``(event_type, state_key)``, whereas the conflicted state set
|
||||||
|
may have multiple events.
|
||||||
|
|
||||||
|
Auth difference
|
||||||
|
The *auth difference* is calculated by first calculating the full auth chain
|
||||||
|
for each state :math:`S_i`, that is the union of the auth chains for each
|
||||||
|
event in :math:`S_i`, and then taking every event that doesn't appear in
|
||||||
|
every auth chain. If :math:`C_i` is the full auth chain of :math:`S_i`, then
|
||||||
|
the auth difference is :math:`\cup C_i - \cap C_i`.
|
||||||
|
|
||||||
|
Full conflicted set
|
||||||
|
The *full conflicted set* is the union of the conflicted state set and the
|
||||||
|
auth difference.
|
||||||
|
|
||||||
|
Reverse topological power ordering
|
||||||
|
The *reverse topological power ordering* of a set of events is the
|
||||||
|
lexicographically smallest topological ordering based on the DAG formed by
|
||||||
|
auth events. The reverse topological power ordering is ordered from earliest
|
||||||
|
event to latest. For comparing two topological orderings to determine which
|
||||||
|
is the lexicographically smallest, the following comparison relation on
|
||||||
|
events is used: for events :math:`x` and :math:`y`, :math:`x<y` if
|
||||||
|
|
||||||
|
1. :math:`x`'s sender has *greater* power level than :math:`y`'s sender,
|
||||||
|
when looking at their respective ``auth_event``\s; or
|
||||||
|
2. the senders have the same power level, but :math:`x`'s
|
||||||
|
``origin_server_ts`` is *less* than :math:`y`'s ``origin_server_ts``; or
|
||||||
|
3. the senders have the same power level and the events have the same
|
||||||
|
``origin_server_ts``, but :math:`x`'s ``event_id`` is *less* than
|
||||||
|
:math:`y`'s ``event_id``.
|
||||||
|
|
||||||
|
The reverse topological power ordering can be found by sorting the events
|
||||||
|
using Kahn's algorithm for topological sorting, and at each step selecting,
|
||||||
|
among all the candidate vertices, the smallest vertex using the above
|
||||||
|
comparison relation.
|
||||||
|
|
||||||
|
Mainline ordering
|
||||||
|
Given an ``m.room.power_levels`` event :math:`P`, the *mainline of* :math:`P`
|
||||||
|
is the list of events generated by starting with :math:`P` and recursively
|
||||||
|
taking the ``m.room.power_levels`` events from the ``auth_events``, ordered
|
||||||
|
such that :math:`P` is last. Given another event :math:`e`, the *closest
|
||||||
|
mainline event to* :math:`e` is the first event encountered in the mainline
|
||||||
|
when iteratively descending through the ``m.room.power_levels`` events in the
|
||||||
|
``auth_events`` starting at :math:`e`. If no mainline event is encountered
|
||||||
|
when iteratively descending through the ``m.room.power_levels`` events, then
|
||||||
|
the closest mainline event to :math:`e` can be considered to be a dummy event
|
||||||
|
that is before any other event in the mainline of :math:`P` for the purposes
|
||||||
|
of condition 1 below.
|
||||||
|
|
||||||
|
The *mainline ordering based on* :math:`P` of a set of events is the
|
||||||
|
ordering, from smallest to largest, using the following comparison relation
|
||||||
|
on events: for events :math:`x` and :math:`y`, :math:`x<y` if
|
||||||
|
|
||||||
|
1. the closest mainline event to :math:`x` appears *before* the closest
|
||||||
|
mainline event to :math:`y`; or
|
||||||
|
2. the closest mainline events are the same, but :math:`x`\'s
|
||||||
|
``origin_server_ts`` is *less* than :math:`y`\'s ``origin_server_ts``; or
|
||||||
|
3. the closest mainline events are the same and the events have the same
|
||||||
|
``origin_server_ts``, but :math:`x`\'s ``event_id`` is *less* than
|
||||||
|
:math:`y`\'s ``event_id``.
|
||||||
|
|
||||||
|
Iterative auth checks
|
||||||
|
The *iterative auth checks algorithm* takes as input an initial room state
|
||||||
|
and a sorted list of state events, and constructs a new room state by
|
||||||
|
iterating through the event list and applying the state event to the room
|
||||||
|
state if the state event is allowed by the `authorization rules`_. If the
|
||||||
|
state event is not allowed by the authorization rules, then the event is
|
||||||
|
ignored. If a ``(event_type, state_key)`` key that is required for checking
|
||||||
|
the authorization rules is not present in the state, then the appropriate
|
||||||
|
state event from the event's ``auth_events`` is used if the auth event is
|
||||||
|
not rejected.
|
||||||
|
|
||||||
|
Algorithm
|
||||||
|
+++++++++
|
||||||
|
|
||||||
|
The *resolution* of a set of states is obtained as follows:
|
||||||
|
|
||||||
|
1. Take all *power events* and any events in their auth chains, recursively,
|
||||||
|
that appear in the *full conflicted set* and order them by the *reverse
|
||||||
|
topological power ordering*.
|
||||||
|
2. Apply the *iterative auth checks algorithm* on the *unconflicted state map*
|
||||||
|
and the list of events from the previous step to get a partially resolved
|
||||||
|
state.
|
||||||
|
3. Take all remaining events that weren't picked in step 1 and order them by
|
||||||
|
the mainline ordering based on the power level in the partially resolved
|
||||||
|
state obtained in step 2.
|
||||||
|
4. Apply the *iterative auth checks algorithm* on the partial resolved
|
||||||
|
state and the list of events from the previous step.
|
||||||
|
5. Update the result by replacing any event with the event with the same key
|
||||||
|
from the *unconflicted state map*, if such an event exists, to get the final
|
||||||
|
resolved state.
|
||||||
|
|
||||||
|
|
||||||
|
.. _`authorization rules`: ../server_server/r0.1.1.html#authorization-rules
|
||||||
|
|
||||||
|
Rejected events
|
||||||
|
+++++++++++++++
|
||||||
|
|
||||||
|
Events that have been rejected due to failing auth based on the state at the
|
||||||
|
event (rather than based on their auth chain) are handled as usual by the
|
||||||
|
algorithm, unless otherwise specified.
|
||||||
|
|
||||||
|
Note that no events rejected due to failure to auth against their auth chain
|
||||||
|
should appear in the process, as they should not appear in state (the algorithm
|
||||||
|
only uses events that appear in either the state sets or in the auth chain of
|
||||||
|
the events in the state sets).
|
||||||
|
|
||||||
|
.. admonition:: Rationale
|
||||||
|
|
||||||
|
This helps ensure that different servers' view of state is more likely to
|
||||||
|
converge, since rejection state of an event may be different. This can happen if
|
||||||
|
a third server gives an incorrect version of the state when a server joins a
|
||||||
|
room via it (either due to being faulty or malicious). Convergence of state is a
|
||||||
|
desirable property as it ensures that all users in the room have a (mostly)
|
||||||
|
consistent view of the state of the room. If the view of the state on different
|
||||||
|
servers diverges it can lead to bifurcation of the room due to e.g. servers
|
||||||
|
disagreeing on who is in the room.
|
||||||
|
|
||||||
|
Intuitively, using rejected events feels dangerous, however:
|
||||||
|
|
||||||
|
1. Servers cannot arbitrarily make up state, since they still need to pass the
|
||||||
|
auth checks based on the event's auth chain (e.g. they can't grant themselves
|
||||||
|
power levels if they didn't have them before).
|
||||||
|
2. For a previously rejected event to pass auth there must be a set of state
|
||||||
|
that allows said event. A malicious server could therefore produce a
|
||||||
|
fork where it claims the state is that particular set of state, duplicate the
|
||||||
|
rejected event to point to that fork, and send the event. The
|
||||||
|
duplicated event would then pass the auth checks. Ignoring rejected events
|
||||||
|
would therefore not eliminate any potential attack vectors.
|
||||||
|
|
||||||
|
|
||||||
|
Rejected auth events are deliberately excluded from use in the iterative auth
|
||||||
|
checks, as auth events aren't re-authed (although non-auth events are) during
|
||||||
|
the iterative auth checks.
|
@ -0,0 +1,124 @@
|
|||||||
|
.. 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.
|
||||||
|
|
||||||
|
Room Version 3
|
||||||
|
==============
|
||||||
|
|
||||||
|
This room version builds on `version 2 <v2.html>`_ with an improved event format.
|
||||||
|
|
||||||
|
.. note:
|
||||||
|
All requirements listed in this room version specification are scoped to rooms
|
||||||
|
which actually use this room version. For example, a requirement of "all APIs must
|
||||||
|
accept the new event format" does in fact apply to all APIs, but only so much as
|
||||||
|
where the contextual room of the request is using this room version. Rooms using
|
||||||
|
other room versions should not be affected by these sweeping requirements.
|
||||||
|
|
||||||
|
.. contents:: Table of Contents
|
||||||
|
.. sectnum::
|
||||||
|
|
||||||
|
|
||||||
|
Client considerations
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
This room version changes the format for event IDs sent to clients. Clients should be
|
||||||
|
aware that these event IDs may contain slashes and other potentially problematic
|
||||||
|
characters. Clients should be treating event IDs as opaque identifiers and should not
|
||||||
|
be attempting to parse them into a usable form, just like with other room versions.
|
||||||
|
|
||||||
|
Clients should expect to see event IDs changed from the format of ``$randomstring:example.org``
|
||||||
|
to something like ``$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk`` (note the lack of
|
||||||
|
domain and the potentially problematic slash).
|
||||||
|
|
||||||
|
|
||||||
|
Server implementation components
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
.. WARNING::
|
||||||
|
The information contained in this section is strictly for server implementors.
|
||||||
|
Applications which use the Client-Server API are generally unaffected by the
|
||||||
|
intricacies contained here. The section above regarding client considerations
|
||||||
|
is the resource that Client-Server API use cases should reference.
|
||||||
|
|
||||||
|
|
||||||
|
Room version 3 uses the state resolution algorithm defined in `room version 2 <v2.html>`_,
|
||||||
|
and the event format defined here.
|
||||||
|
|
||||||
|
Event IDs
|
||||||
|
~~~~~~~~~
|
||||||
|
|
||||||
|
.. admonition:: Rationale
|
||||||
|
|
||||||
|
In other room versions (namely version 1 and 2) the event ID is a distinct field
|
||||||
|
from the remainder of the event, which must be tracked as such. This leads to
|
||||||
|
complications where servers receive multiple events with the same ID in either the
|
||||||
|
same or different rooms where the server cannot easily keep track of which event it
|
||||||
|
should be using. By removing the use of a dedicated event ID, servers are required
|
||||||
|
to track the hashes on an event to determine its ID.
|
||||||
|
|
||||||
|
The event ID is the `reference hash`_ of the event encoded using `Unpadded Base64`_,
|
||||||
|
prefixed with ``$``. A resulting event ID using this approach should look similar to
|
||||||
|
``$CD66HAED5npg6074c6pDtLKalHjVfYb2q4Q3LZgrW6o``.
|
||||||
|
|
||||||
|
Event IDs should not be sent over federation to servers when the room uses
|
||||||
|
this room version. On the receiving end of an event, the server should compute
|
||||||
|
the relevant event ID for itself.
|
||||||
|
|
||||||
|
Additionally, the ``auth_events`` and ``prev_events`` have had a format change
|
||||||
|
compared to other room versions to make it easier to handle. Instead of a tuple
|
||||||
|
of values, they are now plain lists of events.
|
||||||
|
|
||||||
|
{{definition_ss_pdu_v3}}
|
||||||
|
|
||||||
|
Changes to APIs
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Due to the event ID being removed from the event, some APIs need to change. All
|
||||||
|
APIs which currently accept an event ID must do so with the new format. Servers
|
||||||
|
must append the calculated event ID to all events sent to clients where an event
|
||||||
|
ID would normally be expected.
|
||||||
|
|
||||||
|
Because the format of events has changed, servers must be aware of the room version
|
||||||
|
where the event resides so that the server may parse and handle the event. The
|
||||||
|
federation API has taken this concern into consideration by ensuring that servers
|
||||||
|
are aware of (or can find) the room version during a request.
|
||||||
|
|
||||||
|
Authorization rules for events
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The authorization rules for a given event have changed in this room version due
|
||||||
|
to the change in event format:
|
||||||
|
|
||||||
|
* The event no longer needs to be signed by the domain of the event ID (as there
|
||||||
|
is no domain in the event ID), but still needs to be signed by the sender's
|
||||||
|
domain.
|
||||||
|
|
||||||
|
* In past room versions, redactions were only permitted to enter the DAG if the
|
||||||
|
sender's domain matched the domain in the event ID being redacted, or the sender
|
||||||
|
had appropriate permissions per the power levels. Due to servers now not being
|
||||||
|
able to determine where an event came from during event authorization, redaction
|
||||||
|
events are always accepted (provided the event is allowed by ``events`` and
|
||||||
|
``events_default`` in the power levels). However, servers should not apply or send
|
||||||
|
redactions to clients until both the redaction event and original event have been
|
||||||
|
seen, and are valid. Servers should only apply redactions to events where the
|
||||||
|
sender's domains match, or the sender of the redaction has the appropriate
|
||||||
|
permissions per the power levels.
|
||||||
|
|
||||||
|
|
||||||
|
The remaining rules are the same as `room version 1 <v1.html#authorization-rules>`_.
|
||||||
|
|
||||||
|
|
||||||
|
.. _`Unpadded Base64`: ../appendices.html#unpadded-base64
|
||||||
|
.. _`Canonical JSON`: ../appendices.html#canonical-json
|
||||||
|
.. _`Signing Events`: ../server_server/r0.1.1.html#signing-events
|
||||||
|
.. _`reference hash`: ../server_server/r0.1.1.html#reference-hashes
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue