Merge remote-tracking branch 'origin/master' into erikj/search_yet_agian
commit
856dd9100e
@ -1,41 +0,0 @@
|
||||
.. This file is automatically processed by the templating system. To make it
|
||||
.. happy, you MUST use '=' as the title underline and you MUST stick the version
|
||||
.. in the title. The version MUST follow the numbering format
|
||||
.. "v<num>.<num>.<num>" - You cannot use a-z. If the templating system fails to
|
||||
.. find the right info, it will be treated as a test failure and so will show up
|
||||
.. in Jenkins. Comments like this are ignored by both RST and the templating
|
||||
.. system. Add the newest release notes beneath this comment.
|
||||
|
||||
Specification changes in v0.2.0 (2015-10-02)
|
||||
============================================
|
||||
|
||||
This update fundamentally restructures the specification. The specification has
|
||||
been split into more digestible "modules" which each describe a particular
|
||||
function (e.g. typing). This was done in order make the specification easier to
|
||||
maintain and help define which modules are mandatory for certain types
|
||||
of clients. Types of clients along with the mandatory modules can be found in a
|
||||
new "Feature Profiles" section. This update also begins to aggressively
|
||||
standardise on using Swagger and JSON Schema to document HTTP endpoints and
|
||||
Events respectively. It also introduces a number of new concepts to Matrix.
|
||||
|
||||
Additions:
|
||||
- New section: Feature Profiles.
|
||||
- New section: Receipts.
|
||||
- New section: Room history visibility.
|
||||
- New event: ``m.receipt``.
|
||||
- New event: ``m.room.canonical_alias``
|
||||
- New event: ``m.room.history_visibility``
|
||||
- New keys: ``/createRoom`` - allows room "presets" using ``preset`` and
|
||||
``initial_state`` keys.
|
||||
- New endpoint: ``/tokenrefresh`` - Related to refreshing access tokens.
|
||||
|
||||
Modifications:
|
||||
- Convert most of the older HTTP APIs to Swagger documentation.
|
||||
- Convert most of the older event formats to JSON Schema.
|
||||
- Move selected client-server sections to be "Modules".
|
||||
|
||||
Specification changes in v0.1.0 (2015-06-01)
|
||||
============================================
|
||||
- First numbered release.
|
||||
- Restructure the format of Event information. Add more information.
|
||||
- Restructure the format of the Client-Server HTTP APIs.
|
@ -0,0 +1,105 @@
|
||||
swagger: '2.0'
|
||||
info:
|
||||
title: "Matrix Client-Server Administration API"
|
||||
version: "1.0.0"
|
||||
host: localhost:8008
|
||||
schemes:
|
||||
- https
|
||||
- http
|
||||
basePath: /_matrix/client/%CLIENT_MAJOR_VERSION%
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
securityDefinitions:
|
||||
accessToken:
|
||||
type: apiKey
|
||||
description: The user_id or application service access_token
|
||||
name: access_token
|
||||
in: query
|
||||
paths:
|
||||
"/admin/whois/{userId}":
|
||||
get:
|
||||
summary: Gets information about a particular user.
|
||||
description: |-
|
||||
Gets information about a particular user.
|
||||
|
||||
This API may be restricted to only be called by the user being looked
|
||||
up, or by a server admin. Server-local administrator privileges are not
|
||||
specified in this document.
|
||||
security:
|
||||
- accessToken: []
|
||||
parameters:
|
||||
- in: path
|
||||
type: string
|
||||
name: userId
|
||||
description: The user to look up.
|
||||
required: true
|
||||
x-example: "@peter:rabbit.rocks"
|
||||
responses:
|
||||
200:
|
||||
description: The lookup was successful.
|
||||
examples:
|
||||
application/json: |-
|
||||
{
|
||||
"user_id": "@peter:rabbit.rocks",
|
||||
"devices": {
|
||||
"teapot": {
|
||||
"sessions": [
|
||||
{
|
||||
"connections": [
|
||||
{
|
||||
"ip": "127.0.0.1",
|
||||
"last_seen": 1411996332123,
|
||||
"user_agent": "curl/7.31.0-DEV"
|
||||
},
|
||||
{
|
||||
"ip": "10.0.0.2",
|
||||
"last_seen": 1411996332123,
|
||||
"user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
user_id:
|
||||
type: string
|
||||
description: The Matrix user ID of the user.
|
||||
devices:
|
||||
type: object
|
||||
description: |-
|
||||
Each key is an identitfier for one of the user's devices.
|
||||
additionalProperties:
|
||||
type: object
|
||||
title: DeviceInfo
|
||||
properties:
|
||||
sessions:
|
||||
type: array
|
||||
description: A user's sessions (i.e. what they did with an access token from one login).
|
||||
items:
|
||||
type: object
|
||||
title: SessionInfo
|
||||
properties:
|
||||
connections:
|
||||
type: array
|
||||
description: Information particular connections in the session.
|
||||
items:
|
||||
type: object
|
||||
title: ConnectionInfo
|
||||
properties:
|
||||
ip:
|
||||
type: string
|
||||
description: Most recently seen IP address of the session.
|
||||
last_seen:
|
||||
type: number
|
||||
description: Unix timestamp that the session was last active.
|
||||
user_agent:
|
||||
type: string
|
||||
description: User agent string last seen in the session.
|
||||
tags:
|
||||
- Server administration
|
@ -1,53 +0,0 @@
|
||||
{
|
||||
"type": "object",
|
||||
"title": "Event",
|
||||
"properties": {
|
||||
"content": {
|
||||
"type": "object",
|
||||
"title": "EventContent",
|
||||
"description": "The content of this event. The fields in this object will vary depending on the type of event."
|
||||
},
|
||||
"origin_server_ts": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "Timestamp in milliseconds on originating homeserver when this event was sent."
|
||||
},
|
||||
"sender": {
|
||||
"type": "string",
|
||||
"description": "The MXID of the user who sent this event."
|
||||
},
|
||||
"state_key": {
|
||||
"type": "string",
|
||||
"description": "Optional. This key will only be present for state events. A unique key which defines the overwriting semantics for this piece of room state."
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "The type of event."
|
||||
},
|
||||
"unsigned": {
|
||||
"type": "object",
|
||||
"title": "Unsigned",
|
||||
"description": "Information about this event which was not sent by the originating homeserver",
|
||||
"properties": {
|
||||
"age": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "Time in milliseconds since the event was sent."
|
||||
},
|
||||
"prev_content": {
|
||||
"title": "EventContent",
|
||||
"type": "object",
|
||||
"description": "Optional. The previous ``content`` for this state. This will be present only for state events appearing in the ``timeline``. If this is not a state event, or there is no previous content, this key will be missing."
|
||||
},
|
||||
"replaces_state": {
|
||||
"type": "string",
|
||||
"description": "Optional. The event_id of the previous event for this state. This will be present only for state events appearing in the ``timeline``. If this is not a state event, or there is no previous content, this key will be missing."
|
||||
},
|
||||
"transaction_id": {
|
||||
"type": "string",
|
||||
"description": "Optional. The transaction ID set when this message was sent. This key will only be present for message events sent by the device calling this API."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
properties:
|
||||
content:
|
||||
description: The content of this event. The fields in this object will vary depending
|
||||
on the type of event.
|
||||
title: EventContent
|
||||
type: object
|
||||
origin_server_ts:
|
||||
description: Timestamp in milliseconds on originating homeserver when this event
|
||||
was sent.
|
||||
format: int64
|
||||
type: integer
|
||||
sender:
|
||||
description: The MXID of the user who sent this event.
|
||||
type: string
|
||||
state_key:
|
||||
description: Optional. This key will only be present for state events. A unique
|
||||
key which defines the overwriting semantics for this piece of room state.
|
||||
type: string
|
||||
type:
|
||||
description: The type of event.
|
||||
type: string
|
||||
unsigned:
|
||||
description: Information about this event which was not sent by the originating
|
||||
homeserver
|
||||
properties:
|
||||
age:
|
||||
description: Time in milliseconds since the event was sent.
|
||||
format: int64
|
||||
type: integer
|
||||
prev_content:
|
||||
description: Optional. The previous ``content`` for this state. This will
|
||||
be present only for state events appearing in the ``timeline``. If this
|
||||
is not a state event, or there is no previous content, this key will be
|
||||
missing.
|
||||
title: EventContent
|
||||
type: object
|
||||
transaction_id:
|
||||
description: Optional. The transaction ID set when this message was sent.
|
||||
This key will only be present for message events sent by the device calling
|
||||
this API.
|
||||
type: string
|
||||
title: Unsigned
|
||||
type: object
|
||||
title: Event
|
||||
type: object
|
@ -1,13 +0,0 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"events": {
|
||||
"type": "array",
|
||||
"description": "List of events",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"allOf": [{"$ref": "event.json" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
properties:
|
||||
events:
|
||||
description: List of events
|
||||
items:
|
||||
allOf:
|
||||
- $ref: event.yaml
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
@ -1,42 +0,0 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"limit": {
|
||||
"type": "integer",
|
||||
"description":
|
||||
"The maximum number of events to return."
|
||||
},
|
||||
"types": {
|
||||
"type": "array",
|
||||
"description":
|
||||
"A list of event types to include. If this list is absent then all event types are included. A '*' can be used as a wildcard to match any sequence of characters.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"not_types": {
|
||||
"type": "array",
|
||||
"description":
|
||||
"A list of event types to exclude. If this list is absent then no event types are excluded. A matching type will be excluded even if it is listed in the 'types' filter. A '*' can be used as a wildcard to match any sequence of characters.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"senders": {
|
||||
"type": "array",
|
||||
"description":
|
||||
"A list of senders IDs to include. If this list is absent then all senders are included. A '*' can be used as a wildcard to match any sequence of characters.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"not_senders": {
|
||||
"type": "array",
|
||||
"description":
|
||||
"A list of sender IDs to exclude. If this list is absent then no senders are excluded. A matching sender will be excluded even if it is listed in the 'senders' filter. A '*' can be used as a wildcard to match any sequence of characters.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
properties:
|
||||
limit:
|
||||
description: The maximum number of events to return.
|
||||
type: integer
|
||||
not_senders:
|
||||
description: A list of sender IDs to exclude. If this list is absent then no senders
|
||||
are excluded. A matching sender will be excluded even if it is listed in the
|
||||
'senders' filter. A '*' can be used as a wildcard to match any sequence of characters.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
not_types:
|
||||
description: A list of event types to exclude. If this list is absent then no
|
||||
event types are excluded. A matching type will be excluded even if it is listed
|
||||
in the 'types' filter. A '*' can be used as a wildcard to match any sequence
|
||||
of characters.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
senders:
|
||||
description: A list of senders IDs to include. If this list is absent then all
|
||||
senders are included. A '*' can be used as a wildcard to match any sequence
|
||||
of characters.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
types:
|
||||
description: A list of event types to include. If this list is absent then all
|
||||
event types are included. A '*' can be used as a wildcard to match any sequence
|
||||
of characters.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
@ -1,9 +0,0 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"enum": ["event_match", "profile_tag", "contains_display_name", "room_member_count"]
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
properties:
|
||||
kind:
|
||||
enum:
|
||||
- event_match
|
||||
- profile_tag
|
||||
- contains_display_name
|
||||
- room_member_count
|
||||
type: string
|
||||
type: object
|
@ -1,21 +0,0 @@
|
||||
{
|
||||
"title": "PushRule",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"default": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"rule_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"actions": {
|
||||
"items": {
|
||||
"type": ["object", "string"]
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
properties:
|
||||
actions:
|
||||
items:
|
||||
type:
|
||||
- object
|
||||
- string
|
||||
type: array
|
||||
default:
|
||||
type: boolean
|
||||
enabled:
|
||||
type: boolean
|
||||
rule_id:
|
||||
type: string
|
||||
title: PushRule
|
||||
type: object
|
@ -1,65 +0,0 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"content": {
|
||||
"items": {
|
||||
"type": "object",
|
||||
"title": "PushRule",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "push_rule.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"override": {
|
||||
"items": {
|
||||
"type": "object",
|
||||
"title": "PushRule",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "push_rule.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"sender": {
|
||||
"items": {
|
||||
"type": "object",
|
||||
"title": "PushRule",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "push_rule.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"underride": {
|
||||
"items": {
|
||||
"type": "object",
|
||||
"title": "PushRule",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "push_rule.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"room": {
|
||||
"items": {
|
||||
"type": "object",
|
||||
"title": "PushRule",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "push_rule.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
properties:
|
||||
content:
|
||||
items:
|
||||
allOf:
|
||||
- $ref: push_rule.yaml
|
||||
title: PushRule
|
||||
type: object
|
||||
type: array
|
||||
override:
|
||||
items:
|
||||
allOf:
|
||||
- $ref: push_rule.yaml
|
||||
title: PushRule
|
||||
type: object
|
||||
type: array
|
||||
room:
|
||||
items:
|
||||
allOf:
|
||||
- $ref: push_rule.yaml
|
||||
title: PushRule
|
||||
type: object
|
||||
type: array
|
||||
sender:
|
||||
items:
|
||||
allOf:
|
||||
- $ref: push_rule.yaml
|
||||
title: PushRule
|
||||
type: object
|
||||
type: array
|
||||
underride:
|
||||
items:
|
||||
allOf:
|
||||
- $ref: push_rule.yaml
|
||||
title: PushRule
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
@ -1,22 +0,0 @@
|
||||
{
|
||||
"type": "object",
|
||||
"allOf": [{"$ref": "event_filter.json"}],
|
||||
"properties": {
|
||||
"rooms": {
|
||||
"type": "array",
|
||||
"description":
|
||||
"A list of room IDs to include. If this list is absent then all rooms are included. A '*' can be used as a wildcard to match any sequence of characters.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"not_rooms": {
|
||||
"type": "array",
|
||||
"description":
|
||||
"A list of room IDs to exclude. If this list is absent then no rooms are excluded. A matching room will be excluded even if it is listed in the 'rooms' filter. A '*' can be used as a wildcard to match any sequence of characters.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
allOf:
|
||||
- $ref: event_filter.yaml
|
||||
properties:
|
||||
not_rooms:
|
||||
description: A list of room IDs to exclude. If this list is absent then no rooms
|
||||
are excluded. A matching room will be excluded even if it is listed in the 'rooms'
|
||||
filter. A '*' can be used as a wildcard to match any sequence of characters.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
rooms:
|
||||
description: A list of room IDs to include. If this list is absent then all rooms
|
||||
are included. A '*' can be used as a wildcard to match any sequence of characters.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
@ -1,44 +0,0 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"room": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"state": {
|
||||
"description":
|
||||
"The state events to include for rooms.",
|
||||
"allOf": [{"$ref": "room_event_filter.json"}]
|
||||
},
|
||||
"timeline": {
|
||||
"description":
|
||||
"The message and state update events to include for rooms.",
|
||||
"allOf": [{"$ref": "room_event_filter.json"}]
|
||||
},
|
||||
"ephemeral": {
|
||||
"description":
|
||||
"The events that aren't recorded in the room history, e.g. typing and receipts, to include for rooms.",
|
||||
"allOf": [{"$ref": "room_event_filter.json"}]
|
||||
}
|
||||
}
|
||||
},
|
||||
"presence": {
|
||||
"description":
|
||||
"The presence updates to include.",
|
||||
"allOf": [{"$ref": "event_filter.json"}]
|
||||
},
|
||||
"event_format": {
|
||||
"description":
|
||||
"The format to use for events. 'client' will return the events in a format suitable for clients. 'federation' will return the raw event as receieved over federation. The default is 'client'.",
|
||||
"type": "string",
|
||||
"enum": ["client", "federation"]
|
||||
},
|
||||
"event_fields": {
|
||||
"type": "array",
|
||||
"description":
|
||||
"List of event fields to include. If this list is absent then all fields are included. The entries may include '.' charaters to indicate sub-fields. So ['content.body'] will include the 'body' field of the 'content' object. A literal '.' character in a field name may be escaped using a '\\'. A server may include more fields than were requested.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
properties:
|
||||
event_fields:
|
||||
description: List of event fields to include. If this list is absent then all
|
||||
fields are included. The entries may include '.' charaters to indicate sub-fields.
|
||||
So ['content.body'] will include the 'body' field of the 'content' object. A
|
||||
literal '.' character in a field name may be escaped using a '\'. A server may
|
||||
include more fields than were requested.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
event_format:
|
||||
description: The format to use for events. 'client' will return the events in
|
||||
a format suitable for clients. 'federation' will return the raw event as receieved
|
||||
over federation. The default is 'client'.
|
||||
enum:
|
||||
- client
|
||||
- federation
|
||||
type: string
|
||||
presence:
|
||||
allOf:
|
||||
- $ref: event_filter.yaml
|
||||
description: The presence updates to include.
|
||||
room:
|
||||
properties:
|
||||
ephemeral:
|
||||
allOf:
|
||||
- $ref: room_event_filter.yaml
|
||||
description: The events that aren't recorded in the room history, e.g. typing
|
||||
and receipts, to include for rooms.
|
||||
include_leave:
|
||||
description: Include rooms that the user has left in the sync, default false
|
||||
type: boolean
|
||||
state:
|
||||
allOf:
|
||||
- $ref: room_event_filter.yaml
|
||||
description: The state events to include for rooms.
|
||||
timeline:
|
||||
allOf:
|
||||
- $ref: room_event_filter.yaml
|
||||
description: The message and state update events to include for rooms.
|
||||
type: object
|
||||
type: object
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"type": "object",
|
||||
"allOf": [{"$ref":"event_batch.json"}],
|
||||
"properties": {
|
||||
"limited": {
|
||||
"type": "boolean",
|
||||
"description": "True if the number of events returned was limited by the ``limit`` on the filter"
|
||||
},
|
||||
"prev_batch": {
|
||||
"type": "string",
|
||||
"description": "If the batch was limited then this is a token that can be supplied to the server to retrieve earlier events"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
allOf:
|
||||
- $ref: event_batch.yaml
|
||||
properties:
|
||||
limited:
|
||||
description: True if the number of events returned was limited by the ``limit``
|
||||
on the filter
|
||||
type: boolean
|
||||
prev_batch:
|
||||
description: If the batch was limited then this is a token that can be supplied
|
||||
to the server to retrieve earlier events
|
||||
type: string
|
||||
type: object
|
@ -0,0 +1,84 @@
|
||||
swagger: '2.0'
|
||||
info:
|
||||
title: "Matrix Client-Server message redaction API"
|
||||
version: "1.0.0"
|
||||
host: localhost:8008
|
||||
schemes:
|
||||
- https
|
||||
- http
|
||||
basePath: /_matrix/client/api/%CLIENT_MAJOR_VERSION%
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
securityDefinitions:
|
||||
accessToken:
|
||||
type: apiKey
|
||||
description: The user_id or application service access_token
|
||||
name: access_token
|
||||
in: query
|
||||
paths:
|
||||
"/rooms/{roomId}/redact/{eventId}/{txnId}":
|
||||
put:
|
||||
summary: Strips all non-integrity-critical information out of an event.
|
||||
description: |-
|
||||
Strips all information out of an event which isn't critical to the
|
||||
integrity of the server-side representation of the room.
|
||||
|
||||
This cannot be undone.
|
||||
|
||||
Users may redact their own events, and any user with a power level
|
||||
greater than or equal to the `redact` power level of the room may
|
||||
redact events there.
|
||||
security:
|
||||
- accessToken: []
|
||||
parameters:
|
||||
- in: path
|
||||
type: string
|
||||
name: roomId
|
||||
description: The room from which to redact the event.
|
||||
required: true
|
||||
x-example: "!637q39766251:example.com"
|
||||
- in: path
|
||||
type: string
|
||||
name: eventId
|
||||
description: The ID of the event to redact
|
||||
required: true
|
||||
x-example: "bai2b1i9:matrix.org"
|
||||
- in: path
|
||||
name: txnId
|
||||
type: string
|
||||
description: |-
|
||||
The transaction ID for this event. Clients should generate a
|
||||
unique ID; it will be used by the server to ensure idempotency of requests.
|
||||
required: true
|
||||
x-example: "37"
|
||||
- in: body
|
||||
name: body
|
||||
schema:
|
||||
type: object
|
||||
example: |-
|
||||
{
|
||||
"reason": "Indecent material"
|
||||
}
|
||||
properties:
|
||||
reason:
|
||||
type: string
|
||||
description: The reason for the event being redacted.
|
||||
responses:
|
||||
200:
|
||||
description: "An ID for the redaction event."
|
||||
examples:
|
||||
application/json: |-
|
||||
{
|
||||
"event_id": "YUwQidLecu"
|
||||
}
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
event_id:
|
||||
type: string
|
||||
description: |-
|
||||
A unique identifier for the event.
|
||||
tags:
|
||||
- Room participation
|
@ -0,0 +1,37 @@
|
||||
r0
|
||||
===
|
||||
|
||||
This is the first release of the client-server specification. It is largely a dump of what has currently been implemented, and there are several inconsistencies.
|
||||
|
||||
An upcoming minor release will deprecate many of these inconsistencies, and they will be removed in the next major release.
|
||||
|
||||
Since the draft stage, the following major changes have been made:
|
||||
- /api/v1 and /v2_alpha path segments have been replaced with the major version of the release (i.e. 'r0').
|
||||
- Some POST versions of APIs with both POST and PUT have been removed.
|
||||
- The specification has been split into one specification per API. This is the client-server API. The server-server API can be found documented separately.
|
||||
- All APIs are now documented using Swagger
|
||||
- The following modules have been added:
|
||||
- Content repository
|
||||
- Instant messaging
|
||||
- Push notification
|
||||
- History visibility
|
||||
- Search
|
||||
- Invites based on third party identifiers
|
||||
- Room tagging
|
||||
- Guest access
|
||||
- Client config
|
||||
- The following APIs were added:
|
||||
- ``/sync``
|
||||
- ``/publicRooms``
|
||||
- ``/rooms/{roomId}/forget``
|
||||
- ``/admin/whois``
|
||||
- ``/rooms/{roomId}/redact``
|
||||
- ``/user/{userId}/filter``
|
||||
- The following APIs have been significantly modified:
|
||||
- Invitations now contain partial room state
|
||||
- Invitations can now be rejected
|
||||
- ``/directory``
|
||||
- The following events have been added:
|
||||
- ``m.room.avatar``
|
||||
- Example signed json is included for reference
|
||||
- Commentary on display name calculation was added
|
@ -1,11 +1,11 @@
|
||||
Versioning is, like, hard for backfilling backwards because of the number of Home Servers involved.
|
||||
Versioning is, like, hard for backfilling backwards because of the number of homeservers involved.
|
||||
|
||||
The way we solve this is by doing versioning as an acyclic directed graph of PDUs. For backfilling purposes, this is done on a per context basis.
|
||||
When we send a PDU we include all PDUs that have been received for that context that hasn't been subsequently listed in a later PDU. The trivial case is a simple list of PDUs, e.g. A <- B <- C. However, if two servers send out a PDU at the same to, both B and C would point at A - a later PDU would then list both B and C.
|
||||
|
||||
Problems with opaque version strings:
|
||||
- How do you do clustering without mandating that a cluster can only have one transaction in flight to a given remote home server at a time.
|
||||
- How do you do clustering without mandating that a cluster can only have one transaction in flight to a given remote homeserver at a time.
|
||||
If you have multiple transactions sent at once, then you might drop one transaction, receive another with a version that is later than the dropped transaction and which point ARGH WE LOST A TRANSACTION.
|
||||
- How do you do backfilling? A version string defines a point in a stream w.r.t. a single home server, not a point in the context.
|
||||
- How do you do backfilling? A version string defines a point in a stream w.r.t. a single homeserver, not a point in the context.
|
||||
|
||||
We only need to store the ends of the directed graph, we DO NOT need to do the whole one table of nodes and one of edges.
|
||||
|
@ -1,146 +0,0 @@
|
||||
Goals of Key-Distribution in Matrix
|
||||
===================================
|
||||
|
||||
* No Central Authority: Users should not need to trust a central authority
|
||||
when determining the authenticity of keys.
|
||||
|
||||
* Easy to Add New Devices: It should be easy for a user to start using a
|
||||
new device.
|
||||
|
||||
* Possible to discover MITM: It should be possible for a user to determine if
|
||||
they are being MITM.
|
||||
|
||||
* Lost Devices: It should be possible for a user to recover if they lose all
|
||||
their devices.
|
||||
|
||||
* No Copying Keys: Keys should be per device and shouldn't leave the device
|
||||
they were created on.
|
||||
|
||||
A Possible Mechanism for Key Distribution
|
||||
=========================================
|
||||
|
||||
Basic API for setting up keys on a server:
|
||||
|
||||
https://github.com/matrix-org/matrix-doc/pull/24
|
||||
|
||||
Client shouldn't trust the keys unless they have been verified, e.g by
|
||||
comparing fingerprints.
|
||||
|
||||
If a user adds a new device it should some yet to be specified protocol
|
||||
communicate with an old device and obtain a cross-signature from the old
|
||||
device for its public key.
|
||||
|
||||
The new device can then present the cross-signed key to all the devices
|
||||
that the user is in conversations with. Those devices should then include
|
||||
the new device into those conversations.
|
||||
|
||||
If the user cannot cross-sign the new key, e.g. because their old device
|
||||
is lost or stolen. Then they will need to reauthenticate their conversations
|
||||
out of band, e.g by comparing fingerprints.
|
||||
|
||||
|
||||
Goals of End-to-end encryption in Matrix
|
||||
========================================
|
||||
|
||||
* Access to Chat History: Users should be able to see the history of a
|
||||
conversation on a new device. User should be able to control who can
|
||||
see their chat history and how much of the chat history they can see.
|
||||
|
||||
* Forward Secrecy of Discarded Chat History: Users should be able to discard
|
||||
history from their device, once they have discarded the history it should be
|
||||
impossible for an adversary to recover that history.
|
||||
|
||||
* Forward Secrecy of Future Messages: Users should be able to recover from
|
||||
disclosure of the chat history on their device.
|
||||
|
||||
* Deniablity of Chat History: It should not be possible to prove to a third
|
||||
party that a given user sent a message.
|
||||
|
||||
* Authenticity of Chat History: It should be possible to prove amoungst
|
||||
the members of a chat that a message sent by a user was authored by that
|
||||
user.
|
||||
|
||||
|
||||
Bonus Goals:
|
||||
|
||||
* Traffic Analysis: It would be nice if the protocol was resilient to traffic
|
||||
or metadata analysis. However it's not something we want to persue if it
|
||||
harms the usability of the protocol. It might be cool if there was a
|
||||
way for the user to could specify the trade off between performance and
|
||||
resilience to traffic analysis that they wanted.
|
||||
|
||||
|
||||
A Possible Design for Group Chat using Olm
|
||||
==========================================
|
||||
|
||||
Protecting the secrecy of history
|
||||
---------------------------------
|
||||
|
||||
Each message sent by a client has a 32-bit counter. This counter increments
|
||||
by one for each message sent by the client. This counter is used to advance a
|
||||
ratchet. The ratchet is split into a vector four 256-bit values,
|
||||
:math:`R_{n,j}` for :math:`j \in {0,1,2,3}`. The ratchet can be advanced as
|
||||
follows:
|
||||
|
||||
.. math::
|
||||
\begin{align}
|
||||
R_{2^24n,0} &= H_0\left(R_{2^24(i-1),0}\right) \\
|
||||
R_{2^24n,1} &= H_1\left(R_{2^24(i-1),0}\right) \\
|
||||
R_{2^24n,2} &= H_2\left(R_{2^24(i-1),0}\right) \\
|
||||
R_{2^24n,3} &= H_3\left(R_{2^24(i-1),0}\right) \\
|
||||
R_{2^16n,1} &= H_1\left(R_{2^16(i-1),1}\right) \\
|
||||
R_{2^16n,2} &= H_2\left(R_{2^16(i-1),1}\right) \\
|
||||
R_{2^16n,3} &= H_3\left(R_{2^16(i-1),1}\right) \\
|
||||
R_{2^8i,2} &= H_2\left(R_{2^8(i-1),2}\right) \\
|
||||
R_{2^8i,3} &= H_3\left(R_{2^8(i-1),2}\right) \\
|
||||
R_{i,3} &= H_3\left(R_{(i-1),3}\right)
|
||||
\end{align}
|
||||
|
||||
Where :math:`H_0`, :math:`H_1`, :math:`H_2`, and :math:`H_3`
|
||||
are different hash functions. For example
|
||||
:math:`H_0` could be :math:`HMAC\left(X,\text{"\textbackslash x00"}\right)` and
|
||||
:math:`H_1` could be :math:`HMAC\left(X,\text{"\textbackslash x01"}\right)`.
|
||||
|
||||
So every :math:`2^24` iterations :math:`R_{n,1}` is reseeded from :math:`R_{n,0}`.
|
||||
Every :math:`2^16` iterations :math:`R_{n,2}` is reseeded from :math:`R_{n,1}`.
|
||||
Every :math:`2^8` iterations :math:`R_{n,3}` is reseeded from :math:`R_{n,2}`.
|
||||
|
||||
This scheme allows the ratchet to be advanced an arbitrary amount forwards
|
||||
while needing only 1024 hash computations.
|
||||
|
||||
This the value of the ratchet is hashed to generate the keys used to encrypt
|
||||
each mesage.
|
||||
|
||||
A client can decrypt chat history onwards from the earliest value of the
|
||||
ratchet it is aware of. But cannot decrypt history from before that point
|
||||
without reversing the hash function.
|
||||
|
||||
This allows a client to share its ability to decrypt chat history with another
|
||||
from a point in the conversation onwards by giving a copy of the ratchet at
|
||||
that point in the conversation.
|
||||
|
||||
A client can discard history by advancing a ratchet to beyond the last message
|
||||
they want to discard and then forgetting all previous values of the ratchet.
|
||||
|
||||
Proving and denying the authenticity of history
|
||||
-----------------------------------------------
|
||||
|
||||
Client sign the messages they send using a Ed25519 key generated per
|
||||
conversation. That key, along with the ratchet key, is distributed
|
||||
to other clients using 1:1 olm ratchets. Those 1:1 ratchets are started using
|
||||
Triple Diffie-Hellman which provides authenticity of the messages to the
|
||||
participants and deniability of the messages to third parties. Therefore
|
||||
any keys shared over those keys inherit the same levels of deniability and
|
||||
authenticity.
|
||||
|
||||
Protecting the secrecy of future messages
|
||||
-----------------------------------------
|
||||
|
||||
A client would need to generate new keys if it wanted to prevent access to
|
||||
messages beyond a given point in the conversation. It must generate new keys
|
||||
whenever someone leaves the room. It should generate new keys periodically
|
||||
anyway.
|
||||
|
||||
The frequency of key generation in a large room may need to be restricted to
|
||||
keep the frequency of messages broadcast over the individual 1:1 channels
|
||||
low.
|
@ -1,16 +0,0 @@
|
||||
{
|
||||
"type": "object",
|
||||
"title": "Event",
|
||||
"description": "The basic set of fields all events must have.",
|
||||
"properties": {
|
||||
"content": {
|
||||
"type": "object",
|
||||
"title": "EventContent",
|
||||
"description": "The fields in this object will vary depending on the type of event. When interacting with the REST API, this is the HTTP body."
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "The type of event. This SHOULD be namespaced similar to Java package naming conventions e.g. 'com.example.subdomain.event.type'"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
description: The basic set of fields all events must have.
|
||||
properties:
|
||||
content:
|
||||
description: The fields in this object will vary depending on the type of event.
|
||||
When interacting with the REST API, this is the HTTP body.
|
||||
title: EventContent
|
||||
type: object
|
||||
type:
|
||||
description: The type of event. This SHOULD be namespaced similar to Java package
|
||||
naming conventions e.g. 'com.example.subdomain.event.type'
|
||||
type: string
|
||||
title: Event
|
||||
type: object
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "ImageInfo",
|
||||
"description": "Metadata about an image.",
|
||||
"properties": {
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"description": "Size of the image in bytes."
|
||||
},
|
||||
"w": {
|
||||
"type": "integer",
|
||||
"description": "The width of the image in pixels."
|
||||
},
|
||||
"h": {
|
||||
"type": "integer",
|
||||
"description": "The height of the image in pixels."
|
||||
},
|
||||
"mimetype": {
|
||||
"type": "string",
|
||||
"description": "The mimetype of the image, e.g. ``image/jpeg``."
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
$schema: http://json-schema.org/draft-04/schema#
|
||||
description: Metadata about an image.
|
||||
properties:
|
||||
h:
|
||||
description: The height of the image in pixels.
|
||||
type: integer
|
||||
mimetype:
|
||||
description: The mimetype of the image, e.g. ``image/jpeg``.
|
||||
type: string
|
||||
size:
|
||||
description: Size of the image in bytes.
|
||||
type: integer
|
||||
w:
|
||||
description: The width of the image in pixels.
|
||||
type: integer
|
||||
title: ImageInfo
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"type": "object",
|
||||
"title": "Room Event",
|
||||
"description": "In addition to the Event fields, Room Events MUST have the following additional field.",
|
||||
"allOf":[{
|
||||
"$ref": "event.json"
|
||||
}],
|
||||
"properties": {
|
||||
"room_id": {
|
||||
"type": "string",
|
||||
"description": "The ID of the room associated with this event."
|
||||
},
|
||||
"event_id": {
|
||||
"type": "string",
|
||||
"description": "The globally unique event identifier."
|
||||
},
|
||||
"user_id": {
|
||||
"type": "string",
|
||||
"description": "Contains the fully-qualified ID of the user who *sent* this event."
|
||||
}
|
||||
},
|
||||
"required": ["room_id"]
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue