Merge remote-tracking branch 'origin/main' into dmr/additional-properties

This commit is contained in:
David Robertson 2022-07-21 17:38:47 +01:00
commit 7da039a241
No known key found for this signature in database
GPG key ID: 903ECE108A39DEDD
43 changed files with 449 additions and 171 deletions

View file

@ -1,4 +1,4 @@
blank_issues_enabled: true
blank_issues_enabled: false
contact_links:
- name: Matrix Spec Discussion
url: "https://matrix.to/#/#matrix-spec:matrix.org"

View file

@ -323,7 +323,6 @@ footer {
table {
table-layout: fixed;
width: 100%;
margin: 4rem 0;
caption {
caption-side: top;

View file

@ -0,0 +1 @@
Add HTML anchors for object definitions in the formatted specification.

View file

@ -0,0 +1 @@
Mention that the `/rooms/{roomId}/invite` endpoint will return a 200 response if the user is already invited to the room.

View file

@ -0,0 +1 @@
Fix various typos throughout the specification.

View file

@ -0,0 +1 @@
Describe return codes for account data endpoints, and clarify that per-room data does not inherit from the global data.

View file

@ -0,0 +1 @@
Fix various typos throughout the specification.

View file

@ -0,0 +1 @@
Fix various typos throughout the specification.

View file

@ -0,0 +1 @@
Clarify that policy rule globs work like ACL globs. Contributed by Nico.

View file

@ -0,0 +1 @@
Clarify the format of some structures in the End-to-end encryption module.

View file

@ -0,0 +1 @@
Fix various typos throughout the specification.

View file

@ -0,0 +1 @@
Add HTML anchors for object definitions in the formatted specification.

View file

@ -0,0 +1 @@
Add HTML anchors for object definitions in the formatted specification.

View file

@ -0,0 +1 @@
Add HTML anchors for object definitions in the formatted specification.

View file

@ -0,0 +1 @@
For room versions 1 through 10, clarify that events with rejected `auth_events` must be rejected.

View file

@ -0,0 +1 @@
For room versions 210: correct a mistaken clarification to the state resolution algorithm.

View file

@ -0,0 +1 @@
Add HTML anchors for object definitions in the formatted specification.

View file

@ -7,9 +7,12 @@ type: module
Clients can store custom config data for their account on their
homeserver. This account data will be synced between different devices
and can persist across installations on a particular device. Users may
only view the account data for their own account
only view the account data for their own account.
The account\_data may be either global or scoped to a particular rooms.
The account data may be either global or scoped to a particular room.
There is no inheritance mechanism here: a given `type` of data missing
from a room's account data does not fall back to the global account
data with the same `type`.
#### Events

View file

@ -1220,7 +1220,7 @@ replace it with the new key based on the key metadata as follows:
keep the key that has `is_verified` set to `true`;
- if they have the same values for `is_verified`, then it will keep
the key with a lower `first_message_index`;
- and finally, is `is_verified` and `first_message_index` are equal,
- and finally, if `is_verified` and `first_message_index` are equal,
then it will keep the key with a lower `forwarded_count`.
###### Recovery key
@ -1255,25 +1255,12 @@ When a backup is created with the `algorithm` set to
`m.megolm_backup.v1.curve25519-aes-sha2`, the `auth_data` should have
the following format:
`AuthData`
| Parameter | Type | Description |
| -----------| -----------|--------------------------------------------------------------------------------------------------|
| public_key | string | **Required.** The curve25519 public key used to encrypt the backups, encoded in unpadded base64. |
| signatures | Signatures | Optional. Signatures of the ``auth_data``, as Signed JSON |
{{% definition path="api/client-server/definitions/key_backup_auth_data" %}}
The `session_data` field in the backups is constructed as follows:
1. Encode the session key to be backed up as a JSON object with the
properties:
| Parameter | Type | Description |
| --------------------------------|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| algorithm | string | **Required.** The end-to-end message encryption algorithm that the key is for. Must be `m.megolm.v1.aes-sha2`. |
| forwarding_curve25519_key_chain | [string] | **Required.** Chain of Curve25519 keys through which this session was forwarded, via [m.forwarded_room_key](#mforwarded_room_key) events. |
| sender_key | string | **Required.** Unpadded base64-encoded device curve25519 key. |
| sender_claimed_keys | {string: string} | **Required.** A map from algorithm name (`ed25519`) to the identity key for the sending device. |
| session_key | string | **Required.** Unpadded base64-encoded session key in [session-sharing format](https://gitlab.matrix.org/matrix-org/olm/blob/master/docs/megolm.md#session-sharing-format). |
1. Encode the session key to be backed up as a JSON object using the
`SessionData` format defined below.
2. Generate an ephemeral curve25519 key, and perform an ECDH with the
ephemeral key and the backup's public key to generate a shared
@ -1295,6 +1282,8 @@ The `session_data` field in the backups is constructed as follows:
the resulting MAC are base64-encoded, and become the `mac` property
of the `session_data`.
{{% definition path="api/client-server/definitions/key_backup_session_data" %}}
{{% http-api spec="client-server" api="key_backup" %}}
##### Key exports
@ -1344,42 +1333,7 @@ user-supplied passphrase, and is created as follows:
The exported sessions are formatted as a JSON array of `SessionData`
objects described as follows:
`SessionData`
| Parameter | Type | Description |
|-----------------------------------|------------------|---------------------------------------------------------------------------------------------------------------------------------------|
| algorithm | string | Required. The encryption algorithm that the session uses. Must be `m.megolm.v1.aes-sha2`. |
| forwarding_curve25519_key_chain | [string] | Required. Chain of Curve25519 keys through which this session was forwarded, via [m.forwarded_room_key](#mforwarded_room_key) events. |
| room_id | string | Required. The room where the session is used. |
| sender_key | string | Required. The Curve25519 key of the device which initiated the session originally. |
| sender_claimed_keys | {string: string} | Required. The Ed25519 key of the device which initiated the session originally. |
| session_id | string | Required. The ID of the session. |
| session_key | string | Required. The key for the session. |
This is similar to the format before encryption used for the session
keys in [Server-side key backups](#server-side-key-backups) but adds the
`room_id` and `session_id` fields.
Example:
```
[
{
"algorithm": "m.megolm.v1.aes-sha2",
"forwarding_curve25519_key_chain": [
"hPQNcabIABgGnx3/ACv/jmMmiQHoeFfuLB17tzWp6Hw"
],
"room_id": "!Cuyf34gef24t:localhost",
"sender_key": "RF3s+E7RkTQTGF2d8Deol0FkQvgII2aJDf3/Jp5mxVU",
"sender_claimed_keys": {
"ed25519": "<device ed25519 identity key>",
},
"session_id": "X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ",
"session_key": "AgAAAADxKHa9uFxcXzwYoNueL5Xqi69IkD4sni8Llf..."
},
...
]
```
{{% definition path="api/client-server/definitions/megolm_export_session_data" %}}
#### Messaging Algorithms

View file

@ -91,7 +91,7 @@ included in the ban list.
#### Events
The `entity` described by the state events can contain `*` and `?` to
match zero or more and one or more characters respectively. Note that
match zero or more characters and exactly one character respectively. Note that
rules against rooms can describe a room ID or room alias - the
subscriber is responsible for resolving the alias to a room ID if
desired.

View file

@ -276,7 +276,7 @@ Example:
#### Sharing
To request a secret from other devices, a client sends an
`m.secret.requests` device event with `action` set to `request` and
`m.secret.request` device event with `action` set to `request` and
`name` set to the identifier of the secret. A device that wishes to
share the secret will reply with an `m.secret.send` event, encrypted
using olm. When the original client obtains the secret, it sends an

View file

@ -26,22 +26,25 @@ The rules are as follows:
version, reject.
4. If `content` has no `creator` field, reject.
5. Otherwise, allow.
2. Reject if event has `auth_events` that:
1. have duplicate entries for a given `type` and `state_key` pair
2. have entries whose `type` and `state_key` don't match those
2. Considering the event's `auth_events`:
1. If there are duplicate entries for a given `type` and `state_key` pair,
reject.
2. If there are entries whose `type` and `state_key` don't match those
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification.
3. If event does not have a `m.room.create` in its `auth_events`,
reject.
4. If the create event content has the field `m.federate` set to `false`
and the sender domain of the event does not match the sender domain of
the create event, reject.
5. If type is `m.room.aliases`:
algorithm described in the server specification, reject.
3. If there are entries which were themselves rejected under the [checks
performed on receipt of a
PDU](server-server-api/#checks-performed-on-receipt-of-a-pdu), reject.
4. If there is no `m.room.create` event among the entries, reject.
3. If the `content` of the `m.room.create` event in the room state has the
property `m.federate` set to `false`, and the `sender` domain of the event
does not match the `sender` domain of the create event, reject.
4. If type is `m.room.aliases`:
1. If event has no `state_key`, reject.
2. If sender's domain doesn't matches `state_key`, reject.
3. Otherwise, allow.
6. If type is `m.room.member`:
5. If type is `m.room.member`:
1. If no `state_key` key or `membership` key in `content`, reject.
2. If `membership` is `join`:
1. If the only previous event is an `m.room.create` and the
@ -98,15 +101,15 @@ The rules are as follows:
than the `sender`'s power level, allow.
3. Otherwise, reject.
6. Otherwise, the membership is unknown. Reject.
7. If the `sender`'s current membership state is not `join`, reject.
8. If type is `m.room.third_party_invite`:
6. If the `sender`'s current membership state is not `join`, reject.
7. If type is `m.room.third_party_invite`:
1. Allow if and only if `sender`'s current power level is greater
than or equal to the *invite level*.
9. If the event type's *required power level* is greater than the
8. If the event type's *required power level* is greater than the
`sender`'s power level, reject.
10. If the event has a `state_key` that starts with an `@` and does not
9. If the event has a `state_key` that starts with an `@` and does not
match the `sender`, reject.
11. If type is `m.room.power_levels`:
10. If type is `m.room.power_levels`:
1. 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.
@ -130,14 +133,14 @@ The rules are as follows:
1. If the current value is equal to the `sender`'s current
power level, reject.
6. Otherwise, allow.
12. If type is `m.room.redaction`:
11. If type is `m.room.redaction`:
1. If the `sender`'s power level is greater than or equal to the
*redact level*, allow.
2. 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.
3. Otherwise, reject.
13. Otherwise, allow.
12. Otherwise, allow.
{{% boxes/note %}}
Some consequences of these rules:

View file

@ -138,9 +138,11 @@ the auth event is not rejected.
The *resolution* of a set of states is obtained as follows:
1. Select all *power events* that appear in the *full conflicted set*. Compute
the union of their auth chains, including the power events themselves.
Sort the union using the *reverse topological power ordering*.
1. Select the set *X* of all *power events* that appear in the *full
conflicted set*. For each such power event *P*, enlarge *X* by adding
the events in the auth chain of *P* which also belong to the full
conflicted set. Sort $X$ into a list using the *reverse topological
power ordering*.
2. Apply the *iterative auth checks algorithm*, starting from the
*unconflicted state map*, to the list of events from the previous
step to get a partially resolved state.

View file

@ -33,22 +33,25 @@ The complete list of rules, as of room version 3, is as follows:
version, reject.
4. If `content` has no `creator` field, reject.
5. Otherwise, allow.
2. Reject if event has `auth_events` that:
1. have duplicate entries for a given `type` and `state_key` pair
2. have entries whose `type` and `state_key` don't match those
2. Considering the event's `auth_events`:
1. If there are duplicate entries for a given `type` and `state_key` pair,
reject.
2. If there are entries whose `type` and `state_key` don't match those
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification.
3. If event does not have a `m.room.create` in its `auth_events`,
reject.
4. If the create event content has the field `m.federate` set to `false`
and the sender domain of the event does not match the sender domain of
the create event, reject.
5. If type is `m.room.aliases`:
algorithm described in the server specification, reject.
3. If there are entries which were themselves rejected under the [checks
performed on receipt of a
PDU](server-server-api/#checks-performed-on-receipt-of-a-pdu), reject.
4. If there is no `m.room.create` event among the entries, reject.
3. If the `content` of the `m.room.create` event in the room state has the
property `m.federate` set to `false`, and the `sender` domain of the event
does not match the `sender` domain of the create event, reject.
4. If type is `m.room.aliases`:
1. If event has no `state_key`, reject.
2. If sender's domain doesn't matches `state_key`, reject.
3. Otherwise, allow.
6. If type is `m.room.member`:
5. If type is `m.room.member`:
1. If no `state_key` key or `membership` key in `content`, reject.
2. If `membership` is `join`:
1. If the only previous event is an `m.room.create` and the
@ -105,15 +108,15 @@ The complete list of rules, as of room version 3, is as follows:
than the `sender`'s power level, allow.
3. Otherwise, reject.
6. Otherwise, the membership is unknown. Reject.
7. If the `sender`'s current membership state is not `join`, reject.
8. If type is `m.room.third_party_invite`:
6. If the `sender`'s current membership state is not `join`, reject.
7. If type is `m.room.third_party_invite`:
1. Allow if and only if `sender`'s current power level is greater
than or equal to the *invite level*.
9. If the event type's *required power level* is greater than the
8. If the event type's *required power level* is greater than the
`sender`'s power level, reject.
10. If the event has a `state_key` that starts with an `@` and does not
9. If the event has a `state_key` that starts with an `@` and does not
match the `sender`, reject.
11. If type is `m.room.power_levels`:
10. If type is `m.room.power_levels`:
1. 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.
@ -137,7 +140,7 @@ The complete list of rules, as of room version 3, is as follows:
1. If the current value is equal to the `sender`'s current
power level, reject.
6. Otherwise, allow.
12. Otherwise, allow.
11. Otherwise, allow.
{{% boxes/note %}}
Some consequences of these rules:

View file

@ -34,18 +34,21 @@ The rules are as follows:
version, reject.
4. If `content` has no `creator` field, reject.
5. Otherwise, allow.
2. Reject if event has `auth_events` that:
1. have duplicate entries for a given `type` and `state_key` pair
2. have entries whose `type` and `state_key` don't match those
2. Considering the event's `auth_events`:
1. If there are duplicate entries for a given `type` and `state_key` pair,
reject.
2. If there are entries whose `type` and `state_key` don't match those
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification.
3. If event does not have a `m.room.create` in its `auth_events`,
reject.
4. If the create event content has the field `m.federate` set to `false`
and the sender domain of the event does not match the sender domain of
the create event, reject.
5. If type is `m.room.member`:
algorithm described in the server specification, reject.
3. If there are entries which were themselves rejected under the [checks
performed on receipt of a
PDU](server-server-api/#checks-performed-on-receipt-of-a-pdu), reject.
4. If there is no `m.room.create` event among the entries, reject.
3. If the `content` of the `m.room.create` event in the room state has the
property `m.federate` set to `false`, and the `sender` domain of the event
does not match the `sender` domain of the create event, reject.
4. If type is `m.room.member`:
1. If no `state_key` key or `membership` key in `content`, reject.
2. If `content` has a `join_authorised_via_users_server`
key:
@ -119,15 +122,15 @@ The rules are as follows:
or `join`, allow.
4. Otherwise, reject.
8. Otherwise, the membership is unknown. Reject.
6. If the `sender`'s current membership state is not `join`, reject.
7. If type is `m.room.third_party_invite`:
5. If the `sender`'s current membership state is not `join`, reject.
6. If type is `m.room.third_party_invite`:
1. Allow if and only if `sender`'s current power level is greater
than or equal to the *invite level*.
8. If the event type's *required power level* is greater than the
7. If the event type's *required power level* is greater than the
`sender`'s power level, reject.
9. If the event has a `state_key` that starts with an `@` and does not
8. If the event has a `state_key` that starts with an `@` and does not
match the `sender`, reject.
10. If type is `m.room.power_levels`:
9. If type is `m.room.power_levels`:
1. 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.
@ -151,7 +154,7 @@ The rules are as follows:
1. If the current value is equal to the `sender`'s current
power level, reject.
6. Otherwise, allow.
11. Otherwise, allow.
10. Otherwise, allow.
{{% boxes/note %}}
Some consequences of these rules:

View file

@ -106,18 +106,21 @@ The rules are as follows:
version, reject.
4. If `content` has no `creator` field, reject.
5. Otherwise, allow.
2. Reject if event has `auth_events` that:
1. have duplicate entries for a given `type` and `state_key` pair
2. have entries whose `type` and `state_key` don't match those
2. Considering the event's `auth_events`:
1. If there are duplicate entries for a given `type` and `state_key` pair,
reject.
2. If there are entries whose `type` and `state_key` don't match those
specified by the [auth events
selection](/server-server-api#auth-events-selection)
algorithm described in the server specification.
3. If event does not have a `m.room.create` in its `auth_events`,
reject.
4. If the create event content has the field `m.federate` set to `false`
and the sender domain of the event does not match the sender domain of
the create event, reject.
5. If type is `m.room.member`:
algorithm described in the server specification, reject.
3. If there are entries which were themselves rejected under the [checks
performed on receipt of a
PDU](server-server-api/#checks-performed-on-receipt-of-a-pdu), reject.
4. If there is no `m.room.create` event among the entries, reject.
3. If the `content` of the `m.room.create` event in the room state has the
property `m.federate` set to `false`, and the `sender` domain of the event
does not match the `sender` domain of the create event, reject.
4. If type is `m.room.member`:
1. If no `state_key` key or `membership` key in `content`, reject.
2. If `content` has a `join_authorised_via_users_server`
key:
@ -194,15 +197,15 @@ The rules are as follows:
or `join`, allow.
4. Otherwise, reject.
8. Otherwise, the membership is unknown. Reject.
6. If the `sender`'s current membership state is not `join`, reject.
7. If type is `m.room.third_party_invite`:
5. If the `sender`'s current membership state is not `join`, reject.
6. If type is `m.room.third_party_invite`:
1. Allow if and only if `sender`'s current power level is greater
than or equal to the *invite level*.
8. If the event type's *required power level* is greater than the
7. If the event type's *required power level* is greater than the
`sender`'s power level, reject.
9. If the event has a `state_key` that starts with an `@` and does not
8. If the event has a `state_key` that starts with an `@` and does not
match the `sender`, reject.
10. If type is `m.room.power_levels`:
9. If type is `m.room.power_levels`:
1. {{< added-in this="true" >}}
If any of the keys `users_default`, `events_default`, `state_default`,
`ban`, `redact`, `kick`, or `invite` in `content` are present and
@ -233,7 +236,7 @@ The rules are as follows:
1. If the current value is equal to the `sender`'s current
power level, reject.
6. Otherwise, allow.
11. Otherwise, allow.
10. Otherwise, allow.
{{% boxes/note %}}
Some consequences of these rules:

View file

@ -71,6 +71,39 @@ paths:
application/json: {}
schema:
type: object
400:
description: |-
The request body is not a JSON object. Errcode: `M_BAD_JSON`
or `M_NOT_JSON`.
examples:
application/json: {
"errcode": "M_NOT_JSON",
"error": "Content must be a JSON object."
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
403:
description: |-
The access token provided is not authorized to modify this user's account
data. Errcode: `M_FORBIDDEN`.
examples:
application/json: {
"errcode": "M_FORBIDDEN",
"error": "Cannot add account data for other users."
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
405:
examples:
application/json: {
"errcode": "M_BAD_JSON",
"error": "Cannot set m.fully_read through this API."
}
description: |-
This `type` of account data is controlled by the server; it cannot be
modified by clients. Errcode: `M_BAD_JSON`.
schema:
$ref: "../client-server/definitions/errors/error.yaml"
tags:
- User data
get:
@ -106,11 +139,33 @@ paths:
type: object
example: {
"custom_account_data_key": "custom_config_value"}
403:
description: |-
The access token provided is not authorized to retrieve this user's account
data. Errcode: `M_FORBIDDEN`.
examples:
application/json: {
"errcode": "M_FORBIDDEN",
"error": "Cannot add account data for other users."
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
404:
description: |-
No account data has been provided for this user with the given `type`.
Errcode: `M_NOT_FOUND`.
examples:
application/json: {
"errcode": "M_NOT_FOUND",
"error": "Room account data not found."
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
tags:
- User data
"/user/{userId}/rooms/{roomId}/account_data/{type}":
put:
summary: Set some account_data for the user.
summary: Set some account_data for the user that is specific to a room.
description: |-
Set some account_data for the client on a given room. This config is only
visible to the user that set the account_data. The config will be synced to
@ -159,10 +214,44 @@ paths:
application/json: {}
schema:
type: object
400:
description: |-
The request body is not a JSON object (errcode `M_BAD_JSON` or
`M_NOT_JSON`), or the given `roomID` is not a valid room ID
(errcode `M_INVALID_PARAM`).
examples:
application/json: {
"errcode": "M_NOT_JSON",
"error": "Content must be a JSON object."
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
403:
description: |-
The access token provided is not authorized to modify this user's account
data. Errcode: `M_FORBIDDEN`.
examples:
application/json: {
"errcode": "M_FORBIDDEN",
"error": "Cannot add account data for other users."
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
405:
description: |-
This `type` of account data is controlled by the server; it cannot be
modified by clients. Errcode: `M_BAD_JSON`.
examples:
application/json: {
"errcode": "M_BAD_JSON",
"error": "Cannot set m.fully_read through this API."
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
tags:
- User data
get:
summary: Get some account_data for the user.
summary: Get some account_data for the user that is specific to a room.
description: |-
Get some account_data for the client on a given room. This config is only
visible to the user that set the account_data.
@ -201,5 +290,35 @@ paths:
type: object
example: {
"custom_account_data_key": "custom_config_value"}
400:
description: |-
The given `roomID` is not a valid room ID. Errcode: `M_INVALID_PARAM`.
examples:
application/json: {
"errcode": "M_INVALID_PARAM",
"error": "@notaroomid:example.org is not a valid room ID."
}
403:
description: |-
The access token provided is not authorized to retrieve this user's account
data. Errcode: `M_FORBIDDEN`.
examples:
application/json: {
"errcode": "M_FORBIDDEN",
"error": "Cannot add account data for other users."
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
404:
description: |-
No account data has been provided for this user and this room with the
given `type`. Errcode: `M_NOT_FOUND`.
examples:
application/json: {
"errcode": "M_NOT_FOUND",
"error": "Room account data not found."
}
schema:
$ref: "../client-server/definitions/errors/error.yaml"
tags:
- User data

View file

@ -168,7 +168,7 @@ paths:
"user_id": "@alice:example.com",
"device_id": "HIJKLMN",
"algorithms": [
"m.olm.curve25519-aes-sha256",
"m.olm.v1.curve25519-aes-sha256",
"m.megolm.v1.aes-sha"
],
"keys": {

View file

@ -0,0 +1,36 @@
# Copyright 2022 The Matrix.org Foundation C.I.C
#
# 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: AuthData
description: |-
The format of the `auth_data` when a key backup is created with the
`algorithm` set to `m.megolm_backup.v1.curve25519-aes-sha2`.
properties:
public_key:
type: string
description: |-
The curve25519 public key used to encrypt the backups, encoded in unpadded base64.
example: "abcdefg"
signatures:
type: object
description: |-
Signatures of the `auth_data`, as Signed JSON
example: {
"something": {
"ed25519:something": "hijklmnop"
}
}
required: ['public_key']

View file

@ -0,0 +1,62 @@
# Copyright 2022 The Matrix.org Foundation C.I.C
#
# 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: SessionData
description: |-
The format of a backed-up session key, prior to encryption, when using the
`m.megolm_backup.v1.curve25519-aes-sha2` algorithm.
properties:
algorithm:
type: string
description: |-
The end-to-end message encryption algorithm that the key is for. Must be `m.megolm.v1.aes-sha2`.
forwarding_curve25519_key_chain:
type: array
items:
type: string
description: |-
Chain of Curve25519 keys through which this session was forwarded, via [m.forwarded_room_key](#mforwarded_room_key) events.
sender_key:
type: string
description: |-
Unpadded base64-encoded device Curve25519 key.
sender_claimed_keys:
type: object
additionalProperties:
type: string
description: |-
A map from algorithm name (`ed25519`) to the Ed25519 signing key of the sending device.
session_key:
type: string
description: |-
Unpadded base64-encoded session key in [session-export format](https://gitlab.matrix.org/matrix-org/olm/blob/master/docs/megolm.md#session-export-format).
example: {
"algorithm": "m.megolm.v1.aes-sha2",
"forwarding_curve25519_key_chain": [
"hPQNcabIABgGnx3/ACv/jmMmiQHoeFfuLB17tzWp6Hw"
],
"sender_key": "RF3s+E7RkTQTGF2d8Deol0FkQvgII2aJDf3/Jp5mxVU",
"sender_claimed_keys": {
"ed25519": "aj40p+aw64yPIdsxoog8jhPu9i7l7NcFRecuOQblE3Y",
},
"session_key": "AgAAAADxKHa9uFxcXzwYoNueL5Xqi69IkD4sni8Llf..."
}
required:
- algorithm
- forwarding_curve25519_key_chain
- sender_key
- sender_claimed_keys
- session_key

View file

@ -0,0 +1,38 @@
# Copyright 2022 The Matrix.org Foundation C.I.C
#
# 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.
allOf:
- $ref: key_backup_session_data.yaml
- type: object
description: |-
The format used to encode a Megolm session key for export.
This is similar to the format before encryption used for the session keys
in [Server-side key backups](#server-side-key-backups) but adds the
`room_id` and `session_id` fields.
properties:
room_id:
type: string
description: |-
The room where the session is used.
example: "!Cuyf34gef24t:localhost"
session_id:
type: string
description: |-
The Megolm session ID.
example: "X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ"
required:
- room_id
- session_id

View file

@ -80,7 +80,7 @@ paths:
required: ["user_id"]
responses:
200:
description: The user has been invited to join the room.
description: The user has been invited to join the room, or was already invited to the room.
examples:
application/json: {
}

View file

@ -86,6 +86,7 @@ paths:
tags:
- End-to-end encryption
get:
x-addedInMatrixVersion: "1.1"
summary: Get information about the latest backup version.
description: |-
Get information about the latest backup version.
@ -241,6 +242,7 @@ paths:
tags:
- End-to-end encryption
put:
x-addedInMatrixVersion: "1.1"
summary: Update information about an existing backup.
description: |-
Update information about an existing backup. Only `auth_data` can be modified.
@ -330,6 +332,7 @@ paths:
tags:
- End-to-end encryption
delete:
x-addedInMatrixVersion: "1.1"
summary: Delete an existing key backup.
description: |-
Delete an existing key backup. Both the information about the backup,
@ -375,6 +378,7 @@ paths:
- End-to-end encryption
"/room_keys/keys/{roomId}/{sessionId}":
put:
x-addedInMatrixVersion: "1.1"
summary: Store a key in the backup.
description: |-
Store a key in the backup.
@ -447,6 +451,7 @@ paths:
tags:
- End-to-end encryption
get:
x-addedInMatrixVersion: "1.1"
summary: Retrieve a key from the backup.
description: |-
Retrieve a key from the backup.
@ -494,6 +499,7 @@ paths:
tags:
- End-to-end encryption
delete:
x-addedInMatrixVersion: "1.1"
summary: Delete a key from the backup.
description: |-
Delete a key from the backup.
@ -558,6 +564,7 @@ paths:
- End-to-end encryption
"/room_keys/keys/{roomId}":
put:
x-addedInMatrixVersion: "1.1"
summary: Store several keys in the backup for a given room.
description: |-
Store several keys in the backup for a given room.
@ -634,6 +641,7 @@ paths:
tags:
- End-to-end encryption
get:
x-addedInMatrixVersion: "1.1"
summary: Retrieve the keys from the backup for a given room.
description: |-
Retrieve the keys from the backup for a given room.
@ -679,6 +687,7 @@ paths:
tags:
- End-to-end encryption
delete:
x-addedInMatrixVersion: "1.1"
summary: Delete the keys from the backup for a given room.
description: |-
Delete the keys from the backup for a given room.
@ -834,6 +843,7 @@ paths:
tags:
- End-to-end encryption
get:
x-addedInMatrixVersion: "1.1"
summary: Retrieve the keys from the backup.
description: |-
Retrieve the keys from the backup.
@ -897,6 +907,7 @@ paths:
tags:
- End-to-end encryption
delete:
x-addedInMatrixVersion: "1.1"
summary: Delete the keys from the backup.
description: |-
Delete the keys from the backup.

View file

@ -15,7 +15,7 @@ properties:
entity:
description: |-
The entity affected by this rule. Glob characters `*` and `?` can be used
to match zero or more and one or more characters respectively.
to match zero or more characters or exactly one character respectively.
type: string
recommendation:
description: The suggested action to take. Currently only `m.ban` is specified.

View file

@ -53,10 +53,11 @@
<h2>Content</h2>
{{ $additional_types := partial "json-schema/resolve-additional-types" $event_data.properties.content }}
{{ $anchor_base := anchorize $event_name }}
{{ $additional_types := partial "json-schema/resolve-additional-types" (dict "schema" $event_data.properties.content "anchor_base" $anchor_base) }}
{{ range $additional_types }}
{{ partial "openapi/render-object-table" (dict "caption" .title "properties" .properties "required" .required) }}
{{ partial "openapi/render-object-table" . }}
{{end}}
<h2>Examples</h2>

View file

@ -1,25 +1,34 @@
{{/*
Finds and returns all nested objects, given:
Finds and returns all nested objects, given a dict containing:
* `schema`: a JSON schema object
* `anchor_base`: a prefix to add to the HTML anchors generated for each object. If nil, no anchors are generated.
* `this_object`: a JSON schema object
This template finds all nested objects inside `schema`.
Given a schema object, this template finds all nested objects under that
schema.
Assumes that "resolve-refs" and "resolve-allof" has already been called on the
input schema.
It "cleans" each object by copying only the parts of the objects that
the renderer needs, and adds the result to an array, `additional_objects`.
Finally it returns the array of all the objects it found.
Returns an array of all the objects found. For each object, the following properties are returned:
* title
* properties
* required
* enum
* anchor: a string suitable for using as an html anchor for this object (if `anchor_base` was set, and the object has a title)
Note that the returned array may contain duplicate objects.
*/}}
{{ $this_object := partial "json-schema/resolve-allof" . }}
{{ $this_object := .schema }}
{{ $anchor_base := .anchor_base }}
{{ $additional_objects := slice }}
{{ if eq $this_object.type "object" }}
{{/* give this object an anchor, if it has a name */}}
{{ if (and $anchor_base $this_object.title) }}
{{ $this_object = merge $this_object (dict "anchor" (printf "%s_%s" $anchor_base (anchorize $this_object.title))) }}
{{ end }}
{{/*
Add the object we were passed into the $additional_objects array
@ -34,7 +43,7 @@
{{ $additional_objects = $additional_objects | append (partial "clean-object" $this_object.additionalProperties) }}
{{ range $key, $property := $this_object.additionalProperties.properties }}
{{ $additional_objects = partial "get-additional-objects" (dict "this_object" $property "additional_objects" $additional_objects) }}
{{ $additional_objects = partial "get-additional-objects" (dict "this_object" $property "additional_objects" $additional_objects "anchor_base" $anchor_base) }}
{{ end }}
{{ end }}
@ -44,7 +53,7 @@
Add any nested objects referenced in this object's `properties`
*/}}
{{ range $key, $property := $this_object.properties}}
{{ $additional_objects = partial "get-additional-objects" (dict "this_object" $property "additional_objects" $additional_objects) }}
{{ $additional_objects = partial "get-additional-objects" (dict "this_object" $property "additional_objects" $additional_objects "anchor_base" $anchor_base) }}
{{ end }}
{{ end }}
@ -55,10 +64,10 @@
*/}}
{{ if reflect.IsSlice $this_object.items}}
{{ range $this_object.items }}
{{ $additional_objects = partial "get-additional-objects" (dict "this_object" . "additional_objects" $additional_objects) }}
{{ $additional_objects = partial "get-additional-objects" (dict "this_object" . "additional_objects" $additional_objects "anchor_base" $anchor_base) }}
{{ end }}
{{ else }}
{{ $additional_objects = partial "get-additional-objects" (dict "this_object" $this_object.items "additional_objects" $additional_objects) }}
{{ $additional_objects = partial "get-additional-objects" (dict "this_object" $this_object.items "additional_objects" $additional_objects "anchor_base" $anchor_base) }}
{{ end }}
{{ end }}
@ -71,8 +80,12 @@
{{ define "partials/get-additional-objects" }}
{{ $additional_objects := .additional_objects }}
/* although we expect resolve-allof to be called on the input, resolve-allof does not recurse into
* nested objects, so we have to call it again.
*/
{{ $this_object := partial "json-schema/resolve-allof" .this_object }}
{{ $more_objects := partial "json-schema/resolve-additional-types" $this_object }}
{{ $more_objects := partial "json-schema/resolve-additional-types" (dict "schema" $this_object "anchor_base" .anchor_base) }}
{{/*
As far as I know we don't have something like Array.concat(), so add them one at a time
*/}}
@ -88,5 +101,5 @@
but with (for example) different examples will be considered different.
*/}}
{{ define "partials/clean-object" }}
{{ return (dict "title" .title "properties" .properties "required" .required "enum" .enum "additionalProperties" .additionalProperties) }}
{{ return (dict "title" .title "properties" .properties "required" .required "enum" .enum "anchor" .anchor "additionalProperties" .additionalProperties) }}
{{ end }}

View file

@ -2,24 +2,28 @@
Render a table listing the properties of an object, given:
* `caption`: optional caption for the table
* `title`: optional caption for the table
* `anchor`: optional HTML element id for the table
* `properties`: dictionary of the properties to list, each given as:
`property_name` : `property_data`
`property_name` : `property_data`
* `required`: array containing the names of required properties.
In some cases (such as response body specifications) this isn't used, and
instead properties have a `required` boolean attribute. We support this too.
In some cases (such as response body specifications) this isn't used, and
instead properties have a `required` boolean attribute. We support this too.
*/}}
{{ $caption := .caption }}
{{ $title := .title }}
{{ $properties := .properties}}
{{ $required := .required}}
{{ $additionalProperties := .additionalProperties }}
{{ if $properties }}
<table class>
{{ with $caption }}
<table{{ if .anchor }} id="{{ .anchor }}"{{ end }}>
{{ with $title }}
<caption>{{ . }}</caption>
{{ end }}
<thead>
@ -108,7 +112,7 @@
{{/* TODO: should we handle the case where additional properties are
permitted, but must follow an explicit schema? */}}
{{ else if (not $additionalProperties) -}}
{{ errorf "Unexpected additionalProperties=false for %s" $caption }}
{{ errorf "Unexpected additionalProperties=false for %s" $title }}
May **not** have additional properties.
{{ end }}
</td>

View file

@ -22,13 +22,14 @@
{{ $endpoint := .endpoint }}
{{ $operation_data := .operation_data }}
{{ $path := .path }}
{{ $anchor := anchorize $endpoint }}
<section class="rendered-data http-api {{ $method }}">
<details {{ if not site.Params.ui.rendered_data_collapsed }}open{{ end }}>
<summary>
<h1 id="{{ lower $method }}{{ anchorize $endpoint }}">
<h1 id="{{ lower $method }}{{ $anchor }}">
<span class="http-api-method {{ $method }}">{{ $method }}</span>
<span class="endpoint{{ if $operation_data.deprecated }} deprecated-inline{{ end }}">{{ $endpoint }}</span>
</h1>
@ -63,9 +64,9 @@
</table>
<hr/>
{{ partial "openapi/render-request" (dict "parameters" $operation_data.parameters "path" $path) }}
{{ partial "openapi/render-request" (dict "parameters" $operation_data.parameters "path" $path "anchor_base" $anchor ) }}
<hr/>
{{ partial "openapi/render-responses" (dict "responses" $operation_data.responses "path" $path) }}
{{ partial "openapi/render-responses" (dict "responses" $operation_data.responses "path" $path "anchor_base" $anchor ) }}
</details>

View file

@ -25,6 +25,6 @@
{{ end }}
{{/* and render the parameters */}}
{{ partial "openapi/render-object-table" (dict "caption" $caption "properties" $param_dict) }}
{{ partial "openapi/render-object-table" (dict "title" $caption "properties" $param_dict) }}
{{ end }}

View file

@ -4,6 +4,7 @@
* `parameters`: OpenAPI/Swagger data specifying the parameters
* `path`: the path where this definition was found, to enable us to resolve "$ref"
* `anchor_base`: a prefix to add to the HTML anchors generated for each object
This template renders:
* the "simple parameters" (header, path, query parameters)
@ -14,6 +15,7 @@
{{ $parameters := .parameters }}
{{ $path := .path }}
{{ $anchor_base := .anchor_base }}
<h2>Request</h2>
@ -38,10 +40,10 @@
{{ $schema := partial "json-schema/resolve-refs" (dict "schema" $body_parameter.schema "path" $path) }}
{{ $schema := partial "json-schema/resolve-allof" $schema }}
{{ $additional_types := partial "json-schema/resolve-additional-types" $schema }}
{{ $additional_types := partial "json-schema/resolve-additional-types" (dict "schema" $schema "anchor_base" $anchor_base) }}
{{ $additional_types = uniq $additional_types }}
{{ range $additional_types }}
{{ partial "openapi/render-object-table" (dict "caption" .title "properties" .properties "required" .required "additionalProperties" .additionalProperties) }}
{{ partial "openapi/render-object-table" . }}
{{ end }}
<h3>Request body example</h3>

View file

@ -4,6 +4,7 @@
* `responses`: OpenAPI/Swagger data specifying the responses
* `path`: the path where this definition was found, to enable us to resolve "$ref"
* `anchor_base`: a prefix to add to the HTML anchors generated for each object
This template renders:
* a summary of all the different responses
@ -15,6 +16,7 @@
{{ $responses := .responses }}
{{ $path := .path }}
{{ $anchor_base := .anchor_base }}
<h2>Responses</h2>
@ -71,10 +73,10 @@
response. (This will be a no-op for response types which aren't
objects or arrays.)
*/}}
{{ $additional_types := partial "json-schema/resolve-additional-types" $schema }}
{{ $additional_types := partial "json-schema/resolve-additional-types" (dict "schema" $schema "anchor_base" $anchor_base) }}
{{ $additional_types = uniq $additional_types }}
{{ range $additional_types }}
{{ partial "openapi/render-object-table" (dict "caption" .title "properties" .properties "required" .required) }}
{{ partial "openapi/render-object-table" . }}
{{ end }}
{{/*

View file

@ -18,6 +18,10 @@
{{/* The definition is referenced by the .path parameter */}}
{{ $definition := index .Site.Data $pieces }}
{{ if not $definition }}
{{ errorf "site data %s not found" $path }}
{{ end }}
{{/* The base path, which we use to resolve $ref, omits the last component */}}
{{ $pieces = first (sub (len $pieces) 1) $pieces}}
{{ $path = delimit $pieces "/" }}
@ -45,11 +49,11 @@
</summary>
{{ $additional_types := partial "json-schema/resolve-additional-types" $definition }}
{{ $additional_types := partial "json-schema/resolve-additional-types" (dict "schema" $definition) }}
{{ $additional_types = uniq $additional_types }}
{{ range $additional_types }}
{{ partial "openapi/render-object-table" (dict "caption" .title "properties" .properties "required" .required) }}
{{ partial "openapi/render-object-table" . }}
{{end}}
<h2>Examples</h2>

View file

@ -35,9 +35,9 @@
{{ $event = merge $event (dict "title" "") }}
{{ $additional_types := partial "json-schema/resolve-additional-types" $event }}
{{ $additional_types := partial "json-schema/resolve-additional-types" (dict "schema" $event) }}
{{ range $additional_types }}
{{ partial "openapi/render-object-table" (dict "caption" .title "properties" .properties "required" .required) }}
{{ partial "openapi/render-object-table" . }}
{{end}}
</details>