From 1b81970a1edc19a228793441a21086b6c3b33aa2 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 17 Aug 2018 22:01:13 -0400 Subject: [PATCH 0001/1250] initial commit of e2e backup proposal --- .../1219-storing-megolm-keys-serverside.md | 197 ++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 proposals/1219-storing-megolm-keys-serverside.md diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md new file mode 100644 index 00000000..b78fc953 --- /dev/null +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -0,0 +1,197 @@ +Storing megolm keys serverside +============================== + +Background +---------- + +We *optionally* let clients store a copy of their megolm inbound session keys +on the HS so that they can recover history if all devices are lost without an +explicit key export; transparently share history between a user's devices; +transparently share missing keys between a user's devices to fix UISIs; support +clients with limited local storage for keys. + +See also: + +* https://github.com/matrix-org/matrix-doc/issues/1219 +* https://github.com/vector-im/riot-web/issues/3661 +* https://github.com/vector-im/riot-web/issues/5675 +* https://docs.google.com/document/d/1MOoIA9qEKIhUQ3UmKZG-loqA8e0BzgWKKlKRUGMynVc/edit# + (old version of proposal) + +Proposal +-------- + +This proposal creates new APIs to allow clients to back up room decryption keys +on the server. Decryption keys are encrypted (using public key crypto) before +being sent to the server along with some unencrypted metadata to allow the +server to manage the backups, overwriting backups with "better" versions of the +keys. The user is given a private recovery key to save for recovering the keys +from the backup. + +Clients can create new versions of backups. A client would start a new version +of a backup when, for example, a user loses a device, and wants to ensure that +that device does not get any new decryption keys. + +### Possible UX for interactive clients + +On receipt of encryption keys (1st time): + +1. client checks if there is an existing backup: `GET /room_keys/version` + 1. if not, ask if the user wants to back up keys + 1. if yes: + 1. generate new key pair + 2. create new backup version: `POST /room_keys/version` + 3. display private key to user to save + 2. if no, exit and remember decision (user can change their mind later) + 3. while prompting, continue to poll `GET /room_keys/versions`, as + another device may have created a backup. If so, go to 1.2. + 2. if yes, get public key, prompt user to verify a device that signed the + key¹, or enter recovery key (which can derive the backup key). + 1. User can also decide to create a new backup, in which case, go to 1.1. +2. send key to backup: `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v` +3. continue backing up keys as we receive them (may receive a 403 error if a + new backup version has been created: see below) + +On 403 error when trying to `PUT` keys: + +1. get the current version +2. notify the user that there is a new backup version, and display relevant + information +3. confirm with user that they want to use the backup (user may want use the + backup, to stop backing up keys, or to create a new backup) +4. verify the device that signed the backup key¹, or enter recovery key + +¹: cross-signing (when that is completed) can be used to verify the device +that signed the key. + +On receipt of undecryptable message: + +1. ask user if they want to restore backup (ask whether to get individual key, + room keys, or all keys). (This can be done in the same place as asking if + the user wants to request keys from other devices.) +2. if yes, prompt for private key, and get keys: `GET /room_keys/keys` + +### API + +#### Backup versions + +##### `POST /room_keys/version` + +Create a new backup version. + +Body parameters: + +- `algorithm` (string): Required. The algorithm used for storing backups. + Currently, only `m.megolm_backup.v1` is defined. (FIXME: change the algorithm + name to include the encryption method) +- `auth_data` (string or object): Required. algorithm-dependent data. For + `m.megolm_backup.v1`, this is a signedjson object with the following keys: + - `public_key` (string): ... + - `signatures` (object): signatures of the public key + +Example: + +```javascript +{ + "algorithm": "m.megolm_backup.v1", + "auth_data": { + "public_key": { + "public_key": "abcdefg", + "signatures": { + "something": { + "ed25519:something": "hijklmnop" + } + } + } + } +} +``` + +On success, returns a JSON object with keys: + +- `version` (integer): the backup version + +##### `GET /room_keys/version` + +Get information about the current version. + +On success, returns a JSON object with keys: + +- `algorithm` (string): Required. Same as in the body parameters for `POST + /room_keys/version`. +- `auth_data` (string or object): Required. Same as in the body parameters for + `POST /room_keys/version`. +- `version` (integer): the backup version + + +#### Storing keys + +##### `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v` + +Store the key for the given session in the given room, using the given backup +version. + +If the server already has a backup in the backup version for the given session +and room, then it will keep the "better" one ... + +Body parameters: + +- `first_message_index` (integer): Required. The index of the first message + in the session that the key can decrypt. +- `forwarded_count` (integer): Required. The number of times this key has been + forwarded. +- `is_verified` (boolean): Whether the device backing up the key has verified + the device that the key is from. +- `session_data` (string): The backup of the key, encrypted according to the + backup algorithm. + +On success, returns ... ? + +##### `PUT /room_keys/keys/${roomId}?version=$v` + +Store several keys for the given room, using the given backup version. + +Behaves the same way as if the keys were added individually using `PUT +/room_keys/keys/${roomId}/${sessionId}?version=$v`. + +Body paremeters: +- `sessions` (object): an object where the keys are the session IDs, and the + values are objects of the same form as the body in `PUT + /room_keys/keys/${roomId}/${sessionId}?version=$v`. + +On success, returns same as `PUT +/room_keys/keys/${roomId}/${sessionId}?version=$v` + +##### `PUT /room_keys/keys/?version=$v` + +... + +#### Retrieving keys + +##### `GET /room_keys/keys/${roomId}/${sessionId}?version=$v` +##### `GET /room_keys/keys/${roomId}?version=$v` +##### `GET /room_keys/keys/?version=$v` + +#### Deleting keys + +##### `DELETE /room_keys/keys/${roomId}/${sessionId}?version=$v` +##### `DELETE /room_keys/keys/${roomId}?version=$v` +##### `DELETE /room_keys/keys/?version=$v` + +Tradeoffs +--------- + +Security Considerations +----------------------- + +An attacker who gains access to a user's account can delete or corrupt their +key backup. This proposal does not attempt to protect against that. + +Other Issues +------------ + +Since many clients will receive encryption keys at around the same time, +clients should randomly offset their requests ... + +Conclusion +---------- From 6e8ba1f7f8cd14e8540ef54d3efb1ac9694e5167 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 23 Aug 2018 23:04:21 -0400 Subject: [PATCH 0002/1250] add more details --- .../1219-storing-megolm-keys-serverside.md | 75 ++++++++++++++----- 1 file changed, 56 insertions(+), 19 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index b78fc953..3af86f17 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -6,9 +6,8 @@ Background We *optionally* let clients store a copy of their megolm inbound session keys on the HS so that they can recover history if all devices are lost without an -explicit key export; transparently share history between a user's devices; -transparently share missing keys between a user's devices to fix UISIs; support -clients with limited local storage for keys. +explicit key export; fix UISIs; support clients with limited local storage for +keys. See also: @@ -28,9 +27,14 @@ server to manage the backups, overwriting backups with "better" versions of the keys. The user is given a private recovery key to save for recovering the keys from the backup. -Clients can create new versions of backups. A client would start a new version -of a backup when, for example, a user loses a device, and wants to ensure that -that device does not get any new decryption keys. +Clients can create new versions of backups. Aside from the initial backup +creation, a client might start a new version of a backup when, for example, a +user loses a device, and wants to ensure that that device does not get any new +decryption keys. + +Once one client has created a backup version, other clients can fetch the +public key for the backup from the server and add keys to the backup, if they +trust that the backup was not created by a malicious device. ### Possible UX for interactive clients @@ -49,10 +53,11 @@ On receipt of encryption keys (1st time): key¹, or enter recovery key (which can derive the backup key). 1. User can also decide to create a new backup, in which case, go to 1.1. 2. send key to backup: `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v` -3. continue backing up keys as we receive them (may receive a 403 error if a - new backup version has been created: see below) +3. continue backing up keys as we receive them (may receive a + `M_WRONG_ROOM_KEYS_VERSION` error if a new backup version has been created: + see below) -On 403 error when trying to `PUT` keys: +On `M_WRONG_ROOM_KEYS_VERSION` error when trying to `PUT` keys: 1. get the current version 2. notify the user that there is a new backup version, and display relevant @@ -71,6 +76,9 @@ On receipt of undecryptable message: the user wants to request keys from other devices.) 2. if yes, prompt for private key, and get keys: `GET /room_keys/keys` +Users can also set up or disable backups, or restore from backup via user +settings. + ### API #### Backup versions @@ -86,7 +94,7 @@ Body parameters: name to include the encryption method) - `auth_data` (string or object): Required. algorithm-dependent data. For `m.megolm_backup.v1`, this is a signedjson object with the following keys: - - `public_key` (string): ... + - `public_key` (string): the public key used to encrypt the backups - `signatures` (object): signatures of the public key Example: @@ -95,12 +103,10 @@ Example: { "algorithm": "m.megolm_backup.v1", "auth_data": { - "public_key": { - "public_key": "abcdefg", - "signatures": { - "something": { - "ed25519:something": "hijklmnop" - } + "public_key": "abcdefg", + "signatures": { + "something": { + "ed25519:something": "hijklmnop" } } } @@ -123,6 +129,10 @@ On success, returns a JSON object with keys: `POST /room_keys/version`. - `version` (integer): the backup version +Error codes: + +- `M_UNKNOWN`: No backup version has been created. FIXME: why not + `M_NOT_FOUND`? #### Storing keys @@ -142,11 +152,22 @@ Body parameters: forwarded. - `is_verified` (boolean): Whether the device backing up the key has verified the device that the key is from. -- `session_data` (string): The backup of the key, encrypted according to the - backup algorithm. +- `session_data` (string or object): Algorithm-dependent data. For + `m.megolm_backup.v1`, this is an object with the following keys: + - `ciphertext` (string): the encrypted version of the session key. See below + for how the session key is encoded. + - `ephemeral` (string): the public ephemeral key that was used to encrypt the + session key. + - `mac` (string): the message authentication code for the ciphertext. FIXME: + more details On success, returns ... ? +Error codes: + +- `M_WRONG_ROOM_KEYS_VERSION`: the version specified does not match the current + backup version + ##### `PUT /room_keys/keys/${roomId}?version=$v` Store several keys for the given room, using the given backup version. @@ -159,7 +180,7 @@ Body paremeters: values are objects of the same form as the body in `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v`. -On success, returns same as `PUT +Returns the same as `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v` ##### `PUT /room_keys/keys/?version=$v` @@ -178,6 +199,18 @@ On success, returns same as `PUT ##### `DELETE /room_keys/keys/${roomId}?version=$v` ##### `DELETE /room_keys/keys/?version=$v` +#### Key format + +Session keys are encoded as a JSON object with the properties: + +- `algorithm` (string): `m.megolm.v1.aes-sha2` +- `sender_key` (string): base64-encoded device curve25519 key +- `sender_claimed_keys` (object): object containing the identity keys for the + sending device +- `forwardingCurve25519KeyChain` (array): zero or more curve25519 keys for + devices who forwarded the session key +- `session_key` (string): base64-encoded session key + Tradeoffs --------- @@ -187,6 +220,10 @@ Security Considerations An attacker who gains access to a user's account can delete or corrupt their key backup. This proposal does not attempt to protect against that. +An attacker who gains access to a user's account can create a new backup +version using a key that they control. For this reason, clients SHOULD confirm +with users before sending keys to a new backup version. + Other Issues ------------ From 87772329875666f57f1ed5f5540a5626f6f3432e Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 5 Sep 2018 23:21:35 -0400 Subject: [PATCH 0003/1250] various clarifications --- proposals/1219-storing-megolm-keys-serverside.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 3af86f17..e24262e7 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -45,7 +45,8 @@ On receipt of encryption keys (1st time): 1. if yes: 1. generate new key pair 2. create new backup version: `POST /room_keys/version` - 3. display private key to user to save + 3. display private key to user to save TODO: specify how the key is + displayed 2. if no, exit and remember decision (user can change their mind later) 3. while prompting, continue to poll `GET /room_keys/versions`, as another device may have created a backup. If so, go to 1.2. @@ -76,7 +77,7 @@ On receipt of undecryptable message: the user wants to request keys from other devices.) 2. if yes, prompt for private key, and get keys: `GET /room_keys/keys` -Users can also set up or disable backups, or restore from backup via user +Users can also set up, disable, or rotate backups, or restore from backup via user settings. ### API @@ -201,7 +202,7 @@ Returns the same as `PUT #### Key format -Session keys are encoded as a JSON object with the properties: +Each session key is encoded as a JSON object with the properties: - `algorithm` (string): `m.megolm.v1.aes-sha2` - `sender_key` (string): base64-encoded device curve25519 key @@ -211,6 +212,8 @@ Session keys are encoded as a JSON object with the properties: devices who forwarded the session key - `session_key` (string): base64-encoded session key +... + Tradeoffs --------- @@ -227,8 +230,11 @@ with users before sending keys to a new backup version. Other Issues ------------ -Since many clients will receive encryption keys at around the same time, -clients should randomly offset their requests ... +Since many clients will receive encryption keys at around the same time, they +will all want to back up their copies of the keys at around the same time, +which may increase load on the server if this happens in a big room. (TODO: +how much of an issue is this?) For this reason, clients should offset their +backup requests randomly. Conclusion ---------- From 846e9e8fdc7d00a0ee163fae49eaebdc8938cd04 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 6 Sep 2018 17:52:31 -0400 Subject: [PATCH 0004/1250] add clarifications --- .../1219-storing-megolm-keys-serverside.md | 78 ++++++++++++++----- 1 file changed, 58 insertions(+), 20 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index e24262e7..72038436 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -43,7 +43,7 @@ On receipt of encryption keys (1st time): 1. client checks if there is an existing backup: `GET /room_keys/version` 1. if not, ask if the user wants to back up keys 1. if yes: - 1. generate new key pair + 1. generate new curve25519 key pair 2. create new backup version: `POST /room_keys/version` 3. display private key to user to save TODO: specify how the key is displayed @@ -91,18 +91,18 @@ Create a new backup version. Body parameters: - `algorithm` (string): Required. The algorithm used for storing backups. - Currently, only `m.megolm_backup.v1` is defined. (FIXME: change the algorithm - name to include the encryption method) + Currently, only `m.megolm_backup.v1.curve25519-aes-sha2` is defined. - `auth_data` (string or object): Required. algorithm-dependent data. For - `m.megolm_backup.v1`, this is a signedjson object with the following keys: - - `public_key` (string): the public key used to encrypt the backups + `m.megolm_backup.v1.curve25519-aes-sha2`, this is a signedjson object with + the following keys: + - `public_key` (string): the curve25519 public key used to encrypt the backups - `signatures` (object): signatures of the public key Example: ```javascript { - "algorithm": "m.megolm_backup.v1", + "algorithm": "m.megolm_backup.v1.curve25519-aes-sha2", "auth_data": { "public_key": "abcdefg", "signatures": { @@ -143,7 +143,10 @@ Store the key for the given session in the given room, using the given backup version. If the server already has a backup in the backup version for the given session -and room, then it will keep the "better" one ... +and room, then it will keep the "better" one. To determine which one is +"better", key backups are compared first by the `is_verified` flag (`true` is +better than `false`), then by the `first_message_index` (a lower number is better), +and finally by `forwarded_count` (a lower number is better). Body parameters: @@ -154,15 +157,16 @@ Body parameters: - `is_verified` (boolean): Whether the device backing up the key has verified the device that the key is from. - `session_data` (string or object): Algorithm-dependent data. For - `m.megolm_backup.v1`, this is an object with the following keys: - - `ciphertext` (string): the encrypted version of the session key. See below - for how the session key is encoded. - - `ephemeral` (string): the public ephemeral key that was used to encrypt the - session key. + `m.megolm_backup.v1.curve25519-aes-sha2`, this is an object with the + following keys (TODO: this stuff should be moved): + - `ciphertext` (string): the encrypted version of the session key, as an + unpadded base64 string. See below for how the session key is encoded. + - `ephemeral` (string): the public ephemeral curve25519 key that was used to + encrypt the session key, as an unpadded base64 string. - `mac` (string): the message authentication code for the ciphertext. FIXME: more details -On success, returns ... ? +On success, returns the empty JSON object. Error codes: @@ -176,7 +180,7 @@ Store several keys for the given room, using the given backup version. Behaves the same way as if the keys were added individually using `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v`. -Body paremeters: +Body parameters: - `sessions` (object): an object where the keys are the session IDs, and the values are objects of the same form as the body in `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v`. @@ -184,15 +188,43 @@ Body paremeters: Returns the same as `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v` -##### `PUT /room_keys/keys/?version=$v` +##### `PUT /room_keys/keys?version=$v` + +Store several keys, using the given backup version. + +Behaves the same way as if the keys were added individually using `PUT +/room_keys/keys/${roomId}/${sessionId}?version=$v`. + +Body parameters: +- `rooms` (object): an object where the keys are the room IDs, and the values + are objects of the same form as the body in `PUT + /room_keys/keys/${roomId}/?version=$v`. -... +Returns the same as `PUT +/room_keys/keys/${roomId}/${sessionId}?version=$v` #### Retrieving keys ##### `GET /room_keys/keys/${roomId}/${sessionId}?version=$v` + +Retrieve the key for the given session in the given room from the backup. + +On success, returns a JSON object in the same form as the request body of `PUT +/room_keys/keys/${roomId}/${sessionId}?version=$v`. + ##### `GET /room_keys/keys/${roomId}?version=$v` -##### `GET /room_keys/keys/?version=$v` + +Retrieve the all the keys for the given room from the backup. + +On success, returns a JSON object in the same form as the request body of `PUT +/room_keys/keys/${roomId}?version=$v`. + +##### `GET /room_keys/keys?version=$v` + +Retrieve all the keys from the backup. + +On success, returns a JSON object in the same form as the request body of `PUT +/room_keys/keys?version=$v`. #### Deleting keys @@ -200,7 +232,11 @@ Returns the same as `PUT ##### `DELETE /room_keys/keys/${roomId}?version=$v` ##### `DELETE /room_keys/keys/?version=$v` -#### Key format +Deletes keys from the backup. + +On success, returns the empty JSON object. + +#### `m.megolm_backup.v1.curve25519-aes-sha2` Key format Each session key is encoded as a JSON object with the properties: @@ -210,9 +246,11 @@ Each session key is encoded as a JSON object with the properties: sending device - `forwardingCurve25519KeyChain` (array): zero or more curve25519 keys for devices who forwarded the session key -- `session_key` (string): base64-encoded session key +- `session_key` (string): base64-encoded (unpadded) session key -... +The JSON object is then encrypted by generating an ephemeral curve25519 key, +performing an ECDH with the ephemeral key and the backup's public key to +generate an AES key, and encrypting the stringified object using AES. Tradeoffs --------- From 72df5fe43645acb97e6255cbf2c5368ee2aa4ad3 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 10 Oct 2018 16:28:24 -0400 Subject: [PATCH 0005/1250] add details on recovery key format, and some cleanups/fixes --- .../1219-storing-megolm-keys-serverside.md | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 72038436..ab75ccf2 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -45,8 +45,7 @@ On receipt of encryption keys (1st time): 1. if yes: 1. generate new curve25519 key pair 2. create new backup version: `POST /room_keys/version` - 3. display private key to user to save TODO: specify how the key is - displayed + 3. display private key to user to save (see below for the format) 2. if no, exit and remember decision (user can change their mind later) 3. while prompting, continue to poll `GET /room_keys/versions`, as another device may have created a backup. If so, go to 1.2. @@ -80,6 +79,30 @@ On receipt of undecryptable message: Users can also set up, disable, or rotate backups, or restore from backup via user settings. +### Recovery key + +The recovery key is can either be saved by the user directly, or stored +encrypted on the server (as proposed in +[MSC1687](https://github.com/matrix-org/matrix-doc/issues/1687)). If the key +is saved directly by the user, then it the code is constructed as follows: + +1. The 256-bit curve25519 private key is prepended by the bytes `0x8B` and + `0x01` +2. All the bytes in the string are above are XORed together to form a parity + byte. This parity byte is appended to the byte string. +3. The byte string is encoded using base58, using the same mapping as is used + for Bitcoin addresses. + +This 58-character string is presented to the user to save. Implementations may +add whitespace to the recovery key. + +When reading in a recovery key, clients must disregard whitespace. Clients +must base58-decode the code, ensure that the first two bytes of the decoded +string are `0x8B` and `0x01`, ensure that XOR-ing all the bytes together +results in 0, and ensure that the total length of the decoded string +is 35 bytes. Clients must then remove the first two bytes and the last byte, +and use the resulting string as the private key to decrypt backups. + ### API #### Backup versions @@ -118,9 +141,10 @@ On success, returns a JSON object with keys: - `version` (integer): the backup version -##### `GET /room_keys/version` +##### `GET /room_keys/version/{version}` -Get information about the current version. +Get information about the given version, or the current version if `{version}` +is omitted. On success, returns a JSON object with keys: @@ -128,12 +152,11 @@ On success, returns a JSON object with keys: /room_keys/version`. - `auth_data` (string or object): Required. Same as in the body parameters for `POST /room_keys/version`. -- `version` (integer): the backup version +- `version` (integer): Required. The backup version. Error codes: -- `M_UNKNOWN`: No backup version has been created. FIXME: why not - `M_NOT_FOUND`? +- `M_NOT_FOUND`: No backup version has been created. #### Storing keys From de5120335f950a53fec8374058f8c13055a0cecb Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 11 Oct 2018 10:22:42 -0400 Subject: [PATCH 0006/1250] change "string or object" to just "object" --- proposals/1219-storing-megolm-keys-serverside.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index ab75ccf2..312e43bf 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -115,7 +115,7 @@ Body parameters: - `algorithm` (string): Required. The algorithm used for storing backups. Currently, only `m.megolm_backup.v1.curve25519-aes-sha2` is defined. -- `auth_data` (string or object): Required. algorithm-dependent data. For +- `auth_data` (object): Required. algorithm-dependent data. For `m.megolm_backup.v1.curve25519-aes-sha2`, this is a signedjson object with the following keys: - `public_key` (string): the curve25519 public key used to encrypt the backups @@ -150,7 +150,7 @@ On success, returns a JSON object with keys: - `algorithm` (string): Required. Same as in the body parameters for `POST /room_keys/version`. -- `auth_data` (string or object): Required. Same as in the body parameters for +- `auth_data` (object): Required. Same as in the body parameters for `POST /room_keys/version`. - `version` (integer): Required. The backup version. @@ -179,7 +179,7 @@ Body parameters: forwarded. - `is_verified` (boolean): Whether the device backing up the key has verified the device that the key is from. -- `session_data` (string or object): Algorithm-dependent data. For +- `session_data` (object): Algorithm-dependent data. For `m.megolm_backup.v1.curve25519-aes-sha2`, this is an object with the following keys (TODO: this stuff should be moved): - `ciphertext` (string): the encrypted version of the session key, as an From b45416e8b0ab432511eb73ece127f623bf7d8cc9 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 19 Oct 2018 22:19:55 -0400 Subject: [PATCH 0007/1250] change version from string to integer, plus other minor improvements --- proposals/1219-storing-megolm-keys-serverside.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 312e43bf..14149950 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -139,7 +139,7 @@ Example: On success, returns a JSON object with keys: -- `version` (integer): the backup version +- `version` (string): the backup version ##### `GET /room_keys/version/{version}` @@ -152,7 +152,7 @@ On success, returns a JSON object with keys: /room_keys/version`. - `auth_data` (object): Required. Same as in the body parameters for `POST /room_keys/version`. -- `version` (integer): Required. The backup version. +- `version` (string): Required. The backup version. Error codes: @@ -275,9 +275,6 @@ The JSON object is then encrypted by generating an ephemeral curve25519 key, performing an ECDH with the ephemeral key and the backup's public key to generate an AES key, and encrypting the stringified object using AES. -Tradeoffs ---------- - Security Considerations ----------------------- @@ -286,7 +283,8 @@ key backup. This proposal does not attempt to protect against that. An attacker who gains access to a user's account can create a new backup version using a key that they control. For this reason, clients SHOULD confirm -with users before sending keys to a new backup version. +with users before sending keys to a new backup version or verify that it was +created by a trusted device by checking the signature. Other Issues ------------ @@ -299,3 +297,7 @@ backup requests randomly. Conclusion ---------- + +This proposal allows users to securely and conveniently back up and restore +their decryption keys so that users logging into a new device can decrypt old +messages. From 9d51d1e8b70a63fd36328018fde731f26f6b9b71 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Sat, 20 Oct 2018 13:45:35 -0400 Subject: [PATCH 0008/1250] expand the background --- .../1219-storing-megolm-keys-serverside.md | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 14149950..905cd264 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -4,10 +4,28 @@ Storing megolm keys serverside Background ---------- -We *optionally* let clients store a copy of their megolm inbound session keys -on the HS so that they can recover history if all devices are lost without an -explicit key export; fix UISIs; support clients with limited local storage for -keys. +A user who uses end-to-end encyrption will usually have many inbound session +keys. Users who log into new devices and want to read old messages will need a +convenient way to transfer the session keys from one device to another. While +users can currently export their keys from one device and import them to +another, this is involves several steps and may be cumbersome for many users. +Users can also share keys from one device to another, but this has several +limitations, such as the fact that key shares only share one key at a time, and +require another logged-in device to be active. + +To help resolve this, we *optionally* let clients store an encrypted copy of +their megolm inbound session keys on the homeserver. Clients can keep the +backup up to date, so that users will always have the keys needed to decrypt +their conversations. The backup could be used not just for new logins, but +also to try to fix UISIs that occur after a device has logged in (as an +alternative to key sharing), or to support clients with limited local storage +for keys (clients can store old keys to the backup, and remove their local +copy, retrieving the key from the backup when needed). + +To recover keys from the backup, a user will need to enter a recovery key to +decrypt the backup. The backup will be encrypted using public key +cryptography, so that any of a user's devices can back up keys without needing +the user to enter the recovery key until they need to read from the backup. See also: From c8eac3ee2dfb7751640fb80688765484631947c9 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 24 Oct 2018 14:48:02 -0400 Subject: [PATCH 0009/1250] add details on how the encryption is done --- .../1219-storing-megolm-keys-serverside.md | 72 ++++++++++++------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 905cd264..68e23d68 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -134,10 +134,8 @@ Body parameters: - `algorithm` (string): Required. The algorithm used for storing backups. Currently, only `m.megolm_backup.v1.curve25519-aes-sha2` is defined. - `auth_data` (object): Required. algorithm-dependent data. For - `m.megolm_backup.v1.curve25519-aes-sha2`, this is a signedjson object with - the following keys: - - `public_key` (string): the curve25519 public key used to encrypt the backups - - `signatures` (object): signatures of the public key + `m.megolm_backup.v1.curve25519-aes-sha2`, see below for the definition of + this property. Example: @@ -198,14 +196,8 @@ Body parameters: - `is_verified` (boolean): Whether the device backing up the key has verified the device that the key is from. - `session_data` (object): Algorithm-dependent data. For - `m.megolm_backup.v1.curve25519-aes-sha2`, this is an object with the - following keys (TODO: this stuff should be moved): - - `ciphertext` (string): the encrypted version of the session key, as an - unpadded base64 string. See below for how the session key is encoded. - - `ephemeral` (string): the public ephemeral curve25519 key that was used to - encrypt the session key, as an unpadded base64 string. - - `mac` (string): the message authentication code for the ciphertext. FIXME: - more details + `m.megolm_backup.v1.curve25519-aes-sha2`, see below for the definition of + this property. On success, returns the empty JSON object. @@ -277,21 +269,47 @@ Deletes keys from the backup. On success, returns the empty JSON object. -#### `m.megolm_backup.v1.curve25519-aes-sha2` Key format - -Each session key is encoded as a JSON object with the properties: - -- `algorithm` (string): `m.megolm.v1.aes-sha2` -- `sender_key` (string): base64-encoded device curve25519 key -- `sender_claimed_keys` (object): object containing the identity keys for the - sending device -- `forwardingCurve25519KeyChain` (array): zero or more curve25519 keys for - devices who forwarded the session key -- `session_key` (string): base64-encoded (unpadded) session key - -The JSON object is then encrypted by generating an ephemeral curve25519 key, -performing an ECDH with the ephemeral key and the backup's public key to -generate an AES key, and encrypting the stringified object using AES. +#### `m.megolm_backup.v1.curve25519-aes-sha2` definitions + +##### `auth_data` for backup versions + +The `auth_data` property for the backup versions endpoints for +`m.megolm_backup.v1.curve25519-aes-sha2` is a signedjson object with the +followin keys: + +- `public_key` (string): the curve25519 public key used to encrypt the backups +- `signatures` (object): signatures of the public key + +##### `session_data` for key backups + +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: + - `algorithm` (string): `m.megolm.v1.aes-sha2` + - `sender_key` (string): base64-encoded device curve25519 key + - `sender_claimed_keys` (object): object containing the identity keys for the + sending device + - `forwardingCurve25519KeyChain` (array): zero or more curve25519 keys for + devices who forwarded the session key + - `session_key` (string): base64-encoded (unpadded) session key +2. Generate an ephemeral curve25519 key, and perform an ECDH with the ephemeral + key and the backup's public key to generate a shared secret. The public + half of the ephemeral key, encoded using base64, becomes the `ephemeral` + property of the `session_data`. +3. Using the shared secret, generate 80 bytes by performing an HKDF using + SHA-256 as the hash, with a salt of 32 bytes of 0, and with the empty string + as the info. The first 32 bytes are used as the AES key, the next 32 bytes + are used as the MAC key, and the last 16 bytes are used as the AES + initialization vector. +4. Stringify the JSON object, and encrypt it using AES-CBC-256 with PKCS#7 + padding. This encrypted data, encoded using base64, becomes the + `ciphertext` property of the `session_data`. +5. Pass the raw encrypted data (prior to base64 encoding) through HMAC-SHA-256 + using the MAC key generated above. The first 8 bytes of the resulting MAC + are base64-encoded, and become the `mac` property of the `session_data`. + +(The key HKDF, AES, and HMAC steps are the same as what are used for encryption +in olm and megolm.) Security Considerations ----------------------- From dc0dd18eebbe911f76e8c306d8b13fbb0210c4ea Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 25 Oct 2018 13:49:47 -0400 Subject: [PATCH 0010/1250] note that version is optional for GET, and say what to do when no keys are found --- .../1219-storing-megolm-keys-serverside.md | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 68e23d68..9936a6cd 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -238,6 +238,9 @@ Returns the same as `PUT #### Retrieving keys +When retrieving keys, the `version` parameter is optional, and defaults to +retrieving the latest backup version. + ##### `GET /room_keys/keys/${roomId}/${sessionId}?version=$v` Retrieve the key for the given session in the given room from the backup. @@ -245,6 +248,10 @@ Retrieve the key for the given session in the given room from the backup. On success, returns a JSON object in the same form as the request body of `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v`. +Error codes: + +- M_NOT_FOUND: The session is not present in the backup. + ##### `GET /room_keys/keys/${roomId}?version=$v` Retrieve the all the keys for the given room from the backup. @@ -252,6 +259,15 @@ Retrieve the all the keys for the given room from the backup. On success, returns a JSON object in the same form as the request body of `PUT /room_keys/keys/${roomId}?version=$v`. +If no keys are found, then this endpoint returns a successful response with +body: + +``` +{ + "sessions": {} +} +``` + ##### `GET /room_keys/keys?version=$v` Retrieve all the keys from the backup. @@ -259,6 +275,16 @@ Retrieve all the keys from the backup. On success, returns a JSON object in the same form as the request body of `PUT /room_keys/keys?version=$v`. + +If no keys are found, then this endpoint returns a successful response with +body: + +``` +{ + "rooms": {} +} +``` + #### Deleting keys ##### `DELETE /room_keys/keys/${roomId}/${sessionId}?version=$v` From 017b448660edbc27f012e6d0501e0d3edf2d702b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 26 Oct 2018 14:20:21 -0600 Subject: [PATCH 0011/1250] Proposal to add ?via to matrix.to permalinks --- proposals/1704-matrix.to-permalinks.md | 36 ++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 proposals/1704-matrix.to-permalinks.md diff --git a/proposals/1704-matrix.to-permalinks.md b/proposals/1704-matrix.to-permalinks.md new file mode 100644 index 00000000..1430565c --- /dev/null +++ b/proposals/1704-matrix.to-permalinks.md @@ -0,0 +1,36 @@ +# matrix.to permalink navigation + +Currently Matrix uses matrix.to URIs to reference rooms and other entities in a +permanent manner. With just a room ID, users can't get into rooms if their server +is not already aware of the room. This makes permalinks to rooms or events difficult +as the user won't actually be able to join. A matrix.to link generated using a +room's alias is not a permanent link due to aliases being transferable. + +In lieu of an improved way to reference entities permanently in Matrix, a new parameter +is to be added to matrix.to URIs to assist clients and servers receiving permanent links +in joining the room. + +For reference, existing permalinks look like this: + +``` +https://matrix.to/#/!somewhere:example.org +https://matrix.to/#/!somewhere:example.org/$something:example.org +``` + +By adding a new parameter to the end, receivers can more easily join the room: + +``` +https://matrix.to/#/!somewhere:example.org?via=example-1.org&via=example-2.org +https://matrix.to/#/!somewhere:example.org/$something:example.org?via=example-1.org&via=example-2.org +``` + +Clients can pass the servers directly to `/join` in the form of `server_name` +parameters. + +When generating the permalinks, clients should pick servers that have a reasonably +high chance of being in the room in the distant future. The current recommendation +is to pick up to 3 unique servers where the first one is that of the user with the +highest power level in the room, provided that power level is 50 or higher. The other +2 servers should be the most popular servers in the room based on the number of joined +users. This same heuristic should apply to the first server if no user meets the power +level requirements. From 7b4b4a26886dec39be17816cf4d7ea3c85544ba9 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 30 Oct 2018 00:10:05 -0400 Subject: [PATCH 0012/1250] fix some English and some minor additions --- .../1219-storing-megolm-keys-serverside.md | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 9936a6cd..800b3814 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -56,6 +56,9 @@ trust that the backup was not created by a malicious device. ### Possible UX for interactive clients +This section gives an example of how a client might handle key backups. Clients +may behave differently. + On receipt of encryption keys (1st time): 1. client checks if there is an existing backup: `GET /room_keys/version` @@ -63,7 +66,7 @@ On receipt of encryption keys (1st time): 1. if yes: 1. generate new curve25519 key pair 2. create new backup version: `POST /room_keys/version` - 3. display private key to user to save (see below for the format) + 3. display private key for user to save (see below for the format) 2. if no, exit and remember decision (user can change their mind later) 3. while prompting, continue to poll `GET /room_keys/versions`, as another device may have created a backup. If so, go to 1.2. @@ -99,10 +102,10 @@ settings. ### Recovery key -The recovery key is can either be saved by the user directly, or stored -encrypted on the server (as proposed in +The recovery key can either be saved by the user directly, or stored encrypted +on the server (as proposed in [MSC1687](https://github.com/matrix-org/matrix-doc/issues/1687)). If the key -is saved directly by the user, then it the code is constructed as follows: +is saved directly by the user, then the code is constructed as follows: 1. The 256-bit curve25519 private key is prepended by the bytes `0x8B` and `0x01` @@ -112,7 +115,8 @@ is saved directly by the user, then it the code is constructed as follows: for Bitcoin addresses. This 58-character string is presented to the user to save. Implementations may -add whitespace to the recovery key. +add whitespace to the recovery key; adding a space every 4th character is +recommended. When reading in a recovery key, clients must disregard whitespace. Clients must base58-decode the code, ensure that the first two bytes of the decoded @@ -193,9 +197,9 @@ Body parameters: in the session that the key can decrypt. - `forwarded_count` (integer): Required. The number of times this key has been forwarded. -- `is_verified` (boolean): Whether the device backing up the key has verified - the device that the key is from. -- `session_data` (object): Algorithm-dependent data. For +- `is_verified` (boolean): Required. Whether the device backing up the key has + verified the device that the key is from. +- `session_data` (object): Required. Algorithm-dependent data. For `m.megolm_backup.v1.curve25519-aes-sha2`, see below for the definition of this property. From 982abc168a47ef6227e64a45f3af6e6489d11c86 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 30 Oct 2018 00:12:26 -0400 Subject: [PATCH 0013/1250] add some examples --- .../1219-storing-megolm-keys-serverside.md | 81 ++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 800b3814..6fb5c905 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -210,6 +210,28 @@ Error codes: - `M_WRONG_ROOM_KEYS_VERSION`: the version specified does not match the current backup version +Example: + +`PUT /room_keys/keys/!room_id:example.com/sessionid?version=1` + +```javascript +{ + "first_message_index": 1, + "forwarded_count": 0, + "is_verified": true, + "session_data": { + "ephemeral": "base64+ephemeral+key", + "ciphertext": "base64+ciphertext+of+JSON+data", + "mac": "base64+mac+of+ciphertext" + } +} +``` + +Result: + +```javascript +{} +``` ##### `PUT /room_keys/keys/${roomId}?version=$v` Store several keys for the given room, using the given backup version. @@ -223,8 +245,34 @@ Body parameters: /room_keys/keys/${roomId}/${sessionId}?version=$v`. Returns the same as `PUT -/room_keys/keys/${roomId}/${sessionId}?version=$v` +/room_keys/keys/${roomId}/${sessionId}?version=$v`. + +Example: + +`PUT /room_keys/keys/!room_id:example.com?version=1` +```javascript +{ + "sessions": { + "sessionid": { + "first_message_index": 1, + "forwarded_count": 0, + "is_verified": true, + "session_data": { + "ephemeral": "base64+ephemeral+key", + "ciphertext": "base64+ciphertext+of+JSON+data", + "mac": "base64+mac+of+ciphertext" + } + } + } +} +``` + +Result: + +```javascript +{} +``` ##### `PUT /room_keys/keys?version=$v` Store several keys, using the given backup version. @@ -240,6 +288,37 @@ Body parameters: Returns the same as `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v` +Example: + +`PUT /room_keys/keys/!room_id:example.com?version=1` + +```javascript +{ + "rooms": { + "!room_id:example.com": { + "sessions": { + "sessionid": { + "first_message_index": 1, + "forwarded_count": 0, + "is_verified": true, + "session_data": { + "ephemeral": "base64+ephemeral+key", + "ciphertext": "base64+ciphertext+of+JSON+data", + "mac": "base64+mac+of+ciphertext" + } + } + } + } + } +} +``` + +Result: + +```javascript +{} +``` + #### Retrieving keys When retrieving keys, the `version` parameter is optional, and defaults to From 7713a0f402667b3e73efc1edcfac22537de64c5d Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 30 Oct 2018 10:05:27 -0400 Subject: [PATCH 0014/1250] snake-case for consistency --- proposals/1219-storing-megolm-keys-serverside.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 6fb5c905..194d50d1 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -398,8 +398,8 @@ The `session_data` field in the backups is constructed as follows: - `sender_key` (string): base64-encoded device curve25519 key - `sender_claimed_keys` (object): object containing the identity keys for the sending device - - `forwardingCurve25519KeyChain` (array): zero or more curve25519 keys for - devices who forwarded the session key + - `forwarding_curve25519_key_chain` (array): zero or more curve25519 keys + for devices who forwarded the session key - `session_key` (string): base64-encoded (unpadded) session key 2. Generate an ephemeral curve25519 key, and perform an ECDH with the ephemeral key and the backup's public key to generate a shared secret. The public From 3918ed3c38389ee3058742412fb17e9ef354773a Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 30 Oct 2018 14:09:40 -0400 Subject: [PATCH 0015/1250] distinguish between retrieving an empty backup and a nonexistent backup --- .../1219-storing-megolm-keys-serverside.md | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 194d50d1..18f6f877 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -333,7 +333,8 @@ On success, returns a JSON object in the same form as the request body of `PUT Error codes: -- M_NOT_FOUND: The session is not present in the backup. +- M_NOT_FOUND: The session is not present in the backup, or the requested + backup version does not exist. ##### `GET /room_keys/keys/${roomId}?version=$v` @@ -342,8 +343,8 @@ Retrieve the all the keys for the given room from the backup. On success, returns a JSON object in the same form as the request body of `PUT /room_keys/keys/${roomId}?version=$v`. -If no keys are found, then this endpoint returns a successful response with -body: +If the backup version exists but no keys are found, then this endpoint returns +a successful response with body: ``` { @@ -351,6 +352,10 @@ body: } ``` +Error codes: + +- `M_NOT_FOUND`: The requested backup version does not exist. + ##### `GET /room_keys/keys?version=$v` Retrieve all the keys from the backup. @@ -358,9 +363,8 @@ Retrieve all the keys from the backup. On success, returns a JSON object in the same form as the request body of `PUT /room_keys/keys?version=$v`. - -If no keys are found, then this endpoint returns a successful response with -body: +If the backup version exists but no keys are found, then this endpoint returns +a successful response with body: ``` { @@ -368,6 +372,10 @@ body: } ``` +Error codes: + +- `M_NOT_FOUND`: The requested backup version does not exist. + #### Deleting keys ##### `DELETE /room_keys/keys/${roomId}/${sessionId}?version=$v` From 87330b9b9b01dc089a8781d9775e9252c207b4cb Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 5 Nov 2018 18:23:23 +0000 Subject: [PATCH 0016/1250] Proposal for .well-known for server discovery --- proposals/1708-well-known-for-federation.md | 126 ++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 proposals/1708-well-known-for-federation.md diff --git a/proposals/1708-well-known-for-federation.md b/proposals/1708-well-known-for-federation.md new file mode 100644 index 00000000..2b8a3711 --- /dev/null +++ b/proposals/1708-well-known-for-federation.md @@ -0,0 +1,126 @@ +# .well-known support for server name resolution + +Currently, mapping from a server name to a hostname for federation is done via +`SRV` records. This presents two principal difficulties: + + * SRV records are not widely used, and administrators may be unfamiliar with + them, and there may be other practical difficulties in their deployment such + as poor support from hosting providers. [^1] + + * It is likely that we will soon require valid X.509 certificates on the + federation endpoint. It will then be necessary for the homeserver to present + a certificate which is valid for the server name. This presents difficulties + for hosted server offerings: BigCorp may be reluctant to hand over the + keys for `bigcorp.com` to the administrators of the `bigcorp.com` matrix + homeserver. + +Here we propose to solve these problems by augmenting the current `SRV` record +with a `.well-known` lookup. + +## Proposal + +For reference, the current [specification for resolving server +names](https://matrix.org/docs/spec/server_server/unstable.html#resolving-server-names) +is as follows: + +* If the hostname is an IP literal, then that IP address should be used, + together with the given port number, or 8448 if no port is given. + +* Otherwise, if the port is present, then an IP address is discovered by + looking up an AAAA or A record for the hostname, and the specified port is + used. + +* If the hostname is not an IP literal and no port is given, the server is + discovered by first looking up a `_matrix._tcp` SRV record for the + hostname, which may give a hostname (to be looked up using AAAA or A queries) + and port. If the SRV record does not exist, then the server is discovered by + looking up an AAAA or A record on the hostname and taking the default + fallback port number of 8448. + + Homeservers may use SRV records to load balance requests between multiple TLS + endpoints or to failover to another endpoint if an endpoint fails. + +The first two points remain unchanged: if the server name is an IP literal, or +contains a port, then requests will be made directly as before. + +If the hostname is neither an IP literal, nor does it have an explicit port, +then the requesting server should continue to make an SRV lookup as before, and +use the result if one is found. + +If *no* result is found, the requesting server should make a `GET` request to +`https://\/.well-known/matrix/server`, with normal X.509 +certificate validation. If the request fails in any way, then we fall back as +before to using using port 8448 on the hostname. + +Rationale: Falling back to port 8448 (rather than aborting the request) is +necessary to maintain compatibility with existing deployments, which may not +present valid certificates on port 443, or may return 4xx or 5xx errors. + +If the GET request succeeds, it should result in a JSON response, with contents +structured as shown: + +```json +{ + "server": "[:]" +} +``` + +The `server` property has the same format as a [server +name](https://matrix.org/docs/spec/appendices.html#server-name): a hostname +followed by an optional port. + +If the response cannot be parsed as JSON, or lacks a valid `server` property, +the request is considered to have failed, and no fallback to port 8448 takes +place. + +Otherwise, the requesting server performs an `AAAA/A` lookup on the hostname, +and connects to the resultant address and the specifed port. The port defaults +to 8448, if unspecified. + +### Caching + +Servers should not look up the `.well-known` file for every request, as this +would impose an unacceptable overhead on both sides. Instead, the results of +the `.well-known` request should be cached according to the HTTP response +headers, as per [RFC7234](https://tools.ietf.org/html/rfc7234). If the response +does not include an explicit expiry time, the requesting server should use a +sensible default: 24 hours is suggested. + +Because there is no way to request a revalidation, it is also recommended that +requesting servers cap the expiry time. 48 hours is suggested. + +Similarly, a failure to retrieve the `.well-known` file should be cached for +a reasonable period. 24 hours is suggested again. + +### The future of SRV records + +It's worth noting that this proposal is very clear in that we will maintain +support for SRV records for the immediate future; there are no current plans to +deprecate them. + +However, clearly a `.well-known` file can provide much of the functionality of +an SRV record, and having to support both may be undesirable. Accordingly, we +may consider sunsetting SRV record support at some point in the future. + +### Outstanding questions + +Should we follow 30x redirects for the .well-known file? On the one hand, there +is no obvious usecase and they add complexity (for example: how do they +interact with caches?). On the other hand, we'll presumably be using an HTTP +client library to handle some of the caching stuff, and they might be useful +for something? + +## Security considerations + +The `.well-known` file potentially broadens the attack surface for an attacker +wishing to intercept federation traffic to a particular server. + +## Conclusion + +This proposal adds a new mechanism, alongside the existing `SRV` record lookup +for finding the server responsible for a particular matrix server_name, which +will allow greater flexibility in deploying homeservers. + + +[^1] For example, Cloudflare automatically "flattens" SRV record responses. + From e3f10a4fd2049bcd71f4e77fe4192946498059f2 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Mon, 5 Nov 2018 18:37:25 +0000 Subject: [PATCH 0017/1250] Update 1708-well-known-for-federation.md fix title --- proposals/1708-well-known-for-federation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1708-well-known-for-federation.md b/proposals/1708-well-known-for-federation.md index 2b8a3711..beec384f 100644 --- a/proposals/1708-well-known-for-federation.md +++ b/proposals/1708-well-known-for-federation.md @@ -1,4 +1,4 @@ -# .well-known support for server name resolution +# MSC1708: .well-known support for server name resolution Currently, mapping from a server name to a hostname for federation is done via `SRV` records. This presents two principal difficulties: From c4e1949cf8f81b137d9fedebb4d5bf2c5116b112 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 6 Nov 2018 11:38:23 +0000 Subject: [PATCH 0018/1250] Clarifications about what `server` means --- proposals/1708-well-known-for-federation.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/proposals/1708-well-known-for-federation.md b/proposals/1708-well-known-for-federation.md index beec384f..8854eb9f 100644 --- a/proposals/1708-well-known-for-federation.md +++ b/proposals/1708-well-known-for-federation.md @@ -47,8 +47,8 @@ If the hostname is neither an IP literal, nor does it have an explicit port, then the requesting server should continue to make an SRV lookup as before, and use the result if one is found. -If *no* result is found, the requesting server should make a `GET` request to -`https://\/.well-known/matrix/server`, with normal X.509 +If *no* SRV result is found, the requesting server should make a `GET` request +to `https://\/.well-known/matrix/server`, with normal X.509 certificate validation. If the request fails in any way, then we fall back as before to using using port 8448 on the hostname. @@ -65,17 +65,19 @@ structured as shown: } ``` -The `server` property has the same format as a [server -name](https://matrix.org/docs/spec/appendices.html#server-name): a hostname -followed by an optional port. +The `server` property should be a hostname or IP address, followed by an +optional port. If the response cannot be parsed as JSON, or lacks a valid `server` property, the request is considered to have failed, and no fallback to port 8448 takes place. -Otherwise, the requesting server performs an `AAAA/A` lookup on the hostname, -and connects to the resultant address and the specifed port. The port defaults -to 8448, if unspecified. +Otherwise, the requesting server performs an `AAAA/A` lookup on the hostname +(if necessary), and connects to the resultant address and the specifed +port. The port defaults to 8448, if unspecified. + +(The formal grammar for the `server` property is identical to that of a [server +name](https://matrix.org/docs/spec/appendices.html#server-name).) ### Caching From 09d41464e7b3d03eb07fe066b4fae4153f79b3c2 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 6 Nov 2018 11:38:46 +0000 Subject: [PATCH 0019/1250] Add problems section xs --- proposals/1708-well-known-for-federation.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/proposals/1708-well-known-for-federation.md b/proposals/1708-well-known-for-federation.md index 8854eb9f..21365be1 100644 --- a/proposals/1708-well-known-for-federation.md +++ b/proposals/1708-well-known-for-federation.md @@ -112,6 +112,21 @@ interact with caches?). On the other hand, we'll presumably be using an HTTP client library to handle some of the caching stuff, and they might be useful for something? +## Problems + +It will take a while for `.well-known` to be supported across the ecosystem; +until it is, it will be difficult to deploy homeservers which rely on it for +their routing: if Alice is using a current homeserver implementation, and Bob +deploys a new implementation which relies on `.well-known` for routing, then +Alice will be unable to send messages to Bob. (This is the same problem we have with +[SNI](https://github.com/matrix-org/synapse/issues/1491#issuecomment-415153428).) + +The main defence against this seems to be to release support for `.well-known` +as soom as possible, to maximise uptake in the ecosystem. It is likely that, as +we approach Matrix 1.0, there will be sufficient other new features (such as +new Room versions) that upgading will be necessary anyway. + + ## Security considerations The `.well-known` file potentially broadens the attack surface for an attacker From f30e6851127874739659ffe2b2c211c4db6e50f0 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 7 Nov 2018 13:41:53 +0000 Subject: [PATCH 0020/1250] proposal for requiring signed certs for federation --- proposals/1711-x509-for-federation.md | 238 ++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 proposals/1711-x509-for-federation.md diff --git a/proposals/1711-x509-for-federation.md b/proposals/1711-x509-for-federation.md new file mode 100644 index 00000000..9c20eab9 --- /dev/null +++ b/proposals/1711-x509-for-federation.md @@ -0,0 +1,238 @@ +# MSC1711: X.509 certificate verification for federation connections + +TLS connections for server-to-server communication currently rely on an +approach borrowed from the [Perspectives +project](https://web.archive.org/web/20170702024706/https://perspectives-project.org/) +to provide certificate verification, rather than the more normal model using +certificates signed by trusted Certificate Authorities. This document sets out +the reasons that this has not been a success, and suggests that we should +instead revert to the CA model. + +## Background: the failure of the Perspectives approach + +The Perspectives approach replaces the conventional heirarchy of trust provided +by the Certificate Authority model with a large number of "notary" servers +distributed around the world. The intention is that the notary servers +regularly monitor remote servers and observe the certificates they present; +when making a connection to a new site, a client can correlate the certificate +it presents with that seen by the notary servers. In theory this makes it very +hard to mount a Man-in-the-Middle (MitM) attack, because it would require +intercepting traffic between the target server and a large number of the notary +servers. + +It is notable that the Perspectives project itself appears to have largely been +abandoned: its website has largely been repurposed, the [Firefox +extension](https://addons.mozilla.org/en-GB/firefox/addon/perspectives/) does +not work with modern versions of Firefox, the [mailing +list](https://groups.google.com/forum/#!forum/perspectives-dev) is inactive, +and several of the (ten) published notary servers are no longer functional. The +reasons for this are not entirely clear, though clearly it never gained +widespread adoption. + +When Matrix was originally designed in 2014, the Perspectives project was +heavily active, and avoiding dependencies on the relatively centralised +Certificate Authorities was attractive, in accordance with Matrix's design as a +decentralised protocol. However, this has not been a success in practice. + +Matrix was unable to make use of the existing notary servers (largely because +we wanted to extend the protocol to include signing keys): the intention was +that, as the Matrix ecosystem grew, public Matrix servers would act as notary +servers. However, in practice we have ended up in a situation where almost [1](#f1) every Matrix homeserver either uses `matrix.org` as the +sole notary, or does no certificate verification at all. Far from avoiding the +centralisation of the Certificate Authorities, the entire protocol is therefore +dependent on a single point of control at `matrix.org` - and because +`matrix.org` only monitors from a single location, the protection against MitM +attacks is weak. + +It is also clear that the Perspectives approach is poorly-understood. It is a +common error for homeservers to be deployed behind reverse-proxies which make +the Perspectives-based approach unreliable. The CA model, for all its flaws, is +at least commonly used, which makes it easier for administrators to deploy +(secure) homeservers, and allows server implementations to leverage existing +libraries. + +## Proposal + +We propose that Matrix homeservers should be required to present valid TLS +certificates, signed by a known Certificate Authority, on their federation +port. + +In order to ease transition, we could continue to follow the current, +perspectives-based approach for servers whose TLS certificates fail +validation. However, this should be strictly time-limited (for three months, +say), to give administrators time to switch to a signed certificate. The +`matrix.org` team would proactively attempt to reach out to homeserver +administrators who do not update their certificate. + +Once the transition to CA-signed certificates is complete, the +`tls_fingerprints` property of the +[`/_matrix/key/v2`](https://matrix.org/docs/spec/server_server/unstable.html#retrieving-server-keys) +endpoints would be redundant and we should consider removing it. + +The process of determining which CAs are trusted to sign certificates would be +implementation-specific, though it should almost certainly make use of existing +operating-system support for maintaining such lists. It might also be useful if +administrators could override this list, for the purpose of setting up a +private federation using their own CA. + +### Interaction with SRV records + +With the use of `SRV` records, it is possible for the hostname of a homeserver +to be quite different from the matrix domain it is hosting. For example, if +there were an SRV record at `_matrix._tcp.matrix.org` which pointed to +`server.example.com`, then any federation requests for `matrix.org` would be +routed to `server.example.com`. The question arises as to which certificate +`server.example.com` should present. + +In short: the server should present a certificate for the matrix domain +(`matrix.org` in the above example). This ensures that traffic cannot be +intercepted by a MitM who can control the DNS response for the `SRV` record +(perhaps via cache-poisoning or falsifying DNS responses). + +This will be in line with the current +[requirements](https://matrix.org/docs/spec/server_server/unstable.html#resolving-server-names) +in the Federation API specification for the `Host`, and by implication, the TLS +Server Name Indication [2](#f2). + +### Interaction with `.well-known` files + +[MSC1708](https://github.com/matrix-org/matrix-doc/blob/rav/proposal/well-known-for-federation/proposals/1708-well-known-for-federation.md) +proposes an alternative to SRV records, in the form of `.well-known` files. In +this instance, a file at `https://matrix.org/.well-known/matrix/server` might +direct requests to `server.example.com`. + +In this case, `server.example.com` would be required to present a valid +certificate for `server.example.com`. + +Because the request for the `.well-known` file takes place over a validated TLS +connection, this is not subject to the same DNS-based attacks as the SRV +record, and this mechanism allows the owners of a domain to delegate +responsibility for running their Matrix homeserver without having to hand over +TLS keys for the whole domain. + +### Extensions + +HTTP-Based Public Key Pinning (HPKP) and +[https://www.certificate-transparency.org](Certificate transparency) are +both HTTP extensions which attempt to work around some of the deficiencies in +the CA model, by making it more obvious if a CA has issued a certificate +incorrectly. + +HPKP has not been particularly successful, and is +[deprecated]((https://developers.google.com/web/updates/2018/04/chrome-67-deps-rems#deprecate_http-based_public_key_pinning) +in Google Chrome as of April 2018. Certificate transparency, however, is seeing +widespread adoption from Certificate Authories and HTTP clients. + +This proposal sees both technologies as optional techniques which could be +provided by homeserver implementations. We encourage but do not mandate the use +of Certificate Transparency. + +### Related work + +The Perspectives approach is also currently used for exchanging the keys that +are used by homeservers to sign Matrix events and federation requests (the +"signing keys"). Problems similar to those covered here also apply to that +mechanism. A future MSC will propose improvements in that area. + +## Tradeoffs + +There are well-known problems with the CA model, including a number of +widely-published incidents in which CAs have issued certificates +incorrectly. It is therefore important to consider alternatives to the CA +model. + +### Improving support for the Perspectives model + +In principle, we could double-down on the Perspectives approach, and make an effort +to get servers other than `matrix.org` used as notary servers. However, there +remain significant problems with such an approach: + +* Perspectives remain complex to configure correctly. Ideally, administrators + need to make conscious choices about which notaries to trust, which is hard + to do, especially for newcomers to the ecosystem. (In practice, people use + the out-of-the-box configuration, which is why everyone just uses + `matrix.org` today). + +* A *correct* implementation of Perspectives really needs to take into account + more than the latest state seen by the notary servers: some level of history + should be taken into account too. + +Essentially, whilst we still believe the Perspectives approach has some merit, +we believe it needs further research before it can be relied upon. We believe +that the resources of the Matrix ecosystem are better spent elsewhere. + +### DANE + +DNS-Based Authentication of Named Entities (DANE) can be used as an alternative +to the CA model. (It is arguably more appropriately used *together* with the CA +model.) + +It is not obvious to the author of this proposal that DANE provides any +material advantages over the CA model. In particular it replaces the +centralised trust of the CAs with the centralised trust of the DNS registries. + +## Potential issues + +Beyond the problems already discussed with the CA model, requiring signed +certificates comes with a number of downsides. + +### More difficult setup + +Configuring a working, federating homeserver is a process fraught with +pitfalls. This proposal adds the requirement to obtain a signed certificate to +that process. Even with modern intiatives such as Let's Encrypt, this is +another procedure requiring manual intervention across several moving parts[3](#f3). + +On the other hand: obtaining an SSL certificate should be a familiar process to +anybody capable of hosting a production homeserver (indeed, they should +probably already have one for the client port). This change also opens the +possibility of putting the federation port behind a reverse-proxy without the +need for additional configuration. Hopefully making the certificate usage more +conventional will offset the overhead of setting up a certificate. + +### Inferior support for IP literals + +Whilst it is possible to obtain an SSL cert which is valid for a literal IP +address, this typically requires purchase of a premium certificate; in +particular, Let's Encrypt will not issue certificates for IP literals. This may +make it impractical to run a homeserver which uses an IP literal, rather than a +DNS name, as its `server_name`. + +It has long been the view of the `matrix.org` administrators that IP literals +are only really suitable for internal testing. Those who wish to use them for +that purpose could either disable certificate checks inside their network, or +use their own CA to issue certificates. + +### Inferior support for hidden services (`.onion` addresses) + +It is currently possible to correctly route traffic to a homeserver on a +`.onion` domain, provided any remote servers which may need to reach that +server are configured to route to such addresses via the Tor network. However, +it can be difficult to get a certificate for a `.onion` domain (again, Let's +Encrypt do not support them). + +The reasons for requiring a signed certificate (or indeed, for using TLS at +all) are weakened when traffic is routed via the Tor network. It may be +reasonable to relax the requirement for a signed certificate for such traffic. + +## Conclusion + +We believe that requiring homservers to present an X.509 certificate signed by +a recognised Certificate Authority will improve security, reduce +centralisation, and eliminate some common deployment pitfalls. + +[1] It's *possible* to set up homeservers to use servers other than +`matrix.org` as notaries, but we are not aware of any that are set up this +way. [↩](#a1) + +[2] I've not been able to find an authoritative source on this, but +most reverse-proxies will reject requests where the SNI and Host headers do not +match. [↩](#a2) + +[3] Let's Encrypt will issue ACME challenges via port 80 or DNS +(for the `http-01` or `dns-01` challenge types respectively). It is unlikely +that a homeserver implementation would be able to control either port 80 or DNS +responses, so we will be unable to automate a Let's Encrypt certificate +request. [↩](#a3) From efc8056fb62ccb7501efae146abb646914f69b1d Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 7 Nov 2018 13:48:27 +0000 Subject: [PATCH 0021/1250] fix a couple of broken links --- proposals/1711-x509-for-federation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1711-x509-for-federation.md b/proposals/1711-x509-for-federation.md index 9c20eab9..a31ae482 100644 --- a/proposals/1711-x509-for-federation.md +++ b/proposals/1711-x509-for-federation.md @@ -114,13 +114,13 @@ TLS keys for the whole domain. ### Extensions HTTP-Based Public Key Pinning (HPKP) and -[https://www.certificate-transparency.org](Certificate transparency) are +[Certificate transparency](https://www.certificate-transparency.org) are both HTTP extensions which attempt to work around some of the deficiencies in the CA model, by making it more obvious if a CA has issued a certificate incorrectly. HPKP has not been particularly successful, and is -[deprecated]((https://developers.google.com/web/updates/2018/04/chrome-67-deps-rems#deprecate_http-based_public_key_pinning) +[deprecated](https://developers.google.com/web/updates/2018/04/chrome-67-deps-rems#deprecate_http-based_public_key_pinning) in Google Chrome as of April 2018. Certificate transparency, however, is seeing widespread adoption from Certificate Authories and HTTP clients. From f9cf99f1fd6c1b0cbdf77e86b6a4e532c13adb2a Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Thu, 8 Nov 2018 15:31:58 +0000 Subject: [PATCH 0022/1250] typo --- proposals/1711-x509-for-federation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1711-x509-for-federation.md b/proposals/1711-x509-for-federation.md index a31ae482..d30fe566 100644 --- a/proposals/1711-x509-for-federation.md +++ b/proposals/1711-x509-for-federation.md @@ -219,7 +219,7 @@ reasonable to relax the requirement for a signed certificate for such traffic. ## Conclusion -We believe that requiring homservers to present an X.509 certificate signed by +We believe that requiring homeservers to present an X.509 certificate signed by a recognised Certificate Authority will improve security, reduce centralisation, and eliminate some common deployment pitfalls. From bc290155145d9e8d4721dbae111d0d13f83cd01a Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Thu, 8 Nov 2018 16:28:13 +0000 Subject: [PATCH 0023/1250] fix typo --- proposals/1711-x509-for-federation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1711-x509-for-federation.md b/proposals/1711-x509-for-federation.md index d30fe566..52662123 100644 --- a/proposals/1711-x509-for-federation.md +++ b/proposals/1711-x509-for-federation.md @@ -10,7 +10,7 @@ instead revert to the CA model. ## Background: the failure of the Perspectives approach -The Perspectives approach replaces the conventional heirarchy of trust provided +The Perspectives approach replaces the conventional hierarchy of trust provided by the Certificate Authority model with a large number of "notary" servers distributed around the world. The intention is that the notary servers regularly monitor remote servers and observe the certificates they present; From b1e79ac7ab37302c2c90f2f031a8c6f8d4d2d34b Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 9 Nov 2018 11:22:22 +0000 Subject: [PATCH 0024/1250] Update 1708-well-known-for-federation.md --- proposals/1708-well-known-for-federation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1708-well-known-for-federation.md b/proposals/1708-well-known-for-federation.md index 21365be1..bd2f32b8 100644 --- a/proposals/1708-well-known-for-federation.md +++ b/proposals/1708-well-known-for-federation.md @@ -122,9 +122,9 @@ Alice will be unable to send messages to Bob. (This is the same problem we have [SNI](https://github.com/matrix-org/synapse/issues/1491#issuecomment-415153428).) The main defence against this seems to be to release support for `.well-known` -as soom as possible, to maximise uptake in the ecosystem. It is likely that, as +as soon as possible, to maximise uptake in the ecosystem. It is likely that, as we approach Matrix 1.0, there will be sufficient other new features (such as -new Room versions) that upgading will be necessary anyway. +new Room versions) that upgrading will be necessary anyway. ## Security considerations From e789eb186a8f12fe2517d1b30c8e38989d3c3b5f Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 12 Nov 2018 14:02:44 +0000 Subject: [PATCH 0025/1250] link to MSC1711 --- proposals/1708-well-known-for-federation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1708-well-known-for-federation.md b/proposals/1708-well-known-for-federation.md index bd2f32b8..8fa66c7a 100644 --- a/proposals/1708-well-known-for-federation.md +++ b/proposals/1708-well-known-for-federation.md @@ -7,7 +7,8 @@ Currently, mapping from a server name to a hostname for federation is done via them, and there may be other practical difficulties in their deployment such as poor support from hosting providers. [^1] - * It is likely that we will soon require valid X.509 certificates on the + * [MSC1711](https://github.com/matrix-org/matrix-doc/pull/1711) proposes + requiring valid X.509 certificates on the federation endpoint. It will then be necessary for the homeserver to present a certificate which is valid for the server name. This presents difficulties for hosted server offerings: BigCorp may be reluctant to hand over the @@ -140,4 +141,3 @@ will allow greater flexibility in deploying homeservers. [^1] For example, Cloudflare automatically "flattens" SRV record responses. - From 8521c2d6963e878c60a91ffa5ab3d03c245e1cfa Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 13 Nov 2018 11:31:41 -0500 Subject: [PATCH 0026/1250] initial proposal for key verification methods --- proposals/xxxx-key_verification.md | 126 +++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 proposals/xxxx-key_verification.md diff --git a/proposals/xxxx-key_verification.md b/proposals/xxxx-key_verification.md new file mode 100644 index 00000000..b71fcf34 --- /dev/null +++ b/proposals/xxxx-key_verification.md @@ -0,0 +1,126 @@ +# Key verification mechanisms + +Key verification is an essential part of ensuring that end-to-end encrypted +messages are secure. Matrix may support multiple verification methods that +require sending events; in fact, two such methods have already been proposed. + +This proposal tries to present a common framework for verification methods to +use, and presents a way to request key verification. + +## Proposal + +Each key verification method is identified by a name. Verification method +names defined in the Matrix spec will begin with `m.`, and verification method +names that are not defined in the Matrix spec must be namespaced following the +Java package naming convention. + +If Alice wants to verify keys with Bob, Alice's device may send `to_device` +events to Bob's devices with the `type` set to `m.key.verification.request`, as +described below. The event lists the verification methods that Alice's device +supports. Upon receipt of this message, Bob's client should prompt him to +verify keys with Alice using one of the applicable methods. In order to avoid +displaying stale key verification prompts, if Bob does not interact with the +prompt, it should be automatically hidden 10 minutes after the message is sent +(according to the `timestamp` field), or 2 minutes after the client receives +the message, whichever comes first. The prompt should also be hidden if an +appropriate `m.key.verification.cancel` message is received. If Bob chooses to +reject the key verification request, Bob's client should send a +`m.key.verification.cancel` message to Alice's device. If Bob's client does +not understand any of the methods offered, it should display a message to Bob +saying so. + +To initiate a key verification process, Bob's device sends a `to_device` event +to one of Alice's devices with the `type` set to `m.key.verification.start`. +This may either be done in response to an `m.key.verification.request` message, +or can be done independently. If Alice's device receives an +`m.key.verification.start` message in response to an +`m.key.verification.request` message, it should send an +`m.key.verification.cancel` message to Bob's other devices that it had +originally sent an `m.key.verification.request` to, in order to cancel the key +verification request. + +Verification methods can define other events required to complete the +verification. Event types for verification methods defined in the Matrix spec +should be in the `m.key.verification` namespace. Event types that are not +defined in the Matrix spec must be namespaced following the Java package naming +convention. + +Alice's or Bob's devices can cancel a key verification process or a key +verification request by sending a `to_device` event with `type` set to +`m.key.verification.cancel`. + +### Event Definitions + +#### `m.key.verification.request` + +Requests a key verification. + +Properties: + +- `from_device` (string): the device ID of the device requesting verification. +- `transaction_id` (string): an identifier for the verification request. Must + be unique with respect to the pair of devices. +- `methods` ([string]): the verification methods supported by the sender. +- `timestamp` (integer): the time when the request was made. If the timestamp + is in the future (by more than 5 minutes, to allow for clock skew), or more + than 10 minutes in the past, then the message must be ignored. + +#### `m.key.verification.start` + +Begins a key verification process. + +Properties: + +- `method` (string): the verification method to use. +- `from_device` (string): The device ID of the device starting the verification + process. +- `transaction_id` (string): an identifier for the verification process. If + this message is sent in reponse to an `m.key.verification.request` event, then + it must use the same `transaction_id` as the one given in the + `m.key.verification.request`. + +Key verification methods can define additional properties to be included. + +#### `m.key.verification.cancel` + +Cancels a key verification process or a key verification request. Upon +receiving an `m.key.verification.cancel` message, the receiving device must +cancel the verification or the request. If it is a verification process that +is cancelled, or a verification request initiated by the recipient of the +cancellation message, the device should inform the user of the reason. + +Properties: + +- `transaction_id` (string): the identifier for the request or key verification + to cancel. +- `code` (string): machine-readable reason for cancelling. Possible reasons + are: + - `m.user`: the user cancelled the verification. + - `m.timeout`: the verification process has timed out. Different verification + methods may define their own timeouts. + - `m.unknown_transaction`: the device does not know about the given transaction + ID. + - `m.unknown_method`: the device does not know how to handle the given method. + This can be sent in response to an `m.key.verification.start` message, or + can be sent in response to other verification method-specific messages. + - `m.unexpected_message`: the device received an unexpected message. For + example, a message for a verification method may have been received when it + was not expected. +- `reason` (string): human-readable reason for cancelling. This should only be + used if the recieving client does not understand the code given. + +Verification methods may define their own additional cancellation codes. +Cancellation codes defined in the Matrix spec will begin with `m.`; other +cancellation codes must be namespaced following the Java package naming +convention. + +## Tradeoffs + +## Potential issues + +## Security considerations + +## Conclusion + +This proposal presents common event definitions for use by key verification +methods and defines a way for users to request key verification. From ec2e02e8b5479b4734b0d8a6ed5aa8953f495a67 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 13 Nov 2018 11:45:18 -0500 Subject: [PATCH 0027/1250] rename to match MSC number --- proposals/{xxxx-key_verification.md => 1717-key_verification.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/{xxxx-key_verification.md => 1717-key_verification.md} (100%) diff --git a/proposals/xxxx-key_verification.md b/proposals/1717-key_verification.md similarity index 100% rename from proposals/xxxx-key_verification.md rename to proposals/1717-key_verification.md From 2dce23564ff640f1e9e71235126db0aca7b2adef Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 13 Nov 2018 21:37:50 -0500 Subject: [PATCH 0028/1250] wording fixes --- proposals/1219-storing-megolm-keys-serverside.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 18f6f877..527dfe8f 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -4,7 +4,7 @@ Storing megolm keys serverside Background ---------- -A user who uses end-to-end encyrption will usually have many inbound session +A user who uses end-to-end encyrption will usually have many inbound group session keys. Users who log into new devices and want to read old messages will need a convenient way to transfer the session keys from one device to another. While users can currently export their keys from one device and import them to @@ -102,10 +102,10 @@ settings. ### Recovery key -The recovery key can either be saved by the user directly, or stored encrypted -on the server (as proposed in -[MSC1687](https://github.com/matrix-org/matrix-doc/issues/1687)). If the key -is saved directly by the user, then the code is constructed as follows: +The recovery key can be saved by the user directly, stored encrypted on the +server (as proposed in +[MSC1687](https://github.com/matrix-org/matrix-doc/issues/1687)), or both. If +the key is saved directly by the user, then the code is constructed as follows: 1. The 256-bit curve25519 private key is prepended by the bytes `0x8B` and `0x01` From b45cf4483fd9fbd06f2f5963b31bfef4e2286fae Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 13 Nov 2018 21:46:07 -0500 Subject: [PATCH 0029/1250] providing an alternative to key sharing is currently a non-goal --- proposals/1219-storing-megolm-keys-serverside.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 527dfe8f..4d8e8f1c 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -17,10 +17,9 @@ To help resolve this, we *optionally* let clients store an encrypted copy of their megolm inbound session keys on the homeserver. Clients can keep the backup up to date, so that users will always have the keys needed to decrypt their conversations. The backup could be used not just for new logins, but -also to try to fix UISIs that occur after a device has logged in (as an -alternative to key sharing), or to support clients with limited local storage -for keys (clients can store old keys to the backup, and remove their local -copy, retrieving the key from the backup when needed). +also to support clients with limited local storage for keys (clients can store +old keys to the backup, and remove their local copy, retrieving the key from +the backup when needed). To recover keys from the backup, a user will need to enter a recovery key to decrypt the backup. The backup will be encrypted using public key From b535226d407b28709c8d126ef6852f3bb9344c10 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 13 Nov 2018 22:00:42 -0500 Subject: [PATCH 0030/1250] initial work on documenting olm unwedging --- proposals/xxxx-olm_unwedging.md | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 proposals/xxxx-olm_unwedging.md diff --git a/proposals/xxxx-olm_unwedging.md b/proposals/xxxx-olm_unwedging.md new file mode 100644 index 00000000..60f45fe1 --- /dev/null +++ b/proposals/xxxx-olm_unwedging.md @@ -0,0 +1,45 @@ +# Olm unwedging + +Olm sessions sometimes get out of sync, resulting in undecryptable messages. +This proposal documents a method for devices to create a new session to replace +the broken session. + +## Proposal + +When a device receives an olm-encrypted message that it cannot decrypt, it +should assume that the olm session has become corrupted and create a new olm +session to replace it. It should then send a dummy message, using that +session, to the other party in order to inform them of the new session. To +send a dummy message, clients may send an event with type `m.dummy`, and with +empty contents. + +If the corrupted session has already been replaced, the receiving device should +do nothing, under the assumption that the message from the corrupted session +was sent before the sender was informed of the replacement session, in order to +avoid creating too many extra sessions. + +The spec currently says, "If a client has multiple sessions established with +another device, it should use the session from which it last received a +message." (the last paragraph of the [`m.olm.v1.curve25519-aes-sha2` +section](https://matrix.org/docs/spec/client_server/r0.4.0.html#m-olm-v1-curve25519-aes-sha2)). +When comparing the time of the last received message for each session, the +client should consider only consider messages that were successfully decrypted, +and for sessions that have never received a message, it should use the creation +time of the session. The spec will be changed to read: + +> If a client has multiple sessions established with another device, it should +> use the session from which it last received and successfully decrypted a +> message. For these purposes, a session that has not received any messages +> should consider its creation time to be the time that it last received a +> message. + +## Tradeoffs + +## Potential issues + +## Security considerations + +## Conclusion + +This proposal outlines how wedged olm sessions can be replaced by a new +session. From d0bfdc13af8b4b8e5bba695c6f6bb3a2f6d7d275 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 13 Nov 2018 22:03:07 -0500 Subject: [PATCH 0031/1250] rename to match MSC number --- proposals/{xxxx-olm_unwedging.md => 1719-olm_unwedging.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/{xxxx-olm_unwedging.md => 1719-olm_unwedging.md} (100%) diff --git a/proposals/xxxx-olm_unwedging.md b/proposals/1719-olm_unwedging.md similarity index 100% rename from proposals/xxxx-olm_unwedging.md rename to proposals/1719-olm_unwedging.md From 495df02da6efb5d821fad69abb4fb66600db20b4 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 14 Nov 2018 10:19:11 -0500 Subject: [PATCH 0032/1250] we don't actually know which session got stuck, so rate-limit by device --- proposals/1719-olm_unwedging.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/proposals/1719-olm_unwedging.md b/proposals/1719-olm_unwedging.md index 60f45fe1..13c4ea4b 100644 --- a/proposals/1719-olm_unwedging.md +++ b/proposals/1719-olm_unwedging.md @@ -13,10 +13,11 @@ session, to the other party in order to inform them of the new session. To send a dummy message, clients may send an event with type `m.dummy`, and with empty contents. -If the corrupted session has already been replaced, the receiving device should -do nothing, under the assumption that the message from the corrupted session -was sent before the sender was informed of the replacement session, in order to -avoid creating too many extra sessions. +In order to avoid creating too many extra sessions, a client should rate-limit +the number of new sessions it creates per device that it receives a message +from; the client should not create a new session with another device if it has +already created one for that given device in the past 1 hour. (TODO: is 1 hour +the right amount of time?) The spec currently says, "If a client has multiple sessions established with another device, it should use the session from which it last received a From 2b5805255564bb80a63c73dd977b487c67c9007c Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 14 Nov 2018 10:28:26 -0500 Subject: [PATCH 0033/1250] add note about re-requesting megolm keys --- proposals/1719-olm_unwedging.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/proposals/1719-olm_unwedging.md b/proposals/1719-olm_unwedging.md index 13c4ea4b..e696c1e2 100644 --- a/proposals/1719-olm_unwedging.md +++ b/proposals/1719-olm_unwedging.md @@ -19,6 +19,12 @@ from; the client should not create a new session with another device if it has already created one for that given device in the past 1 hour. (TODO: is 1 hour the right amount of time?) +Clients may wish to ask the sender of the undecryptable messages to re-send the +message. For exampe, if the undecryptable message was a megolm session, then +the client can send an +[`m.room_key_request`](https://matrix.org/docs/spec/client_server/r0.4.0.html#m-room-key-request) +message to request that the sender re-send the key. + The spec currently says, "If a client has multiple sessions established with another device, it should use the session from which it last received a message." (the last paragraph of the [`m.olm.v1.curve25519-aes-sha2` From 0e156faaf1c67d1f45345f45ac837f87ca8d74ba Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 12 Dec 2018 21:43:40 +0000 Subject: [PATCH 0034/1250] MSC1753: client-server capabilities API --- proposals/1753-capabilities.md | 99 ++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 proposals/1753-capabilities.md diff --git a/proposals/1753-capabilities.md b/proposals/1753-capabilities.md new file mode 100644 index 00000000..23d22c4f --- /dev/null +++ b/proposals/1753-capabilities.md @@ -0,0 +1,99 @@ +# MSC1753: client-server capabilities API + +A mechanism is needed for clients to interrogate servers to establish whether +particular operations can be performed. + +For example, users may not be able to change their password if a server is +configured to authenticate against a separate system, in which case it is +nonsensical to offer the user such an option. + +## Proposal + +### `POST /_matrix/client/r0/capabilities` + +We will add a new endpoint to the client-server API: `POST +/_matrix/client/r0/capabilities`. The endpoint will be authenticated as normal +via an access token. + +The body of the request will list the capabilities the client is interested +in, as shown: + +```json +{ + "capabilities": { + "m.capability_one": {}, + "com.example.custom_capability": {} + } +} +``` + +The keys of the `capabilities` object are capability identifiers. As with +other identifiers in the Matrix protocol, the `m.` prefix is reserved for +definition in the Matrix specification; other values can be used within an +organisation following the Java package naming conventions. + +The values of the `capabilities` object will depend on the capability +identifier, though in general the empty object will suffice. + +The server should reply with a list of the operations the client may perform, +as shown: + +```json +{ + "capabilities": { + "m.capability_one": {} + } +} +``` + +The server should exclude from the list any operations which the client cannot +currently perform. It should also exclude any capabilities it does not +recognise or support, or whose value in the query did not have the expected +form. + +Again the values of the `capabilities` object will depend on the capability +identifier. + +### Initial capability identifiers + +As a starting point, a single capability identifier is proposed: +`m.change_password`, which should be considered supported if it is possible to +change the user's password via the `POST /_matrix/client/r0/account/password` +API. + +The values of the `capabilities` object should be the empty object in both the +query and the response. + +### Fallback behaviour + +Clients will need to be aware of servers which do not support the new endpoint, +and fall back to their current behaviour if they receive a 404 response. + +## Tradeoffs + +One alternative would be to provide specific ways of establishing support for +each operation: for example, a client might send an `GET +/_matrix/client/r0/account/password` request to see if the user can change +their password. The concern with this approach is that this could require a +large number of requests to establish which entries should appear on a menu or +dialog box. + +Another alternative would be a simple `GET /_matrix/client/r0/capabilities` +query, where a server would return all possible supported operations. The +problem with this is that it may add load to the server, and increase network +traffic, by returning a large number of features which the client may have no +interest in. + +## Potential issues + +None yet identified. + +## Security considerations + +None yet identified. + +## Conclusion + +We propose adding a new endpoint to the Client-Server API, which will allow +clients to query for supported operations so that they can decide whether to +expose them in their user-interface. From d90aeda65836590b42e5f455ddfc22dccb8140fb Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 14 Dec 2018 00:14:03 -0500 Subject: [PATCH 0035/1250] draft of alternate proposal for cross-signing --- proposals/xxxx-cross-signing.md | 135 ++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 proposals/xxxx-cross-signing.md diff --git a/proposals/xxxx-cross-signing.md b/proposals/xxxx-cross-signing.md new file mode 100644 index 00000000..a1b3cf55 --- /dev/null +++ b/proposals/xxxx-cross-signing.md @@ -0,0 +1,135 @@ +Each user has a "master identity key" that is used to sign their devices, and +is signed by all of their devices. When one user (Alice) verifies another +user's (Bob's) identity, Alice will sign Bob's master identity key with her +master identity key. (This will mean that verification methods will need to be +modified to pass along the master identity key.) Alice's device will trust +Bob's device if: + +- Alice's device has signed her master identity key, +- her master identity key has signed Bob's master identity key, +- Bob's master identity key has signed Bob's device, and +- none of those signatures have been revoked. + +If Alice believes that her master identity key has been compromised, she can +revoke it and create a new one. This means that all trust involving Alice +(i.e. Alice trusting other people and other people trusting Alice) needs to +start from scratch. + +The master identity key's private key can be stored encrypted on the server +(possibly along with the megolm key backup). Clients may or may not want to +store a copy of the private key locally. Doing so would mean that an attacker +who steals a device has access to the private key, and so can forge trusted +devices until the user notices and resets their master key. However, not doing +so means that when the user verifies another user, they will need to re-fetch +the private key, which means that they will need to re-enter their recovery +key to decrypt it. + +When a user logs in with a new device, they will fetch and decrypt the private +master key, sign the new device's key with the master key, and sign the master +key with the device's key. + +Users will only be allowed to see signatures made by their own master identity +key, or signatures made by other users' master identity keys on their own +devices. + +# API description + +## Possible API 1 + +Use the same API as MSC1680, but with additions. + +API to create new virtual device: + +`POST /devices/create` + +returns + +``` javascript +{ + "device_id": "ABCDEFG" +} +``` + +Send public key using `/keys/upload` as a normal device, but with a special +"algorithms" list: + +`POST /keys/upload` + +``` javascript +{ + "device_keys": { + "user_id": "@alice:example.com", + "device_id": "ABCDEFG", + "algorithms": ["m.master"], + "keys": { + "ed25519:ABCDEFG": "base64+public+key" + }, + "signatures": { + "@alice:example.com": { + "ed25519:ABCDEFG": "base64+self+signature" + } + } + } +} +``` + +(This may require changes in what `device_id`s are accepted by `/keys/upload`.) + +Attestations/revocations will be uploaded and retrieved as described in +MSC1680. Creating a new master key would involve revoking the old master key +by sending a signed revocation and deleting the device using `DELETE +/devices/{deviceId}`, and then creating a new master key. + +Private master key could be stored as part of the key backup (MSC1219), maybe +as a special room ID + session ID, or possibly in the `auth_data` for the +backup version (the latter would mean that changing the master key would +require creating a new backup version, which may be what users need to do +anyways). Or the private master key could be stored in account data, +e.g. `/user/{userId}/account_data/m.master.{deviceId}`. + +## Possible API 2 + +Treat master key separately from normal devices and adding special handling for +them. This might result in a nicer API, but make the implementation more +complicated. For example, the server could automatically add master key +signatures into a device's `signatures` field, rather than shipping the +attestations separately. + +TODO: write this option out + +# Comparison with MSC1680 + +MSC1680 suffers from the fact that the attestation graph may be arbitrarily +complex and may become ambiguous how the graph should be interpreted. In +particular, it is not obvious exactly how revocations should be interpreted -- +should they be interpreted as only revoking the signature created previously by +the device making the revocation, or should it be interpreted as a statement +that the device should not be trusted at all? As well, a revocation may split +the attestation graph, causing devices that were previously trusted to possibly +become untrusted. Logging out a device may also split the attestation graph. +Moreover, it may not be clear to a user what device verifications would be +needed to reattach the parts of the graph. + +One way to solve this is by registering a "virtual device", which is used to +sign other devices. This solution would be similar to this proposal. However, +real devices would still form an integral part of the attestation graph. For +example, if Alice's phone verifies Bob's tablet, the attestation graph might +look like Alice's laptop <-> Alice's virtual device <-> Alice's phone <-> Bob's +tablet <-> Bob's virtual device <-> Bob's desktop. So if Bob replaces his +tablet without re-verifying with Alice, this will split the graph and Alice +will not be able to verify Bob's other devices. In contrast, in this proposal, +Alice and Bob's master keys directly sign each other, and the attestation graph +would look like Alice's phone <-> Alice's master device <-> Bob's master device +<-> Bob's tablet. In this case, Bob's tablet can be replaced without breaking +the graph. FIXME: graphviz-ify the attestation graphs + +With normal cross-signing, it is not clear how to recover from a stolen device. +For example, if Mallory steals one of Alice's devices and revokes Alice's other +devices, it is unclear how Alice can rebuild the attestation graph with her +devices, as there may be stale attestations and revocations lingering around. +(This also relates to the question of whether a revocation should only revoke +the signature created previously by the device making the attestation, or +whether it should be a statement that the device should not be trusted at all.) +In contrast, with this proposal, there is a clear way to rebuild the +attestation graph: create a new master identity key, and re-verify all devices +with it. From de1173821022d22ea0366231abfcd80363919119 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 14 Dec 2018 00:25:18 -0500 Subject: [PATCH 0036/1250] rename to match PR --- proposals/{xxxx-cross-signing.md => 1756-cross-signing.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/{xxxx-cross-signing.md => 1756-cross-signing.md} (100%) diff --git a/proposals/xxxx-cross-signing.md b/proposals/1756-cross-signing.md similarity index 100% rename from proposals/xxxx-cross-signing.md rename to proposals/1756-cross-signing.md From f3997cd09ef81fe6d9cd97883103426d79c51d52 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 14 Dec 2018 19:08:37 -0500 Subject: [PATCH 0037/1250] graphviz-ify graphs and add some more structure --- proposals/1756-cross-signing.md | 30 ++++++++++++++++++++------- proposals/images/1756-graph1.dot | 13 ++++++++++++ proposals/images/1756-graph1.dot.png | Bin 0 -> 30297 bytes proposals/images/1756-graph2.dot | 13 ++++++++++++ proposals/images/1756-graph2.dot.png | Bin 0 -> 29214 bytes 5 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 proposals/images/1756-graph1.dot create mode 100644 proposals/images/1756-graph1.dot.png create mode 100644 proposals/images/1756-graph2.dot create mode 100644 proposals/images/1756-graph2.dot.png diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index a1b3cf55..0bb365e9 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -1,3 +1,9 @@ +# Background + +FIXME: something something + +# Proposal + Each user has a "master identity key" that is used to sign their devices, and is signed by all of their devices. When one user (Alice) verifies another user's (Bob's) identity, Alice will sign Bob's master identity key with her @@ -114,14 +120,18 @@ One way to solve this is by registering a "virtual device", which is used to sign other devices. This solution would be similar to this proposal. However, real devices would still form an integral part of the attestation graph. For example, if Alice's phone verifies Bob's tablet, the attestation graph might -look like Alice's laptop <-> Alice's virtual device <-> Alice's phone <-> Bob's -tablet <-> Bob's virtual device <-> Bob's desktop. So if Bob replaces his -tablet without re-verifying with Alice, this will split the graph and Alice -will not be able to verify Bob's other devices. In contrast, in this proposal, -Alice and Bob's master keys directly sign each other, and the attestation graph -would look like Alice's phone <-> Alice's master device <-> Bob's master device -<-> Bob's tablet. In this case, Bob's tablet can be replaced without breaking -the graph. FIXME: graphviz-ify the attestation graphs +look like: + +![](images/1756-graph1.dot.png) + +If Bob replaces his tablet without re-verifying with Alice, this will split the +graph and Alice will not be able to verify Bob's other devices. In contrast, +in this proposal, Alice and Bob's master keys directly sign each other, and the +attestation graph would look like: + +![](images/1756-graph2.dot.png) + +In this case, Bob's tablet can be replaced without breaking the graph. With normal cross-signing, it is not clear how to recover from a stolen device. For example, if Mallory steals one of Alice's devices and revokes Alice's other @@ -133,3 +143,7 @@ whether it should be a statement that the device should not be trusted at all.) In contrast, with this proposal, there is a clear way to rebuild the attestation graph: create a new master identity key, and re-verify all devices with it. + +# Conclusion + +This proposal presents an alternative cross-signing mechanism to MSC1680. diff --git a/proposals/images/1756-graph1.dot b/proposals/images/1756-graph1.dot new file mode 100644 index 00000000..8a8c9641 --- /dev/null +++ b/proposals/images/1756-graph1.dot @@ -0,0 +1,13 @@ +graph { +A1 [label="A's PDP-11"] +AV [label="A's virtual device"] +A2 [label="A's Osborne 2"] +B1 [label="B's Dynabook"] +BV [label="B's virtual device"] +B2 [label="B's VAX"] +A1 -- AV +AV -- A2 +A2 -- B1 +B1 -- BV +BV -- B2 +} \ No newline at end of file diff --git a/proposals/images/1756-graph1.dot.png b/proposals/images/1756-graph1.dot.png new file mode 100644 index 0000000000000000000000000000000000000000..87a78f83727c9174c07f3bc1889fc9f9f66553f7 GIT binary patch literal 30297 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%0Adjg5g3&Gz*>?-#Rp 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 literal 0 HcmV?d00001 From 2d3b5f44819f24bbb3673b530503342db11de487 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 14 Dec 2018 19:11:17 -0500 Subject: [PATCH 0038/1250] make text consistent with image --- proposals/1756-cross-signing.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 0bb365e9..c6e86554 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -119,19 +119,19 @@ needed to reattach the parts of the graph. One way to solve this is by registering a "virtual device", which is used to sign other devices. This solution would be similar to this proposal. However, real devices would still form an integral part of the attestation graph. For -example, if Alice's phone verifies Bob's tablet, the attestation graph might +example, if Alice's Osborne 2 verifies Bob's Dynabook, the attestation graph might look like: ![](images/1756-graph1.dot.png) -If Bob replaces his tablet without re-verifying with Alice, this will split the -graph and Alice will not be able to verify Bob's other devices. In contrast, -in this proposal, Alice and Bob's master keys directly sign each other, and the -attestation graph would look like: +If Bob replaces his Dynabook without re-verifying with Alice, this will split +the graph and Alice will not be able to verify Bob's other devices. In +contrast, in this proposal, Alice and Bob's master keys directly sign each +other, and the attestation graph would look like: ![](images/1756-graph2.dot.png) -In this case, Bob's tablet can be replaced without breaking the graph. +In this case, Bob's Dynabook can be replaced without breaking the graph. With normal cross-signing, it is not clear how to recover from a stolen device. For example, if Mallory steals one of Alice's devices and revokes Alice's other From e9aa4081bc8e379625afe9eed285073e9f4c7886 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 17 Dec 2018 15:37:26 -0500 Subject: [PATCH 0039/1250] fix sectioning and add a background --- proposals/1756-cross-signing.md | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index c6e86554..5fe52e4a 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -1,8 +1,22 @@ -# Background +# Cross-signing devices with master keys -FIXME: something something +## Background -# Proposal +A user with multiple devices will have a different key for end-to-end +encryption for each device. Other users who want to communicate securely with +this user must then verify each key on each of their devices. If Alice has *n* +devices, and Bob has *m* devices, then for Alice to be able to communicate with +Bob on any of their devices, this involves *n×m* key verifications. + +One way to addresss this is for each user to use a "master key" for their +identity which signs all of their devices. Thus another user who wishes to +verify their identity only needs to verify their master, key and can use the +master key to verify their devices. + +[MSC1680](https://github.com/matrix-org/matrix-doc/issues/1680) presents a +different solution to the problem. + +## Proposal Each user has a "master identity key" that is used to sign their devices, and is signed by all of their devices. When one user (Alice) verifies another @@ -38,9 +52,9 @@ Users will only be allowed to see signatures made by their own master identity key, or signatures made by other users' master identity keys on their own devices. -# API description +### API description -## Possible API 1 +#### Possible API 1 Use the same API as MSC1680, but with additions. @@ -93,7 +107,7 @@ require creating a new backup version, which may be what users need to do anyways). Or the private master key could be stored in account data, e.g. `/user/{userId}/account_data/m.master.{deviceId}`. -## Possible API 2 +#### Possible API 2 Treat master key separately from normal devices and adding special handling for them. This might result in a nicer API, but make the implementation more @@ -103,7 +117,7 @@ attestations separately. TODO: write this option out -# Comparison with MSC1680 +## Comparison with MSC1680 MSC1680 suffers from the fact that the attestation graph may be arbitrarily complex and may become ambiguous how the graph should be interpreted. In @@ -144,6 +158,8 @@ In contrast, with this proposal, there is a clear way to rebuild the attestation graph: create a new master identity key, and re-verify all devices with it. -# Conclusion +## Security considerations + +## Conclusion This proposal presents an alternative cross-signing mechanism to MSC1680. From d9eddcf7df0dae23a1ded7281324edf090ece1a1 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 17 Dec 2018 20:34:27 -0500 Subject: [PATCH 0040/1250] change language to json in code blocks --- proposals/1756-cross-signing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 5fe52e4a..758194dd 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -64,7 +64,7 @@ API to create new virtual device: returns -``` javascript +``` json { "device_id": "ABCDEFG" } @@ -75,7 +75,7 @@ Send public key using `/keys/upload` as a normal device, but with a special `POST /keys/upload` -``` javascript +``` json { "device_keys": { "user_id": "@alice:example.com", From c0b0db9a55de9969c96759f32440866cd3f5930b Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 17 Dec 2018 22:33:10 -0500 Subject: [PATCH 0041/1250] document alternate API, and some other clarifications --- proposals/1756-cross-signing.md | 189 +++++++++++++++++++++++++++++++- 1 file changed, 186 insertions(+), 3 deletions(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 758194dd..11bfe2c1 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -25,8 +25,8 @@ master identity key. (This will mean that verification methods will need to be modified to pass along the master identity key.) Alice's device will trust Bob's device if: -- Alice's device has signed her master identity key, -- her master identity key has signed Bob's master identity key, +- Alice's device is using a master identity key that has signed Bob's master + identity key, - Bob's master identity key has signed Bob's device, and - none of those signatures have been revoked. @@ -70,6 +70,10 @@ returns } ``` +The server should not allow any client to use this device ID when logging in or +registering; if a client tries to log in using this device ID, then the server +must respond with an error. (FIXME: what error?) + Send public key using `/keys/upload` as a normal device, but with a special "algorithms" list: @@ -115,7 +119,186 @@ complicated. For example, the server could automatically add master key signatures into a device's `signatures` field, rather than shipping the attestations separately. -TODO: write this option out +Send public key using `/keys/upload`, under the `master_key` property. +(Alternatively, could use a special endpoint, like `/keys/master/upload`.) + +`POST /keys/upload` + +``` json +{ + "master_key": { + "user_id": "@alice:example.com", + "key_id": "ABCDEFG", + "algorithm": "ed25519", + "key": "base64+public+key", + "signatures": { + "@alice:example.com": { + "ed25519:ABCDEFG": "base64+self+signature" + } + } + } +} +``` + +The key ID must be unique within the scope of a given user, and must not match +any device ID. This is required so that there will be no collisions in the +`signatures` property. + +(FIXME: how do we make sure that the key ID doesn't collide with an existing +device ID? Just send an error and let the client retry?) + +The server should not allow any client to use the key ID as their device ID +when logging in or registering; if a client tries to log in using this device +ID, then the server must respond with an error. (FIXME: what error?) + +Uploading a new master key should invalidate any previous master key. + +After uploading a master key, it will be included under the `/keys/query` +endpoint under the `master_key` property. + +`GET /keys/query` + +``` json +{ + "failures": {}, + "master_key": { + "@alice:example.com": { + "user_id": "@alice:example.com", + "key_id": "ABCDEFG", + "algorithm": "ed25519", + "key": "base64+public+key", + "signatures": { + "@alice:example.com": { + "ed25519:ABCDEFG": "base64+self+signature" + } + } + } + } +} +``` + +Signatures can be uploaded using `/keys/upload`, under the `signatures` +property. (Alternatively, could use a special endpoint, like +`/keys/signatures/upload`.) + +For example, Alice signs one of her devices (HIJKLMN), and Bob's master key. + +`POST /keys/upload` + +``` json +{ + "signatures": { + "@alice:example.com": { + "HIJKLMN": { + "user_id": "@alice:example.com", + "device_id": "HIJKLMN", + "algorithms": [ + "m.olm.curve25519-aes-sha256", + "m.megolm.v1.aes-sha" + ], + "keys": { + "curve25519:HIJKLMN": "base64+curve25519+key", + "ed25519:HIJKLMN": "base64+ed25519+key" + }, + "signatures": { + "@alice:example.com": { + "ed25519:ABCDEFG": "base64+signature+of+HIJKLMN" + } + } + } + }, + "@bob:example.com": { + "OPQRSTU": { + "user_id": "@bob:example.com", + "key_id": "OPQRSTU", + "algorithm": "ed25519", + "key": "base64+ed25519+key", + "signatures": { + "@alice:example.com": { + "ed25519:ABCDEFG": "base64+signature+of+OPQRSTU" + } + } + } + } + } +} +``` + +After Alice uploads a signature for her own devices, her signature will be +included in the results of the `/keys/query` request when *anyone* requests her +keys: + +`GET /keys/query` + +``` json +{ + "failures": {}, + "device_keys": { + "@alice:example.com": { + "HIJKLMN": { + "user_id": "@alice:example.com", + "device_id": "HIJKLMN", + "algorithms": [ + "m.olm.v1.curve25519-aes-sha256", + "m.megolm.v1.aes-sha" + ], + "keys": { + "curve25519:HIJKLMN": "base64+curve25519+key", + "ed25519:HIJKLMN": "base64+ed25519+key" + }, + "signatures": { + "@alice:example.com": { + "ed25519:HIJKLMN": "base64+self+signature", + "ed25519:ABCDEFG": "base64+signature+of+HIJKLMN" + } + }, + "unsigned": { + "device_display_name": "Alice's Osborne 2" + } + } + } + }, + "master_keys": { + "@alice:example.com": { + "user_id": "@alice:example.com", + "key_id": "ABCDEFG", + "algorithm": "ed25519", + "key": "base64+public+key", + "signatures": { + "@alice:example.com": { + "ed25519:ABCDEFG": "base64+self+signature" + } + } + } + } +} +``` + +After Alice uploads a signature for Bob's master key, her signature will be +included in the results of the `/keys/query` request when Alice requests Bob's +key: + +`GET /keys/query` + +``` json +{ + "failures": {}, + "master_key": { + "@bob:example.com": { + "user_id": "@bob:example.com", + "key_id": "OPQRSTU", + "algorithm": "ed25519", + "key": "base64+ed25519+key", + "signatures": { + "@alice:example.com": { + "ed25519:OPQRSTU": "base64+self+signature+OPQRSTU", + "ed25519:ABCDEFG": "base64+signature+of+OPQRSTU" + } + } + } + } +} +``` ## Comparison with MSC1680 From 68ac2172bab4669cf5243c241b606c0ff254acdb Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 21 Dec 2018 17:39:52 +0000 Subject: [PATCH 0042/1250] Give examples of applications --- proposals/1753-capabilities.md | 43 ++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/proposals/1753-capabilities.md b/proposals/1753-capabilities.md index 23d22c4f..bcc5b2a3 100644 --- a/proposals/1753-capabilities.md +++ b/proposals/1753-capabilities.md @@ -69,6 +69,49 @@ query and the response. Clients will need to be aware of servers which do not support the new endpoint, and fall back to their current behaviour if they receive a 404 response. +### Suitable applications + +In general, capabilities advertised via this endpoiunt should depend in some +way on the state of the user or server - in other words, they will inherently +"optional" features in the API. + +This endpoint should *not* be used to advertise support for experimental or +unstable features, which is better done via `/client/r0/versions` (see +[MSC1497](https://github.com/matrix-org/matrix-doc/issues/1497)). + +Examples of features which might reasonably be advertised here include: + + * Whether the server supports user presence. + + * Whether the server supports other optional features. The following could be + made optional via this mechanism: + * Room directory + * URL previews + + * Policy restricitions, such as: + * Whether certain types of content are permitted on this server. + * The number of rooms you are allowed in. + * Configured ratelimits. + + +Features which might be better advertised elsewhere include: + + * Support for e2e key backups + ([MSC1219](https://github.com/matrix-org/matrix-doc/issues/1219)) - list in + `/client/r0/versions`. + + * Support for lazy-loading of room members - list in `/client/r0/versions`. + + * Media size limits - list in `/media/r0/config`, because the media server may + be a separate process. + + * Optional transports/encodings for the CS API - probably better handled via + HTTP headers etc. + + * Variations in room state resolution - this is implied via the room version + (which is in the `m.room.create` event). + + ## Tradeoffs One alternative would be to provide specific ways of establishing support for From 82f3b8a95a4be1b485a23be775458aea53ba324e Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 21 Dec 2018 17:47:52 +0000 Subject: [PATCH 0043/1250] switch to GET --- proposals/1753-capabilities.md | 43 +++++++--------------------------- 1 file changed, 9 insertions(+), 34 deletions(-) diff --git a/proposals/1753-capabilities.md b/proposals/1753-capabilities.md index bcc5b2a3..386e66dc 100644 --- a/proposals/1753-capabilities.md +++ b/proposals/1753-capabilities.md @@ -9,20 +9,18 @@ nonsensical to offer the user such an option. ## Proposal -### `POST /_matrix/client/r0/capabilities` +### `GET /_matrix/client/r0/capabilities` -We will add a new endpoint to the client-server API: `POST +We will add a new endpoint to the client-server API: `GET /_matrix/client/r0/capabilities`. The endpoint will be authenticated as normal via an access token. -The body of the request will list the capabilities the client is interested -in, as shown: +The server should reply with a list of supported features, as shown: ```json { "capabilities": { - "m.capability_one": {}, - "com.example.custom_capability": {} + "m.capability_one": {} } } ``` @@ -35,25 +33,6 @@ organisation following the Java package naming conventions. The values of the `capabilities` object will depend on the capability identifier, though in general the empty object will suffice. -The server should reply with a list of the operations the client may perform, -as shown: - -```json -{ - "capabilities": { - "m.capability_one": {} - } -} -``` - -The server should exclude from the list any operations which the client cannot -currently perform. It should also exclude any capabilities it does not -recognise or support, or whose value in the query did not have the expected -form. - -Again the values of the `capabilities` object will depend on the capability -identifier. - ### Initial capability identifiers As a starting point, a single capability identifier is proposed: @@ -61,8 +40,8 @@ As a starting point, a single capability identifier is proposed: change the user's password via the `POST /_matrix/client/r0/account/password` API. -The values of the `capabilities` object should be the empty object in both the -query and the response. +The value of the `capabilities` object in the response should be the empty +object. ### Fallback behaviour @@ -93,7 +72,6 @@ Examples of features which might reasonably be advertised here include: * The number of rooms you are allowed in. * Configured ratelimits. - Features which might be better advertised elsewhere include: * Support for e2e key backups @@ -111,7 +89,6 @@ Features which might be better advertised elsewhere include: * Variations in room state resolution - this is implied via the room version (which is in the `m.room.create` event). - ## Tradeoffs One alternative would be to provide specific ways of establishing support for @@ -121,11 +98,9 @@ their password. The concern with this approach is that this could require a large number of requests to establish which entries should appear on a menu or dialog box. -Another alternative would be a simple `GET /_matrix/client/r0/capabilities` -query, where a server would return all possible supported operations. The -problem with this is that it may add load to the server, and increase network -traffic, by returning a large number of features which the client may have no -interest in. +Another alternative is to provide a generic query mechanism where the client +can query for specific capabilities it is interested in. However, this adds +complication and makes it harder to discover capability identifiers. ## Potential issues From 7f5832044c6b16d1099dc117bea481ed7613f338 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 2 Jan 2019 09:55:14 +0000 Subject: [PATCH 0044/1250] Fix typos per review --- proposals/1753-capabilities.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1753-capabilities.md b/proposals/1753-capabilities.md index 386e66dc..4ac0ac05 100644 --- a/proposals/1753-capabilities.md +++ b/proposals/1753-capabilities.md @@ -50,8 +50,8 @@ and fall back to their current behaviour if they receive a 404 response. ### Suitable applications -In general, capabilities advertised via this endpoiunt should depend in some -way on the state of the user or server - in other words, they will inherently +In general, capabilities advertised via this endpoint should depend in some way +on the state of the user or server - in other words, they will be inherently "optional" features in the API. This endpoint should *not* be used to advertise support for experimental or From 962565b15959b032eb38943ad57ff577d5e03cd2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 3 Jan 2019 17:40:49 +0000 Subject: [PATCH 0045/1250] Update proposals/1753-capabilities.md r0/versions isn't a thing Co-Authored-By: richvdh <1389908+richvdh@users.noreply.github.com> --- proposals/1753-capabilities.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1753-capabilities.md b/proposals/1753-capabilities.md index 4ac0ac05..5c3ada41 100644 --- a/proposals/1753-capabilities.md +++ b/proposals/1753-capabilities.md @@ -55,7 +55,7 @@ on the state of the user or server - in other words, they will be inherently "optional" features in the API. This endpoint should *not* be used to advertise support for experimental or -unstable features, which is better done via `/client/r0/versions` (see +unstable features, which is better done via `/client/versions` (see [MSC1497](https://github.com/matrix-org/matrix-doc/issues/1497)). Examples of features which might reasonably be advertised here include: From 40196786619f75f3424258735f3958ac69b6a455 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 3 Jan 2019 17:40:57 +0000 Subject: [PATCH 0046/1250] Update proposals/1753-capabilities.md r0/versions isn't a thing Co-Authored-By: richvdh <1389908+richvdh@users.noreply.github.com> --- proposals/1753-capabilities.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1753-capabilities.md b/proposals/1753-capabilities.md index 5c3ada41..cbda92d8 100644 --- a/proposals/1753-capabilities.md +++ b/proposals/1753-capabilities.md @@ -76,7 +76,7 @@ Features which might be better advertised elsewhere include: * Support for e2e key backups ([MSC1219](https://github.com/matrix-org/matrix-doc/issues/1219)) - list in - `/client/r0/versions`. + `/client/versions`. * Support for lazy-loading of room members - list in `/client/r0/versions`. From ca2e9260d427b9ec620e7fa94c9d13345cda463e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 3 Jan 2019 17:41:06 +0000 Subject: [PATCH 0047/1250] Update proposals/1753-capabilities.md r0/versions isn't a thing Co-Authored-By: richvdh <1389908+richvdh@users.noreply.github.com> --- proposals/1753-capabilities.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1753-capabilities.md b/proposals/1753-capabilities.md index cbda92d8..ec5169ab 100644 --- a/proposals/1753-capabilities.md +++ b/proposals/1753-capabilities.md @@ -78,7 +78,7 @@ Features which might be better advertised elsewhere include: ([MSC1219](https://github.com/matrix-org/matrix-doc/issues/1219)) - list in `/client/versions`. - * Support for lazy-loading of room members - list in `/client/r0/versions`. + * Support for lazy-loading of room members - list in `/client/versions`. * Media size limits - list in `/media/r0/config`, because the media server may be a separate process. From e0fa00fc34c3b67ee8166e19372e569eabce42c9 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 3 Jan 2019 18:21:05 +0000 Subject: [PATCH 0048/1250] Some HSes use more than one notary --- proposals/1711-x509-for-federation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1711-x509-for-federation.md b/proposals/1711-x509-for-federation.md index 52662123..82881d93 100644 --- a/proposals/1711-x509-for-federation.md +++ b/proposals/1711-x509-for-federation.md @@ -224,7 +224,7 @@ a recognised Certificate Authority will improve security, reduce centralisation, and eliminate some common deployment pitfalls. [1] It's *possible* to set up homeservers to use servers other than -`matrix.org` as notaries, but we are not aware of any that are set up this +`matrix.org` as notaries, but only a minority are actually set up this way. [↩](#a1) [2] I've not been able to find an authoritative source on this, but From ffe577371db7482a3df92a4f9dee6f984922119a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Sep 2018 16:29:30 -0600 Subject: [PATCH 0049/1250] Add a room version specification The "Room Specification" (or "Room Version Specification") is the specification that defines which room versions do what and are intended to be documents which speak the truth about how rooms operate under the hood. The approach taken here is a bit different than other specifications. For starters, the specification is versioned in this project instead of relying on the matrix.org repository to track compiled HTML. This is done for a couple reasons, the first being we're still developing the v1 specification while concurrently making a v2 spec and the second being trying to reduce the reliance on matrix.org's repository for specifications. Because the room spec is built into versions, some changes needed to be made. The `targets.yaml` now has a special syntax for indicating what version something is at, and the changelog generator can handle rendering different versions of the same changelog (as parsed from the RST). Some additional work has been put in to the changelog parsing to allow us to reference the v1 room spec as "v1" without having to sacrifice clarity in the changelog headings. Finally, this moves the state resolution algorithms into the versioned spec as a result of MSC1759 (https://github.com/matrix-org/matrix-doc/pull/1759). Note: this does not introduce the concept of versioned schemas (tabs) that I was previously working with. There's currently no use for them, so they are shelved elsewhere. --- changelogs/rooms.rst | 11 + changelogs/rooms/newsfragments/.gitignore | 1 + changelogs/rooms/pyproject.toml | 30 +++ meta/releasing-rooms-v2.md | 38 ++++ scripts/gendoc.py | 7 +- .../templating/matrix_templates/sections.py | 34 ++-- scripts/templating/matrix_templates/units.py | 56 +++++- .../appendices/identifier_grammar.rst | 42 +--- specification/rooms/intro.rst | 70 +++++++ specification/rooms/unstable.rst | 54 +++++ specification/rooms/v1.rst | 112 +++++++++++ specification/rooms/v2.rst | 181 +++++++++++++++++ specification/server_server_api.rst | 189 +----------------- specification/targets.yaml | 29 +++ 14 files changed, 609 insertions(+), 245 deletions(-) create mode 100644 changelogs/rooms.rst create mode 100644 changelogs/rooms/newsfragments/.gitignore create mode 100644 changelogs/rooms/pyproject.toml create mode 100644 meta/releasing-rooms-v2.md create mode 100644 specification/rooms/intro.rst create mode 100644 specification/rooms/unstable.rst create mode 100644 specification/rooms/v1.rst create mode 100644 specification/rooms/v2.rst diff --git a/changelogs/rooms.rst b/changelogs/rooms.rst new file mode 100644 index 00000000..55a16790 --- /dev/null +++ b/changelogs/rooms.rst @@ -0,0 +1,11 @@ +.. version: v2 + +.. Note: We set the version as "version 2" so that we can maintain a specific version +.. variable in the changelog. We already know the next version is going to be v2, so +.. this makes it easier to copy/paste unstable.rst to v2.rst + +Room version 1 +============== +.. version: v1 + +This is the first iteration of rooms in Matrix. diff --git a/changelogs/rooms/newsfragments/.gitignore b/changelogs/rooms/newsfragments/.gitignore new file mode 100644 index 00000000..b722e9e1 --- /dev/null +++ b/changelogs/rooms/newsfragments/.gitignore @@ -0,0 +1 @@ +!.gitignore \ No newline at end of file diff --git a/changelogs/rooms/pyproject.toml b/changelogs/rooms/pyproject.toml new file mode 100644 index 00000000..b56e19a9 --- /dev/null +++ b/changelogs/rooms/pyproject.toml @@ -0,0 +1,30 @@ +[tool.towncrier] + filename = "../rooms.rst" + directory = "newsfragments" + issue_format = "`#{issue} `_" + title_format = "{version}" + + [[tool.towncrier.type]] + directory = "breaking" + name = "Breaking Changes" + showcontent = true + + [[tool.towncrier.type]] + directory = "deprecation" + name = "Deprecations" + showcontent = true + + [[tool.towncrier.type]] + directory = "new" + name = "New Endpoints" + showcontent = true + + [[tool.towncrier.type]] + directory = "feature" + name = "Backwards Compatible Changes" + showcontent = true + + [[tool.towncrier.type]] + directory = "clarification" + name = "Spec Clarifications" + showcontent = true diff --git a/meta/releasing-rooms-v2.md b/meta/releasing-rooms-v2.md new file mode 100644 index 00000000..80277749 --- /dev/null +++ b/meta/releasing-rooms-v2.md @@ -0,0 +1,38 @@ +# How to release Room Version 2 + +Room versions are a bit special for the release given they have been +introduced at v2 rather than ever getting a v1 release. Additionally, +room versions have different release requirements due to the in-project +versioning of documents rather than relying on matrix.org to maintain +old generated output of specifications. + +As of writing, the project is structured to support 3 logical versions +for rooms: v1, v2, and unstable. Unstable is currently pointed at v2 +in order to aid development. After v2 is released, unstable may wish +to be left as an independent version or similarly be pointed at a "v3" +document. + +Due to room versions being versioned in-project, the generated output +from a release is not to be sent off to matrix-doc/matrix.org. Instead, +in `gendoc.py` the default value for `--room_version` should be set to +the current release (`v2`, for example) so the index renders the right +edition in the table. + +After editing `gendoc.py`, the changelog should be generated according +to the towncrier instructions. You may need to fix the `.. version: v2` +comment located in the `rooms.rst` changelog to be just underneath the +title instead of at the end of the section. + +The `targets.yaml` file needs to be set up to point unstable to the +right set of files. Ensure that `unstable.rst` is referenced instead +of `v2.rst`, and that `unstable.rst` has appropriate contents. + +Finally, in the `intro.rst` for room versions, re-add unstable to the +list of available versions. It is currently commented out to avoid +confusing people, so it should be possible to uncomment it and put it +back into the list. + +From there, the standard process of using a release branch, tagging it, +and announcing it to the world should be followed. If required, the +various other APIs should be updated to better support the new room +version. diff --git a/scripts/gendoc.py b/scripts/gendoc.py index 8310ad58..0455c90a 100755 --- a/scripts/gendoc.py +++ b/scripts/gendoc.py @@ -457,7 +457,7 @@ def main(targets, dest_dir, keep_intermediates, substitutions): rst_file = os.path.join(tmp_dir, "spec_%s.rst" % (target_name,)) if version_label: - d = os.path.join(dest_dir, target_name) + d = os.path.join(dest_dir, target_name.split('@')[0]) if not os.path.exists(d): os.mkdir(d) html_file = os.path.join(d, "%s.html" % version_label) @@ -529,6 +529,10 @@ if __name__ == '__main__': "--identity_release", "-i", action="store", default="unstable", help="The identity service release tag to generate, e.g. r1.2" ) + parser.add_argument( + "--room_version", "-r", action="store", default="unstable", + help="The current room version to advertise, e.g. v2" + ) parser.add_argument( "--list_targets", action="store_true", help="Do not update the specification. Instead print a list of targets.", @@ -555,6 +559,7 @@ if __name__ == '__main__': "%APPSERVICE_RELEASE_LABEL%": args.appservice_release, "%IDENTITY_RELEASE_LABEL%": args.identity_release, "%PUSH_GATEWAY_RELEASE_LABEL%": args.push_gateway_release, + "%CURRENT_ROOM_VERSION%": args.room_version, } exit (main(args.target or ["all"], args.dest, args.nodelete, substitutions)) diff --git a/scripts/templating/matrix_templates/sections.py b/scripts/templating/matrix_templates/sections.py index 185970c9..af497674 100644 --- a/scripts/templating/matrix_templates/sections.py +++ b/scripts/templating/matrix_templates/sections.py @@ -17,8 +17,11 @@ from batesian.sections import Sections import inspect import json import os +import logging +logger = logging.getLogger(__name__) + class MatrixSections(Sections): # pass through git ver so it'll be dropped in the input file @@ -28,26 +31,19 @@ class MatrixSections(Sections): def render_git_rev(self): return self.units.get("git_version")["revision"] - def render_client_server_changelog(self): - changelogs = self.units.get("changelogs") - return changelogs["client_server"] - - # TODO: We should make this a generic variable instead of having to add functions all the time. - def render_push_gateway_changelog(self): - changelogs = self.units.get("changelogs") - return changelogs["push_gateway"] - - def render_identity_service_changelog(self): - changelogs = self.units.get("changelogs") - return changelogs["identity_service"] - - def render_server_server_changelog(self): - changelogs = self.units.get("changelogs") - return changelogs["server_server"] - - def render_application_service_changelog(self): + def render_changelogs(self): + rendered = {} changelogs = self.units.get("changelogs") - return changelogs["application_service"] + for spec, versioned in changelogs.items(): + spec_var = "%s_changelog" % spec + logger.info("Rendering changelog for spec: %s" % spec) + for version, changelog in versioned.items(): + version_var = "%s_%s" % (spec_var, version) + logger.info("Rendering changelog for %s" % version_var) + rendered[version_var] = changelog + if version == "unstable": + rendered[spec_var] = changelog + return rendered def _render_events(self, filterFn, sortFn): template = self.env.get_template("events.tmpl") diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index 11a9d441..666434a5 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -757,6 +757,7 @@ class MatrixUnits(Units): is_ver = substitutions.get("%IDENTITY_RELEASE_LABEL%", "unstable") as_ver = substitutions.get("%APPSERVICE_RELEASE_LABEL%", "unstable") push_gw_ver = substitutions.get("%PUSH_GATEWAY_RELEASE_LABEL%", "unstable") + room_ver = substitutions.get("%CURRENT_ROOM_VERSION%", "unstable") # we abuse the typetable to return this info to the templates return TypeTable(rows=[ @@ -780,6 +781,10 @@ class MatrixUnits(Units): "`Push Gateway API `_", push_gw_ver, "Push notifications for Matrix events", + ), TypeTableRow( + "`Rooms `_", + room_ver, + "Specification for behaviour of rooms, such as event formats", ), ]) @@ -906,11 +911,26 @@ class MatrixUnits(Units): def load_changelogs(self): changelogs = {} + # Changelog generation is a bit complicated. We rely on towncrier to + # generate the unstable/current changelog, but otherwise use the RST + # edition to record historical changelogs. This is done by prepending + # the towncrier output to the RST in memory, then parsing the RST by + # hand. We parse the entire changelog to create a changelog for each + # version which may be of use in some APIs. + + # Map specific headers to specific keys that'll be used eventually + # in variables. Things not listed here will get lowercased and formatted + # such that characters not [a-z0-9] will be replaced with an underscore. + keyword_versions = { + "Unreleased Changes": "unstable" + } + + # Only generate changelogs for things that have an RST document for f in os.listdir(CHANGELOG_DIR): if not f.endswith(".rst"): continue path = os.path.join(CHANGELOG_DIR, f) - name = f[:-4] + name = f[:-4] # take off ".rst" # If there's a directory with the same name, we'll try to generate # a towncrier changelog and prepend it to the general changelog. @@ -959,15 +979,39 @@ class MatrixUnits(Units): prev_line = line else: # have title, get body (stop on next title or EOF) if re.match("^[=]{3,}$", line.strip()): - # we added the title in the previous iteration, pop it - # then bail out. - changelog_lines.pop() - break + # we hit another title, so pop the last line of + # the changelog and record the changelog + new_title = changelog_lines.pop() + if name not in changelogs: + changelogs[name] = {} + if title_part in keyword_versions: + title_part = keyword_versions[title_part] + title_part = title_part.strip().replace("^[a-zA-Z0-9]", "_").lower() + changelog = "".join(changelog_lines) + changelogs[name][title_part] = changelog + + # reset for the next version + changelog_lines = [] + title_part = new_title.strip() + continue # Don't generate subheadings (we'll keep the title though) if re.match("^[-]{3,}$", line.strip()): continue + if line.strip().startswith(".. version: "): + # The changelog is directing us to use a different title + # for the changelog. + title_part = line.strip()[len(".. version: "):] + continue + if line.strip().startswith(".. "): + continue # skip comments changelog_lines.append(" " + line + '\n') - changelogs[name] = "".join(changelog_lines) + if len(changelog_lines) > 0 and title_part is not None: + if name not in changelogs: + changelogs[name] = {} + if title_part in keyword_versions: + title_part = keyword_versions[title_part] + changelog = "".join(changelog_lines) + changelogs[name][title_part.replace("^[a-zA-Z0-9]", "_").lower()] = changelog return changelogs diff --git a/specification/appendices/identifier_grammar.rst b/specification/appendices/identifier_grammar.rst index bb5f9297..496aba31 100644 --- a/specification/appendices/identifier_grammar.rst +++ b/specification/appendices/identifier_grammar.rst @@ -16,6 +16,12 @@ Identifier Grammar ------------------ +Some identifiers are specific to given room versions, please see the +`room specification`_ for more information. + +.. _`room specification`: ../rooms/latest.html + + Server Name ~~~~~~~~~~~ @@ -78,38 +84,6 @@ Some recommendations for a choice of server name follow: * The length of the complete server name should not exceed 230 characters. * Server names should not use upper-case characters. - -Room Versions -~~~~~~~~~~~~~ - -Room versions are used to change properties of rooms that may not be compatible -with other servers. For example, changing the rules for event authorization would -cause older servers to potentially end up in a split-brain situation due to them -not understanding the new rules. - -A room version is defined as a string of characters which MUST NOT exceed 32 -codepoints in length. Room versions MUST NOT be empty and SHOULD contain only -the characters ``a-z``, ``0-9``, ``.``, and ``-``. - -Room versions are not intended to be parsed and should be treated as opaque -identifiers. Room versions consisting only of the characters ``0-9`` and ``.`` -are reserved for future versions of the Matrix protocol. - -The complete grammar for a legal room version is:: - - room_version = 1*room_version_char - room_version_char = DIGIT - / %x61-7A ; a-z - / "-" / "." - -Examples of valid room versions are: - -* ``1`` (would be reserved by the Matrix protocol) -* ``1.2`` (would be reserved by the Matrix protocol) -* ``1.2-beta`` -* ``com.example.version`` - - Common Identifier Format ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -327,7 +301,7 @@ matrix.to navigation .. NOTE:: This namespacing is in place pending a ``matrix://`` (or similar) URI scheme. - This is **not** meant to be interpreted as an available web service - see + This is **not** meant to be interpreted as an available web service - see below for more details. Rooms, users, aliases, and groups may be represented as a "matrix.to" URI. @@ -343,7 +317,7 @@ in RFC 3986: The identifier may be a room ID, room alias, user ID, or group ID. The extra parameter is only used in the case of permalinks where an event ID is referenced. The matrix.to URI, when referenced, must always start with ``https://matrix.to/#/`` -followed by the identifier. +followed by the identifier. Clients should not rely on matrix.to URIs falling back to a web server if accessed and instead should perform some sort of action within the client. For example, if diff --git a/specification/rooms/intro.rst b/specification/rooms/intro.rst new file mode 100644 index 00000000..6231d066 --- /dev/null +++ b/specification/rooms/intro.rst @@ -0,0 +1,70 @@ +.. 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. + +Room Specification +================== + +.. contents:: Table of Contents +.. sectnum:: + +Rooms are central to how Matrix operates, and have strict rules for what +is allowed to be contained within them. Rooms can also have various +algorithms that handle different tasks, such as what to do when two or +more events collide in the underlying DAG. To allow rooms to be improved +upon through new algorithms or rules, "room versions" are employed to +manage a set of expectations for each room. + + +Room version grammar +-------------------- + +Room versions are used to change properties of rooms that may not be compatible +with other servers. For example, changing the rules for event authorization would +cause older servers to potentially end up in a split-brain situation due to them +not understanding the new rules. + +A room version is defined as a string of characters which MUST NOT exceed 32 +codepoints in length. Room versions MUST NOT be empty and SHOULD contain only +the characters ``a-z``, ``0-9``, ``.``, and ``-``. + +Room versions are not intended to be parsed and should be treated as opaque +identifiers. Room versions consisting only of the characters ``0-9`` and ``.`` +are reserved for future versions of the Matrix protocol. + +The complete grammar for a legal room version is:: + + room_version = 1*room_version_char + room_version_char = DIGIT + / %x61-7A ; a-z + / "-" / "." + +Examples of valid room versions are: + +* ``1`` (would be reserved by the Matrix protocol) +* ``1.2`` (would be reserved by the Matrix protocol) +* ``1.2-beta`` +* ``com.example.version`` + + +Other room versions +------------------- + +The available room versions are: + +* `Version 1 `_ - The current version of most rooms. +* `Version 2 `_ - Currently in development. + +.. Note: the 'unstable' version is commented out pending a real release of rooms v2 +.. See meta/releasing-rooms-v2.md +.. * `Unstable `_ - The upcoming version of the room specification. diff --git a/specification/rooms/unstable.rst b/specification/rooms/unstable.rst new file mode 100644 index 00000000..44261814 --- /dev/null +++ b/specification/rooms/unstable.rst @@ -0,0 +1,54 @@ +.. 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. + + +.. DEV NOTE: This is stubbed as a template and not actually used anywhere. +.. See v2.rst for the "unstable" room version, which is currently under +.. development. +.. +.. See meta/releasing-rooms-v2.md + + +.. Note: This document appended to the end of the intro, so this next line +.. appears under "Other Room Versions". + +.. Warning:: + + This is the specification for unreleased changes to rooms. The stability + of rooms using this specification cannot be guaranteed. + + +Changelog +--------- + +.. topic:: unstable +{{rooms_changelog_unstable}} + +This version of the specification is generated from +`matrix-doc `_ as of Git commit +`{{git_version}} `_. + +For the full historical changelog, see +https://github.com/matrix-org/matrix-doc/blob/master/changelogs/rooms.rst + + +Some Module +----------- + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sit amet +eros turpis. Quisque commodo diam vel massa ultrices, vel egestas eros +dignissim. Sed sit amet lacus eget metus auctor malesuada at ut odio. +In turpis leo, viverra et mi porttitor, condimentum bibendum dolor. + +.. {-{versioned_test_definition}-} diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst new file mode 100644 index 00000000..6c6795a4 --- /dev/null +++ b/specification/rooms/v1.rst @@ -0,0 +1,112 @@ +.. 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. + + +.. Note: This document appended to the end of the intro, so this next line +.. appears under "Other Room Versions". + +This is the specification for **room version 1** (``"1"``). + +Changelog +--------- + +.. topic:: Room version 1 +{{rooms_changelog_v1}} + +This version of the specification is generated from +`matrix-doc `_ as of Git commit +`{{git_version}} `_. + +For the full historical changelog, see +https://github.com/matrix-org/matrix-doc/blob/master/changelogs/rooms.rst + + +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 be aware that inconsistencies + may occur until room version 2 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`: ../server_server/unstable.html#authorization-rules diff --git a/specification/rooms/v2.rst b/specification/rooms/v2.rst new file mode 100644 index 00000000..a000f056 --- /dev/null +++ b/specification/rooms/v2.rst @@ -0,0 +1,181 @@ +.. 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. + + +.. Note: This document appended to the end of the intro, so this next line +.. appears under "Other Room Versions". + +This is the specification for **room version 2** (``"2"``). + +.. Warning:: + + Room version 2 is under development and cannot be relied on in production + environments. + + +Changelog +--------- + +.. topic:: Room version 2 +{{rooms_changelog_v2}} + +This version of the specification is generated from +`matrix-doc `_ as of Git commit +`{{git_version}} `_. + +For the full historical changelog, see +https://github.com/matrix-org/matrix-doc/blob/master/changelogs/rooms.rst + + +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 2 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. + + +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 have + may 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 Date: Mon, 7 Jan 2019 02:42:03 +0000 Subject: [PATCH 0050/1250] MSC1779: Open Governance for Matrix.org --- proposals/1779-open-governance.md | 386 ++++++++++++++++++++++++++++++ 1 file changed, 386 insertions(+) create mode 100644 proposals/1779-open-governance.md diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md new file mode 100644 index 00000000..a79d175b --- /dev/null +++ b/proposals/1779-open-governance.md @@ -0,0 +1,386 @@ +# Proposal for Open Governance of Matrix.org + +This whole document is a **work in progress** draft of a constitution proposal +for open governance for Matrix.org, and forms the basis of the first full +Articles of Association (AoA) for [The Matrix.org Foundation +C.I.C.](https://beta.companieshouse.gov.uk/company/11648710) - a non-profit legal +entity incorporated to act as the neutral guardian of the Matrix decentralised +communication standard on behalf of the whole Matrix community. + +See https://matrix.org/blog/2018/10/29/introducing-the-matrix-org-foundation-part-1-of-2/ +for more context. + +This obsoletes [MSC1318](https://github.com/matrix-org/matrix-doc/issues/1318) + +## Introduction + +Historically the core team of Matrix has been paid to work on it by the same +employer (currently New Vector; the startup incorporated to hire the core +team in Aug 2017). Whilst convenient in initially getting Matrix built, we +recognise that this could create a potential conflict of interest between the +core team’s responsibilities to neutrally support the wider Matrix.org ecosystem +versus the need for New Vector to be able to support the team, and it has always +been the plan to set up a completely neutral custodian for the standard once it +had reached sufficient maturity. + +This proposal seeks to establish a new open governance process for Matrix.org, +such that once the specification has finally been ‘born’ and reached an initial +‘r0’ release across all APIs, control of Matrix.org can be decoupled from New +Vector and better support contributions from the whole ecosystem. + +The concepts here are somewhat inspired by [Rust’s Governance +Model](https://github.com/rust-lang/rfcs/blob/master/text/1068-rust- +governance.md); a highly regarded solution to a similar problem: an ambitious +open-source project which has been too many years in the making, incubated at +first by a single company (Mozilla Corporation), which also enjoys a very +enthusiastic community! + +## Overview + +Governance of the project is split into two teams: the Spec Core Team and the +Guardians of the Foundation. In brief: + +The Spec Core Team are the technical experts who curate and edit the Matrix +Specification from day to day, and so steer the evolution of the protocol by +having final review over which Matrix Spec Changes (MSCs) are merged into the +core spec. + +The Guardians are the legal directors of the non-profit Foundation, and are +responsible for ensuring that the Foundation (and by extension the Spec Core +Team) keeps on mission and neutrally protects the development of Matrix. +Guardians are typically independent of the commercial Matrix ecosystem and may +even not be members of today’s Matrix community, but are deeply aligned with the +mission of the project, and who are respected and trusted by the wider community +to uphold the guiding principles of the Foundation and keep the other Guardians +honest. + +In other words; the Spec Core Team builds the spec, and the Guardians provide an +independent backstop to ensure the spec evolves in line with the Foundation's +mission. + +## Guiding Principles + +The guiding principles define the core philosophy of the project, and will be a +formal part of the final Articles of Association of the Matrix.org Foundation. + +### Matrix Manifesto + +We believe: + + * People should have full control over their own communication. + + * People should not be locked into centralised communication silos, but free to + pick who they choose to host their communication without limiting who they + can reach. + + * The ability to converse securely and privately is a basic human right. + + * Communication should be available to everyone as an free and open, + unencumbered, standard and global network. + +### Mission + +The Matrix.org Foundation exists to act as a neutral custodian for Matrix and +nurture it as efficiently as possible as a single unfragmented standard, for the +greater benefit of the whole ecosystem; not benefiting or privileging any single +player or subset of players. + +For clarity: the Matrix ecosystem is defined as anyone who uses the Matrix +protocol. This includes (non-exhaustively): + + * End-users of Matrix clients + * Matrix client developers and testers + * Spec developers + * Server admins + * Matrix packagers & maintainers + * Companies building products or services on Matrix + * Bridge developers + * Bot developers + * Widget developers + * Server developers + * Matrix room and community moderators + * End-users who are using Matrix indirectly via bridges + * External systems which are bridged into Matrix + * Anyone using Matrix for data communications + +"Greater benefit" is defined as maximising: + + * the number of end-users reachable on the open Matrix network + * the number of regular users on the Matrix network (e.g. 30-day retained federated users) + * the number of end-users reachable by Matrix (natively or via bridges) + * the number of online servers in the open federation + * the number of developers building on Matrix + * the number of independent implementations which use Matrix + * the quality and utility of the Matrix spec (as defined by ease and ability + with which a developer can implement spec-compliant clients, servers, bots, + bridges, and other integrations without needing to refer to any other + external material) + +N.B. that we consider success to be the growth of the open federated network +rather than closed deployments. For example, if WhatsApp adopted Matrix it +wouldn’t be a complete win unless they openly federated with the rest of the +Matrix network. + +### Values + +As Matrix evolves, it's critical that the Spec Core Team and Guardians are +aligned on the overall philosophy of the project, particularly in more +subjective areas. The values we follow are: + + * Supporting the whole long-term ecosystem rather than individual stakeholder gain + * Openness rather than proprietariness + * Collaboration rather than competition + * Accessibility rather than elitism + * Transparency rather than stealth + * Empathy rather than contrariness + * Pragmatism rather than perfection + * Proof rather than conjecture + +Patent encumbered IP is strictly prohibited from being added to the standard. + +## The Spec Core Team + +The contents and direction of the Matrix Spec is governed by the Spec Core Team; +a set of experts from across the whole Matrix community, representing all +aspects of the Matrix ecosystem. The Spec Core Team acts as a subcommittee of +the Foundation. + +Members of the Spec Core Team pledge to act as a neutral custodian for Matrix on +behalf of the whole ecosystem and uphold the Guiding Principles of the project +as outlined above. In particular, they agree to drive the adoption of Matrix as +a single global federation, an open standard unencumbered from any proprietary +IP or software patents, minimising fragmentation (whilst encouraging +experimentation), evolving rapidly, and prioritising the long-term success and +growth of the overall network over individual commercial concerns. + +Spec Core Team members need to have significant proven domain experience/skill +and have had clear dedication and commitment to the project and community for >6 +months. (In future, once we have subteams a la Rust, folks need to have proven +themselves there first). + +Members need to demonstrate ability to work constructively with the rest of the +team; we want participation in the Spec Core Team to be an efficient, pleasant and +productive place, even in the face of inevitable disagreement. We do not want a +toxic culture of bullying or competitive infighting. Folks need to be able to +compromise; we are not building a culture of folks pushing their personal +agendas at the expense of the overall project. + +We are particularly vigilant against 'trojan horse' additions to the spec - +features which only benefit particular players, or are designed to somehow +cripple or fragment the open protocol and ecosystem in favour of competitive +advantage. Commercial players are of course encouraged to build proprietary +implementations, or use custom event types, or even custom API extensions (e.g. +more efficient network transports) - but implementations must fall back to +interoperating correctly with the rest of the ecosystem. + +### Spec Core Team logistics + +The Spec Core Team itself will be made up of roughly 8 members + 1 project lead. +Roughly half the members are expected to be from the historical core team +(similar to Rust). + +In future we may also have sub-teams (like Rust - e.g. CS/AS/Push API; SS API; +IS API; Crypto), but as a starting point we are beginning with a single core +team in the interests of not over-engineering it and scaling up elastically. + +Spec Core Team members need to be able to commit to at least 1 hour a week of +availability to work on the spec and (where relevant) reference implementations. +Members of the team volunteer their time for free to work on the project. + +Responsibilities include: + + * Reviewing Matrix Spec Change proposals and Spec PRs + + * Contributing to and reviewing reference implementations of Matrix Spec Change + proposals + + * Shepherding Matrix Spec Changes on behalf of authors where needed + + * Triaging Matrix Spec issues + + * Coordinating reference implementations + + * Ensuring the code of conduct for +matrix:matrix.org community rooms is + maintained and applied + +If members are absent for more than 8 weeks without prior agreement, they will +be assumed to have left the project. + +Spec Core Team members can resign whenever they want, but must notify the rest +of the team and the Guardians on doing so. + +New additions to the team require 100% consent from the current team members. +Membership has to be formally proposed by someone already on the Spec Core Team. + +Members can be removed from the team if X% of the team agrees they are no longer +following the goals and guiding principles of the project. + +Guardians act as a backstop, and can appoint or remove Spec Core Team members +(requiring a 75% consensus threshold between the Guardians) if the Spec Core +Team is unable to reach consensus or is failing to align with the Foundation's +mission. + +It's suggested that one of the Spec Core Team members is also be a Guardian, to +facilitate information between the Guardians and the Spec Core Team and +represent the technical angle of the project to the other Guardians. + +The project lead role acts to coordinate the team and to help tie-break in the +event of failing to get acceptance on a Matrix Spec Change. The project lead is +reviewed every 12 months and requires the confidence of 75% of the team to be +renewed. There is no maximum term for the project lead. The lead may be removed +by the core team at any point (with 75% majority), and may resign the role at +any point (notifying the team and the Guardians). The lead automatically resigns +the role if they resign from the Spec Core Team. + +The initial Spec Core Team (and their domain areas) is: + + * Matthew Hodgson (Lead) + * Erik Johnston (Servers) + * Richard van der Hoff (Servers, Cryptography) + * David Baker (Clients, IS API, Push API, Media) + * Hubert Chathi (Cryptography, General) + * Andrew Morgan (Servers, AS API, Spec Process) + * Travis Ralston (Bots and Bridges & AS API, Media, acting with Dimension hat on) + * kitsune (Clients on behalf of Community) + * TBD + +MSCs require >= 75% approval from the Spec Core Team to proceed to Final Comment +Period (see https://matrix.org/docs/spec/proposals for the rest of the MSC +process). + +The above governance process for the Spec Core Team is considered as part of the +spec and is updated using the Matrix Spec Change process. However, changes to +the governance process also require a 75% positive approval from the Guardians +(acting as a formal decision of the Foundation's Directors), in order to ensure +changes are aligned with the Foundation's mission. + +## The Guardians + +*This section will be used as the basis for the legal responsibilities of +Directors in the Articles of Association of the Foundation.* + +The Guardians form the legal Board of Directors of The Matrix.org Foundation CIC +(Community Interest Company). They are responsible for ensuring the Foundation +is following its guiding principles, and provide a safety mechanism if the +structure of the Spec Core Team runs into trouble. + +In practice, this means that: + * Guardians must approve changes to the Spec Core Team + * Guardians must keep each other honest, providing a ‘checks and balances’ + mechanism between each other to ensure that all Guardians and the Spec Core + Team act in the best interests of the protocol and ecosystem. + * Guardians may appoint/dismiss members of the Spec Core Team who are in serious + breach of the guiding principles. + * Guardians must approve changes to the Guiding Principles (above) + * Guardians are responsible for approving use of the Foundation's assets + (e.g. redistributing donations) + * In future, Guardians may also be responsible for ensuring staff are hired by + the Foundation to support administrative functions + * As well as the Spec Core Team committee, they may also oversee committees for + other areas such as marketing Matrix.org, registering custom event types, + or "Made for Matrix" certification. + * It's likely a subset of Guardians will be hands-on for day-to-day + administrative purposes, whilst the others act to keep them in balance. + +Guardians are chosen typically to be independent of the commercial Matrix +ecosystem (and especially independent from New Vector), and may even not be +members of today’s Matrix community. However, they should be deeply aligned with +the mission of the project, and respected and trusted by the wider community to +uphold the guiding principles of the Foundation and keep the other Guardians +honest. + +Guardians are responsible for maintaining and updating the Guiding +Principles and Articles of Association of the Foundation if/when +necessary. Changes to the Guiding Principles require a 75% majority from the +Guardians and are passed as a 'special resolution' of the board. + +New Guardians may be appointed with a 75% majority by the board. + +Guardians may resign at any time, with notification to the board. + +Guardians may be removed due to serious breach of the guiding principles with a +75% majority of the other Guardians, or if absent from 3 consecutive board +meetings, or if they are legally disqualified from acting as a Director. + +We aim to recruit roughly 5 Guardians. The initial Guardians are: + + * Matthew Hodgson (CEO/CTO, New Vector) + * Amandine Le Pape (COO, New Vector) + * TBA (agreed, needs paperwork) + * TBD + * TBD + +The intention is for Matthew & Amandine (the original founders of Matrix) to +form a minority of the Guardians, in order to ensure the neutrality of the +Foundation relative to Matthew & Amandine’s day jobs at New Vector. + +Guardians volunteer their time for free to work on the project. + +## The Core Team + +"The Core Team" is a loose term that describes the set of people with access to +commit code to the public https://github.com/matrix-org repositories, who are +either working on matrix.org's reference implementations or the spec itself. +Commit access is decided by those responsible for the projects in question, much +like any other open source project. Anyone is eligible for commit access if +they have proved themselves a valuable long-term contributor, upholds the +guiding principles and mission of the project and have proved themselves able to +collaborate constructively with the existing core team. + +## Responsibilities for the Foundation + + * Independent legal entity to act as neutral custodian of Matrix + * Gathering donations + * Owns the core Matrix IP in an asset lock, which shall be transferred from New Vector: + * Owns the matrix.org domain and branding + * Owns the copyright of the reference implementations of Matrix (i.e. everything in https://github.com/matrix-org). + By assigning copyright to the Foundation, it’s protected against New Vector ever being tempted to relicense it. + * Owns the IP of the website + * Owns the Matrix.org marketing swag (t-shirts, stickers, exhibition stands etc) + * It's responsible for finding someone to run the Matrix.org homeserver (currently New Vector) + * Publishing the spec + * Responsible for sytest + * Manages IANA-style allocations for Matrix + * mx:// URI scheme? + * TCP port 8448 + * .well-known URIs…? + +In future: + + * contract entities to work on Matrix? (e.g. redistributing donations back to fund development) + * manage a Matrix certification process? + * promote Matrix (e.g. organise meetups & events & fund community activity)? + +## Timings + +The Foundation was incorporated in October 2018 as a UK limited by guarantee +private company, using generic non-profit articles of association combined with +a high-level mission lock aligned with the above: + +> 4. The objects of the Foundation are for the benefit of the community as a whole +> to: + +> 4.1.1 empower users to control their communication data and have freedom over +> their communications infrastructure by creating, maintaining and promoting +> Matrix as an openly standardised secure decentralised communication protocol and +> network, open to all, and available to the public for no charge; + +> 4.1.2 build and develop an appropriate governance model for Matrix through the +> Foundation, in order to drive the adoption of Matrix as a single global +> federation, an open standard unencumbered from any proprietary intellectual +> property and/or software patents, minimising fragmentation (whilst encouraging +> experimentation), maximising speed of development, and prioritising the long- +> term success and growth of the overall network over the commercial concerns of +> an individual person or persons. + +The foundation was then converted into a Community Interest Company, formalising +its non-profit status under the approval of the independent [Community Interest +Companies Regulator](https://www.gov.uk/government/organisations/office-of-the- +regulator- of-community-interest-companies), which took effect Jan 2019. + +We are currently planning to release r0 of the Matrix Spec at the end of Jan 2019, and +finalise the Foundation's articles of association shortly afterwards based on the +contents of this MSC once passed FCP. + +This will coincide with the formal asset transfer of Matrix.org's assets from +New Vector Ltd, and the appointment of the remaining Guardians. From bd72ecfa58f7a565216372c247490095496d1c4c Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 7 Jan 2019 02:43:21 +0000 Subject: [PATCH 0051/1250] oops, wrong branch --- proposals/1779-open-governance.md | 386 ------------------------------ 1 file changed, 386 deletions(-) delete mode 100644 proposals/1779-open-governance.md diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md deleted file mode 100644 index a79d175b..00000000 --- a/proposals/1779-open-governance.md +++ /dev/null @@ -1,386 +0,0 @@ -# Proposal for Open Governance of Matrix.org - -This whole document is a **work in progress** draft of a constitution proposal -for open governance for Matrix.org, and forms the basis of the first full -Articles of Association (AoA) for [The Matrix.org Foundation -C.I.C.](https://beta.companieshouse.gov.uk/company/11648710) - a non-profit legal -entity incorporated to act as the neutral guardian of the Matrix decentralised -communication standard on behalf of the whole Matrix community. - -See https://matrix.org/blog/2018/10/29/introducing-the-matrix-org-foundation-part-1-of-2/ -for more context. - -This obsoletes [MSC1318](https://github.com/matrix-org/matrix-doc/issues/1318) - -## Introduction - -Historically the core team of Matrix has been paid to work on it by the same -employer (currently New Vector; the startup incorporated to hire the core -team in Aug 2017). Whilst convenient in initially getting Matrix built, we -recognise that this could create a potential conflict of interest between the -core team’s responsibilities to neutrally support the wider Matrix.org ecosystem -versus the need for New Vector to be able to support the team, and it has always -been the plan to set up a completely neutral custodian for the standard once it -had reached sufficient maturity. - -This proposal seeks to establish a new open governance process for Matrix.org, -such that once the specification has finally been ‘born’ and reached an initial -‘r0’ release across all APIs, control of Matrix.org can be decoupled from New -Vector and better support contributions from the whole ecosystem. - -The concepts here are somewhat inspired by [Rust’s Governance -Model](https://github.com/rust-lang/rfcs/blob/master/text/1068-rust- -governance.md); a highly regarded solution to a similar problem: an ambitious -open-source project which has been too many years in the making, incubated at -first by a single company (Mozilla Corporation), which also enjoys a very -enthusiastic community! - -## Overview - -Governance of the project is split into two teams: the Spec Core Team and the -Guardians of the Foundation. In brief: - -The Spec Core Team are the technical experts who curate and edit the Matrix -Specification from day to day, and so steer the evolution of the protocol by -having final review over which Matrix Spec Changes (MSCs) are merged into the -core spec. - -The Guardians are the legal directors of the non-profit Foundation, and are -responsible for ensuring that the Foundation (and by extension the Spec Core -Team) keeps on mission and neutrally protects the development of Matrix. -Guardians are typically independent of the commercial Matrix ecosystem and may -even not be members of today’s Matrix community, but are deeply aligned with the -mission of the project, and who are respected and trusted by the wider community -to uphold the guiding principles of the Foundation and keep the other Guardians -honest. - -In other words; the Spec Core Team builds the spec, and the Guardians provide an -independent backstop to ensure the spec evolves in line with the Foundation's -mission. - -## Guiding Principles - -The guiding principles define the core philosophy of the project, and will be a -formal part of the final Articles of Association of the Matrix.org Foundation. - -### Matrix Manifesto - -We believe: - - * People should have full control over their own communication. - - * People should not be locked into centralised communication silos, but free to - pick who they choose to host their communication without limiting who they - can reach. - - * The ability to converse securely and privately is a basic human right. - - * Communication should be available to everyone as an free and open, - unencumbered, standard and global network. - -### Mission - -The Matrix.org Foundation exists to act as a neutral custodian for Matrix and -nurture it as efficiently as possible as a single unfragmented standard, for the -greater benefit of the whole ecosystem; not benefiting or privileging any single -player or subset of players. - -For clarity: the Matrix ecosystem is defined as anyone who uses the Matrix -protocol. This includes (non-exhaustively): - - * End-users of Matrix clients - * Matrix client developers and testers - * Spec developers - * Server admins - * Matrix packagers & maintainers - * Companies building products or services on Matrix - * Bridge developers - * Bot developers - * Widget developers - * Server developers - * Matrix room and community moderators - * End-users who are using Matrix indirectly via bridges - * External systems which are bridged into Matrix - * Anyone using Matrix for data communications - -"Greater benefit" is defined as maximising: - - * the number of end-users reachable on the open Matrix network - * the number of regular users on the Matrix network (e.g. 30-day retained federated users) - * the number of end-users reachable by Matrix (natively or via bridges) - * the number of online servers in the open federation - * the number of developers building on Matrix - * the number of independent implementations which use Matrix - * the quality and utility of the Matrix spec (as defined by ease and ability - with which a developer can implement spec-compliant clients, servers, bots, - bridges, and other integrations without needing to refer to any other - external material) - -N.B. that we consider success to be the growth of the open federated network -rather than closed deployments. For example, if WhatsApp adopted Matrix it -wouldn’t be a complete win unless they openly federated with the rest of the -Matrix network. - -### Values - -As Matrix evolves, it's critical that the Spec Core Team and Guardians are -aligned on the overall philosophy of the project, particularly in more -subjective areas. The values we follow are: - - * Supporting the whole long-term ecosystem rather than individual stakeholder gain - * Openness rather than proprietariness - * Collaboration rather than competition - * Accessibility rather than elitism - * Transparency rather than stealth - * Empathy rather than contrariness - * Pragmatism rather than perfection - * Proof rather than conjecture - -Patent encumbered IP is strictly prohibited from being added to the standard. - -## The Spec Core Team - -The contents and direction of the Matrix Spec is governed by the Spec Core Team; -a set of experts from across the whole Matrix community, representing all -aspects of the Matrix ecosystem. The Spec Core Team acts as a subcommittee of -the Foundation. - -Members of the Spec Core Team pledge to act as a neutral custodian for Matrix on -behalf of the whole ecosystem and uphold the Guiding Principles of the project -as outlined above. In particular, they agree to drive the adoption of Matrix as -a single global federation, an open standard unencumbered from any proprietary -IP or software patents, minimising fragmentation (whilst encouraging -experimentation), evolving rapidly, and prioritising the long-term success and -growth of the overall network over individual commercial concerns. - -Spec Core Team members need to have significant proven domain experience/skill -and have had clear dedication and commitment to the project and community for >6 -months. (In future, once we have subteams a la Rust, folks need to have proven -themselves there first). - -Members need to demonstrate ability to work constructively with the rest of the -team; we want participation in the Spec Core Team to be an efficient, pleasant and -productive place, even in the face of inevitable disagreement. We do not want a -toxic culture of bullying or competitive infighting. Folks need to be able to -compromise; we are not building a culture of folks pushing their personal -agendas at the expense of the overall project. - -We are particularly vigilant against 'trojan horse' additions to the spec - -features which only benefit particular players, or are designed to somehow -cripple or fragment the open protocol and ecosystem in favour of competitive -advantage. Commercial players are of course encouraged to build proprietary -implementations, or use custom event types, or even custom API extensions (e.g. -more efficient network transports) - but implementations must fall back to -interoperating correctly with the rest of the ecosystem. - -### Spec Core Team logistics - -The Spec Core Team itself will be made up of roughly 8 members + 1 project lead. -Roughly half the members are expected to be from the historical core team -(similar to Rust). - -In future we may also have sub-teams (like Rust - e.g. CS/AS/Push API; SS API; -IS API; Crypto), but as a starting point we are beginning with a single core -team in the interests of not over-engineering it and scaling up elastically. - -Spec Core Team members need to be able to commit to at least 1 hour a week of -availability to work on the spec and (where relevant) reference implementations. -Members of the team volunteer their time for free to work on the project. - -Responsibilities include: - - * Reviewing Matrix Spec Change proposals and Spec PRs - - * Contributing to and reviewing reference implementations of Matrix Spec Change - proposals - - * Shepherding Matrix Spec Changes on behalf of authors where needed - - * Triaging Matrix Spec issues - - * Coordinating reference implementations - - * Ensuring the code of conduct for +matrix:matrix.org community rooms is - maintained and applied - -If members are absent for more than 8 weeks without prior agreement, they will -be assumed to have left the project. - -Spec Core Team members can resign whenever they want, but must notify the rest -of the team and the Guardians on doing so. - -New additions to the team require 100% consent from the current team members. -Membership has to be formally proposed by someone already on the Spec Core Team. - -Members can be removed from the team if X% of the team agrees they are no longer -following the goals and guiding principles of the project. - -Guardians act as a backstop, and can appoint or remove Spec Core Team members -(requiring a 75% consensus threshold between the Guardians) if the Spec Core -Team is unable to reach consensus or is failing to align with the Foundation's -mission. - -It's suggested that one of the Spec Core Team members is also be a Guardian, to -facilitate information between the Guardians and the Spec Core Team and -represent the technical angle of the project to the other Guardians. - -The project lead role acts to coordinate the team and to help tie-break in the -event of failing to get acceptance on a Matrix Spec Change. The project lead is -reviewed every 12 months and requires the confidence of 75% of the team to be -renewed. There is no maximum term for the project lead. The lead may be removed -by the core team at any point (with 75% majority), and may resign the role at -any point (notifying the team and the Guardians). The lead automatically resigns -the role if they resign from the Spec Core Team. - -The initial Spec Core Team (and their domain areas) is: - - * Matthew Hodgson (Lead) - * Erik Johnston (Servers) - * Richard van der Hoff (Servers, Cryptography) - * David Baker (Clients, IS API, Push API, Media) - * Hubert Chathi (Cryptography, General) - * Andrew Morgan (Servers, AS API, Spec Process) - * Travis Ralston (Bots and Bridges & AS API, Media, acting with Dimension hat on) - * kitsune (Clients on behalf of Community) - * TBD - -MSCs require >= 75% approval from the Spec Core Team to proceed to Final Comment -Period (see https://matrix.org/docs/spec/proposals for the rest of the MSC -process). - -The above governance process for the Spec Core Team is considered as part of the -spec and is updated using the Matrix Spec Change process. However, changes to -the governance process also require a 75% positive approval from the Guardians -(acting as a formal decision of the Foundation's Directors), in order to ensure -changes are aligned with the Foundation's mission. - -## The Guardians - -*This section will be used as the basis for the legal responsibilities of -Directors in the Articles of Association of the Foundation.* - -The Guardians form the legal Board of Directors of The Matrix.org Foundation CIC -(Community Interest Company). They are responsible for ensuring the Foundation -is following its guiding principles, and provide a safety mechanism if the -structure of the Spec Core Team runs into trouble. - -In practice, this means that: - * Guardians must approve changes to the Spec Core Team - * Guardians must keep each other honest, providing a ‘checks and balances’ - mechanism between each other to ensure that all Guardians and the Spec Core - Team act in the best interests of the protocol and ecosystem. - * Guardians may appoint/dismiss members of the Spec Core Team who are in serious - breach of the guiding principles. - * Guardians must approve changes to the Guiding Principles (above) - * Guardians are responsible for approving use of the Foundation's assets - (e.g. redistributing donations) - * In future, Guardians may also be responsible for ensuring staff are hired by - the Foundation to support administrative functions - * As well as the Spec Core Team committee, they may also oversee committees for - other areas such as marketing Matrix.org, registering custom event types, - or "Made for Matrix" certification. - * It's likely a subset of Guardians will be hands-on for day-to-day - administrative purposes, whilst the others act to keep them in balance. - -Guardians are chosen typically to be independent of the commercial Matrix -ecosystem (and especially independent from New Vector), and may even not be -members of today’s Matrix community. However, they should be deeply aligned with -the mission of the project, and respected and trusted by the wider community to -uphold the guiding principles of the Foundation and keep the other Guardians -honest. - -Guardians are responsible for maintaining and updating the Guiding -Principles and Articles of Association of the Foundation if/when -necessary. Changes to the Guiding Principles require a 75% majority from the -Guardians and are passed as a 'special resolution' of the board. - -New Guardians may be appointed with a 75% majority by the board. - -Guardians may resign at any time, with notification to the board. - -Guardians may be removed due to serious breach of the guiding principles with a -75% majority of the other Guardians, or if absent from 3 consecutive board -meetings, or if they are legally disqualified from acting as a Director. - -We aim to recruit roughly 5 Guardians. The initial Guardians are: - - * Matthew Hodgson (CEO/CTO, New Vector) - * Amandine Le Pape (COO, New Vector) - * TBA (agreed, needs paperwork) - * TBD - * TBD - -The intention is for Matthew & Amandine (the original founders of Matrix) to -form a minority of the Guardians, in order to ensure the neutrality of the -Foundation relative to Matthew & Amandine’s day jobs at New Vector. - -Guardians volunteer their time for free to work on the project. - -## The Core Team - -"The Core Team" is a loose term that describes the set of people with access to -commit code to the public https://github.com/matrix-org repositories, who are -either working on matrix.org's reference implementations or the spec itself. -Commit access is decided by those responsible for the projects in question, much -like any other open source project. Anyone is eligible for commit access if -they have proved themselves a valuable long-term contributor, upholds the -guiding principles and mission of the project and have proved themselves able to -collaborate constructively with the existing core team. - -## Responsibilities for the Foundation - - * Independent legal entity to act as neutral custodian of Matrix - * Gathering donations - * Owns the core Matrix IP in an asset lock, which shall be transferred from New Vector: - * Owns the matrix.org domain and branding - * Owns the copyright of the reference implementations of Matrix (i.e. everything in https://github.com/matrix-org). - By assigning copyright to the Foundation, it’s protected against New Vector ever being tempted to relicense it. - * Owns the IP of the website - * Owns the Matrix.org marketing swag (t-shirts, stickers, exhibition stands etc) - * It's responsible for finding someone to run the Matrix.org homeserver (currently New Vector) - * Publishing the spec - * Responsible for sytest - * Manages IANA-style allocations for Matrix - * mx:// URI scheme? - * TCP port 8448 - * .well-known URIs…? - -In future: - - * contract entities to work on Matrix? (e.g. redistributing donations back to fund development) - * manage a Matrix certification process? - * promote Matrix (e.g. organise meetups & events & fund community activity)? - -## Timings - -The Foundation was incorporated in October 2018 as a UK limited by guarantee -private company, using generic non-profit articles of association combined with -a high-level mission lock aligned with the above: - -> 4. The objects of the Foundation are for the benefit of the community as a whole -> to: - -> 4.1.1 empower users to control their communication data and have freedom over -> their communications infrastructure by creating, maintaining and promoting -> Matrix as an openly standardised secure decentralised communication protocol and -> network, open to all, and available to the public for no charge; - -> 4.1.2 build and develop an appropriate governance model for Matrix through the -> Foundation, in order to drive the adoption of Matrix as a single global -> federation, an open standard unencumbered from any proprietary intellectual -> property and/or software patents, minimising fragmentation (whilst encouraging -> experimentation), maximising speed of development, and prioritising the long- -> term success and growth of the overall network over the commercial concerns of -> an individual person or persons. - -The foundation was then converted into a Community Interest Company, formalising -its non-profit status under the approval of the independent [Community Interest -Companies Regulator](https://www.gov.uk/government/organisations/office-of-the- -regulator- of-community-interest-companies), which took effect Jan 2019. - -We are currently planning to release r0 of the Matrix Spec at the end of Jan 2019, and -finalise the Foundation's articles of association shortly afterwards based on the -contents of this MSC once passed FCP. - -This will coincide with the formal asset transfer of Matrix.org's assets from -New Vector Ltd, and the appointment of the remaining Guardians. From 4538745809d15dbdc6107466f88193f555f3a948 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 7 Jan 2019 02:43:46 +0000 Subject: [PATCH 0052/1250] MSC1779: Open Governance for Matrix.org --- proposals/1779-open-governance.md | 386 ++++++++++++++++++++++++++++++ 1 file changed, 386 insertions(+) create mode 100644 proposals/1779-open-governance.md diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md new file mode 100644 index 00000000..a79d175b --- /dev/null +++ b/proposals/1779-open-governance.md @@ -0,0 +1,386 @@ +# Proposal for Open Governance of Matrix.org + +This whole document is a **work in progress** draft of a constitution proposal +for open governance for Matrix.org, and forms the basis of the first full +Articles of Association (AoA) for [The Matrix.org Foundation +C.I.C.](https://beta.companieshouse.gov.uk/company/11648710) - a non-profit legal +entity incorporated to act as the neutral guardian of the Matrix decentralised +communication standard on behalf of the whole Matrix community. + +See https://matrix.org/blog/2018/10/29/introducing-the-matrix-org-foundation-part-1-of-2/ +for more context. + +This obsoletes [MSC1318](https://github.com/matrix-org/matrix-doc/issues/1318) + +## Introduction + +Historically the core team of Matrix has been paid to work on it by the same +employer (currently New Vector; the startup incorporated to hire the core +team in Aug 2017). Whilst convenient in initially getting Matrix built, we +recognise that this could create a potential conflict of interest between the +core team’s responsibilities to neutrally support the wider Matrix.org ecosystem +versus the need for New Vector to be able to support the team, and it has always +been the plan to set up a completely neutral custodian for the standard once it +had reached sufficient maturity. + +This proposal seeks to establish a new open governance process for Matrix.org, +such that once the specification has finally been ‘born’ and reached an initial +‘r0’ release across all APIs, control of Matrix.org can be decoupled from New +Vector and better support contributions from the whole ecosystem. + +The concepts here are somewhat inspired by [Rust’s Governance +Model](https://github.com/rust-lang/rfcs/blob/master/text/1068-rust- +governance.md); a highly regarded solution to a similar problem: an ambitious +open-source project which has been too many years in the making, incubated at +first by a single company (Mozilla Corporation), which also enjoys a very +enthusiastic community! + +## Overview + +Governance of the project is split into two teams: the Spec Core Team and the +Guardians of the Foundation. In brief: + +The Spec Core Team are the technical experts who curate and edit the Matrix +Specification from day to day, and so steer the evolution of the protocol by +having final review over which Matrix Spec Changes (MSCs) are merged into the +core spec. + +The Guardians are the legal directors of the non-profit Foundation, and are +responsible for ensuring that the Foundation (and by extension the Spec Core +Team) keeps on mission and neutrally protects the development of Matrix. +Guardians are typically independent of the commercial Matrix ecosystem and may +even not be members of today’s Matrix community, but are deeply aligned with the +mission of the project, and who are respected and trusted by the wider community +to uphold the guiding principles of the Foundation and keep the other Guardians +honest. + +In other words; the Spec Core Team builds the spec, and the Guardians provide an +independent backstop to ensure the spec evolves in line with the Foundation's +mission. + +## Guiding Principles + +The guiding principles define the core philosophy of the project, and will be a +formal part of the final Articles of Association of the Matrix.org Foundation. + +### Matrix Manifesto + +We believe: + + * People should have full control over their own communication. + + * People should not be locked into centralised communication silos, but free to + pick who they choose to host their communication without limiting who they + can reach. + + * The ability to converse securely and privately is a basic human right. + + * Communication should be available to everyone as an free and open, + unencumbered, standard and global network. + +### Mission + +The Matrix.org Foundation exists to act as a neutral custodian for Matrix and +nurture it as efficiently as possible as a single unfragmented standard, for the +greater benefit of the whole ecosystem; not benefiting or privileging any single +player or subset of players. + +For clarity: the Matrix ecosystem is defined as anyone who uses the Matrix +protocol. This includes (non-exhaustively): + + * End-users of Matrix clients + * Matrix client developers and testers + * Spec developers + * Server admins + * Matrix packagers & maintainers + * Companies building products or services on Matrix + * Bridge developers + * Bot developers + * Widget developers + * Server developers + * Matrix room and community moderators + * End-users who are using Matrix indirectly via bridges + * External systems which are bridged into Matrix + * Anyone using Matrix for data communications + +"Greater benefit" is defined as maximising: + + * the number of end-users reachable on the open Matrix network + * the number of regular users on the Matrix network (e.g. 30-day retained federated users) + * the number of end-users reachable by Matrix (natively or via bridges) + * the number of online servers in the open federation + * the number of developers building on Matrix + * the number of independent implementations which use Matrix + * the quality and utility of the Matrix spec (as defined by ease and ability + with which a developer can implement spec-compliant clients, servers, bots, + bridges, and other integrations without needing to refer to any other + external material) + +N.B. that we consider success to be the growth of the open federated network +rather than closed deployments. For example, if WhatsApp adopted Matrix it +wouldn’t be a complete win unless they openly federated with the rest of the +Matrix network. + +### Values + +As Matrix evolves, it's critical that the Spec Core Team and Guardians are +aligned on the overall philosophy of the project, particularly in more +subjective areas. The values we follow are: + + * Supporting the whole long-term ecosystem rather than individual stakeholder gain + * Openness rather than proprietariness + * Collaboration rather than competition + * Accessibility rather than elitism + * Transparency rather than stealth + * Empathy rather than contrariness + * Pragmatism rather than perfection + * Proof rather than conjecture + +Patent encumbered IP is strictly prohibited from being added to the standard. + +## The Spec Core Team + +The contents and direction of the Matrix Spec is governed by the Spec Core Team; +a set of experts from across the whole Matrix community, representing all +aspects of the Matrix ecosystem. The Spec Core Team acts as a subcommittee of +the Foundation. + +Members of the Spec Core Team pledge to act as a neutral custodian for Matrix on +behalf of the whole ecosystem and uphold the Guiding Principles of the project +as outlined above. In particular, they agree to drive the adoption of Matrix as +a single global federation, an open standard unencumbered from any proprietary +IP or software patents, minimising fragmentation (whilst encouraging +experimentation), evolving rapidly, and prioritising the long-term success and +growth of the overall network over individual commercial concerns. + +Spec Core Team members need to have significant proven domain experience/skill +and have had clear dedication and commitment to the project and community for >6 +months. (In future, once we have subteams a la Rust, folks need to have proven +themselves there first). + +Members need to demonstrate ability to work constructively with the rest of the +team; we want participation in the Spec Core Team to be an efficient, pleasant and +productive place, even in the face of inevitable disagreement. We do not want a +toxic culture of bullying or competitive infighting. Folks need to be able to +compromise; we are not building a culture of folks pushing their personal +agendas at the expense of the overall project. + +We are particularly vigilant against 'trojan horse' additions to the spec - +features which only benefit particular players, or are designed to somehow +cripple or fragment the open protocol and ecosystem in favour of competitive +advantage. Commercial players are of course encouraged to build proprietary +implementations, or use custom event types, or even custom API extensions (e.g. +more efficient network transports) - but implementations must fall back to +interoperating correctly with the rest of the ecosystem. + +### Spec Core Team logistics + +The Spec Core Team itself will be made up of roughly 8 members + 1 project lead. +Roughly half the members are expected to be from the historical core team +(similar to Rust). + +In future we may also have sub-teams (like Rust - e.g. CS/AS/Push API; SS API; +IS API; Crypto), but as a starting point we are beginning with a single core +team in the interests of not over-engineering it and scaling up elastically. + +Spec Core Team members need to be able to commit to at least 1 hour a week of +availability to work on the spec and (where relevant) reference implementations. +Members of the team volunteer their time for free to work on the project. + +Responsibilities include: + + * Reviewing Matrix Spec Change proposals and Spec PRs + + * Contributing to and reviewing reference implementations of Matrix Spec Change + proposals + + * Shepherding Matrix Spec Changes on behalf of authors where needed + + * Triaging Matrix Spec issues + + * Coordinating reference implementations + + * Ensuring the code of conduct for +matrix:matrix.org community rooms is + maintained and applied + +If members are absent for more than 8 weeks without prior agreement, they will +be assumed to have left the project. + +Spec Core Team members can resign whenever they want, but must notify the rest +of the team and the Guardians on doing so. + +New additions to the team require 100% consent from the current team members. +Membership has to be formally proposed by someone already on the Spec Core Team. + +Members can be removed from the team if X% of the team agrees they are no longer +following the goals and guiding principles of the project. + +Guardians act as a backstop, and can appoint or remove Spec Core Team members +(requiring a 75% consensus threshold between the Guardians) if the Spec Core +Team is unable to reach consensus or is failing to align with the Foundation's +mission. + +It's suggested that one of the Spec Core Team members is also be a Guardian, to +facilitate information between the Guardians and the Spec Core Team and +represent the technical angle of the project to the other Guardians. + +The project lead role acts to coordinate the team and to help tie-break in the +event of failing to get acceptance on a Matrix Spec Change. The project lead is +reviewed every 12 months and requires the confidence of 75% of the team to be +renewed. There is no maximum term for the project lead. The lead may be removed +by the core team at any point (with 75% majority), and may resign the role at +any point (notifying the team and the Guardians). The lead automatically resigns +the role if they resign from the Spec Core Team. + +The initial Spec Core Team (and their domain areas) is: + + * Matthew Hodgson (Lead) + * Erik Johnston (Servers) + * Richard van der Hoff (Servers, Cryptography) + * David Baker (Clients, IS API, Push API, Media) + * Hubert Chathi (Cryptography, General) + * Andrew Morgan (Servers, AS API, Spec Process) + * Travis Ralston (Bots and Bridges & AS API, Media, acting with Dimension hat on) + * kitsune (Clients on behalf of Community) + * TBD + +MSCs require >= 75% approval from the Spec Core Team to proceed to Final Comment +Period (see https://matrix.org/docs/spec/proposals for the rest of the MSC +process). + +The above governance process for the Spec Core Team is considered as part of the +spec and is updated using the Matrix Spec Change process. However, changes to +the governance process also require a 75% positive approval from the Guardians +(acting as a formal decision of the Foundation's Directors), in order to ensure +changes are aligned with the Foundation's mission. + +## The Guardians + +*This section will be used as the basis for the legal responsibilities of +Directors in the Articles of Association of the Foundation.* + +The Guardians form the legal Board of Directors of The Matrix.org Foundation CIC +(Community Interest Company). They are responsible for ensuring the Foundation +is following its guiding principles, and provide a safety mechanism if the +structure of the Spec Core Team runs into trouble. + +In practice, this means that: + * Guardians must approve changes to the Spec Core Team + * Guardians must keep each other honest, providing a ‘checks and balances’ + mechanism between each other to ensure that all Guardians and the Spec Core + Team act in the best interests of the protocol and ecosystem. + * Guardians may appoint/dismiss members of the Spec Core Team who are in serious + breach of the guiding principles. + * Guardians must approve changes to the Guiding Principles (above) + * Guardians are responsible for approving use of the Foundation's assets + (e.g. redistributing donations) + * In future, Guardians may also be responsible for ensuring staff are hired by + the Foundation to support administrative functions + * As well as the Spec Core Team committee, they may also oversee committees for + other areas such as marketing Matrix.org, registering custom event types, + or "Made for Matrix" certification. + * It's likely a subset of Guardians will be hands-on for day-to-day + administrative purposes, whilst the others act to keep them in balance. + +Guardians are chosen typically to be independent of the commercial Matrix +ecosystem (and especially independent from New Vector), and may even not be +members of today’s Matrix community. However, they should be deeply aligned with +the mission of the project, and respected and trusted by the wider community to +uphold the guiding principles of the Foundation and keep the other Guardians +honest. + +Guardians are responsible for maintaining and updating the Guiding +Principles and Articles of Association of the Foundation if/when +necessary. Changes to the Guiding Principles require a 75% majority from the +Guardians and are passed as a 'special resolution' of the board. + +New Guardians may be appointed with a 75% majority by the board. + +Guardians may resign at any time, with notification to the board. + +Guardians may be removed due to serious breach of the guiding principles with a +75% majority of the other Guardians, or if absent from 3 consecutive board +meetings, or if they are legally disqualified from acting as a Director. + +We aim to recruit roughly 5 Guardians. The initial Guardians are: + + * Matthew Hodgson (CEO/CTO, New Vector) + * Amandine Le Pape (COO, New Vector) + * TBA (agreed, needs paperwork) + * TBD + * TBD + +The intention is for Matthew & Amandine (the original founders of Matrix) to +form a minority of the Guardians, in order to ensure the neutrality of the +Foundation relative to Matthew & Amandine’s day jobs at New Vector. + +Guardians volunteer their time for free to work on the project. + +## The Core Team + +"The Core Team" is a loose term that describes the set of people with access to +commit code to the public https://github.com/matrix-org repositories, who are +either working on matrix.org's reference implementations or the spec itself. +Commit access is decided by those responsible for the projects in question, much +like any other open source project. Anyone is eligible for commit access if +they have proved themselves a valuable long-term contributor, upholds the +guiding principles and mission of the project and have proved themselves able to +collaborate constructively with the existing core team. + +## Responsibilities for the Foundation + + * Independent legal entity to act as neutral custodian of Matrix + * Gathering donations + * Owns the core Matrix IP in an asset lock, which shall be transferred from New Vector: + * Owns the matrix.org domain and branding + * Owns the copyright of the reference implementations of Matrix (i.e. everything in https://github.com/matrix-org). + By assigning copyright to the Foundation, it’s protected against New Vector ever being tempted to relicense it. + * Owns the IP of the website + * Owns the Matrix.org marketing swag (t-shirts, stickers, exhibition stands etc) + * It's responsible for finding someone to run the Matrix.org homeserver (currently New Vector) + * Publishing the spec + * Responsible for sytest + * Manages IANA-style allocations for Matrix + * mx:// URI scheme? + * TCP port 8448 + * .well-known URIs…? + +In future: + + * contract entities to work on Matrix? (e.g. redistributing donations back to fund development) + * manage a Matrix certification process? + * promote Matrix (e.g. organise meetups & events & fund community activity)? + +## Timings + +The Foundation was incorporated in October 2018 as a UK limited by guarantee +private company, using generic non-profit articles of association combined with +a high-level mission lock aligned with the above: + +> 4. The objects of the Foundation are for the benefit of the community as a whole +> to: + +> 4.1.1 empower users to control their communication data and have freedom over +> their communications infrastructure by creating, maintaining and promoting +> Matrix as an openly standardised secure decentralised communication protocol and +> network, open to all, and available to the public for no charge; + +> 4.1.2 build and develop an appropriate governance model for Matrix through the +> Foundation, in order to drive the adoption of Matrix as a single global +> federation, an open standard unencumbered from any proprietary intellectual +> property and/or software patents, minimising fragmentation (whilst encouraging +> experimentation), maximising speed of development, and prioritising the long- +> term success and growth of the overall network over the commercial concerns of +> an individual person or persons. + +The foundation was then converted into a Community Interest Company, formalising +its non-profit status under the approval of the independent [Community Interest +Companies Regulator](https://www.gov.uk/government/organisations/office-of-the- +regulator- of-community-interest-companies), which took effect Jan 2019. + +We are currently planning to release r0 of the Matrix Spec at the end of Jan 2019, and +finalise the Foundation's articles of association shortly afterwards based on the +contents of this MSC once passed FCP. + +This will coincide with the formal asset transfer of Matrix.org's assets from +New Vector Ltd, and the appointment of the remaining Guardians. From 303e1081f8e0647b2acd67a4050793789cb5e2a7 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 7 Jan 2019 02:44:59 +0000 Subject: [PATCH 0053/1250] unbreak wordwrap --- proposals/1779-open-governance.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index a79d175b..cf5d0d20 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -375,8 +375,8 @@ a high-level mission lock aligned with the above: The foundation was then converted into a Community Interest Company, formalising its non-profit status under the approval of the independent [Community Interest -Companies Regulator](https://www.gov.uk/government/organisations/office-of-the- -regulator- of-community-interest-companies), which took effect Jan 2019. +Companies Regulator](https://www.gov.uk/government/organisations/office-of-the-regulator-of-community-interest-companies), +which took effect Jan 2019. We are currently planning to release r0 of the Matrix Spec at the end of Jan 2019, and finalise the Foundation's articles of association shortly afterwards based on the From e6fb403dd0919018fced9525412da6f9eaef6701 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 7 Jan 2019 02:47:37 +0000 Subject: [PATCH 0054/1250] add TODO for clarifying features v. extensions --- proposals/1779-open-governance.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index cf5d0d20..006d65b3 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -121,6 +121,10 @@ rather than closed deployments. For example, if WhatsApp adopted Matrix it wouldn’t be a complete win unless they openly federated with the rest of the Matrix network. +TODO: spell out when features should land in the spec, versus via +integration/widget or other non-core extension. e.g. should video conferencing +be in the spec itself, or done via Jitsi? + ### Values As Matrix evolves, it's critical that the Spec Core Team and Guardians are From c073adac9bbdaac30cc24e941185163da19cda12 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 7 Jan 2019 02:51:04 +0000 Subject: [PATCH 0055/1250] incorporate review from #1318 --- proposals/1779-open-governance.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 006d65b3..4fb564a5 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -344,6 +344,7 @@ collaborate constructively with the existing core team. * It's responsible for finding someone to run the Matrix.org homeserver (currently New Vector) * Publishing the spec * Responsible for sytest + * Publishing the website (including ensuring This Week In Matrix and similar exist to promote independent projects) * Manages IANA-style allocations for Matrix * mx:// URI scheme? * TCP port 8448 @@ -352,7 +353,7 @@ collaborate constructively with the existing core team. In future: * contract entities to work on Matrix? (e.g. redistributing donations back to fund development) - * manage a Matrix certification process? + * manage a "Made for Matrix" certification process? (to confirm that products are actually compatible with Matrix) * promote Matrix (e.g. organise meetups & events & fund community activity)? ## Timings From de6a8b20ff26f317d8a3ca8988f15cd59bd1d802 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 7 Jan 2019 02:53:49 +0000 Subject: [PATCH 0056/1250] grammar --- proposals/1779-open-governance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 4fb564a5..79213f89 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -10,7 +10,7 @@ communication standard on behalf of the whole Matrix community. See https://matrix.org/blog/2018/10/29/introducing-the-matrix-org-foundation-part-1-of-2/ for more context. -This obsoletes [MSC1318](https://github.com/matrix-org/matrix-doc/issues/1318) +This obsoletes [MSC1318](https://github.com/matrix-org/matrix-doc/issues/1318). ## Introduction From b8249067090fc533676d23fff7a13fd16fc4ee4f Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 7 Jan 2019 03:23:36 +0000 Subject: [PATCH 0057/1250] typoes --- proposals/1779-open-governance.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 79213f89..34230d70 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -29,8 +29,8 @@ such that once the specification has finally been ‘born’ and reached an init Vector and better support contributions from the whole ecosystem. The concepts here are somewhat inspired by [Rust’s Governance -Model](https://github.com/rust-lang/rfcs/blob/master/text/1068-rust- -governance.md); a highly regarded solution to a similar problem: an ambitious +Model](https://github.com/rust-lang/rfcs/blob/master/text/1068-rust-governance.md); +a highly regarded solution to a similar problem: an ambitious open-source project which has been too many years in the making, incubated at first by a single company (Mozilla Corporation), which also enjoys a very enthusiastic community! @@ -224,8 +224,8 @@ Guardians act as a backstop, and can appoint or remove Spec Core Team members Team is unable to reach consensus or is failing to align with the Foundation's mission. -It's suggested that one of the Spec Core Team members is also be a Guardian, to -facilitate information between the Guardians and the Spec Core Team and +It's suggested that one of the Spec Core Team members should also be a Guardian, +to facilitate information between the Guardians and the Spec Core Team and represent the technical angle of the project to the other Guardians. The project lead role acts to coordinate the team and to help tie-break in the From 258aba5fedf1fff17429494ff25f3a46827e8e5b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 7 Jan 2019 13:09:21 -0700 Subject: [PATCH 0058/1250] Incorporate MSC1693 This is largely blatant copy/paste from the MSC with some formatting done to tidy it up a bit. --- specification/rooms/v2.rst | 43 +++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/specification/rooms/v2.rst b/specification/rooms/v2.rst index a000f056..b04f94b4 100644 --- a/specification/rooms/v2.rst +++ b/specification/rooms/v2.rst @@ -155,7 +155,8 @@ Iterative auth checks 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. + state event from the event's ``auth_events`` is used if the auth event is + not rejected. Algorithm +++++++++ @@ -179,3 +180,43 @@ The *resolution* of a set of states is obtained as follows: .. _`authorization rules`: ../server_server/unstable.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. From 671527360cb68ad8cf789a743fd7bd42f8751e64 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 7 Jan 2019 13:16:45 -0700 Subject: [PATCH 0059/1250] Recommend some kind of WIP tag for MSCs --- specification/proposals_intro.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 73ace98e..0b69e846 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -231,7 +231,7 @@ Lifetime States =============================== ============================= ==================================== Name GitHub Label Description =============================== ============================= ==================================== -Proposal Drafting and Feedback N/A A proposal document which is still work-in-progress but is being shared to incorporate feedback +Proposal Drafting and Feedback N/A A proposal document which is still work-in-progress but is being shared to incorporate feedback. Please prefix your proposal's title with ``[WIP]`` to highlight this state. Proposal In Review proposal-in-review A proposal document which is now ready and waiting for review by the Core Team and community Proposed Final Comment Period proposed-final-comment-period Currently awaiting signoff of a majority of team members in order to enter the final comment period Final Comment Period final-comment-period A proposal document which has reached final comment period either for merge, closure or postponement From bc1303a1a06e6884e42b96518119e98d447daa41 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 7 Jan 2019 13:39:50 -0700 Subject: [PATCH 0060/1250] Add a bit of rationale for WIP tags --- specification/proposals_intro.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 0b69e846..96ffaafc 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -231,7 +231,7 @@ Lifetime States =============================== ============================= ==================================== Name GitHub Label Description =============================== ============================= ==================================== -Proposal Drafting and Feedback N/A A proposal document which is still work-in-progress but is being shared to incorporate feedback. Please prefix your proposal's title with ``[WIP]`` to highlight this state. +Proposal Drafting and Feedback N/A A proposal document which is still work-in-progress but is being shared to incorporate feedback. Please prefix your proposal's title with ``[WIP]`` to make it easier for reviewers to skim their notifications list. Proposal In Review proposal-in-review A proposal document which is now ready and waiting for review by the Core Team and community Proposed Final Comment Period proposed-final-comment-period Currently awaiting signoff of a majority of team members in order to enter the final comment period Final Comment Period final-comment-period A proposal document which has reached final comment period either for merge, closure or postponement From ccc1cdaeadd5a207cc3f23c938e46512e994204b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 7 Jan 2019 14:38:21 -0700 Subject: [PATCH 0061/1250] Add support for unstable feature advertising via /versions Incorporates https://github.com/matrix-org/matrix-doc/issues/1497 --- api/client-server/versions.yaml | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/api/client-server/versions.yaml b/api/client-server/versions.yaml index d3aa0359..4d0fd49e 100644 --- a/api/client-server/versions.yaml +++ b/api/client-server/versions.yaml @@ -33,13 +33,25 @@ paths: Only the latest ``Z`` value will be reported for each supported ``X.Y`` value. i.e. if the server implements ``r0.0.0``, ``r0.0.1``, and ``r1.2.0``, it will report ``r0.0.1`` and ``r1.2.0``. + + The server may additionally advertise experimental features it supports + through ``unstable_features``. These features should be namespaced and + may optionally include version information within their name if desired. + Features listed here are not for optionally toggling parts of the Matrix + specification and should only be used to advertise support for a feature + which has not yet landed in the spec. For example, an accepted proposal + for a feature needing implementation would advertise itself here with + the intention of being removed from this list once the spec changes land. operationId: getVersions responses: 200: description: The versions supported by the server. examples: application/json: { - "versions": ["r0.0.1"] + "versions": ["r0.0.1"], + "unstable_features": { + "org.example.my_feature": true + } } schema: type: object @@ -50,5 +62,15 @@ paths: items: type: string description: The supported versions + unstable_features: + type: object + description: |- + Experimental features the server supports. Features not listed here, + or the lack of this property all together, indicate that a feature is + not supported. + additionalProperties: + type: boolean + description: Whether or not the namespaced feature is supported. + required: ['versions'] tags: - Server administration From 367f61f14a0f475f0f95c77cd2cd27254e0e7124 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 7 Jan 2019 21:38:41 +0000 Subject: [PATCH 0062/1250] cleanups and clarifications --- proposals/1711-x509-for-federation.md | 44 ++++++++++++++++++--------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/proposals/1711-x509-for-federation.md b/proposals/1711-x509-for-federation.md index 82881d93..dc737ff6 100644 --- a/proposals/1711-x509-for-federation.md +++ b/proposals/1711-x509-for-federation.md @@ -58,17 +58,18 @@ We propose that Matrix homeservers should be required to present valid TLS certificates, signed by a known Certificate Authority, on their federation port. -In order to ease transition, we could continue to follow the current, -perspectives-based approach for servers whose TLS certificates fail -validation. However, this should be strictly time-limited (for three months, -say), to give administrators time to switch to a signed certificate. The -`matrix.org` team would proactively attempt to reach out to homeserver -administrators who do not update their certificate. - -Once the transition to CA-signed certificates is complete, the +In order to ease transition and give administrators time to switch to a signed +certificate, we will continue to follow the current, perspectives-based +approach for servers whose TLS certificates fail validation. + +However, this fallback will be strictly time-limited, and Matrix S2S spec r0 +will not accept self-signed certificates, nor will it include the `tls_fingerprints` property of the [`/_matrix/key/v2`](https://matrix.org/docs/spec/server_server/unstable.html#retrieving-server-keys) -endpoints would be redundant and we should consider removing it. +endpoints. Synapse 1.0 will not accept self-signed certificates by default. + +The `matrix.org` team will proactively attempt to reach out to homeserver +administrators who do not update their certificates in the coming weeks. The process of determining which CAs are trusted to sign certificates would be implementation-specific, though it should almost certainly make use of existing @@ -76,6 +77,12 @@ operating-system support for maintaining such lists. It might also be useful if administrators could override this list, for the purpose of setting up a private federation using their own CA. +It would also be useful for administrators to be able to disable the +certificate checks for a whitelist of domains/netmasks. This would be useful +for `.onion` domains (where a certificate is hard to obtain, and where server +verification is provided at the network level), as well as for testing with IP +literals. + ### Interaction with SRV records With the use of `SRV` records, it is possible for the hostname of a homeserver @@ -93,7 +100,10 @@ intercepted by a MitM who can control the DNS response for the `SRV` record This will be in line with the current [requirements](https://matrix.org/docs/spec/server_server/unstable.html#resolving-server-names) in the Federation API specification for the `Host`, and by implication, the TLS -Server Name Indication [2](#f2). +Server Name Indication [2](#f2). It is also consistent with +the recommendations of +[RFC6125](https://tools.ietf.org/html/rfc6125#section-6.2.1) and the +conventions established by the XMPP protocol (per [RFC6120](https://tools.ietf.org/html/rfc6120#section-13.7.2.1). ### Interaction with `.well-known` files @@ -133,9 +143,9 @@ of Certificate Transparency. The Perspectives approach is also currently used for exchanging the keys that are used by homeservers to sign Matrix events and federation requests (the "signing keys"). Problems similar to those covered here also apply to that -mechanism. A future MSC will propose improvements in that area. +mechanism. This is discussed at [#1685](thttps://github.com/matrix-org/matrix-doc/issues/1685). -## Tradeoffs +## Alternatives There are well-known problems with the CA model, including a number of widely-published incidents in which CAs have issued certificates @@ -192,6 +202,12 @@ possibility of putting the federation port behind a reverse-proxy without the need for additional configuration. Hopefully making the certificate usage more conventional will offset the overhead of setting up a certificate. +Furthermore, homeserver implementations could provide an implementation of the +ACME protocol and integration with Let's Encrypt, to make it easier for +administrators to get started. (This would of course be +implementation-specific, and administrators who wanted to keep control of the +certificate creation process would be free to do so). + ### Inferior support for IP literals Whilst it is possible to obtain an SSL cert which is valid for a literal IP @@ -214,8 +230,8 @@ it can be difficult to get a certificate for a `.onion` domain (again, Let's Encrypt do not support them). The reasons for requiring a signed certificate (or indeed, for using TLS at -all) are weakened when traffic is routed via the Tor network. It may be -reasonable to relax the requirement for a signed certificate for such traffic. +all) are weakened when traffic is routed via the Tor network. Administrators +using the Tor network could disable certificate checks for `.onion` addresses. ## Conclusion From 74b2db7937bc23226770d8f0fb457ba667bf0e58 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 7 Jan 2019 21:39:02 +0000 Subject: [PATCH 0063/1250] Remove .well-known section This really belongs in MSC1708. --- proposals/1711-x509-for-federation.md | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/proposals/1711-x509-for-federation.md b/proposals/1711-x509-for-federation.md index dc737ff6..43fd9657 100644 --- a/proposals/1711-x509-for-federation.md +++ b/proposals/1711-x509-for-federation.md @@ -105,22 +105,6 @@ the recommendations of [RFC6125](https://tools.ietf.org/html/rfc6125#section-6.2.1) and the conventions established by the XMPP protocol (per [RFC6120](https://tools.ietf.org/html/rfc6120#section-13.7.2.1). -### Interaction with `.well-known` files - -[MSC1708](https://github.com/matrix-org/matrix-doc/blob/rav/proposal/well-known-for-federation/proposals/1708-well-known-for-federation.md) -proposes an alternative to SRV records, in the form of `.well-known` files. In -this instance, a file at `https://matrix.org/.well-known/matrix/server` might -direct requests to `server.example.com`. - -In this case, `server.example.com` would be required to present a valid -certificate for `server.example.com`. - -Because the request for the `.well-known` file takes place over a validated TLS -connection, this is not subject to the same DNS-based attacks as the SRV -record, and this mechanism allows the owners of a domain to delegate -responsibility for running their Matrix homeserver without having to hand over -TLS keys for the whole domain. - ### Extensions HTTP-Based Public Key Pinning (HPKP) and From 75c084e987d2418f0ca6b0a3a0d321cd49720ecb Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 7 Jan 2019 14:50:55 -0700 Subject: [PATCH 0064/1250] changelog --- changelogs/client_server/newsfragments/1786.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/1786.feature diff --git a/changelogs/client_server/newsfragments/1786.feature b/changelogs/client_server/newsfragments/1786.feature new file mode 100644 index 00000000..6f21778c --- /dev/null +++ b/changelogs/client_server/newsfragments/1786.feature @@ -0,0 +1 @@ +Add support for advertising experimental features to clients. From f33a540e6dbc6287b03c3633f09144a3266c26b4 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 8 Jan 2019 00:25:06 +0000 Subject: [PATCH 0065/1250] Do a SRV lookup before .well-known lookup also other clarifications and corrections. --- proposals/1708-well-known-for-federation.md | 133 ++++++++++---------- 1 file changed, 69 insertions(+), 64 deletions(-) diff --git a/proposals/1708-well-known-for-federation.md b/proposals/1708-well-known-for-federation.md index 8fa66c7a..6e857b85 100644 --- a/proposals/1708-well-known-for-federation.md +++ b/proposals/1708-well-known-for-federation.md @@ -1,21 +1,17 @@ # MSC1708: .well-known support for server name resolution Currently, mapping from a server name to a hostname for federation is done via -`SRV` records. This presents two principal difficulties: - - * SRV records are not widely used, and administrators may be unfamiliar with - them, and there may be other practical difficulties in their deployment such - as poor support from hosting providers. [^1] - - * [MSC1711](https://github.com/matrix-org/matrix-doc/pull/1711) proposes - requiring valid X.509 certificates on the - federation endpoint. It will then be necessary for the homeserver to present - a certificate which is valid for the server name. This presents difficulties - for hosted server offerings: BigCorp may be reluctant to hand over the - keys for `bigcorp.com` to the administrators of the `bigcorp.com` matrix - homeserver. - -Here we propose to solve these problems by augmenting the current `SRV` record +`SRV` records. However, +[MSC1711](https://github.com/matrix-org/matrix-doc/pull/1711) proposes +requiring valid X.509 certificates on the federation endpoint. It will then be +necessary for the homeserver to present a certificate which is valid for the +server name. This presents difficulties for hosted server offerings: BigCorp +may want to delegate responsibility for running its Matrix homeserver to an +outside supplier, but it may be difficult for that supplier to obtain a TLS +certificate for `bigcorp.com` (and BigCorp may be reluctant to let them have +one). + +This MSC proposes to solve this problem by augmenting the current `SRV` record with a `.well-known` lookup. ## Proposal @@ -24,59 +20,80 @@ For reference, the current [specification for resolving server names](https://matrix.org/docs/spec/server_server/unstable.html#resolving-server-names) is as follows: -* If the hostname is an IP literal, then that IP address should be used, - together with the given port number, or 8448 if no port is given. +1. If the hostname is an IP literal, then that IP address should be used, + together with the given port number, or 8448 if no port is given. + +2. Otherwise, if the port is present, then an IP address is discovered by + looking up an AAAA or A record for the hostname, and the specified port is + used. + +3. If the hostname is not an IP literal and no port is given, the server is + discovered by first looking up a `_matrix._tcp` SRV record for the + hostname, which may give a hostname (to be looked up using AAAA or A queries) + and port. + +4. Finally, the server is discovered by looking up an AAAA or A record on the + hostname, and taking the default fallback port number of 8448. + +We insert the following between Steps 3 and 4: + +If the SRV record does not exist, the requesting server should make a `GET` +request to `https:///.well-known/matrix/server`, with normal +X.509 certificate validation. If the request does not return a 200, continue +to step 4, otherwise: + +XXX: should we follow redirects? -* Otherwise, if the port is present, then an IP address is discovered by - looking up an AAAA or A record for the hostname, and the specified port is - used. +The response must have a `Content-Type` of `application/json`, and must be +valid JSON which follows the structure documented below. Otherwise, the +request is aborted. -* If the hostname is not an IP literal and no port is given, the server is - discovered by first looking up a `_matrix._tcp` SRV record for the - hostname, which may give a hostname (to be looked up using AAAA or A queries) - and port. If the SRV record does not exist, then the server is discovered by - looking up an AAAA or A record on the hostname and taking the default - fallback port number of 8448. +If the response is valid, the `m.server` property is parsed as +`[:]`, and processed as follows: - Homeservers may use SRV records to load balance requests between multiple TLS - endpoints or to failover to another endpoint if an endpoint fails. + a. If `` is an IP literal, then that IP address should + be used, together with ``, or 8448 if no port is + given. The server should present a valid TLS certificate for + ``. -The first two points remain unchanged: if the server name is an IP literal, or -contains a port, then requests will be made directly as before. + b. Otherwise, if the port is present, then an IP address is discovered by + looking up an AAAA or A record for ``, and the + specified port is used. The server should present a valid TLS certificate + for ``. -If the hostname is neither an IP literal, nor does it have an explicit port, -then the requesting server should continue to make an SRV lookup as before, and -use the result if one is found. + (In other words, the federation connection is made to + `https://:`). -If *no* SRV result is found, the requesting server should make a `GET` request -to `https://\/.well-known/matrix/server`, with normal X.509 -certificate validation. If the request fails in any way, then we fall back as -before to using using port 8448 on the hostname. + c. If the hostname is not an IP literal and no port is given, a second SRV + record is looked up; this time for `_matrix._tcp.`, + which may give yet another hostname (to be looked up using A/AAAA queries) + and port. The server must present a TLS cert for the + `` from the .well-known. -Rationale: Falling back to port 8448 (rather than aborting the request) is -necessary to maintain compatibility with existing deployments, which may not -present valid certificates on port 443, or may return 4xx or 5xx errors. + d. If no SRV record is found, the server is discovered by looking up an AAAA + or A record on ``, and taking the default fallback + port number of 8448. -If the GET request succeeds, it should result in a JSON response, with contents -structured as shown: + (In other words, the federation connection is made to + `https://:8448`). + +### Structure of the `.well-known` response + +The contents of the `.well-known` response should be structured as shown: ```json { - "server": "[:]" + "m.server": "[:]" } ``` -The `server` property should be a hostname or IP address, followed by an +The `m.server` property should be a hostname or IP address, followed by an optional port. If the response cannot be parsed as JSON, or lacks a valid `server` property, the request is considered to have failed, and no fallback to port 8448 takes place. -Otherwise, the requesting server performs an `AAAA/A` lookup on the hostname -(if necessary), and connects to the resultant address and the specifed -port. The port defaults to 8448, if unspecified. - (The formal grammar for the `server` property is identical to that of a [server name](https://matrix.org/docs/spec/appendices.html#server-name).) @@ -92,18 +109,10 @@ sensible default: 24 hours is suggested. Because there is no way to request a revalidation, it is also recommended that requesting servers cap the expiry time. 48 hours is suggested. -Similarly, a failure to retrieve the `.well-known` file should be cached for -a reasonable period. 24 hours is suggested again. - -### The future of SRV records - -It's worth noting that this proposal is very clear in that we will maintain -support for SRV records for the immediate future; there are no current plans to -deprecate them. - -However, clearly a `.well-known` file can provide much of the functionality of -an SRV record, and having to support both may be undesirable. Accordingly, we -may consider sunsetting SRV record support at some point in the future. +A failure to retrieve the `.well-known` file should also be cached, though care +must be taken that a single 500 error or connection failure should not break +federation for an extended period. A short cache time of about an hour might be +appropriate; alternatively, servers might use an exponential backoff. ### Outstanding questions @@ -127,7 +136,6 @@ as soon as possible, to maximise uptake in the ecosystem. It is likely that, as we approach Matrix 1.0, there will be sufficient other new features (such as new Room versions) that upgrading will be necessary anyway. - ## Security considerations The `.well-known` file potentially broadens the attack surface for an attacker @@ -138,6 +146,3 @@ wishing to intercept federation traffic to a particular server. This proposal adds a new mechanism, alongside the existing `SRV` record lookup for finding the server responsible for a particular matrix server_name, which will allow greater flexibility in deploying homeservers. - - -[^1] For example, Cloudflare automatically "flattens" SRV record responses. From 12fc50cea785d0f071fd29c8cd2ea153a360f1de Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 8 Jan 2019 11:03:36 +0000 Subject: [PATCH 0066/1250] clarify that a whitelist is useful for cjdns too --- proposals/1711-x509-for-federation.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/proposals/1711-x509-for-federation.md b/proposals/1711-x509-for-federation.md index 43fd9657..4eda65ef 100644 --- a/proposals/1711-x509-for-federation.md +++ b/proposals/1711-x509-for-federation.md @@ -79,9 +79,8 @@ private federation using their own CA. It would also be useful for administrators to be able to disable the certificate checks for a whitelist of domains/netmasks. This would be useful -for `.onion` domains (where a certificate is hard to obtain, and where server -verification is provided at the network level), as well as for testing with IP -literals. +for testing, or for networks that provide server verification themselves, +such as like `.onion` domains on Tor or `fc00::/8` IPs on cjdns. ### Interaction with SRV records From fb171cadf48def72258433d2f19fd7d17df03c9d Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 8 Jan 2019 12:51:02 +0000 Subject: [PATCH 0067/1250] formatting fix --- proposals/1708-well-known-for-federation.md | 50 ++++++++++----------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/proposals/1708-well-known-for-federation.md b/proposals/1708-well-known-for-federation.md index 6e857b85..14ba3bf6 100644 --- a/proposals/1708-well-known-for-federation.md +++ b/proposals/1708-well-known-for-federation.md @@ -51,31 +51,31 @@ request is aborted. If the response is valid, the `m.server` property is parsed as `[:]`, and processed as follows: - a. If `` is an IP literal, then that IP address should - be used, together with ``, or 8448 if no port is - given. The server should present a valid TLS certificate for - ``. - - b. Otherwise, if the port is present, then an IP address is discovered by - looking up an AAAA or A record for ``, and the - specified port is used. The server should present a valid TLS certificate - for ``. - - (In other words, the federation connection is made to - `https://:`). - - c. If the hostname is not an IP literal and no port is given, a second SRV - record is looked up; this time for `_matrix._tcp.`, - which may give yet another hostname (to be looked up using A/AAAA queries) - and port. The server must present a TLS cert for the - `` from the .well-known. - - d. If no SRV record is found, the server is discovered by looking up an AAAA - or A record on ``, and taking the default fallback - port number of 8448. - - (In other words, the federation connection is made to - `https://:8448`). +a. If `` is an IP literal, then that IP address should + be used, together with ``, or 8448 if no port is + given. The server should present a valid TLS certificate for + ``. + +b. Otherwise, if the port is present, then an IP address is discovered by + looking up an AAAA or A record for ``, and the + specified port is used. The server should present a valid TLS certificate + for ``. + + (In other words, the federation connection is made to + `https://:`). + +c. If the hostname is not an IP literal and no port is given, a second SRV + record is looked up; this time for `_matrix._tcp.`, + which may give yet another hostname (to be looked up using A/AAAA queries) + and port. The server must present a TLS cert for the + `` from the .well-known. + +d. If no SRV record is found, the server is discovered by looking up an AAAA + or A record on ``, and taking the default fallback + port number of 8448. + + (In other words, the federation connection is made to + `https://:8448`). ### Structure of the `.well-known` response From f1ebbc358bd873988b2e987e32c53105a0e55293 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 8 Jan 2019 12:44:22 +0000 Subject: [PATCH 0068/1250] document dismissed options --- proposals/1708-well-known-for-federation.md | 67 +++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/proposals/1708-well-known-for-federation.md b/proposals/1708-well-known-for-federation.md index 14ba3bf6..b100ef38 100644 --- a/proposals/1708-well-known-for-federation.md +++ b/proposals/1708-well-known-for-federation.md @@ -141,6 +141,73 @@ new Room versions) that upgrading will be necessary anyway. The `.well-known` file potentially broadens the attack surface for an attacker wishing to intercept federation traffic to a particular server. +## Dismissed alternatives + +For future reference, here are the alternative solutions which have been +considered and dismissed. + +### Look up the `.well-known` file before the SRV record + +We could make the request for `.well-known` before looking up the `SRV` +record. On the one hand this is maybe marginally simpler (and avoids the +overhead of having to make *two* `SRV` lookups in the case that a `.well-known` +is found. It might also open a future path for using `.well-known` for +information other than delegation. + +Ultimately we decided to include the initial `SRV` lookup so that deployments +have a mechanism to avoid the `.well-known` overhead in the common case that it +is not required. + +### Subdomain hack + +As well as accepting TLS certs for `example.com`, we could also accept them for +`delegated--matrix.example.com`. This would allow `example.com` to delegate its +matrix hosting by (a) setting up the SRV record at `_matrix._tcp.example.com` +and (b) setting up a CNAME at `delegated--matrix.example.com`. The latter would +enable the delegatee to obtain an acceptable TLS certificate. + +This was certainly an interesting idea, but we dismissed it for the following +reasons: + +* There's a security trap for anybody who lets people sign up for subdomains + (which is certainly not an uncommon business model): if you can register for + delegated--matrix.example.com, you get to intercept all the matrix traffic + for example.com. + +* Generally it feels quite unintuitive and violates the principle of least + surprise. + +* The fact that we can't find any prior art for this sets off alarm bells too. + +### Rely on DNS/DNSSEC + +If we could trust SRV records, we would be able to accept TLS certs for the +*target* of the SRV record, which avoids this whole problem. + +Such trust could come from assuming that plain DNS is "good enough". However, +DNS cache poisoning attacks are a real thing, and the fact that the designers +of TLS chose to implement a server-name check specifically to deal with this +case suggests we would be foolish to make this assumption. + +The alternative is to rely on DNSSEC to provide security for SRV records. The +problem here is simply that DNSSEC is not that widely deployed currently. A +number of large organisations are actively avoiding enabling it on their +domains, so requiring DNSSEC would be a direct impediment to the uptake of +Matrix. Furthermore, if we required DNSSEC-authenticated SRV records for +domains doing delegation, we would end up with a significant number of +homeservers unable to talk to such domains, because their local DNS +infrastructure may not implement DNSSEC. + +Finally, if we're expecting servers to present the cert for the *target* of the +SRV record, then we'll have to change the Host and SNI fields, and that will +break backwards compat everywhere (and it's hard to see how to mitigate that). + +### Stick with perspectives + +The final option is to double-down on the Perspectives approach, ie to skip +[MSC1711](https://github.com/matrix-org/matrix-doc/pull/1711). MSC1711 +discusses the reasons we do not believe this to be a viable option. + ## Conclusion This proposal adds a new mechanism, alongside the existing `SRV` record lookup From 5812450299fc88c58acf284e9f911152e2484812 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 8 Jan 2019 12:50:42 +0000 Subject: [PATCH 0069/1250] spec that we follow redirects --- proposals/1708-well-known-for-federation.md | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/proposals/1708-well-known-for-federation.md b/proposals/1708-well-known-for-federation.md index b100ef38..5981ab9f 100644 --- a/proposals/1708-well-known-for-federation.md +++ b/proposals/1708-well-known-for-federation.md @@ -35,14 +35,12 @@ is as follows: 4. Finally, the server is discovered by looking up an AAAA or A record on the hostname, and taking the default fallback port number of 8448. -We insert the following between Steps 3 and 4: +We insert the following between Steps 3 and 4. If the SRV record does not exist, the requesting server should make a `GET` -request to `https:///.well-known/matrix/server`, with normal -X.509 certificate validation. If the request does not return a 200, continue -to step 4, otherwise: - -XXX: should we follow redirects? +request to `https:///.well-known/matrix/server`, with normal X.509 +certificate validation, and following 30x redirects. If the request does not +return a 200, continue to step 4, otherwise: The response must have a `Content-Type` of `application/json`, and must be valid JSON which follows the structure documented below. Otherwise, the @@ -114,14 +112,6 @@ must be taken that a single 500 error or connection failure should not break federation for an extended period. A short cache time of about an hour might be appropriate; alternatively, servers might use an exponential backoff. -### Outstanding questions - -Should we follow 30x redirects for the .well-known file? On the one hand, there -is no obvious usecase and they add complexity (for example: how do they -interact with caches?). On the other hand, we'll presumably be using an HTTP -client library to handle some of the caching stuff, and they might be useful -for something? - ## Problems It will take a while for `.well-known` to be supported across the ecosystem; From b541c2a247d6b849031574e3151ca44427c4cdb0 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 8 Jan 2019 12:54:52 +0000 Subject: [PATCH 0070/1250] more formatting --- proposals/1708-well-known-for-federation.md | 49 ++++++++++----------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/proposals/1708-well-known-for-federation.md b/proposals/1708-well-known-for-federation.md index 5981ab9f..98cfe8d8 100644 --- a/proposals/1708-well-known-for-federation.md +++ b/proposals/1708-well-known-for-federation.md @@ -49,31 +49,30 @@ request is aborted. If the response is valid, the `m.server` property is parsed as `[:]`, and processed as follows: -a. If `` is an IP literal, then that IP address should - be used, together with ``, or 8448 if no port is - given. The server should present a valid TLS certificate for - ``. - -b. Otherwise, if the port is present, then an IP address is discovered by - looking up an AAAA or A record for ``, and the - specified port is used. The server should present a valid TLS certificate - for ``. - - (In other words, the federation connection is made to - `https://:`). - -c. If the hostname is not an IP literal and no port is given, a second SRV - record is looked up; this time for `_matrix._tcp.`, - which may give yet another hostname (to be looked up using A/AAAA queries) - and port. The server must present a TLS cert for the - `` from the .well-known. - -d. If no SRV record is found, the server is discovered by looking up an AAAA - or A record on ``, and taking the default fallback - port number of 8448. - - (In other words, the federation connection is made to - `https://:8448`). +* If `` is an IP literal, then that IP address should be + used, together with ``, or 8448 if no port is given. The + server should present a valid TLS certificate for ``. + +* Otherwise, if the port is present, then an IP address is discovered by + looking up an AAAA or A record for ``, and the + specified port is used. The server should present a valid TLS certificate + for ``. + + (In other words, the federation connection is made to + `https://:`). + +* If the hostname is not an IP literal and no port is given, a second SRV + record is looked up; this time for `_matrix._tcp.`, + which may give yet another hostname (to be looked up using A/AAAA queries) + and port. The server must present a TLS cert for the + `` from the .well-known. + +* If no SRV record is found, the server is discovered by looking up an AAAA + or A record on ``, and taking the default fallback + port number of 8448. + + (In other words, the federation connection is made to + `https://:8448`). ### Structure of the `.well-known` response From 4994fa115e41fd4b8777b474465c3e3702589f4a Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 8 Jan 2019 14:21:19 +0000 Subject: [PATCH 0071/1250] X=75 --- proposals/1779-open-governance.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 34230d70..4181d7de 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -216,8 +216,8 @@ of the team and the Guardians on doing so. New additions to the team require 100% consent from the current team members. Membership has to be formally proposed by someone already on the Spec Core Team. -Members can be removed from the team if X% of the team agrees they are no longer -following the goals and guiding principles of the project. +Members can be removed from the team if >= 75% of the team agrees they are no +longer following the goals and guiding principles of the project. Guardians act as a backstop, and can appoint or remove Spec Core Team members (requiring a 75% consensus threshold between the Guardians) if the Spec Core From 4fcd38a3a03a48d0610225453ab5adbc51636ab7 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 8 Jan 2019 14:27:03 +0000 Subject: [PATCH 0072/1250] clarify guardians' right to override spec core team membership --- proposals/1779-open-governance.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 4181d7de..07e275dc 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -274,7 +274,8 @@ In practice, this means that: mechanism between each other to ensure that all Guardians and the Spec Core Team act in the best interests of the protocol and ecosystem. * Guardians may appoint/dismiss members of the Spec Core Team who are in serious - breach of the guiding principles. + breach of the guiding principles. This overrides the unanimous consent + requirement for the Spec Core Team when appointing new members. * Guardians must approve changes to the Guiding Principles (above) * Guardians are responsible for approving use of the Foundation's assets (e.g. redistributing donations) From 7831c04e4caa9459cb527338e9ff6ea75ff8703f Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 8 Jan 2019 14:29:24 +0000 Subject: [PATCH 0073/1250] clarify sytest responsibilities --- proposals/1779-open-governance.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 07e275dc..6ba52f4d 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -344,7 +344,8 @@ collaborate constructively with the existing core team. * Owns the Matrix.org marketing swag (t-shirts, stickers, exhibition stands etc) * It's responsible for finding someone to run the Matrix.org homeserver (currently New Vector) * Publishing the spec - * Responsible for sytest + * Responsible for tools and documentation that supports the spec + * Responsible for ensuring reference implementations and test suite exists for the spec * Publishing the website (including ensuring This Week In Matrix and similar exist to promote independent projects) * Manages IANA-style allocations for Matrix * mx:// URI scheme? From e730cc02a9d5ec77a70296b30c66a45e8ae41bf6 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 8 Jan 2019 14:34:20 +0000 Subject: [PATCH 0074/1250] specify how to select a new spec core team lead --- proposals/1779-open-governance.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 6ba52f4d..67d66b2a 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -234,7 +234,9 @@ reviewed every 12 months and requires the confidence of 75% of the team to be renewed. There is no maximum term for the project lead. The lead may be removed by the core team at any point (with 75% majority), and may resign the role at any point (notifying the team and the Guardians). The lead automatically resigns -the role if they resign from the Spec Core Team. +the role if they resign from the Spec Core Team. Resignation automatically +triggers selection of a new lead, who must be selected from the existing core +spec team. The initial Spec Core Team (and their domain areas) is: @@ -276,6 +278,8 @@ In practice, this means that: * Guardians may appoint/dismiss members of the Spec Core Team who are in serious breach of the guiding principles. This overrides the unanimous consent requirement for the Spec Core Team when appointing new members. + * Guardians may also override deadlocks when appointing a Spec Core Team leader + (with a >= 75% majority) * Guardians must approve changes to the Guiding Principles (above) * Guardians are responsible for approving use of the Foundation's assets (e.g. redistributing donations) From 103d2f4ed223be24f798b7d45a4f5cb87c6e8720 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 8 Jan 2019 14:36:32 +0000 Subject: [PATCH 0075/1250] clarify that the project lead doesn't have casting vote --- proposals/1779-open-governance.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 67d66b2a..6280a45b 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -228,15 +228,15 @@ It's suggested that one of the Spec Core Team members should also be a Guardian, to facilitate information between the Guardians and the Spec Core Team and represent the technical angle of the project to the other Guardians. -The project lead role acts to coordinate the team and to help tie-break in the -event of failing to get acceptance on a Matrix Spec Change. The project lead is -reviewed every 12 months and requires the confidence of 75% of the team to be -renewed. There is no maximum term for the project lead. The lead may be removed -by the core team at any point (with 75% majority), and may resign the role at -any point (notifying the team and the Guardians). The lead automatically resigns -the role if they resign from the Spec Core Team. Resignation automatically -triggers selection of a new lead, who must be selected from the existing core -spec team. +The project lead role acts to coordinate the team and to help steer the team to +consensus in the event of failing to get agreement on a Matrix Spec Change. The +project lead is reviewed every 12 months and requires the confidence of 75% of +the team to be renewed. There is no maximum term for the project lead. The lead +may be removed by the core team at any point (with 75% majority), and may resign +the role at any point (notifying the team and the Guardians). The lead +automatically resigns the role if they resign from the Spec Core Team. +Resignation automatically triggers selection of a new lead, who must be selected +from the existing core spec team. The initial Spec Core Team (and their domain areas) is: From 2047ba59daf0632b04ed974dc3598c2224b9335e Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 8 Jan 2019 14:42:49 +0000 Subject: [PATCH 0076/1250] spell out domain spread requirement for spec core team --- proposals/1779-open-governance.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 6280a45b..fb15027a 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -238,6 +238,10 @@ automatically resigns the role if they resign from the Spec Core Team. Resignation automatically triggers selection of a new lead, who must be selected from the existing core spec team. +It is vital that the core spec team has strong domain expertise covering all +different domains of the spec (e.g. we don't want to end up with a core spec +team where nobody has strong experience in cryptography) + The initial Spec Core Team (and their domain areas) is: * Matthew Hodgson (Lead) From c05000b38dd7529fe79f582091de6bea1590509d Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 8 Jan 2019 14:43:44 +0000 Subject: [PATCH 0077/1250] broaden reasons for dysfunctional core spec teams --- proposals/1779-open-governance.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index fb15027a..2c67a5ca 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -221,8 +221,7 @@ longer following the goals and guiding principles of the project. Guardians act as a backstop, and can appoint or remove Spec Core Team members (requiring a 75% consensus threshold between the Guardians) if the Spec Core -Team is unable to reach consensus or is failing to align with the Foundation's -mission. +Team is unable to function or is failing to align with the Foundation's mission. It's suggested that one of the Spec Core Team members should also be a Guardian, to facilitate information between the Guardians and the Spec Core Team and From 0e246b147717b1b7f7d40968211a39b365d6effa Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 8 Jan 2019 14:44:18 +0000 Subject: [PATCH 0078/1250] Update proposals/1779-open-governance.md Co-Authored-By: ara4n --- proposals/1779-open-governance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 2c67a5ca..1a836322 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -243,7 +243,7 @@ team where nobody has strong experience in cryptography) The initial Spec Core Team (and their domain areas) is: - * Matthew Hodgson (Lead) + * Matthew Hodgson (Lead, Guardian) * Erik Johnston (Servers) * Richard van der Hoff (Servers, Cryptography) * David Baker (Clients, IS API, Push API, Media) From 5235293623bfbe62301d8514c6055d321f0aad06 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 8 Jan 2019 14:50:18 +0000 Subject: [PATCH 0079/1250] spell out the Core Team a bit more --- proposals/1779-open-governance.md | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 2c67a5ca..6f8af97d 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -328,16 +328,27 @@ Foundation relative to Matthew & Amandine’s day jobs at New Vector. Guardians volunteer their time for free to work on the project. -## The Core Team - -"The Core Team" is a loose term that describes the set of people with access to -commit code to the public https://github.com/matrix-org repositories, who are -either working on matrix.org's reference implementations or the spec itself. -Commit access is decided by those responsible for the projects in question, much -like any other open source project. Anyone is eligible for commit access if -they have proved themselves a valuable long-term contributor, upholds the -guiding principles and mission of the project and have proved themselves able to -collaborate constructively with the existing core team. +## The Code Core Team (aka The Core Team) + +The "Core Team" (or the "Code Core Team", to disambiguate from the Spec Core +Team) is a loose term that describes the set of people with access to commit +code to the public https://github.com/matrix-org repositories, who are either +working on matrix.org's reference implementations or the spec itself. Commit +access is decided by those responsible for the projects in question, much like +any other open source project. Anyone is eligible for commit access if they +have proved themselves a valuable long-term contributor, upholds the guiding +principles and mission of the project and have proved themselves able to +collaborate constructively with the existing core team. Active participation in +the core team is also signified by membership of the +matrix:matrix.org Matrix +community. + +TODO: spell out some responsibilities. Erik suggests something like: + * Helping to ensure the quality of the projects' repositories + * That all projects follow the Matrix spec + * Engaging with the people in a way that fosters a healthy and happy community + * Following the Guiding Principles and promoting them within the community + +Code Core Team members volunteer their time for free to work on the project. ## Responsibilities for the Foundation From 3a5d56467bcaacf3f1672f3ed522c61da8c097a0 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 8 Jan 2019 14:51:45 +0000 Subject: [PATCH 0080/1250] reword lead renewals --- proposals/1779-open-governance.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index f7712197..1e78d8e0 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -228,14 +228,14 @@ to facilitate information between the Guardians and the Spec Core Team and represent the technical angle of the project to the other Guardians. The project lead role acts to coordinate the team and to help steer the team to -consensus in the event of failing to get agreement on a Matrix Spec Change. The -project lead is reviewed every 12 months and requires the confidence of 75% of -the team to be renewed. There is no maximum term for the project lead. The lead -may be removed by the core team at any point (with 75% majority), and may resign -the role at any point (notifying the team and the Guardians). The lead -automatically resigns the role if they resign from the Spec Core Team. -Resignation automatically triggers selection of a new lead, who must be selected -from the existing core spec team. +consensus in the event of failing to get agreement on a Matrix Spec Change. +Every 12 months, a vote of confidence is held in the project lead, requiring the +confidence of 75% of the team for the lead to be renewed. There is no maximum +term for the project lead. The lead may be removed by the core team at any +point (with 75% majority), and may resign the role at any point (notifying the +team and the Guardians). The lead automatically resigns the role if they resign +from the Spec Core Team. Resignation automatically triggers selection of a new +lead, who must be selected from the existing core spec team. It is vital that the core spec team has strong domain expertise covering all different domains of the spec (e.g. we don't want to end up with a core spec From c02ecb58aec48778d9ca4531bb84f5e875d71210 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 8 Jan 2019 16:11:00 -0500 Subject: [PATCH 0081/1250] mark which fields are required --- proposals/1717-key_verification.md | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/proposals/1717-key_verification.md b/proposals/1717-key_verification.md index b71fcf34..fa1d7373 100644 --- a/proposals/1717-key_verification.md +++ b/proposals/1717-key_verification.md @@ -57,13 +57,15 @@ Requests a key verification. Properties: -- `from_device` (string): the device ID of the device requesting verification. -- `transaction_id` (string): an identifier for the verification request. Must - be unique with respect to the pair of devices. -- `methods` ([string]): the verification methods supported by the sender. -- `timestamp` (integer): the time when the request was made. If the timestamp - is in the future (by more than 5 minutes, to allow for clock skew), or more - than 10 minutes in the past, then the message must be ignored. +- `from_device` (string): Required. The device ID of the device requesting + verification. +- `transaction_id` (string): Required. An identifier for the verification + request. Must be unique with respect to the pair of devices. +- `methods` ([string]): Required. The verification methods supported by the + sender. +- `timestamp` (integer): Required. The time when the request was made. If the + timestamp is in the future (by more than 5 minutes, to allow for clock skew), + or more than 10 minutes in the past, then the message must be ignored. #### `m.key.verification.start` @@ -71,13 +73,13 @@ Begins a key verification process. Properties: -- `method` (string): the verification method to use. -- `from_device` (string): The device ID of the device starting the verification - process. -- `transaction_id` (string): an identifier for the verification process. If - this message is sent in reponse to an `m.key.verification.request` event, then - it must use the same `transaction_id` as the one given in the - `m.key.verification.request`. +- `method` (string): Required. The verification method to use. +- `from_device` (string): Required. The device ID of the device starting the + verification process. +- `transaction_id` (string): Required. An identifier for the verification + process. If this message is sent in reponse to an + `m.key.verification.request` event, then it must use the same + `transaction_id` as the one given in the `m.key.verification.request`. Key verification methods can define additional properties to be included. From ff0b9eac76cfa65222dd82d45ff3358570ab1fd1 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 8 Jan 2019 16:11:15 -0500 Subject: [PATCH 0082/1250] add ability to start verifications that happen in two stages --- proposals/1717-key_verification.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/1717-key_verification.md b/proposals/1717-key_verification.md index fa1d7373..8acc4654 100644 --- a/proposals/1717-key_verification.md +++ b/proposals/1717-key_verification.md @@ -80,6 +80,10 @@ Properties: process. If this message is sent in reponse to an `m.key.verification.request` event, then it must use the same `transaction_id` as the one given in the `m.key.verification.request`. +- `next_method` (string): Optional. If the selected verification method only + verifies one user's key, then this property can be used to indicate the + method to use to verify the other user's key, which will be started + immediately after after the current key verification is complete. Key verification methods can define additional properties to be included. From 09a547d67e0a4b835405af0be9ce739f9dfe400a Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 8 Jan 2019 17:45:13 -0500 Subject: [PATCH 0083/1250] add some cancellation codes, and mention existing verification MSCs --- proposals/1717-key_verification.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/proposals/1717-key_verification.md b/proposals/1717-key_verification.md index 8acc4654..b536be0e 100644 --- a/proposals/1717-key_verification.md +++ b/proposals/1717-key_verification.md @@ -2,7 +2,8 @@ Key verification is an essential part of ensuring that end-to-end encrypted messages are secure. Matrix may support multiple verification methods that -require sending events; in fact, two such methods have already been proposed. +require sending events; in fact, two such methods (such as MSC1267 and MSC1543) +have already been proposed. This proposal tries to present a common framework for verification methods to use, and presents a way to request key verification. @@ -112,6 +113,12 @@ Properties: - `m.unexpected_message`: the device received an unexpected message. For example, a message for a verification method may have been received when it was not expected. + - `m.key_mismatch`: the key was not verified. + - `m.user_mismatch`: the expected user did not match the user verified. + - `m.invalid_message`: an invalid message was received. + - `m.accepted`: when an `m.key.verification.request` is accepted by one + device, an `m.key.verification.cancel` message with `code` set to + `m.accepted` is sent to the other devices - `reason` (string): human-readable reason for cancelling. This should only be used if the recieving client does not understand the code given. From 3e7a5f5ea4841e96508f6eed7e950736a714abc9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 9 Jan 2019 00:09:38 -0700 Subject: [PATCH 0084/1250] Initial draft for SSO support --- api/client-server/sso_login_redirect.yaml | 46 ++++++++++ specification/client_server_api.rst | 12 ++- specification/modules/sso_login.rst | 100 ++++++++++++++++++++++ specification/targets.yaml | 1 + 4 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 api/client-server/sso_login_redirect.yaml create mode 100644 specification/modules/sso_login.rst diff --git a/api/client-server/sso_login_redirect.yaml b/api/client-server/sso_login_redirect.yaml new file mode 100644 index 00000000..acbafc57 --- /dev/null +++ b/api/client-server/sso_login_redirect.yaml @@ -0,0 +1,46 @@ +# 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 SSO Login API" + version: "1.0.0" +host: localhost:8008 +schemes: + - https + - http +basePath: /_matrix/client/%CLIENT_MAJOR_VERSION% +paths: + "/login/sso/redirect": + get: + summary: Redirect the user's browser to the SSO interface. + description: |- + A web-based Matrix client should instruct the user's browser to + navigate to this endpoint in order to log in via SSO. + + The server MUST respond with an HTTP redirect to the SSO interface. + operationId: redirectToSSO + parameters: + - in: query + type: string + name: redirectUrl + description: |- + URI to which the user will be redirected after the homeserver has + authenticated the user with SSO. + required: true + responses: + 302: + description: A redirect to the SSO interface. + headers: + Location: + type: "string" diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 82a576f1..973d3b55 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1016,9 +1016,19 @@ follows: } As with `token-based`_ interactive login, the ``token`` must encode the -user id. In the case that the token is not valid, the homeserver must respond +user ID. In the case that the token is not valid, the homeserver must respond with ``403 Forbidden`` and an error code of ``M_FORBIDDEN``. +To log in with through a Central Authentication Service (CAS) or via Single +Sign-On (SSO), clients should first make a request to ``GET /login`` to ensure +the homeserver supports the appropriate login type. Clients should use the +`CAS endpoints`_ to complete logins for ``m.login.cas`` and the `SSO endpoints`_ +for ``m.login.sso``. In either case, the client is expected to redirect the user +to the appropriate ``/redirect`` endpoint. + +.. _`CAS endpoints`: #cas-based-client-login +.. _`SSO endpoints`: #sso-based-client-login + {{login_cs_http_api}} {{logout_cs_http_api}} diff --git a/specification/modules/sso_login.rst b/specification/modules/sso_login.rst new file mode 100644 index 00000000..a493c851 --- /dev/null +++ b/specification/modules/sso_login.rst @@ -0,0 +1,100 @@ +.. 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. + +SSO-based client login +====================== + +.. _module:sso_login: + +Single Sign-On (SSO) is a generic web-based protocol for logging in users. +This section is the more generic version of `CAS-based client login`_ and +is applicable to a wider range of SSO protocols. + +An overview of the process, as used in Matrix, is as follows: + +1. The Matrix client instructs the user's browser to navigate to the + |/login/sso/redirect|_ endpoint on the user's homeserver. + +2. The homeserver responds with an HTTP redirect to the SSO user interface, + which the browser follows. + +3. The SSO system authenticates the user. + +4. The SSO server and the homeserver interact to verify the user's identity + and other authentication information, potentially using a number of redirects. + +7. The Matrix client receives the login token and passes it to the |/login|_ + API. + +Client behaviour +---------------- + +The client starts the process by instructing the browser to navigate to +|/login/sso/redirect|_ with an appropriate ``redirectUrl``. Once authentication +is successful, the browser will be redirected to that ``redirectUrl``. + +.. TODO-spec + + Should we recommend some sort of CSRF protection here (specifically, we + should guard against people accidentally logging in by sending them a link + to ``/login/sso/redirect``. + + Maybe we should recommend that the ``redirectUrl`` should contain a CSRF + token which the client should then check before sending the login token to + ``/login``? + +{{sso_login_redirect_cs_http_api}} + +Server behaviour +---------------- + +The URI for the SSO system to be used should be configured on the server by the +server administrator. The server is expected to set up any endpoints required to +interact with that SSO system. + +Handling the redirect endpoint +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When responding to the ``/login/sso/redirect`` endpoint, the server must +generate a URI for the SSO login page with any appropriate parameters. + +.. TODO-spec: + + It might be nice if the server did some validation of the ``redirectUrl`` + parameter, so that we could check that aren't going to redirect to a non-TLS + endpoint, and to give more meaningful errors in the case of + faulty/poorly-configured clients. + +Handling the authentication endpoint +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once the homeserver has verified the user's identity with the SSO system, it +MUST map the user ID to a valid `Matrix user identifier <../index.html#user-identifiers>`_. +The guidance in `Mapping from other character sets +<../index.html#mapping-from-other-character-sets>`_ may be useful. + +If the generated user identifier represents a new user, it should be registered +as a new user. + +Finally, the server should generate a short-term login token. The generated +token should be a macaroon, suitable for use with the ``m.login.token`` type of +the |/login|_ API, and `token-based interactive login <#token-based>`_. The +lifetime of this token SHOULD be limited to around five seconds. + + +.. |/login| replace:: ``/login`` +.. _/login: #post-matrix-client-%CLIENT_MAJOR_VERSION%-login +.. |/login/sso/redirect| replace:: ``/login/sso/redirect`` +.. _/login/sso/redirect: #get-matrix-client-%CLIENT_MAJOR_VERSION%-login-sso-redirect +.. _`CAS-based client login`: #cas-based-client-login diff --git a/specification/targets.yaml b/specification/targets.yaml index 93e1b8a6..493814ac 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -62,6 +62,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/admin.rst - modules/event_context.rst - modules/cas_login.rst + - modules/sso_login.rst - modules/dm.rst - modules/ignore_users.rst - modules/stickers.rst From c10394d03f9f82533c8db0a823052df6ba23453d Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 9 Jan 2019 11:26:14 +0000 Subject: [PATCH 0085/1250] Clarifications thanks to @uhoreg --- proposals/1708-well-known-for-federation.md | 23 ++++++++++----------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/proposals/1708-well-known-for-federation.md b/proposals/1708-well-known-for-federation.md index 98cfe8d8..8105a638 100644 --- a/proposals/1708-well-known-for-federation.md +++ b/proposals/1708-well-known-for-federation.md @@ -39,8 +39,9 @@ We insert the following between Steps 3 and 4. If the SRV record does not exist, the requesting server should make a `GET` request to `https:///.well-known/matrix/server`, with normal X.509 -certificate validation, and following 30x redirects. If the request does not -return a 200, continue to step 4, otherwise: +certificate validation, and following 30x redirects (being careful to avoid +redirect loops). If the request does not return a 200, continue to step 4, +otherwise: The response must have a `Content-Type` of `application/json`, and must be valid JSON which follows the structure documented below. Otherwise, the @@ -53,10 +54,10 @@ If the response is valid, the `m.server` property is parsed as used, together with ``, or 8448 if no port is given. The server should present a valid TLS certificate for ``. -* Otherwise, if the port is present, then an IP address is discovered by - looking up an AAAA or A record for ``, and the - specified port is used. The server should present a valid TLS certificate - for ``. +* If `` is not an IP literal, and `` is + present, then an IP address is discovered by looking up an AAAA or A record + for ``, and the specified port is used. The server + should present a valid TLS certificate for ``. (In other words, the federation connection is made to `https://:`). @@ -84,15 +85,13 @@ The contents of the `.well-known` response should be structured as shown: } ``` -The `m.server` property should be a hostname or IP address, followed by an -optional port. - -If the response cannot be parsed as JSON, or lacks a valid `server` property, +If the response cannot be parsed as JSON, or lacks a valid `m.server` property, the request is considered to have failed, and no fallback to port 8448 takes place. -(The formal grammar for the `server` property is identical to that of a [server -name](https://matrix.org/docs/spec/appendices.html#server-name).) +The formal grammar for the `m.server` property is the same as that of a [server +name](https://matrix.org/docs/spec/appendices.html#server-name): it is a +hostname or IP address, followed by an optional port. ### Caching From f738f671d1ed682bcfe2bdee1f035520016af344 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 9 Jan 2019 15:16:18 +0000 Subject: [PATCH 0086/1250] Sticky headers for proposals page --- scripts/css/basic.css | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/css/basic.css b/scripts/css/basic.css index dc86bc26..8d99f6da 100644 --- a/scripts/css/basic.css +++ b/scripts/css/basic.css @@ -462,6 +462,16 @@ dl.glossary dt { font-style: oblique; } +/* -- proposals page -------------------------------------------------------- */ + +#tables-of-tracked-proposals h2 { + margin-top: 7px; + padding-left: 10px; + position: -webkit-sticky; + position: sticky; + top: 0px; +} + /* -- code displays --------------------------------------------------------- */ pre { From d6c33ea0a5d5ea17cfe54a2aa4828831a5025042 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 9 Jan 2019 14:41:46 -0700 Subject: [PATCH 0087/1250] Make CAS a subset of SSO --- specification/client_server_api.rst | 19 ++--- specification/modules/cas_login.rst | 119 ---------------------------- specification/modules/sso_login.rst | 97 +++++++++++++++++++++-- specification/targets.yaml | 1 - 4 files changed, 102 insertions(+), 134 deletions(-) delete mode 100644 specification/modules/cas_login.rst diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 973d3b55..03d71246 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1019,15 +1019,16 @@ As with `token-based`_ interactive login, the ``token`` must encode the user ID. In the case that the token is not valid, the homeserver must respond with ``403 Forbidden`` and an error code of ``M_FORBIDDEN``. -To log in with through a Central Authentication Service (CAS) or via Single -Sign-On (SSO), clients should first make a request to ``GET /login`` to ensure -the homeserver supports the appropriate login type. Clients should use the -`CAS endpoints`_ to complete logins for ``m.login.cas`` and the `SSO endpoints`_ -for ``m.login.sso``. In either case, the client is expected to redirect the user -to the appropriate ``/redirect`` endpoint. - -.. _`CAS endpoints`: #cas-based-client-login -.. _`SSO endpoints`: #sso-based-client-login +If the homeserver advertises ``m.login.sso`` as a viable flow, and the client +supports it, the client should redirect the user to the ``/redirect`` endpoint +for `Single Sign-On <#sso-client-login>`_. After authentication is complete, the +client will need to submit a ``/login`` request matching ``m.login.token``. + +If the homeserver advertises ``m.login.cas`` as a viable flow, and the client +supports it, the client should redirect the user to the ``/redirect`` endpoint +for `CAS <#cas-based-client-login>`_. Just like SSO authentication, the client +is expected to submit a ``/login`` request matching ``m.login.token`` upon +successful authentication. {{login_cs_http_api}} diff --git a/specification/modules/cas_login.rst b/specification/modules/cas_login.rst deleted file mode 100644 index 5de98057..00000000 --- a/specification/modules/cas_login.rst +++ /dev/null @@ -1,119 +0,0 @@ -.. Copyright 2016 OpenMarket Ltd -.. -.. Licensed under the Apache License, Version 2.0 (the "License"); -.. you may not use this file except in compliance with the License. -.. You may obtain a copy of the License at -.. -.. http://www.apache.org/licenses/LICENSE-2.0 -.. -.. Unless required by applicable law or agreed to in writing, software -.. distributed under the License is distributed on an "AS IS" BASIS, -.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -.. See the License for the specific language governing permissions and -.. limitations under the License. - -CAS-based client login -====================== - -.. _module:cas_login: - -`Central Authentication Service -`_ -(CAS) is a web-based single sign-on protocol. - -An overview of the process, as used in Matrix, is as follows: - -1. The Matrix client instructs the user's browser to navigate to the - |/login/cas/redirect|_ endpoint on the user's homeserver. - -2. The homeserver responds with an HTTP redirect to the CAS user interface, - which the browser follows. - -3. The CAS system authenticates the user. - -4. The CAS server responds to the user's browser with a redirect back to the - |/login/cas/ticket|_ endpoint on the homeserver, which the browser - follows. A 'ticket' identifier is passed as a query parameter in the - redirect. - -5. The homeserver receives the ticket ID from the user's browser, and makes a - request to the CAS server to validate the ticket. - -6. Having validated the ticket, the homeserver responds to the browser with a - third HTTP redirect, back to the Matrix client application. A login token - is passed as a query parameter in the redirect. - -7. The Matrix client receives the login token and passes it to the |/login|_ - API. - -Client behaviour ----------------- - -The client starts the process by instructing the browser to navigate to -|/login/cas/redirect|_ with an appropriate ``redirectUrl``. Once authentication -is successful, the browser will be redirected to that ``redirectUrl``. - -.. TODO-spec - - Should we recommend some sort of CSRF protection here (specifically, we - should guard against people accidentally logging in by sending them a link - to ``/login/cas/redirect``. - - Maybe we should recommend that the ``redirectUrl`` should contain a CSRF - token which the client should then check before sending the login token to - ``/login``? - -{{cas_login_redirect_cs_http_api}} -{{cas_login_ticket_cs_http_api}} - -Server behaviour ----------------- - -The URI for the CAS system to be used should be configured on the server by the -server administrator. - -Handling the redirect endpoint -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -When responding to the ``/login/cas/redirect`` endpoint, the server must -generate a URI for the CAS login page. The server should take the base CAS URI -described above, and add a ``service`` query parameter. This parameter MUST be -the URI of the ``/login/cas/ticket`` endpoint, including the ``redirectUrl`` -query parameter. Because the homeserver may not know its base URI, this may -also require manual configuration. - -.. TODO-spec: - - It might be nice if the server did some validation of the ``redirectUrl`` - parameter, so that we could check that aren't going to redirect to a non-TLS - endpoint, and to give more meaningful errors in the case of - faulty/poorly-configured clients. - -Handling the authentication endpoint -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -When responding to the ``/login/cas/ticket`` endpoint, the server MUST make a -request to the CAS server to validate the provided ticket. The server MAY also -check for certain user attributes in the response. Any required attributes -should be configured by the server administrator. - -Once the ticket has been validated, the server MUST map the CAS ``user_id`` -to a valid `Matrix user identifier <../index.html#user-identifiers>`_. The -guidance in `Mapping from other character sets -<../index.html#mapping-from-other-character-sets>`_ may be useful. - -If the generated user identifier represents a new user, it should be registered -as a new user. - -Finally, the server should generate a short-term login token. The generated -token should be a macaroon, suitable for use with the ``m.login.token`` type of -the |/login|_ API, and `token-based interactive login <#token-based>`_. The -lifetime of this token SHOULD be limited to around five seconds. - - -.. |/login| replace:: ``/login`` -.. _/login: #post-matrix-client-%CLIENT_MAJOR_VERSION%-login -.. |/login/cas/redirect| replace:: ``/login/cas/redirect`` -.. _/login/cas/redirect: #get-matrix-client-%CLIENT_MAJOR_VERSION%-login-cas-redirect -.. |/login/cas/ticket| replace:: ``/login/cas/ticket`` -.. _/login/cas/ticket: #get-matrix-client-%CLIENT_MAJOR_VERSION%-login-cas-ticket diff --git a/specification/modules/sso_login.rst b/specification/modules/sso_login.rst index a493c851..977278a7 100644 --- a/specification/modules/sso_login.rst +++ b/specification/modules/sso_login.rst @@ -12,14 +12,14 @@ .. See the License for the specific language governing permissions and .. limitations under the License. -SSO-based client login -====================== +SSO client login +================ .. _module:sso_login: Single Sign-On (SSO) is a generic web-based protocol for logging in users. -This section is the more generic version of `CAS-based client login`_ and -is applicable to a wider range of SSO protocols. +As a special case, the Matrix specification supports `CAS-based login <#cas-based-client-login>`_ +as well as a subset of SSO login. An overview of the process, as used in Matrix, is as follows: @@ -93,8 +93,95 @@ the |/login|_ API, and `token-based interactive login <#token-based>`_. The lifetime of this token SHOULD be limited to around five seconds. +CAS-based client login +---------------------- + +.. _module:cas_login: + +`Central Authentication Service +`_ +(CAS) is a web-based single sign-on protocol. The protocol defined here is an +extension of the SSO protocol defined in this module: it is largely the same, +but has some specific details which make it different. + +An overview of the process, as used in Matrix, is as follows: + +1. The Matrix client instructs the user's browser to navigate to the + |/login/cas/redirect|_ endpoint on the user's homeserver. + +2. The homeserver responds with an HTTP redirect to the CAS user interface, + which the browser follows. + +3. The CAS system authenticates the user. + +4. The CAS server responds to the user's browser with a redirect back to the + |/login/cas/ticket|_ endpoint on the homeserver, which the browser + follows. A 'ticket' identifier is passed as a query parameter in the + redirect. + +5. The homeserver receives the ticket ID from the user's browser, and makes a + request to the CAS server to validate the ticket. + +6. Having validated the ticket, the homeserver responds to the browser with a + third HTTP redirect, back to the Matrix client application. A login token + is passed as a query parameter in the redirect. + +7. The Matrix client receives the login token and passes it to the |/login|_ + API. + +Client behaviour +~~~~~~~~~~~~~~~~ + +The client starts the process by instructing the browser to navigate to +|/login/cas/redirect|_ with an appropriate ``redirectUrl``. Once authentication +is successful, the browser will be redirected to that ``redirectUrl``. + +{{cas_login_redirect_cs_http_api}} +{{cas_login_ticket_cs_http_api}} + +Server behaviour +~~~~~~~~~~~~~~~~ + +The URI for the CAS system to be used should be configured on the server by the +server administrator. + +Handling the redirect endpoint +++++++++++++++++++++++++++++++ + +When responding to the ``/login/cas/redirect`` endpoint, the server must +generate a URI for the CAS login page. The server should take the base CAS URI +described above, and add a ``service`` query parameter. This parameter MUST be +the URI of the ``/login/cas/ticket`` endpoint, including the ``redirectUrl`` +query parameter. Because the homeserver may not know its base URI, this may +also require manual configuration. + +Handling the authentication endpoint +++++++++++++++++++++++++++++++++++++ + +When responding to the ``/login/cas/ticket`` endpoint, the server MUST make a +request to the CAS server to validate the provided ticket. The server MAY also +check for certain user attributes in the response. Any required attributes +should be configured by the server administrator. + +Once the ticket has been validated, the server MUST map the CAS ``user_id`` +to a valid `Matrix user identifier <../index.html#user-identifiers>`_. The +guidance in `Mapping from other character sets +<../index.html#mapping-from-other-character-sets>`_ may be useful. + +If the generated user identifier represents a new user, it should be registered +as a new user. + +Finally, the server should generate a short-term login token. The generated +token should be a macaroon, suitable for use with the ``m.login.token`` type of +the |/login|_ API, and `token-based interactive login <#token-based>`_. The +lifetime of this token SHOULD be limited to around five seconds. + + .. |/login| replace:: ``/login`` .. _/login: #post-matrix-client-%CLIENT_MAJOR_VERSION%-login +.. |/login/cas/redirect| replace:: ``/login/cas/redirect`` +.. _/login/cas/redirect: #get-matrix-client-%CLIENT_MAJOR_VERSION%-login-cas-redirect +.. |/login/cas/ticket| replace:: ``/login/cas/ticket`` +.. _/login/cas/ticket: #get-matrix-client-%CLIENT_MAJOR_VERSION%-login-cas-ticket .. |/login/sso/redirect| replace:: ``/login/sso/redirect`` .. _/login/sso/redirect: #get-matrix-client-%CLIENT_MAJOR_VERSION%-login-sso-redirect -.. _`CAS-based client login`: #cas-based-client-login diff --git a/specification/targets.yaml b/specification/targets.yaml index 493814ac..4172e617 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -61,7 +61,6 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/account_data.rst - modules/admin.rst - modules/event_context.rst - - modules/cas_login.rst - modules/sso_login.rst - modules/dm.rst - modules/ignore_users.rst From 0eabf108d9a8765213f6f80d27c5dcb6a5c2acd3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 9 Jan 2019 15:05:27 -0700 Subject: [PATCH 0088/1250] Add a mechanism for redirecting clients after login Implements https://github.com/matrix-org/matrix-doc/pull/1730 --- .../definitions/wellknown/full.yaml | 39 +++++++++++++++++++ api/client-server/login.yaml | 18 ++++++++- api/client-server/wellknown.yaml | 21 +--------- 3 files changed, 57 insertions(+), 21 deletions(-) create mode 100644 api/client-server/definitions/wellknown/full.yaml diff --git a/api/client-server/definitions/wellknown/full.yaml b/api/client-server/definitions/wellknown/full.yaml new file mode 100644 index 00000000..8d8f4038 --- /dev/null +++ b/api/client-server/definitions/wellknown/full.yaml @@ -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" + } +} diff --git a/api/client-server/login.yaml b/api/client-server/login.yaml index 43aae5df..cef3d26f 100644 --- a/api/client-server/login.yaml +++ b/api/client-server/login.yaml @@ -139,7 +139,15 @@ paths: application/json: { "user_id": "@cheeky_monkey:matrix.org", "access_token": "abc123", - "device_id": "GHTYAJCE" + "device_id": "GHTYAJCE", + "well_known": { + "m.homeserver": { + "base_url": "https://example.org" + }, + "m.identity_server": { + "base_url": "https://id.example.org" + } + } } schema: type: object @@ -166,6 +174,14 @@ paths: description: |- ID of the logged-in device. Will be the same as the corresponding parameter in the request, if one was specified. + well_known: + type: object + description: |- + Optional client configuration provided by the server. If present, + clients SHOULD ise the provided object to reconfigure themselves, + optionally validating the URLs within. This object takes the same + form as the one returned from .well-known autodiscovery. + "$ref": "definitions/wellknown/full.yaml" 400: description: |- Part of the request was invalid. For example, the login type may not be recognised. diff --git a/api/client-server/wellknown.yaml b/api/client-server/wellknown.yaml index 24e190f9..b63bd041 100644 --- a/api/client-server/wellknown.yaml +++ b/api/client-server/wellknown.yaml @@ -38,28 +38,9 @@ paths: responses: 200: description: Server discovery information. - examples: - application/json: { - "m.homeserver": { - "base_url": "https://matrix.example.com" - }, - "m.identity_server": { - "base_url": "https://identity.example.com" - } - } schema: type: object - properties: - m.homeserver: - description: Information about the homeserver to connect to. - "$ref": "definitions/wellknown/homeserver.yaml" - m.identity_server: - description: Optional. Information about the identity server to connect to. - "$ref": "definitions/wellknown/identity_server.yaml" - additionalProperties: - description: Application-dependent keys using Java package naming convention. - required: - - m.homeserver + "$ref": "definitions/wellknown/full.yaml" 404: description: No server discovery information available. tags: From 510468a3b1736d55a4823596bc6359ed2fccb0c8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 9 Jan 2019 15:31:04 -0700 Subject: [PATCH 0089/1250] Changelog --- changelogs/client_server/newsfragments/1789.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/1789.feature diff --git a/changelogs/client_server/newsfragments/1789.feature b/changelogs/client_server/newsfragments/1789.feature new file mode 100644 index 00000000..97c1e5ca --- /dev/null +++ b/changelogs/client_server/newsfragments/1789.feature @@ -0,0 +1 @@ +Add a generic SSO login API. From fbd88611803ced1fcb5900f3b91fab4b95bd7555 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 9 Jan 2019 15:31:43 -0700 Subject: [PATCH 0090/1250] Changelog --- changelogs/client_server/newsfragments/1790.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/1790.feature diff --git a/changelogs/client_server/newsfragments/1790.feature b/changelogs/client_server/newsfragments/1790.feature new file mode 100644 index 00000000..26dccd05 --- /dev/null +++ b/changelogs/client_server/newsfragments/1790.feature @@ -0,0 +1 @@ +Add a mechanism for servers to redirect clients to an alternative homeserver after logging in. From 03802701715d4ac1e404e14d619c1c80be4fca2e Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Wed, 9 Jan 2019 23:29:59 +0000 Subject: [PATCH 0091/1250] spell out that hypothetical employees could come in any size --- proposals/1779-open-governance.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 1e78d8e0..8834da30 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -287,7 +287,8 @@ In practice, this means that: * Guardians are responsible for approving use of the Foundation's assets (e.g. redistributing donations) * In future, Guardians may also be responsible for ensuring staff are hired by - the Foundation to support administrative functions + the Foundation to support administrative functions and other roles required + to facilitate the Foundation's mission. * As well as the Spec Core Team committee, they may also oversee committees for other areas such as marketing Matrix.org, registering custom event types, or "Made for Matrix" certification. From b85f7bb24827b19c5f38e2c6021dc126767e16e5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 9 Jan 2019 17:02:09 -0700 Subject: [PATCH 0092/1250] Add room version upgrades Implements https://github.com/matrix-org/matrix-doc/issues/1501 --- api/client-server/room_upgrades.yaml | 95 +++++++++++++++++++++++++ event-schemas/examples/m.room.create | 6 +- event-schemas/examples/m.room.tombstone | 9 +++ event-schemas/schema/m.room.create | 12 ++++ event-schemas/schema/m.room.tombstone | 27 +++++++ proposals/1501-room-version-upgrades.md | 2 +- specification/modules/room_upgrades.rst | 76 ++++++++++++++++++++ specification/targets.yaml | 1 + 8 files changed, 226 insertions(+), 2 deletions(-) create mode 100644 api/client-server/room_upgrades.yaml create mode 100644 event-schemas/examples/m.room.tombstone create mode 100644 event-schemas/schema/m.room.tombstone create mode 100644 specification/modules/room_upgrades.rst diff --git a/api/client-server/room_upgrades.yaml b/api/client-server/room_upgrades.yaml new file mode 100644 index 00000000..4d6b86b4 --- /dev/null +++ b/api/client-server/room_upgrades.yaml @@ -0,0 +1,95 @@ +# 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, migrating as much + data as possible over to the new room. See the `room_upgrades`_ module + for more information on what this entails. + 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 diff --git a/event-schemas/examples/m.room.create b/event-schemas/examples/m.room.create index 29b6237a..e33dbc3b 100644 --- a/event-schemas/examples/m.room.create +++ b/event-schemas/examples/m.room.create @@ -5,6 +5,10 @@ "content": { "creator": "@example:example.org", "room_version": "1", - "m.federate": true + "m.federate": true, + "predecessor": { + "event_id": "$something:example.org", + "room_id": "!oldroom:example.org" + } } } diff --git a/event-schemas/examples/m.room.tombstone b/event-schemas/examples/m.room.tombstone new file mode 100644 index 00000000..b6224476 --- /dev/null +++ b/event-schemas/examples/m.room.tombstone @@ -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" + } +} diff --git a/event-schemas/schema/m.room.create b/event-schemas/schema/m.room.create index d12b9ccd..a6fe331e 100644 --- a/event-schemas/schema/m.room.create +++ b/event-schemas/schema/m.room.create @@ -14,6 +14,18 @@ properties: room_version: description: The version of the room. Defaults to ``"1"`` if the key does not exist. type: string + predecessor: + description: A reference to the room this room replaces, if the previous room was upgraded. + type: object + title: Previous Room + properties: + room_id: + type: string + description: The ID of the old room. + event_id: + type: string + description: The event ID of the last known event in the old room. + required: [room_id, event_id] required: - creator type: object diff --git a/event-schemas/schema/m.room.tombstone b/event-schemas/schema/m.room.tombstone new file mode 100644 index 00000000..0fd8ba45 --- /dev/null +++ b/event-schemas/schema/m.room.tombstone @@ -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 diff --git a/proposals/1501-room-version-upgrades.md b/proposals/1501-room-version-upgrades.md index 3a726250..7bd310ea 100644 --- a/proposals/1501-room-version-upgrades.md +++ b/proposals/1501-room-version-upgrades.md @@ -48,7 +48,7 @@ When this is called, the server: "state_key": "", "room_id": "!QtykxKocfsgujksjgd:matrix.org", "content": { - "version": "2", + "room_version": "2", "predecessor": { "room_id": "!cURbaf:matrix.org", "event_id": "$1235135aksjgdkg:matrix.org" diff --git a/specification/modules/room_upgrades.rst b/specification/modules/room_upgrades.rst new file mode 100644 index 00000000..81da8aaf --- /dev/null +++ b/specification/modules/room_upgrades.rst @@ -0,0 +1,76 @@ +.. 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 MUST: + +* Hide the old room from the user's list of rooms. Permalinks, backlinks, etc should + still be accessible to this room, however. +* At the very bottom of the old room's timeline/message view, display a message which + indicates the room has been upgraded with a permalink to the new room. When the user + accesses the permalink, they are to be joined to the new room. + + * Note that if the homeserver doesn't support the room version that the user may + receive an error upon trying to join. + * If the replacement room has a tombstone event, the client may automatically follow + the chain until it finds a room which does not have a tombstone in it. + +* Optionally, the client may wish to improve the presentation of unread messages when + the user is in both the old and new rooms. For example, if the user was not active + during the upgrade and had unread messages in the old room, the new room may have an + indicator which shows the sum of unread notifications between the rooms. + +Clients which understand ``m.room.tombstone`` events must also understand the ``predecessor`` +field on ``m.room.create`` events such that: + +* At the top of the scrollback/message view for the new room a message is displayed + indicating that the room is a continuation of a previous room, with a permalink to + the old room. +* Optionally supporting search and other functions of the room to span across the old + and new 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 the power levels, privacy, topic, and other transferable state events to + the new room. This generally excludes membership events. +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``. diff --git a/specification/targets.yaml b/specification/targets.yaml index 93e1b8a6..60da93cd 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -70,6 +70,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/openid.rst - modules/server_acls.rst - modules/mentions.rst + - modules/room_upgrades.rst title_styles: ["=", "-", "~", "+", "^", "`", "@", ":"] From 56bfa7676530d4d52cf26b4acde923315e99d6af Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 9 Jan 2019 17:03:05 -0700 Subject: [PATCH 0093/1250] changelog --- changelogs/client_server/newsfragments/1791.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/1791.feature diff --git a/changelogs/client_server/newsfragments/1791.feature b/changelogs/client_server/newsfragments/1791.feature new file mode 100644 index 00000000..ae961ad3 --- /dev/null +++ b/changelogs/client_server/newsfragments/1791.feature @@ -0,0 +1 @@ +Add room version upgrades From 5cbfafaab73c2585c57a1703f39fa6cb8206dcee Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 9 Jan 2019 17:17:50 -0700 Subject: [PATCH 0094/1250] Fix link to module --- api/client-server/room_upgrades.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/client-server/room_upgrades.yaml b/api/client-server/room_upgrades.yaml index 4d6b86b4..6511d9fc 100644 --- a/api/client-server/room_upgrades.yaml +++ b/api/client-server/room_upgrades.yaml @@ -32,8 +32,8 @@ paths: summary: Upgrades a room to a new room version. description: |- Upgrades the given room to a particular room version, migrating as much - data as possible over to the new room. See the `room_upgrades`_ module - for more information on what this entails. + data as possible over to the new room. See the `room_upgrades <#room-upgrades>`_ + module for more information on what this entails. operationId: upgradeRoom security: - accessToken: [] From 1ea03da9b6781102ba990e79978ce48e95e89763 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Thu, 10 Jan 2019 12:18:22 +0000 Subject: [PATCH 0095/1250] Add .vscode to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a850d2fa..800be2fa 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ *.pyc *.swp _rendered.rst +/.vscode/ From b0adfc67d8e07ec031762601dac4c84be36ac01b Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Thu, 10 Jan 2019 12:17:48 +0000 Subject: [PATCH 0096/1250] MSC 1794 - Federation v2 Invite API --- proposals/1794-federation-v2-invites.md | 79 +++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 proposals/1794-federation-v2-invites.md diff --git a/proposals/1794-federation-v2-invites.md b/proposals/1794-federation-v2-invites.md new file mode 100644 index 00000000..3879683b --- /dev/null +++ b/proposals/1794-federation-v2-invites.md @@ -0,0 +1,79 @@ +# 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, and so 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, and so the event included in the payload would not be +able to be parsed. + +## 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_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 exception 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 a 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. From afa0caee93c8c21c008139babd0061a8a12f2c53 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 10 Jan 2019 18:16:39 +0000 Subject: [PATCH 0097/1250] remove lying footnote --- proposals/1711-x509-for-federation.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/proposals/1711-x509-for-federation.md b/proposals/1711-x509-for-federation.md index 4eda65ef..e97b8532 100644 --- a/proposals/1711-x509-for-federation.md +++ b/proposals/1711-x509-for-federation.md @@ -175,8 +175,7 @@ certificates comes with a number of downsides. Configuring a working, federating homeserver is a process fraught with pitfalls. This proposal adds the requirement to obtain a signed certificate to that process. Even with modern intiatives such as Let's Encrypt, this is -another procedure requiring manual intervention across several moving parts[3](#f3). +another procedure requiring manual intervention across several moving parts. On the other hand: obtaining an SSL certificate should be a familiar process to anybody capable of hosting a production homeserver (indeed, they should @@ -229,9 +228,3 @@ way. [↩](#a1) [2] I've not been able to find an authoritative source on this, but most reverse-proxies will reject requests where the SNI and Host headers do not match. [↩](#a2) - -[3] Let's Encrypt will issue ACME challenges via port 80 or DNS -(for the `http-01` or `dns-01` challenge types respectively). It is unlikely -that a homeserver implementation would be able to control either port 80 or DNS -responses, so we will be unable to automate a Let's Encrypt certificate -request. [↩](#a3) From 2109314c524fbc63952f96452e4989cd2786a863 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 11 Jan 2019 14:34:31 +0000 Subject: [PATCH 0098/1250] Apply suggestions from code review Co-Authored-By: erikjohnston --- proposals/1794-federation-v2-invites.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/1794-federation-v2-invites.md b/proposals/1794-federation-v2-invites.md index 3879683b..8402c447 100644 --- a/proposals/1794-federation-v2-invites.md +++ b/proposals/1794-federation-v2-invites.md @@ -6,9 +6,9 @@ room versions. ## Motivation It is planned for future room versions to be able to change the format of events -in various ways, and so to support this all servers must know the room version +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, and so the event included in the payload would not be +include the room version, so the target server would be unable to parse the event included in the payload. able to be parsed. ## Proposal @@ -41,7 +41,7 @@ The differences between this and `v1` are: 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 exception is returned, in the same way + 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 From 6e8739c989172c351a6ead66f073b413f6340326 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Fri, 11 Jan 2019 08:15:08 -0700 Subject: [PATCH 0099/1250] Fix typo Co-Authored-By: turt2live --- api/client-server/login.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client-server/login.yaml b/api/client-server/login.yaml index cef3d26f..98914a06 100644 --- a/api/client-server/login.yaml +++ b/api/client-server/login.yaml @@ -178,7 +178,7 @@ paths: type: object description: |- Optional client configuration provided by the server. If present, - clients SHOULD ise the provided object to reconfigure themselves, + clients SHOULD use the provided object to reconfigure themselves, optionally validating the URLs within. This object takes the same form as the one returned from .well-known autodiscovery. "$ref": "definitions/wellknown/full.yaml" From b7b96833d0ea436191be36ead1a98a353c9e0ae9 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 11 Jan 2019 16:15:06 +0000 Subject: [PATCH 0100/1250] Fix sticky headers so they don't hide behind header bar on desktop --- scripts/css/basic.css | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/scripts/css/basic.css b/scripts/css/basic.css index 8d99f6da..fdf2980d 100644 --- a/scripts/css/basic.css +++ b/scripts/css/basic.css @@ -465,11 +465,23 @@ dl.glossary dt { /* -- proposals page -------------------------------------------------------- */ #tables-of-tracked-proposals h2 { - margin-top: 7px; - padding-left: 10px; - position: -webkit-sticky; - position: sticky; - top: 0px; + padding-left: 10px; + position: -webkit-sticky; + position: sticky; +} + +/* Move sticky headers below header bar on desktop */ +@media all and (min-width:980px) { + #tables-of-tracked-proposals h2 { + top: 52px; + } +} + +/* Sticky headers stick to the top on mobile */ +@media all and (min-width:0px) and (max-width: 980px) { + #tables-of-tracked-proposals h2 { + top: 0px; + } } /* -- code displays --------------------------------------------------------- */ From c053996a7749b810affe871f36541de481b152c7 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 12 Jan 2019 23:12:56 +0000 Subject: [PATCH 0101/1250] add new technical guidelines to proposals.rst this was originally a todo for MSC1779, but belongs better in proposals.rst --- specification/proposals_intro.rst | 69 +++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 73ace98e..049ad0c8 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -44,15 +44,18 @@ moderators and admins, companies/projects building products or services on Matrix, spec contributors, translators, and those who created it in the first place. -"Greater benefit" could include maximising: +"Greater benefit" includes maximising: * the number of end-users reachable on the open Matrix network -* the number of regular users on the Matrix network (e.g. 30-day retained - federated users) +* the number of regular users on the Matrix network (e.g. 30-day retained federated users) +* the number of end-users reachable by Matrix (natively or via bridges) * the number of online servers in the open federation * the number of developers building on Matrix * the number of independent implementations which use Matrix -* the quality and utility of the Matrix spec +* the quality and utility of the Matrix spec (as defined by ease and ability + with which a developer can implement spec-compliant clients, servers, bots, + bridges, and other integrations without needing to refer to any other + external material) In addition, proposal authors are expected to uphold the following values in their proposed changes to the Matrix protocol: @@ -66,6 +69,64 @@ their proposed changes to the Matrix protocol: * Pragmatism rather than perfection * Proof rather than conjecture +Technical notes +--------------- + +Proposals **must** develop Matrix as a layered protocol: with new features +building on layers of shared abstractions rather than introducing tight vertical +coupling within the stack. This ensures that new features can evolve rapidly by +building on existing layers and swapping out old features without impacting the +rest of the stack or requiring substantial upgrades to the whole ecosystem. +This is critical for Matrix to rapidly evolve and compete effectively with +centralised systems, despite being a federated protocol. + +For instance, new features should be implemented using the highest layer +abstractions possible (e.g. new event types, which layer on top of the existing +room semantics, and so don't even require any API changes). Failing that, the +next recourse would be backwards-compatible changes to the next layer down (e.g. +room APIs); failing that, considering changes to the format of events or the +DAG; etc. It would be a very unusual feature which doesn't build on the +existing infrastructure provided by the spec and instead created new primitives +or low level APIs. + +Backwards compatibility is very important for Matrix, but not at the expense of +hindering the protocol's evolution. Backwards incompatible changes to endpoints +are allowed when no other alternative exists, and must be versioned under a new +major release of the API. Backwards incompatible changes to the room algorithm +are also allowed when no other alternative exists, and must be versioned under a +new version of the room algorithm. + +There is sometimes a dilemma over where to include higher level features: for +instance, should video conferencing be formalised in the spec, or should it be +implemented via widgets (if one assumes that widgets have landed in the spec and +[MSC1236](https://github.com/matrix-org/matrix-doc/issues/1236) is merged)? +Should reputation systems be specified? Should search engine behaviour be +specified? + +There is no universal answer to this, but the following guidelines should be +applied: + * If the feature would benefit the whole Matrix ecosystem and is aligned with + the guiding principles above, then it should be supported by the spec. + For instance, video conferencing is clearly a feature which would benefit + the whole ecosystem, and so the spec should find a way to make it happen. + * If the spec already makes the feature possible without changing any of the + spec *or implementations*, then it may not need to be added to the spec. + For instance, video conferencing done by widgets requires no compulsory + changes to clients nor servers to work, and so could be omitted. + * However, if the best user experience for a feature does require custom + implementation behaviour - e.g. embedding Jitsi into your client rather than + using a widget, then the behaviour should be defined in the spec to allow + implementations to do so. + * However, the spec must never add dependencies on unspecified/nonstandardised + 3rd party behaviour. For instance, defining how to embed Jitsi is unlikely to + ever make it into the spec, given Jitsi does not implement a standardised + interface (although a URL-based calling standard may emerge in future, which + could be used as an extension to the current widget-based approach). + * Therefore, our two options in the specific case of video conferencing are + either to spec SFU conferencing semantics on WebRTC (or refer to an existing spec + for doing so), or to keep it as a widget-based approach (optionally with widget + extensions specific for more deeply integrating video conferencing use cases). + Process ------- From edaf3596f470323a66c74383afb70332d26c28d9 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 12 Jan 2019 23:14:36 +0000 Subject: [PATCH 0102/1250] fix 'which features should go in the spec?' TODO and reword intro --- proposals/1779-open-governance.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 8834da30..9db96756 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -1,11 +1,11 @@ # Proposal for Open Governance of Matrix.org -This whole document is a **work in progress** draft of a constitution proposal -for open governance for Matrix.org, and forms the basis of the first full -Articles of Association (AoA) for [The Matrix.org Foundation -C.I.C.](https://beta.companieshouse.gov.uk/company/11648710) - a non-profit legal -entity incorporated to act as the neutral guardian of the Matrix decentralised -communication standard on behalf of the whole Matrix community. +This whole document is the proposed constitution proposal for Matrix.org, and +will form the basis of the first full Articles of Association (AoA) for [The +Matrix.org Foundation +C.I.C.](https://beta.companieshouse.gov.uk/company/11648710) - a non-profit +legal entity incorporated to act as the neutral guardian of the Matrix +decentralised communication standard on behalf of the whole Matrix community. See https://matrix.org/blog/2018/10/29/introducing-the-matrix-org-foundation-part-1-of-2/ for more context. @@ -121,10 +121,6 @@ rather than closed deployments. For example, if WhatsApp adopted Matrix it wouldn’t be a complete win unless they openly federated with the rest of the Matrix network. -TODO: spell out when features should land in the spec, versus via -integration/widget or other non-core extension. e.g. should video conferencing -be in the spec itself, or done via Jitsi? - ### Values As Matrix evolves, it's critical that the Spec Core Team and Guardians are From 21a781b1d2d5c035763da2d734613d323888eb3d Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 12 Jan 2019 23:16:24 +0000 Subject: [PATCH 0103/1250] fix proprietary wording --- proposals/1779-open-governance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 9db96756..f829f1d8 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -168,7 +168,7 @@ agendas at the expense of the overall project. We are particularly vigilant against 'trojan horse' additions to the spec - features which only benefit particular players, or are designed to somehow cripple or fragment the open protocol and ecosystem in favour of competitive -advantage. Commercial players are of course encouraged to build proprietary +advantage. Commercial players are of course free to build proprietary implementations, or use custom event types, or even custom API extensions (e.g. more efficient network transports) - but implementations must fall back to interoperating correctly with the rest of the ecosystem. From 265a3dc49b3a00f7ce80e00e8b34bc13a5612adc Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 12 Jan 2019 23:20:09 +0000 Subject: [PATCH 0104/1250] clarify removing members --- proposals/1779-open-governance.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index f829f1d8..9013f6b6 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -213,7 +213,8 @@ New additions to the team require 100% consent from the current team members. Membership has to be formally proposed by someone already on the Spec Core Team. Members can be removed from the team if >= 75% of the team agrees they are no -longer following the goals and guiding principles of the project. +longer following the goals and guiding principles of the project. (The 75% is +measured of the whole team, including the member in question) Guardians act as a backstop, and can appoint or remove Spec Core Team members (requiring a 75% consensus threshold between the Guardians) if the Spec Core From e584ae31f4e1e5bf806250a06e28b1bb3d9abcee Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 12 Jan 2019 23:21:02 +0000 Subject: [PATCH 0105/1250] fix missing words --- proposals/1779-open-governance.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 9013f6b6..808e8368 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -221,8 +221,8 @@ Guardians act as a backstop, and can appoint or remove Spec Core Team members Team is unable to function or is failing to align with the Foundation's mission. It's suggested that one of the Spec Core Team members should also be a Guardian, -to facilitate information between the Guardians and the Spec Core Team and -represent the technical angle of the project to the other Guardians. +to facilitate information exchange between the Guardians and the Spec Core Team, +and to represent the technical angle of the project to the other Guardians. The project lead role acts to coordinate the team and to help steer the team to consensus in the event of failing to get agreement on a Matrix Spec Change. From ed820ca27bdc00845f085c48fbf73c06f42c5202 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Sat, 12 Jan 2019 23:21:52 +0000 Subject: [PATCH 0106/1250] s/core spec team/Spec Core Team/ Co-Authored-By: ara4n --- proposals/1779-open-governance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 808e8368..2d0e21ed 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -232,7 +232,7 @@ term for the project lead. The lead may be removed by the core team at any point (with 75% majority), and may resign the role at any point (notifying the team and the Guardians). The lead automatically resigns the role if they resign from the Spec Core Team. Resignation automatically triggers selection of a new -lead, who must be selected from the existing core spec team. +lead, who must be selected from the existing Spec Core Team. It is vital that the core spec team has strong domain expertise covering all different domains of the spec (e.g. we don't want to end up with a core spec From b758ceea5b3976f0ae64da5ad7cf8855f0ee5ab7 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 12 Jan 2019 23:23:46 +0000 Subject: [PATCH 0107/1250] add erik's quorum --- proposals/1779-open-governance.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 2d0e21ed..58142027 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -177,7 +177,8 @@ interoperating correctly with the rest of the ecosystem. The Spec Core Team itself will be made up of roughly 8 members + 1 project lead. Roughly half the members are expected to be from the historical core team -(similar to Rust). +(similar to Rust). The team must have 5 members to be quorate, with the aim of +generally having between 7 and 9 members. In future we may also have sub-teams (like Rust - e.g. CS/AS/Push API; SS API; IS API; Crypto), but as a starting point we are beginning with a single core From 107d96c50e4882924d4823fef92967e09e9bc223 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 12 Jan 2019 23:24:55 +0000 Subject: [PATCH 0108/1250] spell out consensus ftw --- proposals/1779-open-governance.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 58142027..76c6ffa9 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -255,6 +255,9 @@ MSCs require >= 75% approval from the Spec Core Team to proceed to Final Comment Period (see https://matrix.org/docs/spec/proposals for the rest of the MSC process). +Even though a threshold of only 75% is required for approval, the Spec Core Team +is expected to seek consensus on MSCs. + The above governance process for the Spec Core Team is considered as part of the spec and is updated using the Matrix Spec Change process. However, changes to the governance process also require a 75% positive approval from the Guardians From cccd62f03530fcaa78fa38b8fa4992518058100a Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Sat, 12 Jan 2019 23:25:37 +0000 Subject: [PATCH 0109/1250] grammar Co-Authored-By: ara4n --- proposals/1779-open-governance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 76c6ffa9..4de598a9 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -338,7 +338,7 @@ code to the public https://github.com/matrix-org repositories, who are either working on matrix.org's reference implementations or the spec itself. Commit access is decided by those responsible for the projects in question, much like any other open source project. Anyone is eligible for commit access if they -have proved themselves a valuable long-term contributor, upholds the guiding +have proved themselves a valuable long-term contributor, uphold the guiding principles and mission of the project and have proved themselves able to collaborate constructively with the existing core team. Active participation in the core team is also signified by membership of the +matrix:matrix.org Matrix From d00a5eba93926b768555d53a7b081c3a4ccfc9b0 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 12 Jan 2019 23:26:58 +0000 Subject: [PATCH 0110/1250] consistent tenses --- proposals/1779-open-governance.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 4de598a9..16047a2d 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -354,19 +354,19 @@ Code Core Team members volunteer their time for free to work on the project. ## Responsibilities for the Foundation - * Independent legal entity to act as neutral custodian of Matrix - * Gathering donations + * Independent legal entity which acts as neutral custodian of Matrix + * Gathers donations * Owns the core Matrix IP in an asset lock, which shall be transferred from New Vector: * Owns the matrix.org domain and branding * Owns the copyright of the reference implementations of Matrix (i.e. everything in https://github.com/matrix-org). By assigning copyright to the Foundation, it’s protected against New Vector ever being tempted to relicense it. * Owns the IP of the website * Owns the Matrix.org marketing swag (t-shirts, stickers, exhibition stands etc) - * It's responsible for finding someone to run the Matrix.org homeserver (currently New Vector) - * Publishing the spec + * Responsible for finding someone to run the Matrix.org homeserver (currently New Vector) + * Publishes the spec * Responsible for tools and documentation that supports the spec * Responsible for ensuring reference implementations and test suite exists for the spec - * Publishing the website (including ensuring This Week In Matrix and similar exist to promote independent projects) + * Publishes the website (including ensuring This Week In Matrix and similar exist to promote independent projects) * Manages IANA-style allocations for Matrix * mx:// URI scheme? * TCP port 8448 @@ -374,9 +374,9 @@ Code Core Team members volunteer their time for free to work on the project. In future: - * contract entities to work on Matrix? (e.g. redistributing donations back to fund development) - * manage a "Made for Matrix" certification process? (to confirm that products are actually compatible with Matrix) - * promote Matrix (e.g. organise meetups & events & fund community activity)? + * contracts entities to work on Matrix? (e.g. redistributing donations back to fund development) + * manages a "Made for Matrix" certification process? (to confirm that products are actually compatible with Matrix) + * promotes Matrix (e.g. organise meetups & events & fund community activity)? ## Timings From ddc3921318262ad7134b37253030ac5a182833ca Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 12 Jan 2019 23:31:01 +0000 Subject: [PATCH 0111/1250] un-todo code core team responsibilities --- proposals/1779-open-governance.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 16047a2d..f30d50d0 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -344,10 +344,14 @@ collaborate constructively with the existing core team. Active participation in the core team is also signified by membership of the +matrix:matrix.org Matrix community. -TODO: spell out some responsibilities. Erik suggests something like: - * Helping to ensure the quality of the projects' repositories - * That all projects follow the Matrix spec - * Engaging with the people in a way that fosters a healthy and happy community +Responsibilities include: + * Helping ensure the quality of the projects' code repositories + * Ensuring all commits are reviewed + * Ensuring that all projects follow the Matrix spec + * Helping architect the implementations + * Contributing code to the implementations + * Fostering contributions and engaging with contributors constructively in a + way that fosters a healthy and happy community * Following the Guiding Principles and promoting them within the community Code Core Team members volunteer their time for free to work on the project. From 156488384c75aa23290da0cd845902fffb043d1d Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 12 Jan 2019 23:49:27 +0000 Subject: [PATCH 0112/1250] add more examples for spec inclusion; add interoperability as a core value --- proposals/1779-open-governance.md | 1 + specification/proposals_intro.rst | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index f30d50d0..f5a89f5e 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -129,6 +129,7 @@ subjective areas. The values we follow are: * Supporting the whole long-term ecosystem rather than individual stakeholder gain * Openness rather than proprietariness + * Interoperability rather than fragmentation * Collaboration rather than competition * Accessibility rather than elitism * Transparency rather than stealth diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 049ad0c8..b7663e66 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -62,6 +62,7 @@ their proposed changes to the Matrix protocol: * Supporting the whole long-term ecosystem rather than individual stakeholder gain * Openness rather than proprietariness +* Interoperability rather than fragmentation * Collaboration rather than competition * Accessibility rather than elitism * Transparency rather than stealth @@ -110,7 +111,7 @@ applied: For instance, video conferencing is clearly a feature which would benefit the whole ecosystem, and so the spec should find a way to make it happen. * If the spec already makes the feature possible without changing any of the - spec *or implementations*, then it may not need to be added to the spec. + implementations and spec, then it may not need to be added to the spec. For instance, video conferencing done by widgets requires no compulsory changes to clients nor servers to work, and so could be omitted. * However, if the best user experience for a feature does require custom @@ -127,6 +128,19 @@ applied: for doing so), or to keep it as a widget-based approach (optionally with widget extensions specific for more deeply integrating video conferencing use cases). +As an alternative example: it's very unlikely that "how to visualise Magnetic +Resonsance Imaging data over Matrix" would ever be added to the Matrix spec +(other than perhaps a custom event type in a wider standardised Matrix event +registry) given that the spec's existing primitives of file transfer and +extensible events (MSC1767) give excellent tools for transferring and +visualising arbitrary rich data. + +Conversely, features such as reactions, threaded messages, editable messages, +spam/abuse/content filtering, are all features which would clearly benefit the +whole Matrix ecosystem and require both client & server implementation +changes across the board to be implemented in an interoperable way, and so +necessitate a spec change. + Process ------- From f3085812e9c160f63e0cb542378eb827112a54c2 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 12 Jan 2019 23:51:49 +0000 Subject: [PATCH 0113/1250] more examples; remove widget MSC ref --- specification/proposals_intro.rst | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index b7663e66..c8a2fd32 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -99,10 +99,8 @@ new version of the room algorithm. There is sometimes a dilemma over where to include higher level features: for instance, should video conferencing be formalised in the spec, or should it be -implemented via widgets (if one assumes that widgets have landed in the spec and -[MSC1236](https://github.com/matrix-org/matrix-doc/issues/1236) is merged)? -Should reputation systems be specified? Should search engine behaviour be -specified? +implemented via widgets? Should reputation systems be specified? Should search +engine behaviour be specified? There is no universal answer to this, but the following guidelines should be applied: @@ -135,11 +133,17 @@ registry) given that the spec's existing primitives of file transfer and extensible events (MSC1767) give excellent tools for transferring and visualising arbitrary rich data. +Supporting public search engines are likely to not require custom spec features +(other than possibly better bulk access APIs), given they can be implemented as +clients using the existing CS API. An exception could be API features required +by decentralised search infrastructure (avoiding centralisation of power by +a centralised search engine). + Conversely, features such as reactions, threaded messages, editable messages, -spam/abuse/content filtering, are all features which would clearly benefit the -whole Matrix ecosystem and require both client & server implementation -changes across the board to be implemented in an interoperable way, and so -necessitate a spec change. +spam/abuse/content filtering (and reputation systems), are all features which +would clearly benefit the whole Matrix ecosystem and require both client & +server implementation changes across the board to be implemented in an +interoperable way, and so necessitate a spec change. Process ------- From d318ff95f3e835687df9d3411cf52613475516a3 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Mon, 14 Jan 2019 11:55:27 +0000 Subject: [PATCH 0114/1250] MSC1802: Standardised federation response formats --- ...standardised-federation-response-format.md | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 proposals/1802-standardised-federation-response-format.md diff --git a/proposals/1802-standardised-federation-response-format.md b/proposals/1802-standardised-federation-response-format.md new file mode 100644 index 00000000..736cbbd3 --- /dev/null +++ b/proposals/1802-standardised-federation-response-format.md @@ -0,0 +1,55 @@ +# Standardised federation response formats + +Some responses formats in the federation API specifications use the form `[200, +res]` in which `res` is the JSON object containing the actual response for the +affected endpoints. This was due to a mishap while building synapse's federation +features, and has been left as is because fixing it would induce backward +incompatibility. With r0 approaching, and already including features with +backward compatibility issues (e.g. +[MSC1711](https://github.com/matrix-org/matrix-doc/pull/1711)), this is likely +the right timing to address this issue. + +## Proposal + +Change the responses with a 200 status code for the following federation +endpoints: + +* `PUT /_matrix/federation/v1/send/{txnId}` +* `PUT /_matrix/federation/v1/send_join/{roomId}/{eventId}` +* `PUT /_matrix/federation/v1/invite/{roomId}/{eventId}` +* `PUT /_matrix/federation/v1/send_leave/{roomId}/{eventId}` + +From a response using this format: + +``` +[ + 200, + res +] +``` + +To a response using this format: + +``` +res +``` + +Where `res` is the JSON object containing the response to a request directed at +one of the affected endpoints. + +## Potential issues + +As it's already been mentioned in the proposal's introduction, this would induce +backward compatibility issues. However, proposals that have already been merged +at the time this one is being written already induce similar issues. + +As a mitigation solution, we could have a transition period during which both +response formats would be accepted on the affected endpoints. This would give +people time to update their homeservers to a version supporting the new one +without breaking federation entirely. + +## Conclusion + +Such a change would make the federation API specifications more standardised, +but would induce backward incompatible changes. However, with r0 coming up soon, +this is likely the best timing to address this issue. From 09813fc3a080600c13ccaaa74deb61c9df07c1ee Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 14 Jan 2019 12:41:19 +0000 Subject: [PATCH 0115/1250] improve wording around compensation for team members. tweak Greater Benefit (particularly adding SnR and filtering goals --- proposals/1779-open-governance.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index f5a89f5e..63684e40 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -105,12 +105,14 @@ protocol. This includes (non-exhaustively): "Greater benefit" is defined as maximising: - * the number of end-users reachable on the open Matrix network + * the number of Matrix-native end-users reachable on the open Matrix network * the number of regular users on the Matrix network (e.g. 30-day retained federated users) - * the number of end-users reachable by Matrix (natively or via bridges) * the number of online servers in the open federation * the number of developers building on Matrix * the number of independent implementations which use Matrix + * the number of bridged end-users reachable on the open Matrix network + * the signal-to-noise ratio of the content on the open Matrix network (i.e. minimising spam) + * the ability for users to discover content on their terms (empowering them to select what to see and what not to see) * the quality and utility of the Matrix spec (as defined by ease and ability with which a developer can implement spec-compliant clients, servers, bots, bridges, and other integrations without needing to refer to any other @@ -130,6 +132,7 @@ subjective areas. The values we follow are: * Supporting the whole long-term ecosystem rather than individual stakeholder gain * Openness rather than proprietariness * Interoperability rather than fragmentation + * Cross-platform rather than platform-specific * Collaboration rather than competition * Accessibility rather than elitism * Transparency rather than stealth @@ -187,7 +190,7 @@ team in the interests of not over-engineering it and scaling up elastically. Spec Core Team members need to be able to commit to at least 1 hour a week of availability to work on the spec and (where relevant) reference implementations. -Members of the team volunteer their time for free to work on the project. +Members must arrange their own funding for their time. Responsibilities include: @@ -329,7 +332,7 @@ The intention is for Matthew & Amandine (the original founders of Matrix) to form a minority of the Guardians, in order to ensure the neutrality of the Foundation relative to Matthew & Amandine’s day jobs at New Vector. -Guardians volunteer their time for free to work on the project. +Guardians must arrange their own funding for their time. ## The Code Core Team (aka The Core Team) @@ -355,7 +358,7 @@ Responsibilities include: way that fosters a healthy and happy community * Following the Guiding Principles and promoting them within the community -Code Core Team members volunteer their time for free to work on the project. +Code Core Team members must arrange their own funding for their time. ## Responsibilities for the Foundation From 2f20679db514ec6b58970bcf91e18a3f3c46270a Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Mon, 14 Jan 2019 12:48:12 +0000 Subject: [PATCH 0116/1250] deanonymise kitsune Co-Authored-By: ara4n --- proposals/1779-open-governance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 63684e40..a98f36a0 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -252,7 +252,7 @@ The initial Spec Core Team (and their domain areas) is: * Hubert Chathi (Cryptography, General) * Andrew Morgan (Servers, AS API, Spec Process) * Travis Ralston (Bots and Bridges & AS API, Media, acting with Dimension hat on) - * kitsune (Clients on behalf of Community) + * Alexey Rusakov (Clients on behalf of Community) * TBD MSCs require >= 75% approval from the Spec Core Team to proceed to Final Comment From a38e1e6adff27c649b6ac964f7787535b1aa988e Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 14 Jan 2019 12:54:21 +0000 Subject: [PATCH 0117/1250] incorporate kitsune & dbkr review --- proposals/1779-open-governance.md | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index a98f36a0..0b8c0aeb 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -75,7 +75,7 @@ We believe: * The ability to converse securely and privately is a basic human right. - * Communication should be available to everyone as an free and open, + * Communication should be available to everyone as a free and open, unencumbered, standard and global network. ### Mission @@ -130,7 +130,7 @@ aligned on the overall philosophy of the project, particularly in more subjective areas. The values we follow are: * Supporting the whole long-term ecosystem rather than individual stakeholder gain - * Openness rather than proprietariness + * Openness rather than proprietary lock-in * Interoperability rather than fragmentation * Cross-platform rather than platform-specific * Collaboration rather than competition @@ -142,6 +142,10 @@ subjective areas. The values we follow are: Patent encumbered IP is strictly prohibited from being added to the standard. +Making the specification rely on non-standard/unspecified behaviour of other +systems or actors (such as SaaS services, even open-sourced, not governed by a +standard protocol) shall not be accepted, either. + ## The Spec Core Team The contents and direction of the Matrix Spec is governed by the Spec Core Team; @@ -208,8 +212,8 @@ Responsibilities include: * Ensuring the code of conduct for +matrix:matrix.org community rooms is maintained and applied -If members are absent for more than 8 weeks without prior agreement, they will -be assumed to have left the project. +If members are absent (uncontactable) for more than 8 weeks without prior +agreement, they will be assumed to have left the project. Spec Core Team members can resign whenever they want, but must notify the rest of the team and the Guardians on doing so. @@ -375,16 +379,20 @@ Code Core Team members must arrange their own funding for their time. * Responsible for tools and documentation that supports the spec * Responsible for ensuring reference implementations and test suite exists for the spec * Publishes the website (including ensuring This Week In Matrix and similar exist to promote independent projects) - * Manages IANA-style allocations for Matrix - * mx:// URI scheme? + * Manages IANA-style allocations for Matrix, including: + * mx:// URI scheme * TCP port 8448 - * .well-known URIs…? + * .well-known URIs +* Ensures that Matrix promotion is happening (e.g. ensuring that meetups & + events & community activity is supported) In future: - * contracts entities to work on Matrix? (e.g. redistributing donations back to fund development) + * contracts entities to work on Matrix if such contracts help the Foundation to + fulfil its mission and obey the Guiding Principles (e.g. redistributing + donations back to fund development of reference implementations or compliance + kits) * manages a "Made for Matrix" certification process? (to confirm that products are actually compatible with Matrix) - * promotes Matrix (e.g. organise meetups & events & fund community activity)? ## Timings From 70be8393a391baecc23a322800f6843d63d8187a Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 14 Jan 2019 13:01:50 +0000 Subject: [PATCH 0118/1250] clarify the technical note and guiding principles --- specification/proposals_intro.rst | 73 ++++++++++++++++++------------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index c8a2fd32..393a43a2 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -33,25 +33,28 @@ Guiding Principles Proposals **must** act to the greater benefit of the entire Matrix ecosystem, rather than benefiting or privileging any single player or subset of players - -and must not contain any patent encumbered intellectual property. Members of the Core Team pledge to act as +and must not contain any patent encumbered intellectual property. +Members of the Spec Core Team pledge to act as a neutral custodian for Matrix on behalf of the whole ecosystem. For clarity: the Matrix ecosystem is anyone who uses the Matrix protocol. That -includes client users, server admins, client developers, bot developers, -bridge and application service developers, users and admins who are indirectly using Matrix via -3rd party networks which happen to be bridged, server developers, room -moderators and admins, companies/projects building products or services on -Matrix, spec contributors, translators, and those who created it in -the first place. +includes client users, server admins, client developers, bot developers, bridge +and application service developers, users and admins who are indirectly using +Matrix via 3rd party networks which happen to be bridged, server developers, +room moderators and admins, companies/projects building products or services on +Matrix, spec contributors, translators, and those who created it in the first +place. -"Greater benefit" includes maximising: +"Greater benefit" is defined as maximising: -* the number of end-users reachable on the open Matrix network +* the number of Matrix-native end-users reachable on the open Matrix network * the number of regular users on the Matrix network (e.g. 30-day retained federated users) -* the number of end-users reachable by Matrix (natively or via bridges) * the number of online servers in the open federation * the number of developers building on Matrix * the number of independent implementations which use Matrix +* the number of bridged end-users reachable on the open Matrix network +* the signal-to-noise ratio of the content on the open Matrix network (i.e. minimising spam) +* the ability for users to discover content on their terms (empowering them to select what to see and what not to see) * the quality and utility of the Matrix spec (as defined by ease and ability with which a developer can implement spec-compliant clients, servers, bots, bridges, and other integrations without needing to refer to any other @@ -61,8 +64,9 @@ In addition, proposal authors are expected to uphold the following values in their proposed changes to the Matrix protocol: * Supporting the whole long-term ecosystem rather than individual stakeholder gain -* Openness rather than proprietariness +* Openness rather than proprietary lock-in * Interoperability rather than fragmentation +* Cross-platform rather than platform-specific * Collaboration rather than competition * Accessibility rather than elitism * Transparency rather than stealth @@ -70,6 +74,9 @@ their proposed changes to the Matrix protocol: * Pragmatism rather than perfection * Proof rather than conjecture +Please see [MSC1779](https://github.com/matrix-org/matrix-doc/pull/1779) +for full details of the project's Guiding Principles. + Technical notes --------------- @@ -104,33 +111,37 @@ engine behaviour be specified? There is no universal answer to this, but the following guidelines should be applied: - * If the feature would benefit the whole Matrix ecosystem and is aligned with +1. If the feature would benefit the whole Matrix ecosystem and is aligned with the guiding principles above, then it should be supported by the spec. - For instance, video conferencing is clearly a feature which would benefit - the whole ecosystem, and so the spec should find a way to make it happen. - * If the spec already makes the feature possible without changing any of the +2. If the spec already makes the feature possible without changing any of the implementations and spec, then it may not need to be added to the spec. - For instance, video conferencing done by widgets requires no compulsory - changes to clients nor servers to work, and so could be omitted. - * However, if the best user experience for a feature does require custom - implementation behaviour - e.g. embedding Jitsi into your client rather than - using a widget, then the behaviour should be defined in the spec to allow - implementations to do so. - * However, the spec must never add dependencies on unspecified/nonstandardised - 3rd party behaviour. For instance, defining how to embed Jitsi is unlikely to - ever make it into the spec, given Jitsi does not implement a standardised - interface (although a URL-based calling standard may emerge in future, which - could be used as an extension to the current widget-based approach). - * Therefore, our two options in the specific case of video conferencing are - either to spec SFU conferencing semantics on WebRTC (or refer to an existing spec - for doing so), or to keep it as a widget-based approach (optionally with widget - extensions specific for more deeply integrating video conferencing use cases). +3. However, if the best user experience for a feature does require custom + implementation behaviour then the behaviour should be defined in the spec + such that all implementations may implement it. +4. However, the spec must never add dependencies on unspecified/nonstandardised + 3rd party behaviour. + +As a worked example: +1. Video conferencing is clearly a feature which would benefit + the whole ecosystem, and so the spec should find a way to make it happen. +2. Video conferencing can be achieved by widgets without requiring any + compulsory changes to changes to clients nor servers to work, and so could be + omitted from the spec. +3. A better experience could be achieved by embedding Jitsi natively into clients + rather than using a widget... +4. ...except that would add a dependency on unspecified/nonstandardised 3rd party + behaviour, so must not be added to the spec. + +Therefore, our two options in the specific case of video conferencing are +either to spec SFU conferencing semantics for WebRTC (or refer to an existing spec +for doing so), or to keep it as a widget-based approach (optionally with widget +extensions specific for more deeply integrating video conferencing use cases). As an alternative example: it's very unlikely that "how to visualise Magnetic Resonsance Imaging data over Matrix" would ever be added to the Matrix spec (other than perhaps a custom event type in a wider standardised Matrix event registry) given that the spec's existing primitives of file transfer and -extensible events (MSC1767) give excellent tools for transferring and +extensible events (MSC1767) give excellent tools for transfering and visualising arbitrary rich data. Supporting public search engines are likely to not require custom spec features From 811e65a4d1cf92b1314889330a01f86a16d23148 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 14 Jan 2019 13:14:43 +0000 Subject: [PATCH 0119/1250] kitsune review on when to add things to the spec --- specification/proposals_intro.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 393a43a2..1e93a22a 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -150,11 +150,10 @@ clients using the existing CS API. An exception could be API features required by decentralised search infrastructure (avoiding centralisation of power by a centralised search engine). -Conversely, features such as reactions, threaded messages, editable messages, +Features such as reactions, threaded messages, editable messages, spam/abuse/content filtering (and reputation systems), are all features which -would clearly benefit the whole Matrix ecosystem and require both client & -server implementation changes across the board to be implemented in an -interoperable way, and so necessitate a spec change. +would clearly benefit the whole Matrix ecosystem, and cannot be implemented in an +interoperable way using the current spec; so they necessitate a spec change. Process ------- From c88c9c29413c2da12b2d0b9fc9a1b698ddd7cdba Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 14 Jan 2019 14:19:58 +0000 Subject: [PATCH 0120/1250] Update proposals/1794-federation-v2-invites.md Co-Authored-By: erikjohnston --- proposals/1794-federation-v2-invites.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1794-federation-v2-invites.md b/proposals/1794-federation-v2-invites.md index 8402c447..de5c70f6 100644 --- a/proposals/1794-federation-v2-invites.md +++ b/proposals/1794-federation-v2-invites.md @@ -48,7 +48,7 @@ The response is identical to `v1`, except that: bring the invite API into line with the rest of the federation API. -If a call to `v2` `/invite` results in a unrecognised request exception **AND** +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. From b90ee6baaba293681e24ce503465626363d87c30 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Mon, 14 Jan 2019 14:20:57 +0000 Subject: [PATCH 0121/1250] 'invite_room_state' should be an array --- proposals/1794-federation-v2-invites.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1794-federation-v2-invites.md b/proposals/1794-federation-v2-invites.md index de5c70f6..65e63825 100644 --- a/proposals/1794-federation-v2-invites.md +++ b/proposals/1794-federation-v2-invites.md @@ -22,7 +22,7 @@ PUT /_matrix/federation/v2/invite// { "room_version": , "event": { ... }, - "invite_room_state": { ... } + "invite_room_state": [ ... ] } ``` From ebf37178b5acb9f3ba376fa429fb56263a87e4a3 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Mon, 14 Jan 2019 15:53:23 +0000 Subject: [PATCH 0122/1250] Update proposals/1794-federation-v2-invites.md Co-Authored-By: erikjohnston --- proposals/1794-federation-v2-invites.md | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/1794-federation-v2-invites.md b/proposals/1794-federation-v2-invites.md index 65e63825..a2f2bb35 100644 --- a/proposals/1794-federation-v2-invites.md +++ b/proposals/1794-federation-v2-invites.md @@ -9,7 +9,6 @@ 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. -able to be parsed. ## Proposal From 749b1777fa549ba1e6c156d26dfb43b5eb88127f Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Mon, 14 Jan 2019 16:17:40 +0000 Subject: [PATCH 0123/1250] Propose a backward-compatible option instead of an incompatible one --- ...standardised-federation-response-format.md | 44 ++++++++----------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/proposals/1802-standardised-federation-response-format.md b/proposals/1802-standardised-federation-response-format.md index 736cbbd3..f4cefc8f 100644 --- a/proposals/1802-standardised-federation-response-format.md +++ b/proposals/1802-standardised-federation-response-format.md @@ -4,22 +4,21 @@ Some responses formats in the federation API specifications use the form `[200, res]` in which `res` is the JSON object containing the actual response for the affected endpoints. This was due to a mishap while building synapse's federation features, and has been left as is because fixing it would induce backward -incompatibility. With r0 approaching, and already including features with -backward compatibility issues (e.g. -[MSC1711](https://github.com/matrix-org/matrix-doc/pull/1711)), this is likely -the right timing to address this issue. +incompatibility. + +This proposal proposes a backward compatible alternative ## Proposal -Change the responses with a 200 status code for the following federation -endpoints: +Add a new version of the following endpoints under the prefix +`/_matrix/federation/v2`: -* `PUT /_matrix/federation/v1/send/{txnId}` -* `PUT /_matrix/federation/v1/send_join/{roomId}/{eventId}` -* `PUT /_matrix/federation/v1/invite/{roomId}/{eventId}` -* `PUT /_matrix/federation/v1/send_leave/{roomId}/{eventId}` +* `PUT /_matrix/federation/v2/send/{txnId}` +* `PUT /_matrix/federation/v2/send_join/{roomId}/{eventId}` +* `PUT /_matrix/federation/v2/send_leave/{roomId}/{eventId}` -From a response using this format: +Which are the exact same endpoints as their equivalents under the `v1` prefix, +except for the response format, which changes from: ``` [ @@ -28,7 +27,7 @@ From a response using this format: ] ``` -To a response using this format: +To: ``` res @@ -37,19 +36,12 @@ res Where `res` is the JSON object containing the response to a request directed at one of the affected endpoints. -## Potential issues - -As it's already been mentioned in the proposal's introduction, this would induce -backward compatibility issues. However, proposals that have already been merged -at the time this one is being written already induce similar issues. - -As a mitigation solution, we could have a transition period during which both -response formats would be accepted on the affected endpoints. This would give -people time to update their homeservers to a version supporting the new one -without breaking federation entirely. +This proposal doesn't address the `PUT +/_matrix/federation/v1/invite/{roomId}/{eventId}` endpoint since +[MSC1794](https://github.com/matrix-org/matrix-doc/pull/1794) already takes care +of it. -## Conclusion +## Alternative solutions -Such a change would make the federation API specifications more standardised, -but would induce backward incompatible changes. However, with r0 coming up soon, -this is likely the best timing to address this issue. +An alternative solution would be to make the change in the `v1` fedration API, +but would break backward compatibility, thus would be harder to manage. From 9e435d6dabdeb2e482d15e1ceb9bcda0bbe9b432 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Mon, 14 Jan 2019 23:33:03 +0000 Subject: [PATCH 0124/1250] scifi IANA Co-Authored-By: ara4n --- proposals/1779-open-governance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 0b8c0aeb..f6d5b959 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -379,7 +379,7 @@ Code Core Team members must arrange their own funding for their time. * Responsible for tools and documentation that supports the spec * Responsible for ensuring reference implementations and test suite exists for the spec * Publishes the website (including ensuring This Week In Matrix and similar exist to promote independent projects) - * Manages IANA-style allocations for Matrix, including: + * Manages any future IANA-style allocations for Matrix, such as: * mx:// URI scheme * TCP port 8448 * .well-known URIs From 6ff0155a324510b863f3c66843817f4d45e5b9e7 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 15 Jan 2019 00:16:33 +0000 Subject: [PATCH 0125/1250] s/responsibilities/functions --- proposals/1779-open-governance.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index f6d5b959..28c18791 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -364,7 +364,7 @@ Responsibilities include: Code Core Team members must arrange their own funding for their time. -## Responsibilities for the Foundation +## Functions of the Foundation * Independent legal entity which acts as neutral custodian of Matrix * Gathers donations @@ -392,7 +392,8 @@ In future: fulfil its mission and obey the Guiding Principles (e.g. redistributing donations back to fund development of reference implementations or compliance kits) - * manages a "Made for Matrix" certification process? (to confirm that products are actually compatible with Matrix) + * manages a "Made for Matrix" certification process? (to confirm that products + are actually compatible with Matrix) ## Timings From 822d84e50c46f335efbd04af8f565fbf98af7b96 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 15 Jan 2019 00:29:07 +0000 Subject: [PATCH 0126/1250] append fullstops to lists to make vdh happy --- proposals/1779-open-governance.md | 128 +++++++++++++++--------------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 28c18791..58e43b80 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -88,35 +88,35 @@ player or subset of players. For clarity: the Matrix ecosystem is defined as anyone who uses the Matrix protocol. This includes (non-exhaustively): - * End-users of Matrix clients - * Matrix client developers and testers - * Spec developers - * Server admins - * Matrix packagers & maintainers - * Companies building products or services on Matrix - * Bridge developers - * Bot developers - * Widget developers - * Server developers - * Matrix room and community moderators - * End-users who are using Matrix indirectly via bridges - * External systems which are bridged into Matrix - * Anyone using Matrix for data communications + * End-users of Matrix clients. + * Matrix client developers and testers. + * Spec developers. + * Server admins. + * Matrix packagers & maintainers. + * Companies building products or services on Matrix. + * Bridge developers. + * Bot developers. + * Widget developers. + * Server developers. + * Matrix room and community moderators. + * End-users who are using Matrix indirectly via bridges. + * External systems which are bridged into Matrix. + * Anyone using Matrix for data communications. "Greater benefit" is defined as maximising: - * the number of Matrix-native end-users reachable on the open Matrix network - * the number of regular users on the Matrix network (e.g. 30-day retained federated users) - * the number of online servers in the open federation - * the number of developers building on Matrix - * the number of independent implementations which use Matrix - * the number of bridged end-users reachable on the open Matrix network - * the signal-to-noise ratio of the content on the open Matrix network (i.e. minimising spam) - * the ability for users to discover content on their terms (empowering them to select what to see and what not to see) + * the number of Matrix-native end-users reachable on the open Matrix network. + * the number of regular users on the Matrix network (e.g. 30-day retained federated users). + * the number of online servers in the open federation. + * the number of developers building on Matrix. + * the number of independent implementations which use Matrix. + * the number of bridged end-users reachable on the open Matrix network. + * the signal-to-noise ratio of the content on the open Matrix network (i.e. minimising spam). + * the ability for users to discover content on their terms (empowering them to select what to see and what not to see). * the quality and utility of the Matrix spec (as defined by ease and ability with which a developer can implement spec-compliant clients, servers, bots, bridges, and other integrations without needing to refer to any other - external material) + external material). N.B. that we consider success to be the growth of the open federated network rather than closed deployments. For example, if WhatsApp adopted Matrix it @@ -129,16 +129,16 @@ As Matrix evolves, it's critical that the Spec Core Team and Guardians are aligned on the overall philosophy of the project, particularly in more subjective areas. The values we follow are: - * Supporting the whole long-term ecosystem rather than individual stakeholder gain - * Openness rather than proprietary lock-in - * Interoperability rather than fragmentation - * Cross-platform rather than platform-specific - * Collaboration rather than competition - * Accessibility rather than elitism - * Transparency rather than stealth - * Empathy rather than contrariness - * Pragmatism rather than perfection - * Proof rather than conjecture + * Supporting the whole long-term ecosystem rather than individual stakeholder gain. + * Openness rather than proprietary lock-in. + * Interoperability rather than fragmentation. + * Cross-platform rather than platform-specific. + * Collaboration rather than competition. + * Accessibility rather than elitism. + * Transparency rather than stealth. + * Empathy rather than contrariness. + * Pragmatism rather than perfection. + * Proof rather than conjecture. Patent encumbered IP is strictly prohibited from being added to the standard. @@ -198,19 +198,19 @@ Members must arrange their own funding for their time. Responsibilities include: - * Reviewing Matrix Spec Change proposals and Spec PRs + * Reviewing Matrix Spec Change proposals and Spec PRs. * Contributing to and reviewing reference implementations of Matrix Spec Change - proposals + proposals. - * Shepherding Matrix Spec Changes on behalf of authors where needed + * Shepherding Matrix Spec Changes on behalf of authors where needed. - * Triaging Matrix Spec issues + * Triaging Matrix Spec issues. - * Coordinating reference implementations + * Coordinating reference implementations. * Ensuring the code of conduct for +matrix:matrix.org community rooms is - maintained and applied + maintained and applied. If members are absent (uncontactable) for more than 8 weeks without prior agreement, they will be assumed to have left the project. @@ -283,18 +283,18 @@ is following its guiding principles, and provide a safety mechanism if the structure of the Spec Core Team runs into trouble. In practice, this means that: - * Guardians must approve changes to the Spec Core Team - * Guardians must keep each other honest, providing a ‘checks and balances’ + * Guardians must approve changes to the Spec Core Team. + * Guardians must keep each other honest, providing a ‘checks and balances’. mechanism between each other to ensure that all Guardians and the Spec Core Team act in the best interests of the protocol and ecosystem. * Guardians may appoint/dismiss members of the Spec Core Team who are in serious breach of the guiding principles. This overrides the unanimous consent requirement for the Spec Core Team when appointing new members. * Guardians may also override deadlocks when appointing a Spec Core Team leader - (with a >= 75% majority) + (with a >= 75% majority). * Guardians must approve changes to the Guiding Principles (above) * Guardians are responsible for approving use of the Foundation's assets - (e.g. redistributing donations) + (e.g. redistributing donations). * In future, Guardians may also be responsible for ensuring staff are hired by the Foundation to support administrative functions and other roles required to facilitate the Foundation's mission. @@ -354,46 +354,46 @@ community. Responsibilities include: * Helping ensure the quality of the projects' code repositories - * Ensuring all commits are reviewed - * Ensuring that all projects follow the Matrix spec - * Helping architect the implementations - * Contributing code to the implementations + * Ensuring all commits are reviewed. + * Ensuring that all projects follow the Matrix spec. + * Helping architect the implementations. + * Contributing code to the implementations. * Fostering contributions and engaging with contributors constructively in a - way that fosters a healthy and happy community - * Following the Guiding Principles and promoting them within the community + way that fosters a healthy and happy community. + * Following the Guiding Principles and promoting them within the community. Code Core Team members must arrange their own funding for their time. ## Functions of the Foundation - * Independent legal entity which acts as neutral custodian of Matrix - * Gathers donations + * Independent legal entity which acts as neutral custodian of Matrix. + * Gathers donations. * Owns the core Matrix IP in an asset lock, which shall be transferred from New Vector: - * Owns the matrix.org domain and branding + * Owns the matrix.org domain and branding. * Owns the copyright of the reference implementations of Matrix (i.e. everything in https://github.com/matrix-org). By assigning copyright to the Foundation, it’s protected against New Vector ever being tempted to relicense it. - * Owns the IP of the website - * Owns the Matrix.org marketing swag (t-shirts, stickers, exhibition stands etc) - * Responsible for finding someone to run the Matrix.org homeserver (currently New Vector) - * Publishes the spec - * Responsible for tools and documentation that supports the spec - * Responsible for ensuring reference implementations and test suite exists for the spec - * Publishes the website (including ensuring This Week In Matrix and similar exist to promote independent projects) + * Owns the IP of the website. + * Owns the Matrix.org marketing swag (t-shirts, stickers, exhibition stands etc). + * Responsible for finding someone to run the Matrix.org homeserver (currently New Vector). + * Publishes the spec. + * Responsible for tools and documentation that supports the spec. + * Responsible for ensuring reference implementations and test suite exists for the spec. + * Publishes the website (including ensuring This Week In Matrix and similar exist to promote independent projects). * Manages any future IANA-style allocations for Matrix, such as: - * mx:// URI scheme - * TCP port 8448 + * mx:// URI scheme. + * TCP port 8448. * .well-known URIs * Ensures that Matrix promotion is happening (e.g. ensuring that meetups & - events & community activity is supported) + events & community activity is supported). In future: * contracts entities to work on Matrix if such contracts help the Foundation to fulfil its mission and obey the Guiding Principles (e.g. redistributing donations back to fund development of reference implementations or compliance - kits) + kits). * manages a "Made for Matrix" certification process? (to confirm that products - are actually compatible with Matrix) + are actually compatible with Matrix). ## Timings From cc6b6ea021645f93b339bc17df1cfaf92f079fd2 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 15 Jan 2019 00:31:08 +0000 Subject: [PATCH 0127/1250] clarify wording for trojan horsen --- proposals/1779-open-governance.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 58e43b80..38469a06 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -173,13 +173,13 @@ toxic culture of bullying or competitive infighting. Folks need to be able to compromise; we are not building a culture of folks pushing their personal agendas at the expense of the overall project. -We are particularly vigilant against 'trojan horse' additions to the spec - -features which only benefit particular players, or are designed to somehow -cripple or fragment the open protocol and ecosystem in favour of competitive -advantage. Commercial players are of course free to build proprietary -implementations, or use custom event types, or even custom API extensions (e.g. -more efficient network transports) - but implementations must fall back to -interoperating correctly with the rest of the ecosystem. +The team should be particularly vigilant against 'trojan horse' additions to the +spec - features which only benefit particular players, or are designed to +somehow cripple or fragment the open protocol and ecosystem in favour of +competitive advantage. Commercial players are of course free to build +proprietary implementations, or use custom event types, or even custom API +extensions (e.g. more efficient network transports) - but implementations must +fall back to interoperating correctly with the rest of the ecosystem. ### Spec Core Team logistics From 8f4e1d9686993097df415ee71bf4dd16d4257b34 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 15 Jan 2019 00:32:14 +0000 Subject: [PATCH 0128/1250] clarify guardian selection wording --- proposals/1779-open-governance.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 38469a06..7fbb786f 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -50,9 +50,9 @@ responsible for ensuring that the Foundation (and by extension the Spec Core Team) keeps on mission and neutrally protects the development of Matrix. Guardians are typically independent of the commercial Matrix ecosystem and may even not be members of today’s Matrix community, but are deeply aligned with the -mission of the project, and who are respected and trusted by the wider community -to uphold the guiding principles of the Foundation and keep the other Guardians -honest. +mission of the project. Guardians are selected to be respected and trusted by +the wider community to uphold the guiding principles of the Foundation and keep +the other Guardians honest. In other words; the Spec Core Team builds the spec, and the Guardians provide an independent backstop to ensure the spec evolves in line with the Foundation's From 80b9c83ccea64d31732a35642653eeb326cf2f20 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 15 Jan 2019 10:00:17 +0000 Subject: [PATCH 0129/1250] clarify dual-hatted guardians & spec core teamistas --- proposals/1779-open-governance.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 7fbb786f..9f6a49d3 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -270,7 +270,9 @@ The above governance process for the Spec Core Team is considered as part of the spec and is updated using the Matrix Spec Change process. However, changes to the governance process also require a 75% positive approval from the Guardians (acting as a formal decision of the Foundation's Directors), in order to ensure -changes are aligned with the Foundation's mission. +changes are aligned with the Foundation's mission. For avoidance of doubt, Spec +Core Team votes and Guardians' votes are distinct and a person having both hats +has to vote independently on both forums with the respective hat on. ## The Guardians From aeb524ef89f2ef6751dd0b7067c225b0c8a6a7c2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 16 Jan 2019 16:13:53 -0700 Subject: [PATCH 0130/1250] Remove CAS login and reference it against r0.4.0 The SSO module should cover what CAS provides, and r0.4.0 is good as a reference for how CAS could be implemented without us repeating it here. --- api/client-server/cas_login_redirect.yaml | 54 ----------- api/client-server/cas_login_ticket.yaml | 66 ------------- specification/client_server_api.rst | 6 -- specification/modules/sso_login.rst | 110 ++++------------------ 4 files changed, 18 insertions(+), 218 deletions(-) delete mode 100644 api/client-server/cas_login_redirect.yaml delete mode 100644 api/client-server/cas_login_ticket.yaml diff --git a/api/client-server/cas_login_redirect.yaml b/api/client-server/cas_login_redirect.yaml deleted file mode 100644 index abe9069b..00000000 --- a/api/client-server/cas_login_redirect.yaml +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 2016 OpenMarket Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -swagger: '2.0' -info: - title: "Matrix Client-Server CAS Login API" - version: "1.0.0" -host: localhost:8008 -schemes: - - https - - http -basePath: /_matrix/client/%CLIENT_MAJOR_VERSION% -paths: - "/login/cas/redirect": - get: - summary: Redirect the user's browser to the CAS interface. - description: |- - A web-based Matrix client should instruct the user's browser to - navigate to this endpoint in order to log in via CAS. - - The server MUST respond with an HTTP redirect to the CAS interface. The - URI MUST include a ``service`` parameter giving the path of the - |/login/cas/ticket|_ endpoint (including the ``redirectUrl`` query - parameter). - - For example, if the endpoint is called with - ``redirectUrl=https://client.example.com/?q=p``, it might redirect to - ``https://cas.example.com/?service=https%3A%2F%2Fserver.example.com%2F_matrix%2Fclient%2F%CLIENT_MAJOR_VERSION%%2Flogin%2Fcas%2Fticket%3FredirectUrl%3Dhttps%253A%252F%252Fclient.example.com%252F%253Fq%253Dp``. - - operationId: redirectToCAS - parameters: - - in: query - type: string - name: redirectUrl - description: |- - URI to which the user will be redirected after the homeserver has - authenticated the user with CAS. - required: true - responses: - 302: - description: A redirect to the CAS interface. - headers: - Location: - type: "string" diff --git a/api/client-server/cas_login_ticket.yaml b/api/client-server/cas_login_ticket.yaml deleted file mode 100644 index a08565a0..00000000 --- a/api/client-server/cas_login_ticket.yaml +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2016 OpenMarket Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -swagger: '2.0' -info: - title: "Matrix Client-Server CAS Login API" - version: "1.0.0" -host: localhost:8008 -schemes: - - https - - http -basePath: /_matrix/client/%CLIENT_MAJOR_VERSION% -paths: - "/login/cas/ticket": - get: - summary: Receive and validate a CAS login ticket. - description: |- - Once the CAS server has authenticated the user, it will redirect the - browser to this endpoint (assuming |/login/cas/redirect|_ gave it the - correct ``service`` parameter). - - The server MUST call ``/proxyValidate`` on the CAS server, to validate - the ticket supplied by the browser. - - If validation is successful, the server must generate a Matrix login - token. It must then respond with an HTTP redirect to the URI given in - the ``redirectUrl`` parameter, adding a ``loginToken`` query parameter - giving the generated token. - - If validation is unsuccessful, the server should respond with a ``401 - Unauthorized`` error, the body of which will be displayed to the user. - operationId: loginByCASTicket - parameters: - - in: query - type: string - name: redirectUrl - description: |- - The ``redirectUrl`` originally provided by the client to - |/login/cas/redirect|_. - required: true - - in: query - type: string - name: ticket - description: |- - CAS authentication ticket. - required: true - responses: - 302: - description: A redirect to the Matrix client. - headers: - Location: - type: "string" - x-example: |- - https://client.example.com/?q=p&loginToken=secrettoken - 401: - description: The server was unable to validate the CAS ticket. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 03d71246..4df83814 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1024,12 +1024,6 @@ supports it, the client should redirect the user to the ``/redirect`` endpoint for `Single Sign-On <#sso-client-login>`_. After authentication is complete, the client will need to submit a ``/login`` request matching ``m.login.token``. -If the homeserver advertises ``m.login.cas`` as a viable flow, and the client -supports it, the client should redirect the user to the ``/redirect`` endpoint -for `CAS <#cas-based-client-login>`_. Just like SSO authentication, the client -is expected to submit a ``/login`` request matching ``m.login.token`` upon -successful authentication. - {{login_cs_http_api}} {{logout_cs_http_api}} diff --git a/specification/modules/sso_login.rst b/specification/modules/sso_login.rst index 977278a7..57188500 100644 --- a/specification/modules/sso_login.rst +++ b/specification/modules/sso_login.rst @@ -34,8 +34,17 @@ An overview of the process, as used in Matrix, is as follows: 4. The SSO server and the homeserver interact to verify the user's identity and other authentication information, potentially using a number of redirects. -7. The Matrix client receives the login token and passes it to the |/login|_ - API. +5. The browser is directed to the ``redirectUrl`` provided by the client with + a ``loginToken`` query parameter for the client to log in with. + +.. Note:: + In the older `r0.4.0 version `_ + of this specification it was possible to authenticate via CAS when the server + provides a ``m.login.cas`` login flow. This specification deprecates the use + of ``m.login.cas`` to instead prefer ``m.login.sso``, which is the same process + with the only change being which redirect endpoint to use: for ``m.login.cas``, use + ``/cas/redirect`` and for ``m.login.sso`` use ``/sso/redirect`` (described below). + The endpoints are otherwise the same. Client behaviour ---------------- @@ -61,7 +70,11 @@ Server behaviour The URI for the SSO system to be used should be configured on the server by the server administrator. The server is expected to set up any endpoints required to -interact with that SSO system. +interact with that SSO system. For example, for CAS authentication the homeserver +should provide a means for the administrator to configure where the CAS server is +and the REST endpoints which consume the ticket. A good reference for how CAS could +be implemented is available in the older `r0.4.0 version `_ +of this specification. Handling the redirect endpoint ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -90,98 +103,11 @@ as a new user. Finally, the server should generate a short-term login token. The generated token should be a macaroon, suitable for use with the ``m.login.token`` type of the |/login|_ API, and `token-based interactive login <#token-based>`_. The -lifetime of this token SHOULD be limited to around five seconds. - - -CAS-based client login ----------------------- - -.. _module:cas_login: - -`Central Authentication Service -`_ -(CAS) is a web-based single sign-on protocol. The protocol defined here is an -extension of the SSO protocol defined in this module: it is largely the same, -but has some specific details which make it different. - -An overview of the process, as used in Matrix, is as follows: - -1. The Matrix client instructs the user's browser to navigate to the - |/login/cas/redirect|_ endpoint on the user's homeserver. - -2. The homeserver responds with an HTTP redirect to the CAS user interface, - which the browser follows. - -3. The CAS system authenticates the user. - -4. The CAS server responds to the user's browser with a redirect back to the - |/login/cas/ticket|_ endpoint on the homeserver, which the browser - follows. A 'ticket' identifier is passed as a query parameter in the - redirect. - -5. The homeserver receives the ticket ID from the user's browser, and makes a - request to the CAS server to validate the ticket. - -6. Having validated the ticket, the homeserver responds to the browser with a - third HTTP redirect, back to the Matrix client application. A login token - is passed as a query parameter in the redirect. - -7. The Matrix client receives the login token and passes it to the |/login|_ - API. - -Client behaviour -~~~~~~~~~~~~~~~~ - -The client starts the process by instructing the browser to navigate to -|/login/cas/redirect|_ with an appropriate ``redirectUrl``. Once authentication -is successful, the browser will be redirected to that ``redirectUrl``. - -{{cas_login_redirect_cs_http_api}} -{{cas_login_ticket_cs_http_api}} - -Server behaviour -~~~~~~~~~~~~~~~~ - -The URI for the CAS system to be used should be configured on the server by the -server administrator. - -Handling the redirect endpoint -++++++++++++++++++++++++++++++ - -When responding to the ``/login/cas/redirect`` endpoint, the server must -generate a URI for the CAS login page. The server should take the base CAS URI -described above, and add a ``service`` query parameter. This parameter MUST be -the URI of the ``/login/cas/ticket`` endpoint, including the ``redirectUrl`` -query parameter. Because the homeserver may not know its base URI, this may -also require manual configuration. - -Handling the authentication endpoint -++++++++++++++++++++++++++++++++++++ - -When responding to the ``/login/cas/ticket`` endpoint, the server MUST make a -request to the CAS server to validate the provided ticket. The server MAY also -check for certain user attributes in the response. Any required attributes -should be configured by the server administrator. - -Once the ticket has been validated, the server MUST map the CAS ``user_id`` -to a valid `Matrix user identifier <../index.html#user-identifiers>`_. The -guidance in `Mapping from other character sets -<../index.html#mapping-from-other-character-sets>`_ may be useful. - -If the generated user identifier represents a new user, it should be registered -as a new user. - -Finally, the server should generate a short-term login token. The generated -token should be a macaroon, suitable for use with the ``m.login.token`` type of -the |/login|_ API, and `token-based interactive login <#token-based>`_. The -lifetime of this token SHOULD be limited to around five seconds. +lifetime of this token SHOULD be limited to around five seconds. This token is +given to the client via the ``loginToken`` query parameter previously mentioned. .. |/login| replace:: ``/login`` .. _/login: #post-matrix-client-%CLIENT_MAJOR_VERSION%-login -.. |/login/cas/redirect| replace:: ``/login/cas/redirect`` -.. _/login/cas/redirect: #get-matrix-client-%CLIENT_MAJOR_VERSION%-login-cas-redirect -.. |/login/cas/ticket| replace:: ``/login/cas/ticket`` -.. _/login/cas/ticket: #get-matrix-client-%CLIENT_MAJOR_VERSION%-login-cas-ticket .. |/login/sso/redirect| replace:: ``/login/sso/redirect`` .. _/login/sso/redirect: #get-matrix-client-%CLIENT_MAJOR_VERSION%-login-sso-redirect From 71e6321f4d448d840bfb6634d3ee381876d35a97 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 16 Jan 2019 16:57:45 -0700 Subject: [PATCH 0131/1250] Rework how room versions are represented Versions are actually on a scale of recommendations, and are expected to be created as needed. The scale presented here (develop/beta/default/recommended/mandatory) is a more wordy version of what was previously discussed/intended for room versions - the labels aren't final and may be changed. --- changelogs/rooms/newsfragments/.gitignore | 1 - changelogs/rooms/pyproject.toml | 30 -------- meta/releasing-rooms-v2.md | 38 --------- scripts/gendoc.py | 5 -- scripts/templating/matrix_templates/units.py | 5 -- specification/index.rst | 81 ++++++++++++++++++++ specification/rooms/intro.rst | 70 ----------------- specification/rooms/unstable.rst | 54 ------------- specification/rooms/v1.rst | 24 ++---- specification/rooms/v2.rst | 30 ++------ specification/targets.yaml | 21 ----- 11 files changed, 91 insertions(+), 268 deletions(-) delete mode 100644 changelogs/rooms/newsfragments/.gitignore delete mode 100644 changelogs/rooms/pyproject.toml delete mode 100644 meta/releasing-rooms-v2.md delete mode 100644 specification/rooms/intro.rst delete mode 100644 specification/rooms/unstable.rst diff --git a/changelogs/rooms/newsfragments/.gitignore b/changelogs/rooms/newsfragments/.gitignore deleted file mode 100644 index b722e9e1..00000000 --- a/changelogs/rooms/newsfragments/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore \ No newline at end of file diff --git a/changelogs/rooms/pyproject.toml b/changelogs/rooms/pyproject.toml deleted file mode 100644 index b56e19a9..00000000 --- a/changelogs/rooms/pyproject.toml +++ /dev/null @@ -1,30 +0,0 @@ -[tool.towncrier] - filename = "../rooms.rst" - directory = "newsfragments" - issue_format = "`#{issue} `_" - title_format = "{version}" - - [[tool.towncrier.type]] - directory = "breaking" - name = "Breaking Changes" - showcontent = true - - [[tool.towncrier.type]] - directory = "deprecation" - name = "Deprecations" - showcontent = true - - [[tool.towncrier.type]] - directory = "new" - name = "New Endpoints" - showcontent = true - - [[tool.towncrier.type]] - directory = "feature" - name = "Backwards Compatible Changes" - showcontent = true - - [[tool.towncrier.type]] - directory = "clarification" - name = "Spec Clarifications" - showcontent = true diff --git a/meta/releasing-rooms-v2.md b/meta/releasing-rooms-v2.md deleted file mode 100644 index 80277749..00000000 --- a/meta/releasing-rooms-v2.md +++ /dev/null @@ -1,38 +0,0 @@ -# How to release Room Version 2 - -Room versions are a bit special for the release given they have been -introduced at v2 rather than ever getting a v1 release. Additionally, -room versions have different release requirements due to the in-project -versioning of documents rather than relying on matrix.org to maintain -old generated output of specifications. - -As of writing, the project is structured to support 3 logical versions -for rooms: v1, v2, and unstable. Unstable is currently pointed at v2 -in order to aid development. After v2 is released, unstable may wish -to be left as an independent version or similarly be pointed at a "v3" -document. - -Due to room versions being versioned in-project, the generated output -from a release is not to be sent off to matrix-doc/matrix.org. Instead, -in `gendoc.py` the default value for `--room_version` should be set to -the current release (`v2`, for example) so the index renders the right -edition in the table. - -After editing `gendoc.py`, the changelog should be generated according -to the towncrier instructions. You may need to fix the `.. version: v2` -comment located in the `rooms.rst` changelog to be just underneath the -title instead of at the end of the section. - -The `targets.yaml` file needs to be set up to point unstable to the -right set of files. Ensure that `unstable.rst` is referenced instead -of `v2.rst`, and that `unstable.rst` has appropriate contents. - -Finally, in the `intro.rst` for room versions, re-add unstable to the -list of available versions. It is currently commented out to avoid -confusing people, so it should be possible to uncomment it and put it -back into the list. - -From there, the standard process of using a release branch, tagging it, -and announcing it to the world should be followed. If required, the -various other APIs should be updated to better support the new room -version. diff --git a/scripts/gendoc.py b/scripts/gendoc.py index 0455c90a..72e3047c 100755 --- a/scripts/gendoc.py +++ b/scripts/gendoc.py @@ -529,10 +529,6 @@ if __name__ == '__main__': "--identity_release", "-i", action="store", default="unstable", help="The identity service release tag to generate, e.g. r1.2" ) - parser.add_argument( - "--room_version", "-r", action="store", default="unstable", - help="The current room version to advertise, e.g. v2" - ) parser.add_argument( "--list_targets", action="store_true", help="Do not update the specification. Instead print a list of targets.", @@ -559,7 +555,6 @@ if __name__ == '__main__': "%APPSERVICE_RELEASE_LABEL%": args.appservice_release, "%IDENTITY_RELEASE_LABEL%": args.identity_release, "%PUSH_GATEWAY_RELEASE_LABEL%": args.push_gateway_release, - "%CURRENT_ROOM_VERSION%": args.room_version, } exit (main(args.target or ["all"], args.dest, args.nodelete, substitutions)) diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index 666434a5..721501ff 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -757,7 +757,6 @@ class MatrixUnits(Units): is_ver = substitutions.get("%IDENTITY_RELEASE_LABEL%", "unstable") as_ver = substitutions.get("%APPSERVICE_RELEASE_LABEL%", "unstable") push_gw_ver = substitutions.get("%PUSH_GATEWAY_RELEASE_LABEL%", "unstable") - room_ver = substitutions.get("%CURRENT_ROOM_VERSION%", "unstable") # we abuse the typetable to return this info to the templates return TypeTable(rows=[ @@ -781,10 +780,6 @@ class MatrixUnits(Units): "`Push Gateway API `_", push_gw_ver, "Push notifications for Matrix events", - ), TypeTableRow( - "`Rooms `_", - room_ver, - "Specification for behaviour of rooms, such as event formats", ), ]) diff --git a/specification/index.rst b/specification/index.rst index bb918739..2f17ec29 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -418,6 +418,87 @@ dedicated API. The API is symmetrical to managing Profile data. Would it really be overengineered to use the same API for both profile & private user data, but with different ACLs? + +Room Versions +------------- + +Rooms are central to how Matrix operates, and have strict rules for what +is allowed to be contained within them. Rooms can also have various +algorithms that handle different tasks, such as what to do when two or +more events collide in the underlying DAG. To allow rooms to be improved +upon through new algorithms or rules, "room versions" are employed to +manage a set of expectations for each room. New room versions are assigned +as needed. + +Room version grammar +~~~~~~~~~~~~~~~~~~~~ + +Room versions are used to change properties of rooms that may not be compatible +with other servers. For example, changing the rules for event authorization would +cause older servers to potentially end up in a split-brain situation due to them +not understanding the new rules. + +A room version is defined as a string of characters which MUST NOT exceed 32 +codepoints in length. Room versions MUST NOT be empty and SHOULD contain only +the characters ``a-z``, ``0-9``, ``.``, and ``-``. + +Room versions are not intended to be parsed and should be treated as opaque +identifiers. Room versions consisting only of the characters ``0-9`` and ``.`` +are reserved for future versions of the Matrix protocol. + +The complete grammar for a legal room version is:: + + room_version = 1*room_version_char + room_version_char = DIGIT + / %x61-7A ; a-z + / "-" / "." + +Examples of valid room versions are: + +* ``1`` (would be reserved by the Matrix protocol) +* ``1.2`` (would be reserved by the Matrix protocol) +* ``1.2-beta`` +* ``com.example.version`` + +Recommended room versions +~~~~~~~~~~~~~~~~~~~~~~~~~ + +There are varying degrees of what "recommended" means for a given room version. +Currently, this is split into 5 categories: + +* **Development**: This is the default state for all room versions. When in this + state, a room version is documented but not recommended for use outside of a + development environment. These versions are not production-ready. +* **Beta**: Versions in this state are not intended for wide-spread usage but + should be stable enough if a room requires the feature(s) introduced within. + Rooms will need to opt-in to these versions and should not be promoted to + upgrade. +* **Default**: Exactly 1 room version will be in this category. The version under + this category should be used when creating rooms (unless another version is + requested by the user). Servers may wish to promote rooms to opt-in to this + version. +* **Recommended**: Exactly 1 room version will be in this category as well. The + version here should be heavily promoted by servers for rooms to opt-in to using. + This version is often going to be the same as the Default version. +* **Mandatory**: Servers are required to implement versions in this category. When + a version is flagged as mandatory, additional rules may apply to rooms. For example, + servers may be required to stop supporting another room version and automatically + upgrade all affected rooms. + +With the above categories, the following applies: + +* Servers MUST have Room Version 1 as the Default room version. +* Servers MUST have Room Version 1 as the Recommended room version. +* Servers MUST implement Room Version 1 as a Mandatory room version. + +Complete list of room versions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The available room versions are: + +* `Version 1 `_ - The current version of most rooms. +* `Version 2 `_ - **Beta**. Implements State Resolution Version 2. + Specification Versions ---------------------- diff --git a/specification/rooms/intro.rst b/specification/rooms/intro.rst deleted file mode 100644 index 6231d066..00000000 --- a/specification/rooms/intro.rst +++ /dev/null @@ -1,70 +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. - -Room Specification -================== - -.. contents:: Table of Contents -.. sectnum:: - -Rooms are central to how Matrix operates, and have strict rules for what -is allowed to be contained within them. Rooms can also have various -algorithms that handle different tasks, such as what to do when two or -more events collide in the underlying DAG. To allow rooms to be improved -upon through new algorithms or rules, "room versions" are employed to -manage a set of expectations for each room. - - -Room version grammar --------------------- - -Room versions are used to change properties of rooms that may not be compatible -with other servers. For example, changing the rules for event authorization would -cause older servers to potentially end up in a split-brain situation due to them -not understanding the new rules. - -A room version is defined as a string of characters which MUST NOT exceed 32 -codepoints in length. Room versions MUST NOT be empty and SHOULD contain only -the characters ``a-z``, ``0-9``, ``.``, and ``-``. - -Room versions are not intended to be parsed and should be treated as opaque -identifiers. Room versions consisting only of the characters ``0-9`` and ``.`` -are reserved for future versions of the Matrix protocol. - -The complete grammar for a legal room version is:: - - room_version = 1*room_version_char - room_version_char = DIGIT - / %x61-7A ; a-z - / "-" / "." - -Examples of valid room versions are: - -* ``1`` (would be reserved by the Matrix protocol) -* ``1.2`` (would be reserved by the Matrix protocol) -* ``1.2-beta`` -* ``com.example.version`` - - -Other room versions -------------------- - -The available room versions are: - -* `Version 1 `_ - The current version of most rooms. -* `Version 2 `_ - Currently in development. - -.. Note: the 'unstable' version is commented out pending a real release of rooms v2 -.. See meta/releasing-rooms-v2.md -.. * `Unstable `_ - The upcoming version of the room specification. diff --git a/specification/rooms/unstable.rst b/specification/rooms/unstable.rst deleted file mode 100644 index 44261814..00000000 --- a/specification/rooms/unstable.rst +++ /dev/null @@ -1,54 +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. - - -.. DEV NOTE: This is stubbed as a template and not actually used anywhere. -.. See v2.rst for the "unstable" room version, which is currently under -.. development. -.. -.. See meta/releasing-rooms-v2.md - - -.. Note: This document appended to the end of the intro, so this next line -.. appears under "Other Room Versions". - -.. Warning:: - - This is the specification for unreleased changes to rooms. The stability - of rooms using this specification cannot be guaranteed. - - -Changelog ---------- - -.. topic:: unstable -{{rooms_changelog_unstable}} - -This version of the specification is generated from -`matrix-doc `_ as of Git commit -`{{git_version}} `_. - -For the full historical changelog, see -https://github.com/matrix-org/matrix-doc/blob/master/changelogs/rooms.rst - - -Some Module ------------ - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sit amet -eros turpis. Quisque commodo diam vel massa ultrices, vel egestas eros -dignissim. Sed sit amet lacus eget metus auctor malesuada at ut odio. -In turpis leo, viverra et mi porttitor, condimentum bibendum dolor. - -.. {-{versioned_test_definition}-} diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index 6c6795a4..c263a108 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -1,4 +1,4 @@ -.. Copyright 2018 New Vector Ltd +.. 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. @@ -12,25 +12,11 @@ .. See the License for the specific language governing permissions and .. limitations under the License. +Room Version 1 +============== -.. Note: This document appended to the end of the intro, so this next line -.. appears under "Other Room Versions". - -This is the specification for **room version 1** (``"1"``). - -Changelog ---------- - -.. topic:: Room version 1 -{{rooms_changelog_v1}} - -This version of the specification is generated from -`matrix-doc `_ as of Git commit -`{{git_version}} `_. - -For the full historical changelog, see -https://github.com/matrix-org/matrix-doc/blob/master/changelogs/rooms.rst - +This room version is the first ever version for rooms, and contains the building +blocks for other room versions. Server implementation components -------------------------------- diff --git a/specification/rooms/v2.rst b/specification/rooms/v2.rst index b04f94b4..eef03497 100644 --- a/specification/rooms/v2.rst +++ b/specification/rooms/v2.rst @@ -1,4 +1,4 @@ -.. Copyright 2018 New Vector Ltd +.. 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. @@ -12,31 +12,11 @@ .. See the License for the specific language governing permissions and .. limitations under the License. +Room Version 2 +============== -.. Note: This document appended to the end of the intro, so this next line -.. appears under "Other Room Versions". - -This is the specification for **room version 2** (``"2"``). - -.. Warning:: - - Room version 2 is under development and cannot be relied on in production - environments. - - -Changelog ---------- - -.. topic:: Room version 2 -{{rooms_changelog_v2}} - -This version of the specification is generated from -`matrix-doc `_ as of Git commit -`{{git_version}} `_. - -For the full historical changelog, see -https://github.com/matrix-org/matrix-doc/blob/master/changelogs/rooms.rst - +This room version builds off of `version 1 `_ with an improved state +resolution algorithm. Server implementation components -------------------------------- diff --git a/specification/targets.yaml b/specification/targets.yaml index b940148d..e966f66b 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -26,35 +26,14 @@ targets: files: - push_gateway.rst version_label: "%PUSH_GATEWAY_RELEASE_LABEL%" - rooms: - files: - - rooms/intro.rst - - # TODO: Switch this back to unstable.rst after releasing rooms v2 - # We temporarily do this so that "unstable" points to the in-dev - # version, however we may also want to hardlink to v2 in places and - # thus we maintain a v2 version of the same doc. - # - # See meta/releasing-rooms-v2.md - - #- rooms/unstable.rst - - rooms/v2.rst - version_label: unstable rooms@v1: # this is translated to be rooms/v1.html files: - - rooms/intro.rst - rooms/v1.rst version_label: v1 rooms@v2: # this is translated to be rooms/v2.html files: - - rooms/intro.rst - rooms/v2.rst version_label: v2 - rooms@latest: # this is translated to be rooms/latest.html - files: - - rooms/intro.rst - - rooms/v1.rst # TODO: Find a better way to link to the v2 spec - version_label: latest appendices: files: - appendices.rst From 3b47a5924b2a67f817aa14ae8ec03e797f09e819 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 16 Jan 2019 17:02:41 -0700 Subject: [PATCH 0132/1250] Remove extraneous changelog --- changelogs/rooms.rst | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 changelogs/rooms.rst diff --git a/changelogs/rooms.rst b/changelogs/rooms.rst deleted file mode 100644 index 55a16790..00000000 --- a/changelogs/rooms.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. version: v2 - -.. Note: We set the version as "version 2" so that we can maintain a specific version -.. variable in the changelog. We already know the next version is going to be v2, so -.. this makes it easier to copy/paste unstable.rst to v2.rst - -Room version 1 -============== -.. version: v1 - -This is the first iteration of rooms in Matrix. From 166d4ada8613a9e786c6d1b0b124b5bd6a02732f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 16 Jan 2019 17:05:57 -0700 Subject: [PATCH 0133/1250] Fix room versions reference in appendices & s2s spec --- specification/appendices/identifier_grammar.rst | 6 +++--- specification/server_server_api.rst | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/specification/appendices/identifier_grammar.rst b/specification/appendices/identifier_grammar.rst index 496aba31..b4678988 100644 --- a/specification/appendices/identifier_grammar.rst +++ b/specification/appendices/identifier_grammar.rst @@ -16,10 +16,10 @@ Identifier Grammar ------------------ -Some identifiers are specific to given room versions, please see the -`room specification`_ for more information. +Some identifiers are specific to given room versions, please refer to the +`room versions specification`_ for more information. -.. _`room specification`: ../rooms/latest.html +.. _`room versions specification`: ../index.html#room-versions Server Name diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 05e6617b..8645888b 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -1318,4 +1318,4 @@ Example code .. _`Checking for a signature`: ../appendices.html#checking-for-a-signature .. _`Device Management module`: ../client_server/%CLIENT_RELEASE_LABEL%.html#device-management .. _`End-to-End Encryption module`: ../client_server/%CLIENT_RELEASE_LABEL%.html#end-to-end-encryption -.. _`room version specification`: ../rooms/latest.html +.. _`room version specification`: ../index.html#room-versions From 7fee7373ea619b05c9dc325a07bc8a9d7adcb912 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 16 Jan 2019 17:32:07 -0700 Subject: [PATCH 0134/1250] Proposal for advertising capable room versions to clients --- .../1804-advertising-capable-room-versions.md | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 proposals/1804-advertising-capable-room-versions.md diff --git a/proposals/1804-advertising-capable-room-versions.md b/proposals/1804-advertising-capable-room-versions.md new file mode 100644 index 00000000..fca22409 --- /dev/null +++ b/proposals/1804-advertising-capable-room-versions.md @@ -0,0 +1,49 @@ +# 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 prompt 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": { + "m.development": ["state-res-v2-test", "event-ids-as-hashes-test", "3"], + "m.beta": ["2"], + "m.default": "1", + "m.recommended": "1", + "m.mandatory": ["1"] + } + } +} +``` + +The labels picked (`m.development`, etc) are based upon the categories for different room versions. +Note that `m.default` and `m.recommended` reinforce that there is exactly 1 version in each category. + +Clients are encouraged to make use of this capability to determine if the server supports a given +version, and at what state. Clients should cross-reference the versions with the room version spec +where possible. For example, if a slightly older server hasn't yet put version `2` into `m.default`, +but the spec says `2` is the new default and the client knows this, the client should treat `2` as +the new default. + +Similarly, clients should prompt room administrators (or those with enough permission) to upgrade +their rooms where possible. + + +## 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. From 5da17d0114979e08fbbf5ab6855e1fb811266f5f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 17 Jan 2019 09:41:11 -0700 Subject: [PATCH 0135/1250] Remove recommendation for clients to respect the spec over the server --- proposals/1804-advertising-capable-room-versions.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/1804-advertising-capable-room-versions.md b/proposals/1804-advertising-capable-room-versions.md index fca22409..924cd77f 100644 --- a/proposals/1804-advertising-capable-room-versions.md +++ b/proposals/1804-advertising-capable-room-versions.md @@ -30,10 +30,10 @@ The labels picked (`m.development`, etc) are based upon the categories for diffe Note that `m.default` and `m.recommended` reinforce that there is exactly 1 version in each category. Clients are encouraged to make use of this capability to determine if the server supports a given -version, and at what state. Clients should cross-reference the versions with the room version spec -where possible. For example, if a slightly older server hasn't yet put version `2` into `m.default`, -but the spec says `2` is the new default and the client knows this, the client should treat `2` as -the new default. +version, and at what state. + +Clients should prompt people with sufficient permissions to perform an upgrade to upgrade their rooms +to the `m.recommended` room version. Similarly, clients should prompt room administrators (or those with enough permission) to upgrade their rooms where possible. From 853d7ede30e00a52b2ed516a956769b84f197f15 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 17 Jan 2019 09:41:24 -0700 Subject: [PATCH 0136/1250] Clarify the categories and the interaction between them --- .../1804-advertising-capable-room-versions.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/proposals/1804-advertising-capable-room-versions.md b/proposals/1804-advertising-capable-room-versions.md index 924cd77f..7686f1b2 100644 --- a/proposals/1804-advertising-capable-room-versions.md +++ b/proposals/1804-advertising-capable-room-versions.md @@ -35,8 +35,18 @@ version, and at what state. Clients should prompt people with sufficient permissions to perform an upgrade to upgrade their rooms to the `m.recommended` room version. -Similarly, clients should prompt room administrators (or those with enough permission) to upgrade -their rooms where possible. +Room versions might appear under multiple categories under some circumstances. In particular, it is +expected that anything in `m.development` or `m.beta` appears exactly once in the whole capability +whereas `m.default`, `m.recommended`, and `m.mandatory` may duplicate a room version. The duplication +is possible due to the definitions of each category: + +* `m.default` - This is the room version that the server is going to apply to all new rooms by default. +* `m.recommended` - The version clients should be prompting people to upgrade to. +* `m.mandatory` - The version the server is going to enforce on all pre-existing rooms. + +With these definitions, it is possible that a room version fits multiple criteria (ie: "please upgrade +your rooms to version X which is also the default for new rooms"). Clients will generally only be +interested in the `m.recommended` room version, leaving the rest as informational for users. ## Potential issues From 82ee3a6035bb56240898f23a40fc83c2fd92c7e3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 17 Jan 2019 11:18:48 -0700 Subject: [PATCH 0137/1250] Adjust wording for SSO introduction --- specification/modules/sso_login.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/specification/modules/sso_login.rst b/specification/modules/sso_login.rst index 57188500..6dd4a332 100644 --- a/specification/modules/sso_login.rst +++ b/specification/modules/sso_login.rst @@ -17,9 +17,9 @@ SSO client login .. _module:sso_login: -Single Sign-On (SSO) is a generic web-based protocol for logging in users. -As a special case, the Matrix specification supports `CAS-based login <#cas-based-client-login>`_ -as well as a subset of SSO login. +Single Sign-On (SSO) is a generic term which refers to protocols which allow +users to log into applications via a single web-based authentication portal. +Examples include "Central Authentication Service" (CAS) and SAML. An overview of the process, as used in Matrix, is as follows: From 5f12419afb108fab117840dfbed517165ef69049 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 17 Jan 2019 11:41:50 -0700 Subject: [PATCH 0138/1250] Clarify that changelog entries end with a full stop --- CONTRIBUTING.rst | 6 +++--- changelogs/client_server/newsfragments/1744.clarification | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index c592cf02..0666c579 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -76,11 +76,11 @@ Adding to the changelog Currently only changes to the client-server API need to end up in a changelog. The other APIs are not yet stable and therefore do not have a changelog. Adding to the changelog can only be done after you've opened your pull request, so be sure to do -that first. +that first. The changelog is managed by Towncrier (https://github.com/hawkowl/towncrier) in the form of "news fragments". The news fragments for the client-server API are stored -under ``changelogs/client_server/newsfragments``. +under ``changelogs/client_server/newsfragments``. To create a changelog entry, create a file named in the format ``prNumber.type`` in the ``newsfragments`` directory. The ``type`` can be one of the following: @@ -99,7 +99,7 @@ the ``newsfragments`` directory. The ``type`` can be one of the following: * ``deprecation`` - Used when deprecating something All news fragments must have a brief summary explaining the change in the contents -of the file. +of the file. The summary must end in a full stop to be in line with the style guide. Changes that do not change the spec, such as changes to the build script, formatting, CSS, etc should not get a news fragment. diff --git a/changelogs/client_server/newsfragments/1744.clarification b/changelogs/client_server/newsfragments/1744.clarification index 6ed00067..dc103920 100644 --- a/changelogs/client_server/newsfragments/1744.clarification +++ b/changelogs/client_server/newsfragments/1744.clarification @@ -1 +1 @@ -Add missing status_msg to m.presence schema +Add missing status_msg to m.presence schema. From 4e0533a5f34022d780bc43271d694d90f495e5a9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 17 Jan 2019 13:56:48 -0700 Subject: [PATCH 0139/1250] Soften UX requirements --- specification/modules/room_upgrades.rst | 33 ++++++------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/specification/modules/room_upgrades.rst b/specification/modules/room_upgrades.rst index 81da8aaf..2015a4b1 100644 --- a/specification/modules/room_upgrades.rst +++ b/specification/modules/room_upgrades.rst @@ -29,32 +29,13 @@ Events Client behaviour ---------------- -Clients which understand ``m.room.tombstone`` events MUST: - -* Hide the old room from the user's list of rooms. Permalinks, backlinks, etc should - still be accessible to this room, however. -* At the very bottom of the old room's timeline/message view, display a message which - indicates the room has been upgraded with a permalink to the new room. When the user - accesses the permalink, they are to be joined to the new room. - - * Note that if the homeserver doesn't support the room version that the user may - receive an error upon trying to join. - * If the replacement room has a tombstone event, the client may automatically follow - the chain until it finds a room which does not have a tombstone in it. - -* Optionally, the client may wish to improve the presentation of unread messages when - the user is in both the old and new rooms. For example, if the user was not active - during the upgrade and had unread messages in the old room, the new room may have an - indicator which shows the sum of unread notifications between the rooms. - -Clients which understand ``m.room.tombstone`` events must also understand the ``predecessor`` -field on ``m.room.create`` events such that: - -* At the top of the scrollback/message view for the new room a message is displayed - indicating that the room is a continuation of a previous room, with a permalink to - the old room. -* Optionally supporting search and other functions of the room to span across the old - and new rooms. +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 to hide 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}} From 2457438f1eacb0cf26636a02df9a7e2c913586d2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 17 Jan 2019 13:57:02 -0700 Subject: [PATCH 0140/1250] Encourage servers to transfer whatever they can while being open-ended --- specification/modules/room_upgrades.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/specification/modules/room_upgrades.rst b/specification/modules/room_upgrades.rst index 2015a4b1..21a1ed2d 100644 --- a/specification/modules/room_upgrades.rst +++ b/specification/modules/room_upgrades.rst @@ -48,10 +48,14 @@ When the client requests to upgrade a known room to a known version, the server: 2. Creates a replacement room with a ``m.room.create`` event containing a ``predecessor`` field and the applicable ``room_version``. 3. Replicates the power levels, privacy, topic, and other transferable state events to - the new room. This generally excludes membership events. + the new room. This generally excludes membership events but may include client-specified + events and other presentation details. 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 may wish to automatically transfer/replicate +some of the user's personalized settings such as notifications, tags, etc. From f5fa7e59241cc7d1907a11e0d194aa597f0c3439 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 17 Jan 2019 14:05:30 -0700 Subject: [PATCH 0141/1250] Change wording to encourage servers to make reasonable decisions --- api/client-server/versions.yaml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/api/client-server/versions.yaml b/api/client-server/versions.yaml index 4d0fd49e..109e852c 100644 --- a/api/client-server/versions.yaml +++ b/api/client-server/versions.yaml @@ -39,9 +39,12 @@ paths: may optionally include version information within their name if desired. Features listed here are not for optionally toggling parts of the Matrix specification and should only be used to advertise support for a feature - which has not yet landed in the spec. For example, an accepted proposal - for a feature needing implementation would advertise itself here with - the intention of being removed from this list once the spec changes land. + which has not yet landed in the spec. For example, a feature currently + undergoing the proposal process may appear here and eventually be taken + off this list once the feature lands in the spec and the server deems it + reasonable to do so. Servers may wish to keep advertising features here + after they've been released into the spec to give clients a chance to + upgrade appropriately. operationId: getVersions responses: 200: From a6f5d015867eff953e8f6690c78d7ce1c9a0a729 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 17 Jan 2019 14:39:06 -0700 Subject: [PATCH 0142/1250] Clarify that servers don't have to implement development/beta versions --- specification/index.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/specification/index.rst b/specification/index.rst index 2f17ec29..ff51f7c0 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -468,11 +468,12 @@ Currently, this is split into 5 categories: * **Development**: This is the default state for all room versions. When in this state, a room version is documented but not recommended for use outside of a - development environment. These versions are not production-ready. + development environment. These versions are not production-ready and servers + are not required to implement these versions. * **Beta**: Versions in this state are not intended for wide-spread usage but should be stable enough if a room requires the feature(s) introduced within. Rooms will need to opt-in to these versions and should not be promoted to - upgrade. + upgrade. Servers additionally do not have to implement these versions. * **Default**: Exactly 1 room version will be in this category. The version under this category should be used when creating rooms (unless another version is requested by the user). Servers may wish to promote rooms to opt-in to this From 96d754f42904b62da0eb6bba17263e563b346e51 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 17 Jan 2019 14:43:11 -0700 Subject: [PATCH 0143/1250] promote -> prompt --- specification/index.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/specification/index.rst b/specification/index.rst index ff51f7c0..f4abf292 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -472,14 +472,14 @@ Currently, this is split into 5 categories: are not required to implement these versions. * **Beta**: Versions in this state are not intended for wide-spread usage but should be stable enough if a room requires the feature(s) introduced within. - Rooms will need to opt-in to these versions and should not be promoted to + Rooms will need to opt-in to these versions and should not be prompted to upgrade. Servers additionally do not have to implement these versions. * **Default**: Exactly 1 room version will be in this category. The version under this category should be used when creating rooms (unless another version is - requested by the user). Servers may wish to promote rooms to opt-in to this + requested by the user). Servers may wish to prompt rooms to opt-in to this version. -* **Recommended**: Exactly 1 room version will be in this category as well. The - version here should be heavily promoted by servers for rooms to opt-in to using. +* **Recommended**: Exactly 1 room version will be in this category as well. Servers + should prompt as strongly as possible for rooms to opt-in to upgrade to this version. This version is often going to be the same as the Default version. * **Mandatory**: Servers are required to implement versions in this category. When a version is flagged as mandatory, additional rules may apply to rooms. For example, From 0dde2489b666be2c6448a785e27acb15e13f8581 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 17 Jan 2019 14:48:42 -0700 Subject: [PATCH 0144/1250] Clarify what a Mandatory room version is --- specification/index.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/specification/index.rst b/specification/index.rst index f4abf292..cdd56cb2 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -481,10 +481,13 @@ Currently, this is split into 5 categories: * **Recommended**: Exactly 1 room version will be in this category as well. Servers should prompt as strongly as possible for rooms to opt-in to upgrade to this version. This version is often going to be the same as the Default version. -* **Mandatory**: Servers are required to implement versions in this category. When - a version is flagged as mandatory, additional rules may apply to rooms. For example, - servers may be required to stop supporting another room version and automatically - upgrade all affected rooms. +* **Mandatory**: Servers are required to implement versions in this category, + regardless as to how they are otherwise categorized. This allows for a Beta room + version to be mandatorily implemented by all servers in extremely rare circumstances, + as an example. Being a Mandatory room version does not imply that it is Recommended + or a Default version, just that the server needs to support it. Additional rules + may apply to room versions which are Mandatory, such as forcing servers to upgrade + all known rooms to a particular version where possible. With the above categories, the following applies: From 19e94815f9bc65bacca00e9c3c078d983a941b91 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 17 Jan 2019 15:13:01 -0700 Subject: [PATCH 0145/1250] Try and improve the understanding of room versions --- specification/index.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/specification/index.rst b/specification/index.rst index cdd56cb2..ea4026f0 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -430,6 +430,13 @@ upon through new algorithms or rules, "room versions" are employed to manage a set of expectations for each room. New room versions are assigned as needed. +There is no implicit ordering or hierarchy to room versions, and their principles +are immutable once placed in the specification. Although there is a recommended +set of versions, some rooms may benefit from features introduced by other versions. +Rooms move between different versions by "upgrading" to the desired version. Due +to versions not being ordered or hierarchical, this means a room can "upgrade" to +version 1 from version 2, if it so desired. + Room version grammar ~~~~~~~~~~~~~~~~~~~~ From ba37f2d311aaba01dfa395195f14394e1c91f633 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 17 Jan 2019 16:19:25 -0700 Subject: [PATCH 0146/1250] prompt->advertise --- specification/index.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/specification/index.rst b/specification/index.rst index ea4026f0..67a0fa96 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -479,15 +479,15 @@ Currently, this is split into 5 categories: are not required to implement these versions. * **Beta**: Versions in this state are not intended for wide-spread usage but should be stable enough if a room requires the feature(s) introduced within. - Rooms will need to opt-in to these versions and should not be prompted to - upgrade. Servers additionally do not have to implement these versions. + Rooms may opt-in to these versions on their own, but should not be asked to + upgrade automatically. Servers do not have to implement these versions. * **Default**: Exactly 1 room version will be in this category. The version under this category should be used when creating rooms (unless another version is - requested by the user). Servers may wish to prompt rooms to opt-in to this + requested by the user). Servers may wish to advertise that rooms opt-in to this version. * **Recommended**: Exactly 1 room version will be in this category as well. Servers - should prompt as strongly as possible for rooms to opt-in to upgrade to this version. - This version is often going to be the same as the Default version. + should advertise as strongly as possible for rooms to opt-in to upgrade to this + version. This version is often going to be the same as the Default version. * **Mandatory**: Servers are required to implement versions in this category, regardless as to how they are otherwise categorized. This allows for a Beta room version to be mandatorily implemented by all servers in extremely rare circumstances, From 3b86fa0e3c5ef217e112cd1bcf3dc4c082638520 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 17 Jan 2019 23:56:49 +0000 Subject: [PATCH 0147/1250] incorporating delph & vdh reviews --- proposals/1779-open-governance.md | 100 ++++++++++++++++++------------ specification/proposals_intro.rst | 22 +++---- 2 files changed, 72 insertions(+), 50 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 9f6a49d3..dde9aeac 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -69,9 +69,9 @@ We believe: * People should have full control over their own communication. - * People should not be locked into centralised communication silos, but free to - pick who they choose to host their communication without limiting who they - can reach. + * People should not be locked into centralised communication silos, but instead + be free to pick who they choose to host their communication without limiting + who they can reach. * The ability to converse securely and privately is a basic human right. @@ -80,9 +80,9 @@ We believe: ### Mission -The Matrix.org Foundation exists to act as a neutral custodian for Matrix and +The Matrix.org Foundation exists to act as a neutral custodian for Matrix and to nurture it as efficiently as possible as a single unfragmented standard, for the -greater benefit of the whole ecosystem; not benefiting or privileging any single +greater benefit of the whole ecosystem, not benefiting or privileging any single player or subset of players. For clarity: the Matrix ecosystem is defined as anyone who uses the Matrix @@ -185,8 +185,8 @@ fall back to interoperating correctly with the rest of the ecosystem. The Spec Core Team itself will be made up of roughly 8 members + 1 project lead. Roughly half the members are expected to be from the historical core team -(similar to Rust). The team must have 5 members to be quorate, with the aim of -generally having between 7 and 9 members. +(similar to Rust). The team must have 5 members to be able to function, with +the aim of generally having between 7 and 9 members. In future we may also have sub-teams (like Rust - e.g. CS/AS/Push API; SS API; IS API; Crypto), but as a starting point we are beginning with a single core @@ -221,13 +221,14 @@ of the team and the Guardians on doing so. New additions to the team require 100% consent from the current team members. Membership has to be formally proposed by someone already on the Spec Core Team. -Members can be removed from the team if >= 75% of the team agrees they are no -longer following the goals and guiding principles of the project. (The 75% is -measured of the whole team, including the member in question) +Members can be removed from the team if 75% of the current members approves and +agrees they are no longer following the goals and guiding principles of the +project. (The 75% is measured of the whole team, including the member in +question). -Guardians act as a backstop, and can appoint or remove Spec Core Team members -(requiring a 75% consensus threshold between the Guardians) if the Spec Core -Team is unable to function or is failing to align with the Foundation's mission. +Guardians act as a safety net, and can appoint or remove Spec Core Team members +(requiring approval by 75% of the current Guardians) if the Spec Core Team is +unable to function or is failing to align with the Foundation's mission. It's suggested that one of the Spec Core Team members should also be a Guardian, to facilitate information exchange between the Guardians and the Spec Core Team, @@ -236,12 +237,14 @@ and to represent the technical angle of the project to the other Guardians. The project lead role acts to coordinate the team and to help steer the team to consensus in the event of failing to get agreement on a Matrix Spec Change. Every 12 months, a vote of confidence is held in the project lead, requiring the -confidence of 75% of the team for the lead to be renewed. There is no maximum -term for the project lead. The lead may be removed by the core team at any -point (with 75% majority), and may resign the role at any point (notifying the -team and the Guardians). The lead automatically resigns the role if they resign -from the Spec Core Team. Resignation automatically triggers selection of a new -lead, who must be selected from the existing Spec Core Team. +approval of 75% of the current Spec Core Team members for the lead to be +renewed. There is no maximum term for the project lead. The lead may be +removed by the core team at any point (requiring 75% approval of current +members), and may resign the role at any point (notifying the team and the +Guardians). The lead automatically resigns the role if they resign from the +Spec Core Team. Resignation automatically triggers selection of a new lead, who +must be selected from the existing Spec Core Team with 75% approval from current +members within 14 days. It is vital that the core spec team has strong domain expertise covering all different domains of the spec (e.g. we don't want to end up with a core spec @@ -259,21 +262,24 @@ The initial Spec Core Team (and their domain areas) is: * Alexey Rusakov (Clients on behalf of Community) * TBD -MSCs require >= 75% approval from the Spec Core Team to proceed to Final Comment -Period (see https://matrix.org/docs/spec/proposals for the rest of the MSC -process). +MSCs require approval by 75% of the current members of the Spec Core Team to +proceed to Final Comment Period (see https://matrix.org/docs/spec/proposals for +the rest of the MSC process). Even though a threshold of only 75% is required for approval, the Spec Core Team is expected to seek consensus on MSCs. The above governance process for the Spec Core Team is considered as part of the spec and is updated using the Matrix Spec Change process. However, changes to -the governance process also require a 75% positive approval from the Guardians +the governance process also require approval by 75% of the current Guardians (acting as a formal decision of the Foundation's Directors), in order to ensure changes are aligned with the Foundation's mission. For avoidance of doubt, Spec Core Team votes and Guardians' votes are distinct and a person having both hats has to vote independently on both forums with the respective hat on. +Spec Core Team decisions (e.g. appointing/removing members and lead) +should be published openly and transparently for the public. + ## The Guardians *This section will be used as the basis for the legal responsibilities of @@ -285,16 +291,23 @@ is following its guiding principles, and provide a safety mechanism if the structure of the Spec Core Team runs into trouble. In practice, this means that: - * Guardians must approve changes to the Spec Core Team. + + * Guardians are responsible for ensuring the Spec Core Team continues to + function, and have the power to appoint/dismiss members of the spec core team + (with the agreement of 75% of the Guardians) to address issues with the Spec + Core Team. * Guardians must keep each other honest, providing a ‘checks and balances’. mechanism between each other to ensure that all Guardians and the Spec Core Team act in the best interests of the protocol and ecosystem. - * Guardians may appoint/dismiss members of the Spec Core Team who are in serious - breach of the guiding principles. This overrides the unanimous consent - requirement for the Spec Core Team when appointing new members. + * Guardians may dismiss members of the Spec Core Team who are in serious + breach of the guiding principles. + * Guardians may appoint members of the Spec Core Team to break deadlocks in the + unanimous consent requirement for the Spec Core Team when appointing new + members. * Guardians may also override deadlocks when appointing a Spec Core Team leader - (with a >= 75% majority). - * Guardians must approve changes to the Guiding Principles (above) + (with approval of 75% of the current Guardians). + * Guardians must approve changes to the above Guiding Principles (with approval + of 75% of the current Guardians) * Guardians are responsible for approving use of the Foundation's assets (e.g. redistributing donations). * In future, Guardians may also be responsible for ensuring staff are hired by @@ -303,8 +316,14 @@ In practice, this means that: * As well as the Spec Core Team committee, they may also oversee committees for other areas such as marketing Matrix.org, registering custom event types, or "Made for Matrix" certification. - * It's likely a subset of Guardians will be hands-on for day-to-day - administrative purposes, whilst the others act to keep them in balance. + * Guardians are responsible for choosing if, when and how staff are located by + the Foundation to fill administrative and other functions required to + facilitate the Foundations' mission. + * Guardians are responsible for choosing if and when additional committees are + formed, and to oversee those committees. + * Guardians are not required to be involved on a day-to-day basis, however + those not taking a hands on approach are required to monitor to ensure a + suitable balance is kept by those that do. Guardians are chosen typically to be independent of the commercial Matrix ecosystem (and especially independent from New Vector), and may even not be @@ -313,18 +332,18 @@ the mission of the project, and respected and trusted by the wider community to uphold the guiding principles of the Foundation and keep the other Guardians honest. -Guardians are responsible for maintaining and updating the Guiding -Principles and Articles of Association of the Foundation if/when -necessary. Changes to the Guiding Principles require a 75% majority from the -Guardians and are passed as a 'special resolution' of the board. +Guardians are responsible for maintaining and updating the Guiding Principles +and Articles of Association of the Foundation if/when necessary. Changes to the +Guiding Principles require approval from 75% of the current Guardians and are +passed as a 'special resolution' of the board. -New Guardians may be appointed with a 75% majority by the board. +New Guardians may be appointed with approval from 75% of the current Guardians. Guardians may resign at any time, with notification to the board. -Guardians may be removed due to serious breach of the guiding principles with a -75% majority of the other Guardians, or if absent from 3 consecutive board -meetings, or if they are legally disqualified from acting as a Director. +Guardians may be removed due to serious breach of the guiding principles with +approval by 75% of the other current Guardians, or if absent from 3 consecutive +board meetings, or if they are legally disqualified from acting as a Director. We aim to recruit roughly 5 Guardians. The initial Guardians are: @@ -340,6 +359,9 @@ Foundation relative to Matthew & Amandine’s day jobs at New Vector. Guardians must arrange their own funding for their time. +Guardian decisions (e.g. appointing/removing guardians; changes to the spec core +team; etc) should be published openly and transparently for the public. + ## The Code Core Team (aka The Core Team) The "Core Team" (or the "Code Core Team", to disambiguate from the Spec Core diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 1e93a22a..87828916 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -19,10 +19,10 @@ proposal being accepted, then actually having your ideas implemented as committed changes to the `Specification repository `_. -Meet the `members of the Core Team +Meet the `members of the Spec Core Team `_, a group of individuals tasked with ensuring the spec process is as smooth and painless as -possible. Members of the Core Team will do their best to participate in +possible. Members of the Spec Core Team will do their best to participate in discussion, summarise when things become long-winded, and generally try to act towards the benefit of everyone. As a majority, team members have the ability to change the state of a proposal, and individually have the final say in @@ -74,7 +74,7 @@ their proposed changes to the Matrix protocol: * Pragmatism rather than perfection * Proof rather than conjecture -Please see [MSC1779](https://github.com/matrix-org/matrix-doc/pull/1779) +Please see [MSC1779](https://github.com/matrix-org/matrix-doc/blob/matthew/msc1779/proposals/1779-open-governance.md) for full details of the project's Guiding Principles. Technical notes @@ -213,25 +213,25 @@ follows: viewpoints and get consensus, but this can sometimes be time-consuming (or the author may be biased), in which case an impartial 'shepherd' can be assigned to help guide the proposal through this process instead. A shepherd is - typically a neutral party from the Core Team or an experienced member of + typically a neutral party from the Spec Core Team or an experienced member of the community. There is no formal process for assignment. Simply ask for a shepherd to help get your proposal through and one will be assigned based on availability. Having a shepherd is not a requirement for proposal acceptance. -- Members of the Core Team and community will review and discuss the PR in the +- Members of the Spec Core Team and community will review and discuss the PR in the comments and in relevant rooms on Matrix. Discussion outside of GitHub should be summarised in a comment on the PR. -- When a member of the Core Team believes that no new discussion points are +- When a member of the Spec Core Team believes that no new discussion points are being made, they will propose a motion for a final comment period (FCP), along with a *disposition* of either merge, close or postpone. This FCP is provided to allow a short period of time for any invested party to provide a final objection before a major decision is made. If sufficient reasoning is given, an FCP can be cancelled. It is often preceded by a comment summarising the current state of the discussion, along with reasoning for its occurrence. -- A concern can be raised by a Core Team member at any time, which will block - an FCP from beginning. An FCP will only begin when a **majority** of core - team members agree on its outcome, and all existing concerns have been +- A concern can be raised by a Spec Core Team member at any time, which will block + an FCP from beginning. An FCP will only begin when 75% of the members of the + Spec Core Team team agree on its outcome, and all existing concerns have been resolved. - The FCP will then begin and last for 5 days, giving anyone else some time to speak up before it concludes. On its conclusion, the disposition of the FCP @@ -321,7 +321,7 @@ Lifetime States Name GitHub Label Description =============================== ============================= ==================================== Proposal Drafting and Feedback N/A A proposal document which is still work-in-progress but is being shared to incorporate feedback -Proposal In Review proposal-in-review A proposal document which is now ready and waiting for review by the Core Team and community +Proposal In Review proposal-in-review A proposal document which is now ready and waiting for review by the Spec Core Team and community Proposed Final Comment Period proposed-final-comment-period Currently awaiting signoff of a majority of team members in order to enter the final comment period Final Comment Period final-comment-period A proposal document which has reached final comment period either for merge, closure or postponement Final Commment Period Complete finished-final-comment-period The final comment period has been completed. Waiting for a demonstration implementation @@ -342,7 +342,7 @@ pull request trackers of the `matrix-doc `_ repo. We use labels and some metadata in MSC PR descriptions to generate this page. -Labels are assigned by the Core Team whilst triaging the proposals based on those +Labels are assigned by the Spec Core Team whilst triaging the proposals based on those which exist in the `matrix-doc `_ repo already. From f4fe318a85f4cefe00ca15e49914ea2b7b061bea Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 17 Jan 2019 23:52:36 -0500 Subject: [PATCH 0148/1250] update with user-signing and self-signing keys --- proposals/1756-cross-signing.md | 357 +++++++++++++-------------- proposals/images/1756-graph2.dot | 23 +- proposals/images/1756-graph2.dot.png | Bin 29214 -> 49417 bytes 3 files changed, 187 insertions(+), 193 deletions(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 11bfe2c1..09747011 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -1,4 +1,4 @@ -# Cross-signing devices with master keys +# Cross-signing devices with device signing keys ## Background @@ -8,215 +8,188 @@ this user must then verify each key on each of their devices. If Alice has *n* devices, and Bob has *m* devices, then for Alice to be able to communicate with Bob on any of their devices, this involves *n×m* key verifications. -One way to addresss this is for each user to use a "master key" for their -identity which signs all of their devices. Thus another user who wishes to -verify their identity only needs to verify their master, key and can use the -master key to verify their devices. +One way to address this is for each user to use a device signing key to signs +all of their devices. Thus another user who wishes to verify their identity +only needs to verify the device signing key and can use the signatures created +by the device signing key to verify their devices. [MSC1680](https://github.com/matrix-org/matrix-doc/issues/1680) presents a -different solution to the problem. +different solution to the problem. A comparison between this proposal and +MSC1680 is presented below. ## Proposal -Each user has a "master identity key" that is used to sign their devices, and -is signed by all of their devices. When one user (Alice) verifies another -user's (Bob's) identity, Alice will sign Bob's master identity key with her -master identity key. (This will mean that verification methods will need to be -modified to pass along the master identity key.) Alice's device will trust -Bob's device if: - -- Alice's device is using a master identity key that has signed Bob's master - identity key, -- Bob's master identity key has signed Bob's device, and -- none of those signatures have been revoked. - -If Alice believes that her master identity key has been compromised, she can -revoke it and create a new one. This means that all trust involving Alice -(i.e. Alice trusting other people and other people trusting Alice) needs to -start from scratch. - -The master identity key's private key can be stored encrypted on the server -(possibly along with the megolm key backup). Clients may or may not want to -store a copy of the private key locally. Doing so would mean that an attacker -who steals a device has access to the private key, and so can forge trusted -devices until the user notices and resets their master key. However, not doing -so means that when the user verifies another user, they will need to re-fetch -the private key, which means that they will need to re-enter their recovery -key to decrypt it. - -When a user logs in with a new device, they will fetch and decrypt the private -master key, sign the new device's key with the master key, and sign the master -key with the device's key. - -Users will only be allowed to see signatures made by their own master identity -key, or signatures made by other users' master identity keys on their own -devices. +Each user has a self-signing key pair that is used to sign their own devices, +and a user-signing key pair that is used to sign other users' signing keys. A +user's user-signing key is also signed by their own self-signing key. When one +user (e.g. Alice) verifies another user's (Bob's) identity, Alice will sign +Bob's self-signing key with her user-signing key. (This will mean that +verification methods will need to be modified to pass along the self-signing +identity key.) Alice's device will trust Bob's device if: + +- Alice's device is using a self-signing key that has signed her user-signing key, +- Alice's user-signing key has signed Bob's self-signing key, and +- Bob's self-signing key has signed Bob's device key. + +### Key security + +A user's private half of their user-signing key pair may be kept unlocked on a +device, but their self-signing key should not; the private half of the +self-signing key pair should only be stored encrypted, requiring a passphrase +to access. By keeping the user-signing key unlocked, Alice can verify Bob's +identity and distribute signatures to all her devices without needing to enter +a passphrase to decrypt the key. + +If a user's device is compromised, they can issue a new user-signing key, +signed by their self-signing key, rendering the old user-signing key useless. +If they are certain that the old user-signing key has not yet been used by an +attacker, then they may also reissue signatures made by the old user-signing +key by using the new user-signing key. Otherwise, they will need to re-verify +the other users. + +If a user's self-signing key is compromised, then the user will need to issue +both a new self-signing key and a new device-signing key. The user may sign +their new self-signing key with their old self-signing key, allowing other +users who have verified the old self-signing key to automatically trust the new +self-signing key if they wish to. Otherwise, the users will need to re-verify +each other. + +The private halves of the user-signing key pair and self-signing key pair may +be stored encrypted on the server (possibly along with the megolm key backup) +so that they may be retrieved by new devices. FIXME: explain how to do this + +### Signature distribution + +Currently, users will only be allowed to see signatures made by their own +self-signing or user-signing keys, or signatures made by other users' +self-signing keys about their own devices. This is done in order to preserve +the privacy of social connections. Future proposals may define mechanisms for +distributing signatures to other users in order to allow for other web-of-trust +use cases. ### API description -#### Possible API 1 +Public keys for the self-signing and user-signing keys are uploaded to the +servers using `/keys/device_signing/upload`. This endpoint requires [UI +Auth](https://matrix.org/docs/spec/client_server/r0.4.0.html#user-interactive-authentication-api). -Use the same API as MSC1680, but with additions. - -API to create new virtual device: - -`POST /devices/create` - -returns - -``` json -{ - "device_id": "ABCDEFG" -} -``` - -The server should not allow any client to use this device ID when logging in or -registering; if a client tries to log in using this device ID, then the server -must respond with an error. (FIXME: what error?) - -Send public key using `/keys/upload` as a normal device, but with a special -"algorithms" list: - -`POST /keys/upload` +`POST /keys/device_signing/upload` ``` json { - "device_keys": { + "self_signing_key": { + "user_id": "@alice:example.com", + "usage": ["self_signing"], + "keys": { + "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key", + } + }, + "user_signing_key": { "user_id": "@alice:example.com", - "device_id": "ABCDEFG", - "algorithms": ["m.master"], "keys": { - "ed25519:ABCDEFG": "base64+public+key" + "ed25519:base64+device+signing+public+key": "base64+device+signing+public+key", }, + "usage": ["user_signing"], "signatures": { "@alice:example.com": { - "ed25519:ABCDEFG": "base64+self+signature" + "ed25519:base64+self+signing+public+key": "base64+signature" } } } } ``` -(This may require changes in what `device_id`s are accepted by `/keys/upload`.) +In order to ensure that there will be no collisions in the `signatures` +property, the server must respond with an error (FIXME: what error?) if any of +the uploaded public keys match an existing device ID for the user. Similarly, +if a user attempts to log in specifying a device ID matching one of the signing +keys, the server must respond with an error (FIXME: what error?). -Attestations/revocations will be uploaded and retrieved as described in -MSC1680. Creating a new master key would involve revoking the old master key -by sending a signed revocation and deleting the device using `DELETE -/devices/{deviceId}`, and then creating a new master key. +If a user-signing key is uploaded, it must be signed by the current +self-signing key (or the self-signing key that is included in the request) -Private master key could be stored as part of the key backup (MSC1219), maybe -as a special room ID + session ID, or possibly in the `auth_data` for the -backup version (the latter would mean that changing the master key would -require creating a new backup version, which may be what users need to do -anyways). Or the private master key could be stored in account data, -e.g. `/user/{userId}/account_data/m.master.{deviceId}`. +If a previous self-signing key exists, then the new self-signing key must have +a `replaces` property whose value is the previous public self-signing key. +Otherwise the server must respond with an error (FIXME: what error?). The new +self-signing key may also be signed with the old self-signing key. -#### Possible API 2 +FIXME: document `usage` property -Treat master key separately from normal devices and adding special handling for -them. This might result in a nicer API, but make the implementation more -complicated. For example, the server could automatically add master key -signatures into a device's `signatures` field, rather than shipping the -attestations separately. +After uploading self-signing and user-signing keys, they will be included under +the `/keys/query` endpoint under the `self_signing_key` and `user_signing_key` +properties, respectively. The `user_signing_key` will only be included when a +user requests their own keys. -Send public key using `/keys/upload`, under the `master_key` property. -(Alternatively, could use a special endpoint, like `/keys/master/upload`.) - -`POST /keys/upload` +`POST /keys/query` ``` json { - "master_key": { - "user_id": "@alice:example.com", - "key_id": "ABCDEFG", - "algorithm": "ed25519", - "key": "base64+public+key", - "signatures": { - "@alice:example.com": { - "ed25519:ABCDEFG": "base64+self+signature" - } - } - } + "device_keys": { + "@alice:example.com": [] + }, + "token": "string" } ``` -The key ID must be unique within the scope of a given user, and must not match -any device ID. This is required so that there will be no collisions in the -`signatures` property. - -(FIXME: how do we make sure that the key ID doesn't collide with an existing -device ID? Just send an error and let the client retry?) - -The server should not allow any client to use the key ID as their device ID -when logging in or registering; if a client tries to log in using this device -ID, then the server must respond with an error. (FIXME: what error?) - -Uploading a new master key should invalidate any previous master key. - -After uploading a master key, it will be included under the `/keys/query` -endpoint under the `master_key` property. - -`GET /keys/query` +response: ``` json { "failures": {}, - "master_key": { + "device_keys": { + "@alice:example.com": { + // ... + } + }, + "self_signing_key": { "@alice:example.com": { "user_id": "@alice:example.com", - "key_id": "ABCDEFG", - "algorithm": "ed25519", - "key": "base64+public+key", - "signatures": { - "@alice:example.com": { - "ed25519:ABCDEFG": "base64+self+signature" - } + "usage": ["self_signing"], + "keys": { + "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key" } } } } ``` -Signatures can be uploaded using `/keys/upload`, under the `signatures` -property. (Alternatively, could use a special endpoint, like -`/keys/signatures/upload`.) +Signatures of keys can be uploaded using `/keys/signatures/upload`. -For example, Alice signs one of her devices (HIJKLMN), and Bob's master key. +For example, Alice signs one of her devices (HIJKLMN), and Bob's self-signing key. -`POST /keys/upload` +`POST /keys/signatures/upload` ``` json { - "signatures": { - "@alice:example.com": { - "HIJKLMN": { - "user_id": "@alice:example.com", - "device_id": "HIJKLMN", - "algorithms": [ - "m.olm.curve25519-aes-sha256", - "m.megolm.v1.aes-sha" - ], - "keys": { - "curve25519:HIJKLMN": "base64+curve25519+key", - "ed25519:HIJKLMN": "base64+ed25519+key" - }, - "signatures": { - "@alice:example.com": { - "ed25519:ABCDEFG": "base64+signature+of+HIJKLMN" - } + "@alice:example.com": { + "HIJKLMN": { + "user_id": "@alice:example.com", + "device_id": "HIJKLMN", + "algorithms": [ + "m.olm.curve25519-aes-sha256", + "m.megolm.v1.aes-sha" + ], + "keys": { + "curve25519:HIJKLMN": "base64+curve25519+key", + "ed25519:HIJKLMN": "base64+ed25519+key" + }, + "signatures": { + "@alice:example.com": { + "ed25519:base64+user+signing+public+key": "base64+signature+of+HIJKLMN" } } - }, - "@bob:example.com": { - "OPQRSTU": { - "user_id": "@bob:example.com", - "key_id": "OPQRSTU", - "algorithm": "ed25519", - "key": "base64+ed25519+key", - "signatures": { - "@alice:example.com": { - "ed25519:ABCDEFG": "base64+signature+of+OPQRSTU" - } + } + }, + "@bob:example.com": { + "bobs+base64+self+signing+public+key": { + "user_id": "@bob:example.com", + "keys": { + "ed25519:bobs+base64+self+signing+public+key": "bobs+base64+self+signing+public+key" + }, + "usage": ["self_signing"], + "signatures": { + "@alice:example.com": { + "ed25519:base64+user+signing+public+key": "base64+signature+of+bobs+self+signing+key" } } } @@ -228,7 +201,18 @@ After Alice uploads a signature for her own devices, her signature will be included in the results of the `/keys/query` request when *anyone* requests her keys: -`GET /keys/query` +`POST /keys/query` + +``` json +{ + "device_keys": { + "@alice:example.com": [] + }, + "token": "string" +} +``` + +response: ``` json { @@ -249,7 +233,7 @@ keys: "signatures": { "@alice:example.com": { "ed25519:HIJKLMN": "base64+self+signature", - "ed25519:ABCDEFG": "base64+signature+of+HIJKLMN" + "ed25519:base64+user+signing+public+key": "base64+signature+of+HIJKLMN" } }, "unsigned": { @@ -258,41 +242,40 @@ keys: } } }, - "master_keys": { - "@alice:example.com": { - "user_id": "@alice:example.com", - "key_id": "ABCDEFG", - "algorithm": "ed25519", - "key": "base64+public+key", - "signatures": { - "@alice:example.com": { - "ed25519:ABCDEFG": "base64+self+signature" - } - } + "self_signing_key": { + "user_id": "@alice:example.com", + "usage": ["self_signing"], + "keys": { + "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key", } } } ``` -After Alice uploads a signature for Bob's master key, her signature will be -included in the results of the `/keys/query` request when Alice requests Bob's -key: +After Alice uploads a signature for Bob's user-signing key, her signature will +be included in the results of the `/keys/query` request when Alice requests +Bob's key: `GET /keys/query` ``` json { "failures": {}, - "master_key": { + "device_keys": { + "@bob:example.com": { + // ... + } + }, + "self_signing_key": { "@bob:example.com": { "user_id": "@bob:example.com", - "key_id": "OPQRSTU", - "algorithm": "ed25519", - "key": "base64+ed25519+key", + "keys": { + "ed25519:bobs+base64+self+signing+public+key": "bobs+base64+self+signing+public+key" + }, + "usage": ["self_signing"], "signatures": { "@alice:example.com": { - "ed25519:OPQRSTU": "base64+self+signature+OPQRSTU", - "ed25519:ABCDEFG": "base64+signature+of+OPQRSTU" + "ed25519:base64+user+signing+public+key": "base64+signature+of+bobs+self+signing+key" } } } @@ -300,6 +283,8 @@ key: } ``` +FIXME: s2s stuff + ## Comparison with MSC1680 MSC1680 suffers from the fact that the attestation graph may be arbitrarily @@ -323,8 +308,8 @@ look like: If Bob replaces his Dynabook without re-verifying with Alice, this will split the graph and Alice will not be able to verify Bob's other devices. In -contrast, in this proposal, Alice and Bob's master keys directly sign each -other, and the attestation graph would look like: +contrast, in this proposal, Alice and Bob sign each other's self-signing key +with their user-signing keys, and the attestation graph would look like: ![](images/1756-graph2.dot.png) @@ -337,12 +322,16 @@ devices, as there may be stale attestations and revocations lingering around. (This also relates to the question of whether a revocation should only revoke the signature created previously by the device making the attestation, or whether it should be a statement that the device should not be trusted at all.) -In contrast, with this proposal, there is a clear way to rebuild the -attestation graph: create a new master identity key, and re-verify all devices -with it. +In contrast, with this proposal, if a device is stolen, then only the +user-signing key must be re-issued. ## Security considerations +This proposal relies on servers to communicate when self-signing or +user-signing keys are deleted and replaced. An attacker who is able to both +steal a user's device and control their homeserver could prevent that device +from being marked as untrusted. + ## Conclusion This proposal presents an alternative cross-signing mechanism to MSC1680. diff --git a/proposals/images/1756-graph2.dot b/proposals/images/1756-graph2.dot index 6a45abe9..8eaa1df8 100644 --- a/proposals/images/1756-graph2.dot +++ b/proposals/images/1756-graph2.dot @@ -1,13 +1,18 @@ -graph { +digraph { A1 [label="A's PDP-11"] -AM [label="A's master key"] A2 [label="A's Osborne 2"] +AS [label="A's self-signing key"] +AU [label="A's user-signing key"] +BU [label="B's user-signing key"] +BS [label="B's self-signing key"] B1 [label="B's Dynabook"] -BM [label="B's master key"] B2 [label="B's VAX"] -A1 -- AM -AM -- A2 -AM -- BM -B1 -- BM -BM -- B2 -} \ No newline at end of file +AS -> A1 +AS -> A2 +AS -> AU +AU -> BS +BS -> BU +BU -> AS +BS -> B1 +BS -> B2 +} diff --git a/proposals/images/1756-graph2.dot.png b/proposals/images/1756-graph2.dot.png index 93379122bb948f3edecd2133c7f34972589825e1..3af9270f094b2361858930630945b05e40b2c6fd 100644 GIT binary patch literal 49417 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 GQu0Bt7+ePe1W@TYUs^3Vjg81* z8tl;3tJ}#`DDJDvpYw8O;g&rOvLgG)@bL3z&oasfZ6?zX_qgob!$>7a?pD)8!F{KH|D93at$DLsESi>sM(l#H8voT!pI^+ZSj9Nc!WRh z{7z#;j|H)g`jlu`>O{N5?C{xl1qSZ92}p||B@hF9s?d4-@ueSsLZDuedP1bKBA3Y) z1ZU?(gBj1TFs;5Nkqde*%+ApI_;3i`{E}K^E<{s@-cf@s(@H9XwvLWVDl$I1>KYsG z96WgNpOw_C9W-(E+BHM-<}_o}Z`-wTAS4C|WiFMpJt9*e7Qm~7$m6ujH3~4RWa6jt zZ>$Y4TyzJA`zJLc08{tjLx^sPd(7yaca&zcV~uG=NYN4-89pNb!}ErNjPzc>h2m~A z7DdYogUDO)Ccnh#m!CsZSf(01;GRt&Np@)1< zUfyQNWf%&9kF9j=+D?Mik!mploOF*mN}GS#pPE8OKTt=>`24A8aVlb^?!PR4Ruu0z zB0^8R^RG3Cn{<&~h0;Hv`6PX68^RSEq012A1>;lHcv!`+x<-fx2CJ2+W+c}5E0Lu_T&5g&8&DN5G@(W&ga|l$6*qEc0pN_o zlQ9A@CplR>Oq-FmgSZU?GSaA%zHVz%bDBSp1biYXBAO849?EUZ`JMNax6yWyd5~zl zABK&=e<%U(+wxX$EPehw7%!8E0Ckms5jyit$7=cjhrA#edxG|0LP6la8^bdF?2RM1 zDJ}}6PC5Ua{pX4Ew!huk7r$t;l0u*XqWb-XdzE@#fJR!j7sU{Ri&6)V-9Ioe8*?Wm zCpY_^Pf)&52a4NrbHgr-{qn#mF(PjsS#q|U_zk^L6DJS$9NzU4jq$88UG)SQ(HUSX z5)gM#oyv*W4QZ%e&_i~|d;&(@bAh${pc_##NC$>Wyd#J9LD{Ji02LXJg}tP86O#s2 z%K|zjaW)epBZC{U$OeE$S75Ph!E&5ZQwztg&P2?jfmwT^h5sP?JB$`*p{79@sD?Py zs-fpm1qo&0iIk8jHo*{@kcfbQHB^tIVad}7*_+yvi!i6YF9)+8*GTc$- z$+RDr5!o%^G-F@RsWBC>dCKJ2~)YUG1|L$EG8M(k< z5GrUn#$m||v=G4h_ZAix6;<$WlAs_XvH1>z90=$TAo?pg>ax$VEx%q%q2T^q>{zLW z{OpoywB5|gs)oe%@CHJB4G?D~L@de31@r{uSi5SsCmXO)&X7_Q)%l2AON_jJeyw6RRs)yqMF3tYCiIi(0w7l(|z z28qmofeK@ZD)0mrEN!3Oc!76xf;G*-^(Ao$5EVnbj>5Sw##9_AE!k`7eHuO)FF8;| zogvT=?;Arzf(mbo6Y2XDw-!ylAhGB=q#_Z7^noRS>uYkDU{Z zVx(H)XBdgX2raxXg3QU78o|2U5z9&x=M*0bh_X3!>+UFX3GbDn>?|$%Czv ztnX|!P4GwTsl(XO46B6H#l{j4LLj4+4jkotrai6kTEQyR@Q%pq9iX?iRek+>Z>HhS zQK5S$NWv9LAbybs&=PE&L==Ia@QSoh42g(F^Kf&I>+a$9>EU6xfgZsU!TdP0^8LX4m=7`i$u}^V@@T=^8rm9Id+U5I>WrET^Yu4 z^WgyI*>LmnuEj(R(oN(!U_0YgCL}J;M_q&TtS|}xK}iEZ!#kPCWCBj!I(GKA{srX? zY}}~8(2T(U!bjDQ?MK@rA!CwyqY*`(^y9~mWHR#E*(aTSeYB|e$i!59{K$lvC>oP@ zCKY1vG;qeqkOVSXN`S)fj>ubHMkJ@+vZ+}s;@z-pu;0#TX!IA_E3vaNjMQ*dB9>3y z$ANvj8SiL7-y*aLJAy=c5adGgX=m0e#plT5k}YK0%dkAx%|ez0w?hJo$Sad=d@4?Q z1MrA@l=OBoc8LB>CJ?|d$Uru}IAXQraD(cTI2XPHZ58cr{V#aQ0pe98j*br}=}lGD z02Lwf;zYdLgq4-mJ0;$g!3bN>KG3OXtYR(R(W-Lg%9f7g+wxd)1R9T``I0nte0&(F zA$hX}UM{W$-dwvQ+T7#Xq{wY}$q=AgT2%>=jQ2y?FnIa+8WPueQOGg;VC5OQ6vm-R7J1nr|LAd9v7ATzdE{9BYXQgZf#aU~kU; zeCp!tsX07^ckir|q8gcUX>g5i`>igHzx%B-y{O2iNn_w@Bo~HnM_g1)+coS>MZGlo zD=0ifOf4P;|4H4NOBA1cI|BoA_D}?)gtVlY0PQa^EBux4=Ho{-)E7E4x6fLG1gGMq zcO$VoxOMTd+PZZsaFrE$5;#d?=RlIrBp~X8v*Op^>$2kyfPneZJaIM&&B-s3m*VbS zQSD2jks<$oP~7uhQ>IVfj0TI9vE(-|{M(4G1_m}WX1s7P>F~Y$CnSPI+HjxHz2C&P z&bQKD{|vdO#1?0E?O=I9WoYMjW7vy{T`+c@T9BVFu?SgOJB4wZ1-u2Z6MeAI z??vCUo1s27Y>$G=f|reNlD%4D1Sn9&Bm^Vs*1g^Ir-R=8${pE~Lx@Wp6L5W9XssWM zu4l5t)74+Ta%JgF_IbC9TNPBB0wQAUA$HTYB09cq-i-!7Pkfs}EhfQW z)20n?=hZkS@MnZcbpM~fvZnw2xA8)ca@U4GmjAo;qek*~lM44$@kM@*t_`u}b}ow# zGqD5hUhG9`$N338Hhf%Rem8I2dmHlRYYpdEkZg>gpgNEM;37wIuYbPNntksMqR&c0 zUyTf_N9zc9Ql$!1R%BP&_;hYfjEe|xTlxfAnTC0i_vT}+G;W2aYQ2`%I%|^1wjO-c zg3HGvlozXM{>Hq0lUJxFwN;+z`lzY%b9$Cu?7i-7%zOiH@aCy)F?!#youfv$T$1XM zvuC$fV>G&!hK}t%1O*3wwXLsrtnm>3n!F1PN2}jzxwXj6*zyBEuDfFL%9WD2=sf`<}r01={->ElF_k9=L zlx=SfbR8GhT!>|uXXkSUy+hb>dx zF#hlXuAtNZu0UI^=+FP=E#^|kL$gcO%W;}}RKvW=)11Kn&KeDekJuFo;i@&83gitp z&bqBl^=}Suxpm`3{*J=5Q|qR^?$-QA(fwNLzlv2ee>3dQ{b*71q2^&4lvp0YW*f4R zcOmQx;`e*2)qF|B2cQLC?Ns!ZN;W(m8DozPfo6Wymk@}%mBpwvnl#ECF3n0$5bMm3kFTF0?7@96(^XI5{lxig^?O#PJkb-aiK_Oh)9&iM0) z3N!=5OoiYLT{!Blu6gxEZBTEkZ{gKV^WiFaEESxshyl?;5*UaHpa^?8XCP!Yt~kHqW^|otKXkIPBPtthA~;qP~Zb6 zS$IuqY+kj#<|dV~B+DKQEG}IcPq}Af6S)4Ao=<7B|J+;4Y28WLO0w`4z84;-&ScAa zg$-&}3{F#$!CLRzrQsCD00?wGm$DKDQs!|Cb&WPKw_a3p89PQCeKgW^*AoIjpXV1$ zXI}%1DhSj6-w#-~cimw$?r%0Op>vGa+~G_t^xy>;@V^%#2dKoj;mA{b5?J!riH-G+ z^#9+>{ovWNmWY2}uWrCIqd*q}?J_5yzyp8Y1shYp^$3t-6GPgdDbI`HekRuZ5m)Cr zMrqt?@uySIVh%DdXsXf6y5>(g%{-~Ga-B5v-6RZwb&j@)2$n>*zkCAy4-H<(9&m`G zm1QWZ7BdcAijZ`SmHfv({rlId==zTMuobJ}>DAf3jDRvo4!oARhJzyXfE>r*O$twb znqSOi*Wrwiosj=iKetUox%xVM!w)EjTSE^>Oc<~MixGBBYKuS9H@?SSxw89vET$bC z5KwM&ot=kTSR~GV%o((`;DCF?!5Qhlm3=7{r0Q^Vti5K{~wyk-|>pv5o(=l&FkEN!tiU|<%qIk!>KjVb8cYSPeR8qRsf z$=}!QAZKdSoL|2dJbU5(tgoUdt}dW4{WXOj?cs{(b67ShK|>ELTX)X;O#ko;7q)*m z$r1KSr(LWROXj0#&qXTzvwH(`wkGZ8a4DWtT~a$R!h-XJevMb?$>xi6wA>KZPBLC zsw`QznSz;u6VwFv)-{iBJimcCsC6Ia&(4ojdcoyzbl}X4C^!P$l9-DzOD zxnw3vByeRse=$ALV}*o-AOom}KhUs|ufF5?KYLo3r)(Qwp%Rve!oG#VQP1>BT{{ZZ z)?ott5Jv@>h>j|{;RIu~V{WJzq7{!@vmk7BW8{&AO!U4Y_jpvQKR6K#-s4 z1;o-BZwXWzpnOLwFSed}y_N>xT>^XnXnwX+Ewp02kbGuJ0x+HFc8pN`Ce9lRwhF|Y zAJ30_hbxc^GX7{eJo3sF{Z5^ZTWEn*TG3rfZ>*_G!>|F7`c2>^VNrl-%6@3fkaL_NA$qWIX zBfQfbM~%Q;6n1zIB`#NM;EHZ;g@uconqQrOl)0==hnoJBfDwPTAHnbmN+YwSwu(x| zU#gZaH9H><&H<~7gn5BGxL|C`yVFptdK@rM&&{-2wyZaht$F3!8;0Ws^$@5JWpT(Qpr7^e^AopHc6MW*L8>*sm%>J( zaGUp-anG%b#SDr+F&e>vgqXND2gTvG3X%n1@DlSL?g_WOKCU;lELbRfcwl9rU;IAan0qAcpaQgH=!riBN!2zj>O{gii!NY`WII(>h+vxVk@CO_XrN(MdvHZ zbqI)i2TWRvp%e|t$@6(9n5wb4#f+6oXu9ga_#eD`8o*NPGc z$-&Fa+}WVadoSk%QUbW5jfe*A(IM?IUTy$dRbjYQO;NKnKw*$sSSQ-1+`wMlAt#IkM$DXf?x8W-{B44N z3-jmT;NbsVa&LfwUK8Jan`~w3(OMfVGYa}~K9Hl>G5DEVe$2_3Nm6(Z;muDchfnpBeP^UT^HPz5xM^7DWQe7Y%T37WDh) ztzVFON${+K?c2tAv`m;8mO%Oyn7+;2tpIz82-(x~*NA?!g4!zD6 zFSh=?U8hQ%+=lKQo1zVb4!S5@Ae+N$sxOaV%at@x)y<*V?}3;-plc+*5tG_TJ@OF#;j z&~b7e)bm~ct3&h6)jE3HXbtGEH?bl9SK%NiYF-u;B;|+*qNq1h7<@!DDp_A*F(nhJ zH2T^BoiwdPnMDH;)(p^Co+E^0tlbkKix@AVkSQ?y%MSmz<2jKtDU1*RIPm>RLtN=! z0P<*$UPc^P2+A+4`Mv_c&t;Vms}S2#;!K&bst(myNm-eMszjw0-T%5ebM2y`mX?xD zLjZ{|9E#E(YY$@G0%^h^CiIqD#ZfPm))Vq>>&Z2i621g{_ua5>n2 z)~$NY3DeV>eTIsyj*7~+f5(gsAc??4>`k+`7@eG$!l}OpoK{?%TZ~o!NvnANEJo5-2z_|$ezr69(>+j~vwuf!Djr|2(TU@-@{UkM(}{QlhiSsYh@X~}TeW}FL*ih2 zWUNVBj}oP|G7E>9Iusk9zFeT@mKw_1TA`5B=<%sZIfk*vlR%%v!72xbLLMDJGKL7A zqh1mM(obnUr=`Jr@t_YG7f`&XxViG)8ZG!h}2~7WJfPJ051L)vXMcT?S^JNeQJfz z76IVH0v*j>6*Ya?$y2B35UY|ATrGjkMs~Ngc>LAKMY)693|yfm^#cqB?dkoxnyHDV7$En&v7KVwyXGww!N>H_zv*J)Tn4@@Aj zgQlXW7{Wl3t~rXboz26}XMS~Nyp>x1^T+>}6j>5o{z#F(JO59LOnt3Th`NA7_1&bb zO?{l7_u-v)8&K}6*05&p#be0kcgL;e2#52dYZri_L%W(A1g*%bRf5LQo_9fFFNbYw zvvJ6;io;1xE6OW4aq;?y=Qz|5;iT)q_k-Dd`WLVNsK0+o*ts$&#-QqG0~&B-k+YO)?D(1W>z(=1P*ss!d2l$I(4o z0l;x`#@fzs3qX53%)vpALn5Yp_^@ux%L{wUPQ$6YJbH9L&ABr_V13r30nor>8a!il zeZ&C+h*lVEq4{Zn3^x2LB9H*Yf}!J(_$sBB_U z)k-*2Ib-`T3ll-mgv^>tcV+W%EES&cKu9{b7mqh~*s^?;JExB#;n}m83A(I-YDMmk zz79<0K#-eLw5GW5GjyN*7MU}qePHL#o!(ev%TBtG^SnjJz2hoam+yted=Ouwy4}gFR5k`Sa&r z#%hM!*A(PH@9Lb-Rq67GWc!vv2_yS$x4!_Y&+pbwqNPg+txXt=Kg(R982qy|)9_#{ z&f{xU?@uGj7D@%58)B=g&ZlFOzQboh0AX?;MydS^C87-66faGSa0&Ek<>Yv&b?&pk2dygK)HWQ}&+4iS6 z7H~#5)~WTQ!fweg{NJwU&;*%yDK<9OA!BlmR9j zT++XU++a0rlChi=(XTX;^LCCn+O22LKv8B)nmqZ7ow`h&I(O}hYOMqX2tfaS$ofS| zLa#cN;yadUG{I@k|F7b6AumhLm9q0mQzlQoh_evWd2f72G*nv99J99kESnaBuB=u9 zck5q@ps5t8;yD>v`((l|A^R})=+ z>;EsrJ~MHJL!tkki!NPmwU^fp%j1e z$vrg~-S69X@9v5r7JVc7!xGbksr`S3kO*FNpKI4>(quhw2Dr>uyKNb4;=Uv*f(A&@ zX1v{9Awm=m3r;A&Kf(VH&!Z#gdFMO{;YVHCR-EpX{Pd~BK(^Ajv?vvJ&7P-6XJXEg zy(Yk~GjJ+L4_KZBUL<9+A*kOHxTm62xj}n61Vt~^LZ#v6LAvnmICTot$Ms^61K(0% zkBbYPU;Ox}9!-gnK6L1iQnPvywlV8@8O&fsS{T|MGVSS;zVVK{wIDXGgS|o|rIu#c zn;xBwfE=C&+P%lB_#xn=pL>PH+JeoWO#{MC`YfvXdaRL68CTjiZCZmh`_7#2G@x@q8n`4>*Xm$CF_Dj_vq~0ogicycF^Z) zrH{<#0xYXQ4=VFl-8MQZ4lff9<^eB=B%4xQzogJCpgTQx{kpcyEx`d-om&DmC}=AB zUyW9+R3#i|WcwpeDUxL+k(Xdgh7)z37*Hwlh=3n(L_J79z+bBKyVD@k0J;{FPlSDT zd-2k{Yp^Ye5Cqt?&721zX260J{`~4q$a?g2bs;eO9BtHc0K^D%Q?zd2-o5o<1w{%& zs)HF)I*`>0!<}m8)%C#x@~)*JBX3UZ6~#-f`@`)>iW8S6${)0oT%G89BsT=w=V6}m}7e+~z9lDvX+jG#0DXsb3isK?7Mlb%4u1$#udz%DC6MaYwcsgAYn zRS!g1X2k+*G2YXP(JS=a3I)3))5n^$s7-v&s)*gyoE9H~DE2n}&0MWf5)yLL`EGK* z_beX?wSfu*@JK-SL%M^cn-S-GC?ev4+cO_|D|g z-hc_;aw|O2mYR^%yB27A$?beSSddjeI1=s+_dx~F>p2R8c_)lu~WyGB7G z;egd4PDeF#1ng&Dx{D5nmy$6ri|J-+j6MnlBcx+I7ypg~nnl`y-t7L@)4B>Y1_3om ziHlqRE}!}I@na>02)$muOekxzl~+%sKTDQ`z0mJvUtNg*^_BQ;>PZP|7oENJ^y#g^ zy|Ww+fBCfzG1anwzU=gKF-eGBDLi0S?t|mIKYur zODvtB_0=veb25~drWy6>^pBX=IwJ76cW+Ar)f)D|A2bMUKn=gJ1{z4_ zv7)~p(c54$ayN=uSc_CUzLQk<@LYm#!k@!v&>2R@fB5iWV7Dax4)t)h6IwZe%|XsY zI73PyFZF>L9rV7K2}1DZ1jsf2M@jZNRtO!9W9_AyXtAYG-r#P@AkvEzTYqwq3V*>x!l<7J5dV{U#k&eAVp6xA$P2W&qVb7Ih!Bo9k6WQ(rkL18Qe> z9>Gt}8P1H`g60w4CE?B;zv87=C9t?!DocYYDds)mDkLJyBY5bB?2{#S%%AFf39S@0 z#$x}@8cT;@2SFbzBQfQ&K8rY$00*goGU^~Vi0R9&I%rCU2|TroUPg*0(m@UaNfD+l z0~NK5sD9tuy$R}!xGfKFZ-2CLN-87M$eX&hW zq;^)uzIq$j4qZik_zfQhmLU)-&ZxJ&njO`*5}ftYrMy_RUZ!ZoTkF;OuNFWcVdPvg zOIuQ;*i9T{ga!aW?4TG?rFePW@GR=G@*y{sjEex;s>W>N38-E#;5vd-{A$-q@8_oK z<8mAs=0pe3?fQt48kAdl1@gRnK%FE%pKoO0GOO3fk*Q|QR257Pu7ix(g17m_y5DPL zh>7f-*qU++E$5r7bge#0tPuW8dY@=!U9L5odL)4;IWn1Rv$|e^q$2YehSfY!`|&?L z{ghk6b8*tEpav5g$&A&79hlA8u46|(ZpNyG)%*E2q*o`7+i%!z-ChhSk{u>tYd`=b zxV>H7z^|&ZgEvxhiO3_lS9o+bUO5n@%#`%U+@p=Z+^soMg?Xg@c+f>lAFsLO_sEoq zpeZwMz$G9{O(|<07~k2Vb6`tI6^Ty>0VeD3lI@9Q8rU{AwEea~uPxO#FB!9llBc=X zj?*VjBp?T5Fnz$fpC4vcWaa+4)3ED%Xmht!wYH&%&+t*+%g_ycTX~dUw>fz@YkU|C zLt-z&cD?Jvs`sQfs62t)T*r9rNI^da=EAd)A=j_TbSv;{c2xIY6WkGmFo#{g9$GxU zDhO0X4m;lHYhO~jN~wqLZ!xqAYxKyJnr}?5iO`5t<06tw=Tl=Gh6WHE?l5(nVEn1A zOMw0Kwp-We9F~55`DPBUkIef+?@?*EHBhJKph>=e-xudhu2bMz{ej~uHg-B-O8+4< zr-_2p!<1PKy7!-}<~MEY_eAfV2e*>M-*HI0TCJpv-@X%C4mACXoysb;iw;9!k7ZRz zGefej9PfNzFu4lDB@bH~gqh0U^sZC$H!-`a*72SQeNM|I(>(^!S}QzpwTZkIEZb&W z*ugX_CjwZh1mrcd+jR5cn>mg>4@I`3Dm3FvB+#{srdlulym}D<-{8B~;k*)kv)en3 z!nP>`l*cWSzomOv#3DF9%^aUa)i0F#+&5ufLsx{Cu;fMZODnR!_2gY0 zgC|@ITOGbc?txE_nx8~fI@+YppaqK-iCKsy@;`4fyNm52k?zIb(o01#3Mb4>%8%Wp zG_qgiG*n|8$$U3`x0>HW`ECUC8<(oJ!!c2WbhE(3zzdStiRVsDS8_Zt+WwnpuBli} zcOGmUQ~d~j3YUiLL{n9BRKGJPppjYasx`_LUCc*_l(8BWS%e*0#Ak)qlg~PGkjPgh zg|BiQvaS+&Ek!fo!5lA1^rrf|fc~{=h}I#FQg$T&M`!N*42w-p<5aolHqWxYJc_`z zyV0hBCV@tj*lik5LVy{I6J_dWs1jCsNbAXuQc^Y*f3a@Fega%L%%o1hyBo=Ah|9V9 z?Mc<|bJgCD9!yV8aO*Onkf>#ubp?S+7xRoa4@8`X>$+v)j=_WX{n%1kE!N6N18#VC zzS&=ap`AbG=lfFTN}GtnS5^XSWN!ZU!QnO!*YRyL+R93^9&(uf$t|s_tV};2KElu3 z?00x_+TFZrtc5 z&2PQRt_e5ZMRQO%Ot#C^bX<%HU=Xm5wu_X;p>TS$ndP@;sBBzS<2VrL5x_(dN_me! z$l&iV^x&Fr(_E&G1IFfyE=8;AMfr?U;WKyiaB^CWz9(=kZ>tLSGl|i)OF6U{SV%o_ zQ(WcS{o?qRcaDnHZI$IV$EJJI4=kv3U;O0~l;S2nJhYzHnpQmU+-@_jX-UHmRgQ(k zbRe^+iejlIgtIHcuMN|~U7E`JCpbQnIGSC_}AW^2~b}%5w zOkZO1s#{n3JV3ryG7UX==*pUhN*rwq)~O6={bHBmsmUmM0OHq#ol+$v;EF#_!cw)t zrq%XK;DC}kAhVM`PCRaJCVK-H4TliSFHwUPKNHo??d!S{pU_n>b zChX^}3BDF%-F6;i(u|m>syB?nPOJ(5q;Q*(-^u(wRA#awfJOkKGtP%wJi?Ry?O`H3 z%}Q=Yvk4lnT>Dp&?AMy3v`)?1YTvzkL%7rGs_f=zRPi#$9hbeNbRcDrjYZ=AWhCyG zdSj{ns}Tw6<($FCSeB$gOthb5`Sw?G+Kjc8PWyf=toOg)OHF0*t@dyfpAEZK{eB+% zHTuM<-|JqUBYJVSnaVS>?V~jt+w{B9U1R9Tlrx&;)g9Nec^$`@b5{NSRbo_La7*9t-uaM%yd`b1W0fB$S1W%IQcmo` zcd)3Jd*>XGxh^1rnZ->zyp6z|cQ`ZMg<6}V_}HBdd)8eoe>;bj<=B772dk;$6MCwB z-Gh#+ObFJNigRgU(@NC$*<|+OH@fV8#Z*^=nQ2pN zjWhaGS#UoMwZsK@seV2S+uqrs?B}p2>BzbEbp*5nL0~_8Sh$qtRVY82)Fq5Zl<+YK zmL%BV05flulU@Ek7B!7rC&ymX_E!$lX@pecp{eDlIlKA~$%7e!2C@?jjljc*|@Ea(z8tdq&$JlN|N)s8o<%{_%`~o7*k6rP}9A*9F2;2H>gMF>; zmG;Amki;U-+G5;cXY#*gwM{e+rX>-gL9*lTg#JTt(5Ld)`neE2A%)*pgE`*u-@Fx`p3GG zARv?aWRUqEbp~e-snfnIg46Ebm&_j{3{8{^C;s~Tt=XS%MxU)Xm{uIw;t^a~(;nAL zcZ@iFknz%Bwb2ek0e>X92H3<)K5z#;1T%Wbs#8R}o7~_$d-m(mNMNs5pdjM$Jaqc> zW`0I$NT!fXoK{5gq(WhPeRVS|QZ7+hTA9nv*W6J)S4Kw@zjmU~M(1ABH__3uAM+jKO0^@FP_0T@eA}L=8X-qyw_6Z~u?K%;n{qk$2fRvJk&~R9at50Yb zdo90JYOC|^TF^WgF{Li2(04uhBm9{VQZ}<4N3BaJ_g>vh39!gWE#S8f1;v>5qPh_Ek^^e!II<@b$P+ zQ>FyBK6J>$(nlT{MDhIi9(5Ws08tg7PDZW3(@;k%e*Df=IqDvN*wFOh}ZGhuME-$DK=p0^Q?F+*R`% z1#kwbsA(yvjkU0j?}RKu;ydX81Afr6BjZ^%!M(rt`@4eEap=5o>wLqV&MAxmRSo}o zK9)dDQ~m9SsF^qoMbEu0**)OCSV$NH3#>|wHh(kz6*E*m;3|yF9JiO94FXAgDF4+$ zo*Fy({p$5R1EHToXH2|T@HOo4VQ+*=gRdCQ{v$GkLH82%V~Z9N8c4^Cwlr^TQ=Jy< z7k`{WoW0yaA-%S4Z3ylt+C{N!%&L0fDZ9j6pHUqX>27Qwb~%c1P{=3_?iL^M)}Uod z;lZ<|fK8{{v~G#}Vh@C&1Ij`Wy6&Ao8s^Tu8)^FM>o}x&kpq=SSats%+MzYIVs<0? z_G;@&5~|pUpi?n1d%u4_m^@l;{;5+F-$qV(hWuJ<(8``u>NnYZTg*5J;HkO=Bmz(L z`2H!Xg57N5lVwLSqFy_rhSGMY(6v1}oZHR6(4wn|$L4hV3y{8`5uRl0^*_hI-`ChJY^bwy{*2iE zm83@vBl?Q&bkdGy`4fo^2|Z~8J?0IR^=IG)?i70^0O(Tfo(^T@4NI;Qql% zxir_Qj-< z56VQ)9^(VH<|MoX!A~VuQV-R9N4CEW#Y2Nj~+PuC{EFB87v_rcoU&fa^t1oAR5^ zN;+5|_a#63)MZ!UoAP)UpMA_HAXfCjH6#xn6B!^(!}!B-n>Pf)rSqPf8wQJM9PkYv zRra)f)Wi`TCUw?adiGfP7_m_@0e(bktIXbH)C>4ed15_sqqCNFI^#VO^&xi4G>V~v#Pfe

uud2Zki_XHF3;Vjc|~P{e<3QC2?#Q= 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 ZwJnJord#H|})G(jZw8Nr)7(Bcl`{%HCve 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 From ebe887d9314b3533b80956b0ef803e3b7e319be2 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 18 Jan 2019 09:56:04 -0700 Subject: [PATCH 0149/1250] Grammar Co-Authored-By: turt2live --- specification/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/index.rst b/specification/index.rst index 67a0fa96..0b024c9e 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -435,7 +435,7 @@ are immutable once placed in the specification. Although there is a recommended set of versions, some rooms may benefit from features introduced by other versions. Rooms move between different versions by "upgrading" to the desired version. Due to versions not being ordered or hierarchical, this means a room can "upgrade" to -version 1 from version 2, if it so desired. +version 1 from version 2, if it is so desired. Room version grammar ~~~~~~~~~~~~~~~~~~~~ From 20b9a33b1240a45cae4419ba19ff5670195cfb99 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 18 Jan 2019 22:39:26 +0000 Subject: [PATCH 0150/1250] clarify 100% threshold for new spec core team additions --- proposals/1779-open-governance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index dde9aeac..779e94ab 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -218,7 +218,7 @@ agreement, they will be assumed to have left the project. Spec Core Team members can resign whenever they want, but must notify the rest of the team and the Guardians on doing so. -New additions to the team require 100% consent from the current team members. +New additions to the team must be approved by all current members of the team. Membership has to be formally proposed by someone already on the Spec Core Team. Members can be removed from the team if 75% of the current members approves and From 41c14c9e7df76efbbcc70eab2b93669a64909a40 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 18 Jan 2019 22:56:19 +0000 Subject: [PATCH 0151/1250] uhoreg tweaks Co-Authored-By: ara4n --- proposals/1779-open-governance.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 779e94ab..0a1cfca4 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -377,7 +377,7 @@ the core team is also signified by membership of the +matrix:matrix.org Matrix community. Responsibilities include: - * Helping ensure the quality of the projects' code repositories + * Helping ensure the quality of the projects' code repositories. * Ensuring all commits are reviewed. * Ensuring that all projects follow the Matrix spec. * Helping architect the implementations. @@ -400,7 +400,7 @@ Code Core Team members must arrange their own funding for their time. * Owns the Matrix.org marketing swag (t-shirts, stickers, exhibition stands etc). * Responsible for finding someone to run the Matrix.org homeserver (currently New Vector). * Publishes the spec. - * Responsible for tools and documentation that supports the spec. + * Responsible for tools and documentation that support the spec. * Responsible for ensuring reference implementations and test suite exists for the spec. * Publishes the website (including ensuring This Week In Matrix and similar exist to promote independent projects). * Manages any future IANA-style allocations for Matrix, such as: @@ -412,11 +412,11 @@ Code Core Team members must arrange their own funding for their time. In future: - * contracts entities to work on Matrix if such contracts help the Foundation to + * Contracts entities to work on Matrix if such contracts help the Foundation to fulfil its mission and obey the Guiding Principles (e.g. redistributing donations back to fund development of reference implementations or compliance kits). - * manages a "Made for Matrix" certification process? (to confirm that products + * Manages a "Made for Matrix" certification process? (to confirm that products are actually compatible with Matrix). ## Timings From 3ec3adbc24f287d8d38b837bbd5d1eb1a01fcd44 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 22 Jan 2019 10:51:22 +0000 Subject: [PATCH 0152/1250] Proposal for add room_version to make_* fed APIs --- proposals/1812-federation-make-membership.md | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 proposals/1812-federation-make-membership.md diff --git a/proposals/1812-federation-make-membership.md b/proposals/1812-federation-make-membership.md new file mode 100644 index 00000000..7960bf42 --- /dev/null +++ b/proposals/1812-federation-make-membership.md @@ -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`. From bd5e760a0d1a8fe3498fd77e27b948504762bef6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 22 Jan 2019 18:02:21 -0700 Subject: [PATCH 0153/1250] Simplify the description for room versions Instead of trying to describe maturity, stability, and recommendedness in one list we should describe what is "safe" and "unsafe" to use. The default version is just something that servers should use, and is normally going to be stable. --- specification/index.rst | 49 ++++++++++------------------------------- 1 file changed, 12 insertions(+), 37 deletions(-) diff --git a/specification/index.rst b/specification/index.rst index 0b024c9e..e5f01abf 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -467,48 +467,23 @@ Examples of valid room versions are: * ``1.2-beta`` * ``com.example.version`` -Recommended room versions -~~~~~~~~~~~~~~~~~~~~~~~~~ - -There are varying degrees of what "recommended" means for a given room version. -Currently, this is split into 5 categories: - -* **Development**: This is the default state for all room versions. When in this - state, a room version is documented but not recommended for use outside of a - development environment. These versions are not production-ready and servers - are not required to implement these versions. -* **Beta**: Versions in this state are not intended for wide-spread usage but - should be stable enough if a room requires the feature(s) introduced within. - Rooms may opt-in to these versions on their own, but should not be asked to - upgrade automatically. Servers do not have to implement these versions. -* **Default**: Exactly 1 room version will be in this category. The version under - this category should be used when creating rooms (unless another version is - requested by the user). Servers may wish to advertise that rooms opt-in to this - version. -* **Recommended**: Exactly 1 room version will be in this category as well. Servers - should advertise as strongly as possible for rooms to opt-in to upgrade to this - version. This version is often going to be the same as the Default version. -* **Mandatory**: Servers are required to implement versions in this category, - regardless as to how they are otherwise categorized. This allows for a Beta room - version to be mandatorily implemented by all servers in extremely rare circumstances, - as an example. Being a Mandatory room version does not imply that it is Recommended - or a Default version, just that the server needs to support it. Additional rules - may apply to room versions which are Mandatory, such as forcing servers to upgrade - all known rooms to a particular version where possible. - -With the above categories, the following applies: - -* Servers MUST have Room Version 1 as the Default room version. -* Servers MUST have Room Version 1 as the Recommended room version. -* Servers MUST implement Room Version 1 as a Mandatory room version. - Complete list of room versions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Room versions are divided into two distinct groups: stable and unstable. Stable +room versions may be used by rooms safely. Unstable room versions are everything +else which is either not listed in the specification or flagged as unstable for +some other reason. Versions can switch between stable and unstable periodically +for a variety of reasons, including discovered security vulnerabilites and age. + +Clients should not ask room administrators to upgrade their rooms if the room is +running a stable version. Servers SHOULD use room version 1 as the default room +version when creating new rooms. + The available room versions are: -* `Version 1 `_ - The current version of most rooms. -* `Version 2 `_ - **Beta**. Implements State Resolution Version 2. +* `Version 1 `_ - **Stable**. The current version of most rooms. +* `Version 2 `_ - **Stable**. Implements State Resolution Version 2. Specification Versions ---------------------- From 0dfc64a9f4f1772c5839c60fac63f15a8cc7603e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 22 Jan 2019 18:11:36 -0700 Subject: [PATCH 0154/1250] Improve wording --- specification/modules/room_upgrades.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/room_upgrades.rst b/specification/modules/room_upgrades.rst index 21a1ed2d..49ff4414 100644 --- a/specification/modules/room_upgrades.rst +++ b/specification/modules/room_upgrades.rst @@ -31,7 +31,7 @@ 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 to hide the old room from the user's room list +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 From 50eba23669bf10d7b7b3f707ed11d70d51aa650a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 22 Jan 2019 18:24:04 -0700 Subject: [PATCH 0155/1250] Update MSC to match how room versions work As per 1773. --- .../1804-advertising-capable-room-versions.md | 38 +++++++------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/proposals/1804-advertising-capable-room-versions.md b/proposals/1804-advertising-capable-room-versions.md index 7686f1b2..abcf56e9 100644 --- a/proposals/1804-advertising-capable-room-versions.md +++ b/proposals/1804-advertising-capable-room-versions.md @@ -3,7 +3,7 @@ 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 prompt people to upgrade shouldn't be impossible, or even a judgement call. +for when to encourage people to upgrade shouldn't be impossible, or even a judgement call. ## Proposal @@ -16,37 +16,27 @@ this proposal suggests a `m.room_versions` capability be introduced like the fol { "capabilities": { "m.room_versions": { - "m.development": ["state-res-v2-test", "event-ids-as-hashes-test", "3"], - "m.beta": ["2"], - "m.default": "1", - "m.recommended": "1", - "m.mandatory": ["1"] + "default": "1", + "available": { + "1": "stable", + "2": "stable", + "state-res-v2-test": "unstable", + "event-ids-as-hashes": "unstable", + "3": "unstable" + } } } } ``` -The labels picked (`m.development`, etc) are based upon the categories for different room versions. -Note that `m.default` and `m.recommended` reinforce that there is exactly 1 version in each category. - Clients are encouraged to make use of this capability to determine if the server supports a given -version, and at what state. - -Clients should prompt people with sufficient permissions to perform an upgrade to upgrade their rooms -to the `m.recommended` room version. - -Room versions might appear under multiple categories under some circumstances. In particular, it is -expected that anything in `m.development` or `m.beta` appears exactly once in the whole capability -whereas `m.default`, `m.recommended`, and `m.mandatory` may duplicate a room version. The duplication -is possible due to the definitions of each category: +version, and at what level of stability. -* `m.default` - This is the room version that the server is going to apply to all new rooms by default. -* `m.recommended` - The version clients should be prompting people to upgrade to. -* `m.mandatory` - The version the server is going to enforce on all pre-existing rooms. +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. -With these definitions, it is possible that a room version fits multiple criteria (ie: "please upgrade -your rooms to version X which is also the default for new rooms"). Clients will generally only be -interested in the `m.recommended` room version, leaving the rest as informational for users. +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 From 5cafcd103fbdbce8122fbe8f67c0d65d08ac28ac Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 22 Jan 2019 21:43:32 -0700 Subject: [PATCH 0156/1250] Fix copyright > Since this is a copy-and-paste of old text, I think the copyright year should match when the original text was written, which according to git was 2017. Co-Authored-By: turt2live --- specification/rooms/v1.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index c263a108..207fe8bc 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -1,4 +1,4 @@ -.. Copyright 2018-2019 New Vector Ltd +.. 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. From 061f59547a393ab2d1d52eacf76368bc8c3800e6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 23 Jan 2019 09:10:14 -0700 Subject: [PATCH 0157/1250] Minor wording changes --- specification/index.rst | 8 ++++---- specification/rooms/v1.rst | 4 ++-- specification/rooms/v2.rst | 4 ++-- specification/server_server_api.rst | 5 ++--- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/specification/index.rst b/specification/index.rst index e5f01abf..0a2224d2 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -434,16 +434,16 @@ There is no implicit ordering or hierarchy to room versions, and their principle are immutable once placed in the specification. Although there is a recommended set of versions, some rooms may benefit from features introduced by other versions. Rooms move between different versions by "upgrading" to the desired version. Due -to versions not being ordered or hierarchical, this means a room can "upgrade" to -version 1 from version 2, if it is so desired. +to versions not being ordered or hierarchical, this means a room can "upgrade" +from version 2 to version 1, if it is so desired. Room version grammar ~~~~~~~~~~~~~~~~~~~~ Room versions are used to change properties of rooms that may not be compatible with other servers. For example, changing the rules for event authorization would -cause older servers to potentially end up in a split-brain situation due to them -not understanding the new rules. +cause older servers to potentially end up in a split-brain situation due to not +understanding the new rules. A room version is defined as a string of characters which MUST NOT exceed 32 codepoints in length. Room versions MUST NOT be empty and SHOULD contain only diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index 207fe8bc..37b1b7ce 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -34,8 +34,8 @@ 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 be aware that inconsistencies - may occur until room version 2 is ready and adopted. + aware that restrictions should be generally relaxed and that inconsistencies + may occur until room version 2 (or later) is ready and adopted. State resolution ~~~~~~~~~~~~~~~~ diff --git a/specification/rooms/v2.rst b/specification/rooms/v2.rst index eef03497..d39a7caa 100644 --- a/specification/rooms/v2.rst +++ b/specification/rooms/v2.rst @@ -60,8 +60,8 @@ 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 have - may remove someone's ability to do something in the room. + ``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 diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 8645888b..09ad333f 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -752,9 +752,8 @@ is at the top):: Suppose E3 and E4 are both ``m.room.name`` events which set the name of the room. What should the name of the room be at E5? -Servers must use the appropriate recursively-defined algorithm as required -by the room version. For a description of each room version's algorithm, please -see the `room version specification`_ . +The algorithm to be used for state resolution depends on the room version. For +a description of each room version's algorithm, please see the `room version specification`_. Backfilling and retrieving missing events From 413bfaeb68f3e9c072adf539aa54c2b6c7ee218f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 23 Jan 2019 19:03:14 -0700 Subject: [PATCH 0158/1250] Add clarification that clients shouldn't use unstable things as stable --- api/client-server/versions.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/client-server/versions.yaml b/api/client-server/versions.yaml index 109e852c..2464af1d 100644 --- a/api/client-server/versions.yaml +++ b/api/client-server/versions.yaml @@ -44,7 +44,8 @@ paths: off this list once the feature lands in the spec and the server deems it reasonable to do so. Servers may wish to keep advertising features here after they've been released into the spec to give clients a chance to - upgrade appropriately. + upgrade appropriately. Additionally, clients should avoid using unstable + features in their stable releases. operationId: getVersions responses: 200: From 577edeb53b7cf4dafa37b88f9d04cb90d91c6b3f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 25 Jan 2019 09:27:23 -0700 Subject: [PATCH 0159/1250] Say that !stable == unstable --- proposals/1804-advertising-capable-room-versions.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/1804-advertising-capable-room-versions.md b/proposals/1804-advertising-capable-room-versions.md index abcf56e9..684bd524 100644 --- a/proposals/1804-advertising-capable-room-versions.md +++ b/proposals/1804-advertising-capable-room-versions.md @@ -22,7 +22,7 @@ this proposal suggests a `m.room_versions` capability be introduced like the fol "2": "stable", "state-res-v2-test": "unstable", "event-ids-as-hashes": "unstable", - "3": "unstable" + "3": "future-scifi-label" } } } @@ -30,7 +30,8 @@ this proposal suggests a `m.room_versions` capability be introduced like the fol ``` Clients are encouraged to make use of this capability to determine if the server supports a given -version, and at what level of stability. +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. From 9f443225ac377afb1cf2c0e7227ba394058b093d Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Sat, 26 Jan 2019 20:10:32 +0000 Subject: [PATCH 0160/1250] fix incorrect spelling of homeserver --- specification/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/index.rst b/specification/index.rst index 0a2224d2..3893ac4c 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -315,8 +315,8 @@ The following conceptual diagram shows an | Content: { JSON object } | |....................................| -Federation maintains *shared data structures* per-room between multiple home -servers. The data is split into ``message events`` and ``state events``. +Federation maintains *shared data structures* per-room between multiple +homeservers. The data is split into ``message events`` and ``state events``. Message events: These describe transient 'once-off' activity in a room such as an From a358e2d4d8e8d1128dc308306eaec91b188ed547 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 28 Jan 2019 14:57:59 +0000 Subject: [PATCH 0161/1250] rst --- specification/proposals_intro.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 9274b2a9..44fcf4b1 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -111,6 +111,7 @@ engine behaviour be specified? There is no universal answer to this, but the following guidelines should be applied: + 1. If the feature would benefit the whole Matrix ecosystem and is aligned with the guiding principles above, then it should be supported by the spec. 2. If the spec already makes the feature possible without changing any of the @@ -122,6 +123,7 @@ applied: 3rd party behaviour. As a worked example: + 1. Video conferencing is clearly a feature which would benefit the whole ecosystem, and so the spec should find a way to make it happen. 2. Video conferencing can be achieved by widgets without requiring any From bf2b6e6daac2fc7cd7240050737cf372ed6ac60b Mon Sep 17 00:00:00 2001 From: Neil Johnson Date: Mon, 28 Jan 2019 15:05:10 +0000 Subject: [PATCH 0162/1250] remove references to presence lists --- api/client-server/presence.yaml | 100 ------------------ .../event-schemas/m.device_list_update.yaml | 2 +- specification/modules/presence.rst | 19 +--- specification/server_server_api.rst | 20 +--- 4 files changed, 7 insertions(+), 134 deletions(-) diff --git a/api/client-server/presence.yaml b/api/client-server/presence.yaml index 91b75c6a..874ac59b 100644 --- a/api/client-server/presence.yaml +++ b/api/client-server/presence.yaml @@ -136,103 +136,3 @@ paths: "$ref": "definitions/errors/error.yaml" tags: - Presence - "/presence/list/{userId}": - post: - summary: Add or remove users from this presence list. - description: |- - Adds or removes users from this presence list. - operationId: modifyPresenceList - security: - - accessToken: [] - parameters: - - in: path - type: string - name: userId - description: The user whose presence list is being modified. - required: true - x-example: "@alice:example.com" - - in: body - name: presence_diff - description: The modifications to make to this presence list. - required: true - schema: - type: object - example: { - "invite": [ - "@bob:matrix.org" - ], - "drop": [ - "@alice:matrix.org" - ] - } - properties: - invite: - type: array - description: A list of user IDs to add to the list. - items: - type: string - description: A list of user IDs. - drop: - type: array - description: A list of user IDs to remove from the list. - items: - type: string - description: A list of user IDs. - responses: - 200: - description: The list was updated. - examples: - application/json: { - } - schema: - type: object # empty json object - 429: - description: This request was rate-limited. - schema: - "$ref": "definitions/errors/rate_limited.yaml" - tags: - - Presence - get: - summary: Get presence events for this presence list. - description: |- - Retrieve a list of presence events for every user on this list. - operationId: getPresenceForList - parameters: - - in: path - type: string - name: userId - description: The user whose presence list should be retrieved. - required: true - x-example: "@alice:example.com" - responses: - 200: - description: A list of presence events for this list. - examples: - application/json: [ - { - "content": { - "last_active_ago": 395, - "presence": "offline", - "user_id": "@alice:matrix.org" - }, - "type": "m.presence" - }, - { - "content": { - "last_active_ago": 16874, - "presence": "online", - "user_id": "@marisa:matrix.org", - "currently_active": true - }, - "type": "m.presence" - } - ] - schema: - type: array - items: - type: object - title: PresenceEvent - allOf: - - "$ref": "definitions/event-schemas/schema/core-event-schema/event.yaml" - tags: - - Presence diff --git a/api/server-server/definitions/event-schemas/m.device_list_update.yaml b/api/server-server/definitions/event-schemas/m.device_list_update.yaml index f11e957e..d511bfae 100644 --- a/api/server-server/definitions/event-schemas/m.device_list_update.yaml +++ b/api/server-server/definitions/event-schemas/m.device_list_update.yaml @@ -21,7 +21,7 @@ description: |- # FIXME: It's very unclear why we have this API surface for synchronising # device lists, rather than just using a room (which could also be used for -# presence lists, profile info, etc). But documenting what we have for now... +# profile info, etc). But documenting what we have for now... allOf: - $ref: ../edu.yaml diff --git a/specification/modules/presence.rst b/specification/modules/presence.rst index 822b298d..4873776a 100644 --- a/specification/modules/presence.rst +++ b/specification/modules/presence.rst @@ -26,14 +26,8 @@ Each user has the concept of presence information. This encodes: This information is collated from both per-device (``online``, ``idle``, ``last_active``) and per-user (status) data, aggregated by the user's homeserver -and transmitted as an ``m.presence`` event. This is one of the few events which -are sent *outside the context of a room*. Presence events are sent to all users -who subscribe to this user's presence through a presence list or by sharing -membership of a room. - -A presence list is a list of user IDs whose presence the user wants to follow. -To be added to this list, the user being added must be invited by the list owner -who must accept the invitation. +and transmitted as an ``m.presence`` event. Presence event are sent to +interested parties where users share a room membership. User's presence state is represented by the ``presence`` key, which is an enum of one of the following: @@ -53,17 +47,10 @@ Events Client behaviour ---------------- -Clients can manually set/get their presence/presence list using the HTTP APIs -listed below. +Clients can manually set/get their presence using the HTTP APIs listed below. {{presence_cs_http_api}} -Server behaviour ----------------- - -Each user's homeserver stores a "presence list" per user. Once a user accepts -a presence list, both user's HSes must track the subscription. - Last active ago ~~~~~~~~~~~~~~~ The server maintains a timestamp of the last time it saw a pro-active event from diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 09ad333f..7457cfd4 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -1012,15 +1012,8 @@ The server API for presence is based entirely on exchange of the following EDUs. There are no PDUs or Federation Queries involved. Servers should only send presence updates for users that the receiving server -would be interested in. This can include the receiving server sharing a room -with a given user, or a user on the receiving server has added one of the -sending server's users to their presence list. - -Clients may define lists of users that they are interested in via "Presence -Lists" through the `Client-Server API`_. When users are added to a presence -list, a ``m.presence_invite`` EDU is sent to them. The user may then accept -or deny their involvement in the list by sending either an ``m.presence_accept`` -or ``m.presence_deny`` EDU back. +would be interested in. Such as the receiving server sharing a room +with a given user. .. TODO-doc - Explain the timing-based round-trip reduction mechanism for presence @@ -1030,13 +1023,6 @@ or ``m.presence_deny`` EDU back. {{definition_ss_event_schemas_m_presence}} -{{definition_ss_event_schemas_m_presence_invite}} - -{{definition_ss_event_schemas_m_presence_accept}} - -{{definition_ss_event_schemas_m_presence_deny}} - - Receipts -------- @@ -1114,7 +1100,7 @@ which should be used to correlate with subsequent ``m.device_list_update`` EDUs. .. TODO: this whole thing desperately feels like it should just be state in a room, rather than inventing a whole different DAG. The same room could be used for - profiles, presence lists, etc. + profiles etc. {{user_devices_ss_http_api}} From ed68f940cd899183d36a19ed39a165a2fdaf4f8f Mon Sep 17 00:00:00 2001 From: Neil Johnson Date: Mon, 28 Jan 2019 17:49:20 +0000 Subject: [PATCH 0163/1250] towncrier --- changelogs/client_server/newsfragments/1817.deprecation | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/1817.deprecation diff --git a/changelogs/client_server/newsfragments/1817.deprecation b/changelogs/client_server/newsfragments/1817.deprecation new file mode 100644 index 00000000..9a888e85 --- /dev/null +++ b/changelogs/client_server/newsfragments/1817.deprecation @@ -0,0 +1 @@ +Remove references to presence lists From 9f517f33cee2a555fa635b9291a2422b27ff7802 Mon Sep 17 00:00:00 2001 From: Neil Johnson Date: Mon, 28 Jan 2019 17:59:17 +0000 Subject: [PATCH 0164/1250] Create 1819-remove-presence-lists.md --- proposals/1819-remove-presence-lists.md | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 proposals/1819-remove-presence-lists.md diff --git a/proposals/1819-remove-presence-lists.md b/proposals/1819-remove-presence-lists.md new file mode 100644 index 00000000..7595f569 --- /dev/null +++ b/proposals/1819-remove-presence-lists.md @@ -0,0 +1,26 @@ +# Remove references to presence lists + +[Presence](https://matrix.org/docs/spec/client_server/r0.4.0.html#id388) 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. + +## 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. From aca9437bf37fef38986a52a312bf7f4c58a4f5e7 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 28 Jan 2019 21:05:33 -0700 Subject: [PATCH 0165/1250] Specification for v2 s2s invite API Original proposal: https://github.com/matrix-org/matrix-doc/pull/1794 Implementation proofs: * https://github.com/matrix-org/synapse/pull/4402 * https://github.com/matrix-org/synapse/pull/4496 There are no changes from the original proposal. --- .../{invites.yaml => invites-v1.yaml} | 12 +- api/server-server/invites-v2.yaml | 234 ++++++++++++++++++ specification/server_server_api.rst | 7 +- 3 files changed, 246 insertions(+), 7 deletions(-) rename api/server-server/{invites.yaml => invites-v1.yaml} (96%) create mode 100644 api/server-server/invites-v2.yaml diff --git a/api/server-server/invites.yaml b/api/server-server/invites-v1.yaml similarity index 96% rename from api/server-server/invites.yaml rename to api/server-server/invites-v1.yaml index 6d905e17..44db1f8d 100644 --- a/api/server-server/invites.yaml +++ b/api/server-server/invites-v1.yaml @@ -1,4 +1,4 @@ -# Copyright 2018 New Vector Ltd +# 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. @@ -20,7 +20,7 @@ host: localhost:8448 schemes: - https basePath: /_matrix/federation/v1 -consumes: +consumes: - application/json produces: - application/json @@ -32,9 +32,13 @@ paths: summary: Invites a remote user to a room description: |- 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 + homeserver and the invited homeserver, it can be sent to all of the servers in the room by the inviting homeserver. - operationId: sendInvite + + Servers should prefer to use the v2 API for invites instead of the v1 API. Servers + which receive a v1 invite request must assume that the room version is either ``"1"`` + or ``"2"``. + operationId: sendInviteV1 security: - signedRequest: [] parameters: diff --git a/api/server-server/invites-v2.yaml b/api/server-server/invites-v2.yaml new file mode 100644 index 00000000..4ebbd218 --- /dev/null +++ b/api/server-server/invites-v2.yaml @@ -0,0 +1,234 @@ +# 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 may wish to retry using the v1 + API as the server may be older, if the room version supports doing so. + 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/pdu.json", + "type": "m.room.member", + "state_key": "@joe:elsewhere.com", + "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. + 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/pdu.json", + "type": "m.room.member", + "state_key": "@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" + } diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 09ad333f..a63bf0a6 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -1,6 +1,5 @@ .. Copyright 2016 OpenMarket Ltd -.. Copyright 2017 New Vector Ltd -.. Copyright 2018 New Vector Ltd +.. 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. @@ -889,7 +888,9 @@ the homeserver may sign the membership event itself and skip the process defined here. However, when a user invites another user on a different homeserver, a request to that homeserver to have the event signed and verified must be made. -{{invites_ss_http_api}} +{{invites_v1_ss_http_api}} + +{{invites_v2_ss_http_api}} Leaving Rooms (Rejecting Invites) --------------------------------- From d12593feeac9d3370afd8020e82eebab197fb967 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 28 Jan 2019 22:15:59 -0700 Subject: [PATCH 0166/1250] Specify the room_version response property on /make_{leave|join} Original proposal: https://github.com/matrix-org/matrix-doc/pull/1813 Implementation proof: https://github.com/matrix-org/synapse/pull/4447 There are no changes from the original proposal. --- api/server-server/joins.yaml | 15 +++++++++++---- api/server-server/leaving.yaml | 11 +++++++++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/api/server-server/joins.yaml b/api/server-server/joins.yaml index 6d97e3aa..3c0ec48f 100644 --- a/api/server-server/joins.yaml +++ b/api/server-server/joins.yaml @@ -65,6 +65,12 @@ paths: schema: type: object properties: + room_version: + type: string + description: |- + The version of the room where the server is trying to join. If not provided, + the room version is assumed to be either "1" or "2". + example: "2" event: allOf: - $ref: "definitions/unsigned_pdu.yaml" @@ -80,7 +86,7 @@ paths: origin: type: string description: The name of the resident homeserver. - example: "matrix.org" + example: "matrix.org" origin_server_ts: type: integer format: int64 @@ -113,7 +119,7 @@ paths: type: array description: |- An event reference list containing the authorization events that would - allow the member to join the room. This should normally be the + allow the member to join the room. This should normally be the ``m.room.create``, ``m.room.power_levels``, and ``m.room.join_rules`` events. items: @@ -143,7 +149,8 @@ paths: - state_key examples: application/json: { - event: { + "room_version": "2", + "event": { "$ref": "examples/unsigned_pdu.json", "type": "m.room.member", "state_key": "@someone:example.org", @@ -220,7 +227,7 @@ paths: origin: type: string description: The name of the joining homeserver. - example: "matrix.org" + example: "matrix.org" origin_server_ts: type: integer format: int64 diff --git a/api/server-server/leaving.yaml b/api/server-server/leaving.yaml index bb4bbe3d..68ada9d7 100644 --- a/api/server-server/leaving.yaml +++ b/api/server-server/leaving.yaml @@ -57,6 +57,12 @@ paths: schema: type: object properties: + room_version: + type: string + description: |- + The version of the room where the server is trying to leave. If not provided, + the room version is assumed to be either "1" or "2". + example: "2" event: allOf: - $ref: "definitions/unsigned_pdu.yaml" @@ -101,7 +107,7 @@ paths: type: array description: |- An event reference list containing the authorization events that would - allow the member to leave the room. This should normally be the + allow the member to leave the room. This should normally be the ``m.room.create``, ``m.room.power_levels``, and ``m.room.join_rules`` events. items: @@ -131,6 +137,7 @@ paths: - state_key examples: application/json: { + "room_version": "2", "event": { "$ref": "examples/unsigned_pdu.json", "type": "m.room.member", @@ -194,7 +201,7 @@ paths: origin: type: string description: The name of the leaving homeserver. - example: "matrix.org" + example: "matrix.org" origin_server_ts: type: integer format: int64 From 0712fd36a2ed96e1fcf507832320e493358d8ea2 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 29 Jan 2019 14:36:26 +0000 Subject: [PATCH 0167/1250] 75% majority now required for FCP --- specification/proposals_intro.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 96ffaafc..d95128b7 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -141,7 +141,7 @@ follows: given, an FCP can be cancelled. It is often preceded by a comment summarising the current state of the discussion, along with reasoning for its occurrence. - A concern can be raised by a Core Team member at any time, which will block - an FCP from beginning. An FCP will only begin when a **majority** of core + an FCP from beginning. An FCP will only begin when a **75% majority** of core team members agree on its outcome, and all existing concerns have been resolved. - The FCP will then begin and last for 5 days, giving anyone else some time to @@ -233,7 +233,7 @@ Name GitHub Label Description =============================== ============================= ==================================== Proposal Drafting and Feedback N/A A proposal document which is still work-in-progress but is being shared to incorporate feedback. Please prefix your proposal's title with ``[WIP]`` to make it easier for reviewers to skim their notifications list. Proposal In Review proposal-in-review A proposal document which is now ready and waiting for review by the Core Team and community -Proposed Final Comment Period proposed-final-comment-period Currently awaiting signoff of a majority of team members in order to enter the final comment period +Proposed Final Comment Period proposed-final-comment-period Currently awaiting signoff of a 75% majority of team members in order to enter the final comment period Final Comment Period final-comment-period A proposal document which has reached final comment period either for merge, closure or postponement Final Commment Period Complete finished-final-comment-period The final comment period has been completed. Waiting for a demonstration implementation Spec PR Missing spec-pr-missing The proposal has been agreed, and proven with a demonstration implementation. Waiting for a PR against the Spec From de57d3950f0fb1fe7b0a9d21877d5e699709df36 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 29 Jan 2019 14:46:27 +0000 Subject: [PATCH 0168/1250] Relax the requirement for a content-type on .well-known (#1824) The main reason for this is that Apache etc won't stick a content-type on by default, because they don't know it's JSON, so requiring it seems like it will require unnecessary hoop-humping for everyone who wants to use a .well-known. --- proposals/1708-well-known-for-federation.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/1708-well-known-for-federation.md b/proposals/1708-well-known-for-federation.md index 8105a638..d23c0e2f 100644 --- a/proposals/1708-well-known-for-federation.md +++ b/proposals/1708-well-known-for-federation.md @@ -43,9 +43,9 @@ certificate validation, and following 30x redirects (being careful to avoid redirect loops). If the request does not return a 200, continue to step 4, otherwise: -The response must have a `Content-Type` of `application/json`, and must be -valid JSON which follows the structure documented below. Otherwise, the -request is aborted. +The response must be valid JSON which follows the structure documented +below. Otherwise, the request is aborted. It is NOT necessary for the response +to have a `Content-Type` of `application/json`. If the response is valid, the `m.server` property is parsed as `[:]`, and processed as follows: From c0039c30f28a546dab63de54a0ce00294460e707 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 29 Jan 2019 09:05:20 -0700 Subject: [PATCH 0169/1250] Minor wording changes from code review Co-Authored-By: turt2live --- api/server-server/invites-v2.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/server-server/invites-v2.yaml b/api/server-server/invites-v2.yaml index 4ebbd218..f8695195 100644 --- a/api/server-server/invites-v2.yaml +++ b/api/server-server/invites-v2.yaml @@ -40,8 +40,8 @@ paths: 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 may wish to retry using the v1 - API as the server may be older, if the room version supports doing so. + 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". operationId: sendInviteV2 security: - signedRequest: [] From c09fa6845ea6394588a10ee31115533c1620b65c Mon Sep 17 00:00:00 2001 From: Neil Johnson Date: Tue, 29 Jan 2019 18:23:30 +0000 Subject: [PATCH 0170/1250] Update presence.rst --- specification/modules/presence.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/presence.rst b/specification/modules/presence.rst index 4873776a..53a33550 100644 --- a/specification/modules/presence.rst +++ b/specification/modules/presence.rst @@ -26,7 +26,7 @@ Each user has the concept of presence information. This encodes: This information is collated from both per-device (``online``, ``idle``, ``last_active``) and per-user (status) data, aggregated by the user's homeserver -and transmitted as an ``m.presence`` event. Presence event are sent to +and transmitted as an ``m.presence`` event. Presence events are sent to interested parties where users share a room membership. User's presence state is represented by the ``presence`` key, which is an enum From 5151aa0aa7bfa6ee3b8ce9c2d43deb2d6305aec4 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Wed, 30 Jan 2019 10:44:15 +0000 Subject: [PATCH 0171/1250] Update proposals/1819-remove-presence-lists.md Co-Authored-By: neilisfragile --- proposals/1819-remove-presence-lists.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1819-remove-presence-lists.md b/proposals/1819-remove-presence-lists.md index 7595f569..e082f5fa 100644 --- a/proposals/1819-remove-presence-lists.md +++ b/proposals/1819-remove-presence-lists.md @@ -1,6 +1,6 @@ # Remove references to presence lists -[Presence](https://matrix.org/docs/spec/client_server/r0.4.0.html#id388) lists allow a given user the ability to subscribe to other users and be alerted to their current presence status. +[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. From 4f13f5289e656813a43083bc84d81533241a5c8d Mon Sep 17 00:00:00 2001 From: Neil Johnson Date: Wed, 30 Jan 2019 11:20:38 +0000 Subject: [PATCH 0172/1250] Update 1819-remove-presence-lists.md Add references to exactly what this proposal would remove --- proposals/1819-remove-presence-lists.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/proposals/1819-remove-presence-lists.md b/proposals/1819-remove-presence-lists.md index e082f5fa..38c31883 100644 --- a/proposals/1819-remove-presence-lists.md +++ b/proposals/1819-remove-presence-lists.md @@ -16,6 +16,18 @@ Additionally, no major client has implemented the behaviour to date and the only 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. From 2eae933ed6e03247ee3387ad0db267c19bff9679 Mon Sep 17 00:00:00 2001 From: Neil Johnson Date: Wed, 30 Jan 2019 11:28:53 +0000 Subject: [PATCH 0173/1250] hard wrap to 80 chars --- proposals/1819-remove-presence-lists.md | 41 +++++++++++++++++-------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/proposals/1819-remove-presence-lists.md b/proposals/1819-remove-presence-lists.md index 38c31883..7c542509 100644 --- a/proposals/1819-remove-presence-lists.md +++ b/proposals/1819-remove-presence-lists.md @@ -1,38 +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. +[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. +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. +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) +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. +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. +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. +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) +* [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. +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. +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. From afd399d7d4c75c921252bbb6111436138e1ea27a Mon Sep 17 00:00:00 2001 From: Neil Johnson Date: Wed, 30 Jan 2019 11:43:30 +0000 Subject: [PATCH 0174/1250] remove unused schema defs --- .../event-schemas/m.presence_accept.yaml | 46 ---------------- .../event-schemas/m.presence_deny.yaml | 55 ------------------- .../event-schemas/m.presence_invite.yaml | 45 --------------- 3 files changed, 146 deletions(-) delete mode 100644 api/server-server/definitions/event-schemas/m.presence_accept.yaml delete mode 100644 api/server-server/definitions/event-schemas/m.presence_deny.yaml delete mode 100644 api/server-server/definitions/event-schemas/m.presence_invite.yaml diff --git a/api/server-server/definitions/event-schemas/m.presence_accept.yaml b/api/server-server/definitions/event-schemas/m.presence_accept.yaml deleted file mode 100644 index 3ba78b47..00000000 --- a/api/server-server/definitions/event-schemas/m.presence_accept.yaml +++ /dev/null @@ -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'] diff --git a/api/server-server/definitions/event-schemas/m.presence_deny.yaml b/api/server-server/definitions/event-schemas/m.presence_deny.yaml deleted file mode 100644 index 811c296a..00000000 --- a/api/server-server/definitions/event-schemas/m.presence_deny.yaml +++ /dev/null @@ -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'] diff --git a/api/server-server/definitions/event-schemas/m.presence_invite.yaml b/api/server-server/definitions/event-schemas/m.presence_invite.yaml deleted file mode 100644 index a584897b..00000000 --- a/api/server-server/definitions/event-schemas/m.presence_invite.yaml +++ /dev/null @@ -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'] From ca0baa54df97eb63e8f6713129f62b9affb7c4b1 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 30 Jan 2019 11:26:21 -0500 Subject: [PATCH 0175/1250] various fixes - fix typo - make property name plural since it may contain multiple items - mention that users will appear in sync when they upload keys --- proposals/1756-cross-signing.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 09747011..f3c13f01 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -8,7 +8,7 @@ this user must then verify each key on each of their devices. If Alice has *n* devices, and Bob has *m* devices, then for Alice to be able to communicate with Bob on any of their devices, this involves *n×m* key verifications. -One way to address this is for each user to use a device signing key to signs +One way to address this is for each user to use a device signing key to sign all of their devices. Thus another user who wishes to verify their identity only needs to verify the device signing key and can use the signatures created by the device signing key to verify their devices. @@ -141,7 +141,7 @@ response: // ... } }, - "self_signing_key": { + "self_signing_keys": { "@alice:example.com": { "user_id": "@alice:example.com", "usage": ["self_signing"], @@ -153,6 +153,10 @@ response: } ``` +After uploading self-signing and user-signing keys, the user will show up in +the `changed` property of the `device_lists` field of the sync result of any +others users who share an encrypted room with that user. + Signatures of keys can be uploaded using `/keys/signatures/upload`. For example, Alice signs one of her devices (HIJKLMN), and Bob's self-signing key. @@ -242,11 +246,13 @@ response: } } }, - "self_signing_key": { - "user_id": "@alice:example.com", - "usage": ["self_signing"], - "keys": { - "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key", + "self_signing_keys": { + "@alice:example.com": { + "user_id": "@alice:example.com", + "usage": ["self_signing"], + "keys": { + "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key", + } } } } @@ -266,7 +272,7 @@ Bob's key: // ... } }, - "self_signing_key": { + "self_signing_keys": { "@bob:example.com": { "user_id": "@bob:example.com", "keys": { From 1c0742ed6a5febdaf1ec26d0d0a925af57c25b87 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Wed, 30 Jan 2019 17:08:21 +0000 Subject: [PATCH 0176/1250] MSC 1659 Proposal: Change Event IDs to Hashes (#1659) --- proposals/1659-event-id-as-hashes.md | 130 +++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 proposals/1659-event-id-as-hashes.md diff --git a/proposals/1659-event-id-as-hashes.md b/proposals/1659-event-id-as-hashes.md new file mode 100644 index 00000000..1187d95e --- /dev/null +++ b/proposals/1659-event-id-as-hashes.md @@ -0,0 +1,130 @@ +# Changing Event IDs to be Hashes + +## Motivation + +Having event IDs separate from the hashes leads to issues when a server receives +multiple events with the same event ID but different reference hashes. While +APIs could be changed to better support dealing with this situation, it is +easier and nicer to simply drop the idea of a separate event ID entirely, and +instead use the reference hash of an event as its ID. + +## Identifier Format + +Currently hashes in our event format include the hash name, allowing servers to +choose which hash functions to use. The idea here was to allow a gradual change +between hash functions without the need to globally coordinate shifting from one +hash function to another. + +However now that room versions exist, changing hash functions can be achieved by +bumping the room version. Using this method would allow using a simple string as +the event ID rather than a full structure, significantly easing their usage. + +One side effect of this would be that there would be no indication about which +hash function was actually used, and it would need to be inferred from the room +version. To aid debuggability it may be worth encoding the hash function into +the ID format. + +**Conclusion:** Don't encode the hash function, since the hash will depend on +the version specific redaction algorithm anyway. + +The proposal is therefore that the event IDs are a sha256 hash, encoded using +[unpadded +Base64](https://matrix.org/docs/spec/appendices.html#unpadded-base64), and +prefixed with `$` (to aid distinguishing different types of identifiers). For +example, an event ID might be: `$CD66HAED5npg6074c6pDtLKalHjVfYb2q4Q3LZgrW6o`. + +The hash is calculated in the same way as previous event reference hashes were, +which is: + +1. Redact the event +2. Remove `signatures` field from the event +3. Serialize the event to canonical JSON +4. Compute the hash of the JSON bytes + +Event IDs will no longer be included as part of the event, and so must be +calculated by servers receiving the event. + + +## Changes to Event Formats + +As well as changing the format of event IDs, we also change the format of the +`auth_events` and `prev_events` keys in events to simply be lists of event IDs +(rather than being lists of tuples). + +A full event would therefore look something like (note that this is just an +illustrative example, and that the hashes are not correct): + +```json +{ + "auth_events": [ + "$5hdALbO+xIhzcLTxCkspx5uqry9wO8322h/OI9ApnHE", + "$Ga0DBIICBsWIZbN292ATv8fTHIGGimwjb++w+zcHLRo", + "$zc4ip/DpPI9FZVLM1wN9RLqN19vuVBURmIqAohZ1HXg", + ], + "content": { + "body": "Here is the message content", + "msgtype": "m.message" + }, + "depth": 6, + "hashes": { + "sha256": "M6/LmcMMJKc1AZnNHsuzmf0PfwladVGK2Xbz+sUTN9k" + }, + "origin": "localhost:8800", + "origin_server_ts": 1548094046693, + "prev_events": [ + "$MoOzCuB/sacqHAvgBNOLICiGLZqGT4zB16MSFOuiO0s", + ], + "room_id": "!eBrhCHJWOgqrOizwwW:localhost:8800", + "sender": "@anon-20190121_180719-33:localhost:8800", + "signatures": { + "localhost:8800": { + "ed25519:a_iIHH": "N7hwZjvHyH6r811ebZ4wwLzofKhJuIAtrQzaD3NZbf4WQNijXl5Z2BNB047aWIQCS1JyFOQKPVom4et0q9UOAA" + } + }, + "type": "m.room.message" +} +``` + +## Changes to existing APIs + +All APIs that accept event IDs must accept event IDs in the new format. + +For S2S API, whenever a server needs to parse an event from a request or +response they must either already know the room version *or* be told the room +version in the request/response. There are separate MSCs to update APIs where +necessary. + +For C2S API, the only change clients will see is that the event IDs have changed +format. Clients should already be treating event IDs as opaque strings, so no +changes should be required. Servers must add the `event_id` when sending the +event to clients, however. + +Note that the `auth_events` and `prev_events` fields aren't sent to clients, and +so the changes proposed above won't affect clients. + + +## Protocol Changes + +The `auth_events` and `prev_events` fields on an event need to be changed from a +list of tuples to a list of strings, i.e. remove the old event ID and simply +have the list of hashes. + +The auth rules also need to change: + +- The event no longer needs to be signed by the domain of the event ID (but + still needs to be signed by the sender’s domain) + +- We currently allow redactions if the domain of the redaction event ID + matches the domain of the event ID it is redacting; which allows self + redaction. This check is removed and redaction events are always accepted. + Instead, the redaction event only takes effect and is sent down to clients + if/when the original event is received, and the domain of the events' + senders match. (While this is clearly suboptimal, it is the only practical + suggestion) + + +## Room Version + +There will be a new room version v3 that is the same as v2 except uses the new +event format proposed above. v3 will be marked as 'stable' as defined in [MSC1804](https://github.com/matrix-org/matrix-doc/blob/travis/msc/room-version-client-advertising/proposals/1804-advertising-capable-room-versions.md) + From ff75996524c573f7ca64e617732b94b3017a3d78 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 30 Jan 2019 17:03:03 -0700 Subject: [PATCH 0177/1250] Add specification for room version 3: Event IDs as hashes Original proposal: https://github.com/matrix-org/matrix-doc/pull/1659 Implementation proofs (some traversing of the PR tree may be required to get all of them): * https://github.com/matrix-org/synapse/pull/4483 * https://github.com/matrix-org/synapse/pull/4499 This doesn't intentionally change anything from the proposal. **Implementation details**: The simple part of this is the introduction of a rooms/v3.html document. The somewhat unclear part is the stuff done to the s2s definitions. This pulls `unsigned_pdu` out to `unsigned_pdu_base` (all fields except `event_id`) where it can be reused in `pdu` and `pdu_v3` (for rooms v3). These definitions are further moved into the room version specifications where they can highlight the exact schemas in detail. Version 1 has been updated to include the pre-existing event format, however the core principles of the room have not been changed. The same applies to room version 2. Room versions have immutable core principles once in the spec, otherwise these format changes would land in a pre-existing version. The client-server API event formats will need updating, however that is being punted to a different commit to try and keep these changes reviewable. --- api/server-server/definitions/pdu_v3.yaml | 73 +++++++ .../definitions/unsigned_pdu.yaml | 145 +------------ .../definitions/unsigned_pdu_base.yaml | 151 +++++++++++++ api/server-server/examples/pdu_v3.json | 19 ++ api/server-server/examples/unsigned_pdu.json | 29 +-- .../examples/unsigned_pdu_base.json | 26 +++ specification/index.rst | 1 + specification/rooms/v1.rst | 200 +++++++++++++++++- specification/rooms/v3.rst | 122 +++++++++++ specification/server_server_api.rst | 188 +--------------- specification/targets.yaml | 4 + 11 files changed, 610 insertions(+), 348 deletions(-) create mode 100644 api/server-server/definitions/pdu_v3.yaml create mode 100644 api/server-server/definitions/unsigned_pdu_base.yaml create mode 100644 api/server-server/examples/pdu_v3.json create mode 100644 api/server-server/examples/unsigned_pdu_base.json create mode 100644 specification/rooms/v3.rst diff --git a/api/server-server/definitions/pdu_v3.yaml b/api/server-server/definitions/pdu_v3.yaml new file mode 100644 index 00000000..97747ca8 --- /dev/null +++ b/api/server-server/definitions/pdu_v3.yaml @@ -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. +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 and reference hashes for the authorization events that would + allow this event to be in the room. + example: ["$abase64encodedhash", "$anotherevent"] + prev_events: + type: array + items: + type: string + description: Event ID. + 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. + example: ["$abase64encodedhash", "$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: thishashcoversallfieldsincasthisisredacted + required: ['sha256'] + signatures: + type: object + description: |- + Signatures for the PDU, following the algorithm specified in `Signing Events`_. + example: { + "example.com": { + "ed25519:key_version:": "these86bytesofbase64signaturecoveressentialfieldsincludinghashessocancheckredactedpdus" + } + } + additionalProperties: + type: object + title: Server Signatures + additionalProperties: + type: string + required: + - auth_events + - prev_events + - hashes + - signatures diff --git a/api/server-server/definitions/unsigned_pdu.yaml b/api/server-server/definitions/unsigned_pdu.yaml index c5ad801d..a27a21cd 100644 --- a/api/server-server/definitions/unsigned_pdu.yaml +++ b/api/server-server/definitions/unsigned_pdu.yaml @@ -1,4 +1,4 @@ -# Copyright 2018 New Vector Ltd +# 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. @@ -16,140 +16,13 @@ title: Unsigned Persistent Data Unit description: An unsigned persistent data unit (event) example: $ref: "../examples/unsigned_pdu.json" -properties: - event_id: - type: string - description: The event ID for the PDU. - example: "$a4ecee13e2accdadf56c1025:example.com" - 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": "abase64encodedsha256hashshouldbe43byteslong" - } - properties: - sha256: - type: string - description: The event hash. - example: abase64encodedsha256hashshouldbe43byteslong - 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": "abase64encodedsha256hashshouldbe43byteslong" - } - properties: - sha256: - type: string - description: The event hash. - example: abase64encodedsha256hashshouldbe43byteslong - 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"} +allOf: + - $ref: "unsigned_pdu_base.yaml" + - type: object properties: - age: - type: integer - description: The number of milliseconds that have passed since this message was sent. - example: 4612 - replaces_state: + event_id: 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 + description: The event ID for the PDU. + example: "$a4ecee13e2accdadf56c1025:example.com" + required: + - event_id diff --git a/api/server-server/definitions/unsigned_pdu_base.yaml b/api/server-server/definitions/unsigned_pdu_base.yaml new file mode 100644 index 00000000..d447b3a3 --- /dev/null +++ b/api/server-server/definitions/unsigned_pdu_base.yaml @@ -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": "abase64encodedsha256hashshouldbe43byteslong" + } + properties: + sha256: + type: string + description: The event hash. + example: abase64encodedsha256hashshouldbe43byteslong + 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": "abase64encodedsha256hashshouldbe43byteslong" + } + properties: + sha256: + type: string + description: The event hash. + example: abase64encodedsha256hashshouldbe43byteslong + 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 diff --git a/api/server-server/examples/pdu_v3.json b/api/server-server/examples/pdu_v3.json new file mode 100644 index 00000000..6a454b4e --- /dev/null +++ b/api/server-server/examples/pdu_v3.json @@ -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" + ] +} diff --git a/api/server-server/examples/unsigned_pdu.json b/api/server-server/examples/unsigned_pdu.json index f4d2e749..b886a365 100644 --- a/api/server-server/examples/unsigned_pdu.json +++ b/api/server-server/examples/unsigned_pdu.json @@ -1,27 +1,4 @@ { - "room_id": "!UcYsUzyxTGDxLBEvLy:example.org", - "sender": "@alice:example.com", - "origin": "example.com", - "event_id": "$a4ecee13e2accdadf56c1025:example.com", - "origin_server_ts": 1404838188000, - "depth": 12, - "auth_events": [ - [ - "$af232176:example.org", - {"sha256": "abase64encodedsha256hashshouldbe43byteslong"} - ] - ], - "type": "m.room.message", - "prev_events": [ - [ - "$af232176:example.org", - {"sha256": "abase64encodedsha256hashshouldbe43byteslong"} - ] - ], - "content": { - "key": "value" - }, - "unsigned": { - "age": 4612 - } -} \ No newline at end of file + "$ref": "unsigned_pdu_base.json", + "event_id": "$a4ecee13e2accdadf56c1025:example.com" +} diff --git a/api/server-server/examples/unsigned_pdu_base.json b/api/server-server/examples/unsigned_pdu_base.json new file mode 100644 index 00000000..4826ccef --- /dev/null +++ b/api/server-server/examples/unsigned_pdu_base.json @@ -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 + } +} diff --git a/specification/index.rst b/specification/index.rst index 3893ac4c..fa9ca3d6 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -484,6 +484,7 @@ The available room versions are: * `Version 1 `_ - **Stable**. The current version of most rooms. * `Version 2 `_ - **Stable**. Implements State Resolution Version 2. +* `Version 3 `_ - **Stable**. Introduces a new event format. Specification Versions ---------------------- diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index 37b1b7ce..e09420e4 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -77,7 +77,7 @@ results of the resolution so far. * 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 + 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. @@ -95,4 +95,200 @@ A *conflict* occurs between states where those states have different affected are said to be *conflicting* events. -.. _`authorization rules`: ../server_server/unstable.html#authorization-rules +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 intial 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/unstable.html#auth-events-selection +.. _`Signing Events`: ../../server_server/unstable.html#signing-events diff --git a/specification/rooms/v3.rst b/specification/rooms/v3.rst new file mode 100644 index 00000000..22276ab3 --- /dev/null +++ b/specification/rooms/v3.rst @@ -0,0 +1,122 @@ +.. 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 off of `version 2 `_ 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. + + +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 `_, +and the event format defined here. Other event formats and applicable algorithms +may be used in other room versions. + +Event IDs +~~~~~~~~~ + +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 must be a sha256 hash of the event, encoded using `Unpadded Base64`_ +and prefixed with `$`. For example, an event ID might be +``$CD66HAED5npg6074c6pDtLKalHjVfYb2q4Q3LZgrW6o``. + +The hash itself is calculated the same as previous reference hashes are: + +1. Redact the event. +2. Remove the `signatures` field from the event. +3. Serialize the event into `Canonical JSON`_. +4. Compute the hash of the JSON bytes. + +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 servers are not communicating the event ID over the wire to each other, +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. + +* Previously, redactions were allowed if the sender's domain matched the domain + in the event ID it was redacting, allowing self redaction. This check is removed + and redaction events are always accepted. Redaction events only take effect + when the original event is received, and the domain of the each event matches. + Servers should not send redactions down to clients until the redaction has + taken effect. + +The remaining rules are the same as room version 1. + + +.. _`Unpadded Base64`: ../../appendices.html#unpadded-base64 +.. _`Canonical JSON`: ../../appendices.html#canonical-json +.. _`Signing Events`: ../../server_server/unstable.html#signing-events diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index a63bf0a6..8f021e62 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -327,7 +327,7 @@ following subset of the room state: ``m.room.third_party_invite`` event with ``state_key`` matching ``content.third_party_invite.signed.token``, if any. -{{definition_ss_pdu}} +For a full schema of what a PDU looks like, see the `room version specification`_. Checks performed on receipt of a PDU ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -379,189 +379,9 @@ Authorization rules The rules governing whether an event is authorized depends on a set of state. A given event is checked multiple times against different sets of state, as -specified above. 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 above. - -#. 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 intial 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. - +specified above. Each room version can have a different algorithm for how the +rules work, and which rules are applied. For more detailed information, please +see the `room version specification`_. Rejection +++++++++ diff --git a/specification/targets.yaml b/specification/targets.yaml index f78d124b..830449ae 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -34,6 +34,10 @@ targets: files: - rooms/v2.rst version_label: v2 + rooms@v3: # this is translated to be rooms/v3.html + files: + - rooms/v3.rst + version_label: v3 appendices: files: - appendices.rst From ccce6c196d9a941b8ceeb6b47c2781bb65cfc1ac Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 30 Jan 2019 19:43:55 -0700 Subject: [PATCH 0178/1250] Specify how capabilities work in the c2s API Original proposals: * https://github.com/matrix-org/matrix-doc/pull/1753 * https://github.com/matrix-org/matrix-doc/pull/1804 Implementation proof: * https://github.com/matrix-org/synapse/pull/4472 * https://github.com/matrix-org/matrix-js-sdk/pull/830 There is one change to MSC1753 which is included in this commit. MSC1804 remains unchanged. In the original proposal, the change password capability being present was an indication that password changes were possible. It was found that this doesn't really communicate the state very well to clients in that lack of a capability (or a 404, etc) would mean that users would erroneously not be able to change their passwords. A simple boolean flag was added to assist clients in detecting this capability. --- api/client-server/capabilities.yaml | 108 ++++++++++++++++++ .../client_server/newsfragments/1829.feature | 1 + proposals/1753-capabilities.md | 6 +- specification/client_server_api.rst | 101 ++++++++++++++++ 4 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 api/client-server/capabilities.yaml create mode 100644 changelogs/client_server/newsfragments/1829.feature diff --git a/api/client-server/capabilities.yaml b/api/client-server/capabilities.yaml new file mode 100644 index 00000000..acec600d --- /dev/null +++ b/api/client-server/capabilities.yaml @@ -0,0 +1,108 @@ +# 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"] + additionalProperties: + type: object + description: |- + The custom capabilities the server supports, using the + Java package naming convention. + 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 diff --git a/changelogs/client_server/newsfragments/1829.feature b/changelogs/client_server/newsfragments/1829.feature new file mode 100644 index 00000000..107291f3 --- /dev/null +++ b/changelogs/client_server/newsfragments/1829.feature @@ -0,0 +1 @@ +Support optional features by having clients query for capabilities. diff --git a/proposals/1753-capabilities.md b/proposals/1753-capabilities.md index ec5169ab..5a56eaca 100644 --- a/proposals/1753-capabilities.md +++ b/proposals/1753-capabilities.md @@ -40,8 +40,10 @@ As a starting point, a single capability identifier is proposed: change the user's password via the `POST /_matrix/client/r0/account/password` API. -The value of the `capabilities` object in the response should be the empty -object. +The value of the `capabilities` object in the response should contain a single +boolean flag, `enabled`, to indicate whether a password change is possible. If +the capability is not listed, the client should assume that password changes +are possible. ### Fallback behaviour diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 4df83814..40ac5588 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1070,6 +1070,107 @@ Current account information {{whoami_cs_http_api}} +Capabilities negotiation +------------------------ + +A homeserver may not support certain operations and clients must be able to +query for what the homeserver can and can't offer. For example, a homeserver +may not support users changing their password as it is configured to perform +authentication against an external system. + +The capabilities advertised through this system are intended to advertise +functionality which is optional in the API, or which depend in some way on +the state of the user or server. This system should not be used to advertise +unstable or experimental features - this is better done by the ``/versions`` +endpoint. + +Some examples of what a reasonable capability could be are: + +* Whether the server supports user presence. + +* Whether the server supports optional features, such as the user or room + directories. + +* The rate limits or file type restrictions imposed on clients by the server. + +Some examples of what should **not** be a capability are: + +* Whether the server supports a feature in the ``unstable`` specification. + +* Media size limits - these are handled by the ``/media/%CLIENT_MAJOR_VERSION%/config`` + API. + +* Optional encodings or alternative transports for communicating with the + server. + +Capabilities prefixed with ``m.`` are reserved for definition in the Matrix +specification while other values may be used by servers using the Java package +naming convention. The capabilities supported by the Matrix specification are +defined later in this section. + +{{capabilities_cs_http_api}} + + +``m.change_password`` capability +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This capability has a single flag, ``enabled``, which indicates whether or not +the user can use the ``/account/password`` API to change their password. If not +present, the client should assume that password changes are possible via the +API. When present, clients SHOULD respect the capability's ``enabled`` flag +and indicate to the user if they are unable to change their password. + +An example of the capability API's response for this capability is:: + + { + "capabilities": { + "m.change_password": { + "enabled": false + } + } + } + + +``m.room_versions`` capability +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This capability describes the default and available room versions a server +supports, and at what level of stability. Clients should make use of this +capability to determine if users need to be encouraged to upgrade their rooms. + +An example of the capability API's response for this capability is:: + + { + "capabilities": { + "m.room_versions": { + "default": "1", + "available": { + "1": "stable", + "2": "stable", + "3": "unstable", + "custom-version": "unstable" + } + } + } + } + +This capability mirrors the same restrictions of `room versions`_ to describe +which versions are stable and unstable. Clients should assume that the ``default`` +version is ``stable``. Any version not explicitly labelled as ``stable`` in the +``available`` versions is to be treated as ``unstable``. For example, a version +listed as ``future-stable`` should be treated as ``unstable``. + +The ``default`` version is the version the server is using to create new rooms. +Clients should encourage users with sufficient permissions in a room to upgrade +their room to the ``default`` version when the room is using an ``unstable`` +version. + +When this capability is not listed, clients should use ``"1"`` as the default +and only stable ``available`` room version. + +.. _`room versions`: ../index.html#room-versions + + Pagination ---------- From 9193d57dfdbc176d65f7582e22faa667bac81477 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 30 Jan 2019 19:47:16 -0700 Subject: [PATCH 0179/1250] full stop --- api/client-server/capabilities.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client-server/capabilities.yaml b/api/client-server/capabilities.yaml index acec600d..63a3ea91 100644 --- a/api/client-server/capabilities.yaml +++ b/api/client-server/capabilities.yaml @@ -38,7 +38,7 @@ paths: responses: 200: description: - The capabilities of the server + The capabilities of the server. examples: application/json: { "capabilities": { From 0347e873efca4f80460492bdff9271601c7bc341 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 30 Jan 2019 22:11:31 -0700 Subject: [PATCH 0180/1250] Specify .well-known s2s discovery and X.509 validation Original proposals: * https://github.com/matrix-org/matrix-doc/pull/1708 (note: the JSON requirements were softened by https://github.com/matrix-org/matrix-doc/pull/1824) * https://github.com/matrix-org/matrix-doc/pull/1711 Implementation proofs: * https://github.com/matrix-org/synapse/pull/4489 * No explicit PRs for MSC1711 could be found, however Synapse is known to implement it. There are no intentional changes which differ from the proposals in this commit, however the author has relied upon various historical conversations outside of the proposals to gain the required context. Inaccuracies introduced by the author are purely accidental. --- api/server-server/definitions/keys.yaml | 23 +--- api/server-server/examples/server_key.json | 5 +- api/server-server/wellknown.yaml | 53 +++++++++ specification/server_server_api.rst | 124 ++++++++++++++++----- 4 files changed, 155 insertions(+), 50 deletions(-) create mode 100644 api/server-server/wellknown.yaml diff --git a/api/server-server/definitions/keys.yaml b/api/server-server/definitions/keys.yaml index 738e9e46..06619641 100644 --- a/api/server-server/definitions/keys.yaml +++ b/api/server-server/definitions/keys.yaml @@ -25,9 +25,9 @@ properties: verify_keys: type: object description: |- - Public keys of the homeserver for verifying digital signatures. - - The object's key is the algorithm and version combined (``ed25519`` being the + Public keys of the homeserver for verifying digital signatures. + + The object's key is the algorithm and version combined (``ed25519`` being the algorithm and ``abc123`` being the version in the example below). Together, this forms the Key ID. The version must have characters matching the regular expression ``[a-zA-Z0-9_]``. @@ -49,9 +49,9 @@ properties: old_verify_keys: type: object description: |- - The public keys that the server used to use and when it stopped using them. - - The object's key is the algorithm and version combined (``ed25519`` being the + The public keys that the server used to use and when it stopped using them. + + The object's key is the algorithm and version combined (``ed25519`` being the algorithm and ``0ldK3y`` being the version in the example below). Together, this forms the Key ID. The version must have characters matching the regular expression ``[a-zA-Z0-9_]``. @@ -90,17 +90,6 @@ properties: additionalProperties: type: string name: Encoded Signature Verification Key - tls_fingerprints: - type: array - description: Hashes of X.509 TLS certificates used by this server. - items: - type: object - title: TLS Fingerprint - properties: - sha256: - type: string - description: The `Unpadded Base64`_ encoded fingerprint. - example: "VGhpcyBpcyBoYXNoIHdoaWNoIHNob3VsZCBiZSBieXRlcw" valid_until_ts: type: integer format: int64 diff --git a/api/server-server/examples/server_key.json b/api/server-server/examples/server_key.json index bebd8445..ffdfcb5a 100644 --- a/api/server-server/examples/server_key.json +++ b/api/server-server/examples/server_key.json @@ -16,8 +16,5 @@ "ed25519:auto2": "VGhpcyBzaG91bGQgYWN0dWFsbHkgYmUgYSBzaWduYXR1cmU" } }, - "tls_fingerprints": [{ - "sha256": "VGhpcyBpcyBoYXNoIHdoaWNoIHNob3VsZCBiZSBieXRlcw" - }], "valid_until_ts": 1652262000000 -} \ No newline at end of file +} diff --git a/api/server-server/wellknown.yaml b/api/server-server/wellknown.yaml new file mode 100644 index 00000000..273da7eb --- /dev/null +++ b/api/server-server/wellknown.yaml @@ -0,0 +1,53 @@ +# 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 must result in server discovery failure (no + attempts should be made to continue finding an IP address/port number to connect + to). + 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>`_. diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index a63bf0a6..c88bd7ae 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -90,35 +90,94 @@ Server discovery Resolving server names ~~~~~~~~~~~~~~~~~~~~~~ -Each matrix homeserver is identified by a server name consisting of a hostname +Each Matrix homeserver is identified by a server name consisting of a hostname and an optional port, as described by the `grammar -<../appendices.html#server-name>`_. Server names should be resolved to an IP -address and port using the following process: - -* If the hostname is an IP literal, then that IP address should be used, - together with the given port number, or 8448 if no port is given. - -* Otherwise, if the port is present, then an IP address is discovered by - looking up an AAAA or A record for the hostname, and the specified port is - used. - -* If the hostname is not an IP literal and no port is given, the server is - discovered by first looking up a ``_matrix._tcp`` SRV record for the - hostname, which may give a hostname (to be looked up using AAAA or A queries) - and port. If the SRV record does not exist, then the server is discovered by - looking up an AAAA or A record on the hostname and taking the default - fallback port number of 8448. - - Homeservers may use SRV records to load balance requests between multiple TLS - endpoints or to failover to another endpoint if an endpoint fails. - -When making requests to servers, use the hostname of the target server in the -``Host`` header, regardless of any hostname given in the SRV record. For -example, if the server name is ``example.org``, and the SRV record resolves to -``matrix.example.org``, the ``Host`` header in the request should be -``example.org``. If an explicit port was given in the server name, it should be -included in the ``Host`` header; otherwise, no port number should be given in -the ``Host`` header. +<../appendices.html#server-name>`_. Where applicable, a delegated server name +uses the same grammar. + +Server names are resolved to an IP address and port to connect to, and have +various conditions affecting which certificates and ``Host`` headers to send. +The process overall is as follows: + +.. Note from the author: The repetitive "use this Host header and this cert" + comments are intentional. The process is overall quite complicated, and + explaining explicitly what requests look like at each step helps ease the + understanding and ensure everyone is on the same page. Implementations + are of course welcome to realize where the process can be optimized, and + do so - just ensure that the result is the same! + +1. If the hostname is an IP literal, then that IP address should be used, + together with the given port number, or 8448 if no port is given. A + valid TLS certificate must be provided by the target server for the + IP address on all requests. Requests must be made with a ``Host`` + header containing the IP address, without port. + +2. If the hostname is not an IP literal, a server is found by resolving + an SRV record for ``_matrix._tcp.``. This may result in + a hostname (to be resolved using AAAA or A records) and port. Requests + are made to the resolved IP address and port, using 8448 as a default + port, with a ``Host`` header of ````. A valid TLS certificate + for ```` must be provided by the target server on all requests. + +3. If the SRV record yielded no results, a ``/.well-known`` request is + made to the hostname (using port 443 exclusively, ignoring the port + provided in the server name). The target must present a valid TLS + certificate for the hostname, and a ``Host`` header containing the + hostname is used to make the request. The schema of the ``/.well-known`` + request is later in this section. Assuming the response is valid, + the ``m.server`` property is parsed as ``[:]`` + and processed as follows: + + * If ```` is an IP literal, then that IP address + should be used together with the ```` or 8448 if no + port is provided. A valid TLS certificate must be provided by the + target server for that IP address. Requests must be made with a + ``Host`` header containing the IP address, without port. + + * If ```` is not an IP literal, and ```` + is present, an IP address is disovered by looking up an AAAA or A + record for ````. The resulting IP address is + used, alongside the ````, to make requests with a + ``Host`` header of ````. A valid TLS certificate + must be provided by the target server for ````. + + * If ```` is not an IP literal and no + ```` is present, an SRV record is looked up for + ``_matrix._tcp.``. This may result in another + hostname (to be resolved using AAAA or A records) and port. Requests + should be made to the resolved IP address and port with a ``Host`` + header containing the ````. Additionally, a + valid TLS certificate must be provided by the target server for the + ````. + + * If no SRV record is found, an IP address is resolved using AAAA + or A records. Requests are then made to the resolve IP address + and a port of 8448, using a ``Host`` header of ````. + A valid TLS certificate for ```` must be + provided by the target server. + +4. If the `/.well-known` request was invalid or returned an error response, + and the SRV record was not found, an IP address is resolved using AAAA + and A records. Requests are made to the resolved IP address using port + 8448 and a ``Host`` header containing the ````. A valid TLS + certificate for ```` must be provided by the target server + on all requests. + + +The TLS certificate provided by the target server must be present on all +requests made to the server. The TLS certificate must be signed by a known +Certificate Authority. Servers are ultimately responsible for determining +the trusted Certificate Authorities, however are strongly encouraged to +rely on the operating system's judgement. Servers can offer administrators +a means to override the trusted authorities list. Servers can additionally +skip the certificate validation for a given whitelist of domains or netmasks +for the purposes of testing or in networks where verification is done +elsewhere, such as with ``.onion`` addresses. + +Servers are encouraged to make use of the +`Certificate Transparency `_ project. + +{{wellknown_ss_http_api}} Server implementation ~~~~~~~~~~~~~~~~~~~~~~ @@ -130,9 +189,16 @@ Retrieving server keys .. NOTE:: There was once a "version 1" of the key exchange. It has been removed from the - specification due to lack of significance. It may be reviewed `here + specification due to lack of significance. It may be reviewed `from the historical draft `_. +.. NOTE:: + Older drafts of this specification made use of a different style of key verification, + however for reasons discussed in `MSC1711 `_, + the approach was removed from the initial version of the specification. The older + draft may be reviewed `thanks to web.archive.org + `_. + Each homeserver publishes its public keys under ``/_matrix/key/v2/server/{keyId}``. Homeservers query for keys by either getting ``/_matrix/key/v2/server/{keyId}`` directly or by querying an intermediate notary server using a From c888f3f080a12393abae7577eea1038fe1d44c79 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 00:09:30 -0700 Subject: [PATCH 0181/1250] Make example strings more legible --- api/server-server/definitions/pdu.yaml | 6 +++--- api/server-server/definitions/pdu_v3.yaml | 10 +++++----- api/server-server/definitions/unsigned_pdu_base.yaml | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/api/server-server/definitions/pdu.yaml b/api/server-server/definitions/pdu.yaml index d86b8538..93de20e6 100644 --- a/api/server-server/definitions/pdu.yaml +++ b/api/server-server/definitions/pdu.yaml @@ -26,13 +26,13 @@ allOf: description: |- Content hashes of the PDU, following the algorithm specified in `Signing Events`_. example: { - "sha256": "thishashcoversallfieldsincasethisisredacted" + "sha256": "ThisHashCoversAllFieldsInCaseThisIsRedacted" } properties: sha256: type: string description: The hash. - example: thishashcoversallfieldsincasthisisredacted + example: ThisHashCoversAllFieldsInCaseThisIsRedacted required: ['sha256'] signatures: type: object @@ -40,7 +40,7 @@ allOf: Signatures for the PDU, following the algorithm specified in `Signing Events`_. example: { "example.com": { - "ed25519:key_version:": "these86bytesofbase64signaturecoveressentialfieldsincludinghashessocancheckredactedpdus" + "ed25519:key_version:": "86BytesOfUnpaddedBase64ToCoverAllFieldsIncludingHashes" } } additionalProperties: diff --git a/api/server-server/definitions/pdu_v3.yaml b/api/server-server/definitions/pdu_v3.yaml index 97747ca8..40093962 100644 --- a/api/server-server/definitions/pdu_v3.yaml +++ b/api/server-server/definitions/pdu_v3.yaml @@ -28,7 +28,7 @@ allOf: description: |- Event IDs and reference hashes for the authorization events that would allow this event to be in the room. - example: ["$abase64encodedhash", "$anotherevent"] + example: ["$base64EncodedHash", "$AnotherEvent"] prev_events: type: array items: @@ -37,20 +37,20 @@ allOf: 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. - example: ["$abase64encodedhash", "$anotherevent"] + 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" + "sha256": "ThisHashCoversAllFieldsInCaseThisIsRedacted" } properties: sha256: type: string description: The hash. - example: thishashcoversallfieldsincasthisisredacted + example: ThisHashCoversAllFieldsInCaseThisIsRedacted required: ['sha256'] signatures: type: object @@ -58,7 +58,7 @@ allOf: Signatures for the PDU, following the algorithm specified in `Signing Events`_. example: { "example.com": { - "ed25519:key_version:": "these86bytesofbase64signaturecoveressentialfieldsincludinghashessocancheckredactedpdus" + "ed25519:key_version:": "86BytesOfUnpaddedBase64ToCoverAllFieldsIncludingHashes" } } additionalProperties: diff --git a/api/server-server/definitions/unsigned_pdu_base.yaml b/api/server-server/definitions/unsigned_pdu_base.yaml index d447b3a3..283e4fed 100644 --- a/api/server-server/definitions/unsigned_pdu_base.yaml +++ b/api/server-server/definitions/unsigned_pdu_base.yaml @@ -64,13 +64,13 @@ properties: - type: object title: Event Hash example: { - "sha256": "abase64encodedsha256hashshouldbe43byteslong" + "sha256": "Base64EncodedSha256HashesShouldBe43BytesLong" } properties: sha256: type: string description: The event hash. - example: abase64encodedsha256hashshouldbe43byteslong + example: Base64EncodedSha256HashesShouldBe43BytesLong required: ['sha256'] depth: type: integer @@ -95,13 +95,13 @@ properties: - type: object title: Event Hash example: { - "sha256": "abase64encodedsha256hashshouldbe43byteslong" + "sha256": "Base64EncodedSha256HashesShouldBe43BytesLong" } properties: sha256: type: string description: The event hash. - example: abase64encodedsha256hashshouldbe43byteslong + example: Base64EncodedSha256HashesShouldBe43BytesLong required: ['sha256'] redacts: type: string From 0e90cf6a0c8529cb17dd5a4ed57bc2e221667a02 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 09:38:58 -0700 Subject: [PATCH 0182/1250] Proposal to change the order of .well-known and SRV discovery techniques --- proposals/1831-srv-after-wellknown.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 proposals/1831-srv-after-wellknown.md diff --git a/proposals/1831-srv-after-wellknown.md b/proposals/1831-srv-after-wellknown.md new file mode 100644 index 00000000..53f5ddac --- /dev/null +++ b/proposals/1831-srv-after-wellknown.md @@ -0,0 +1,19 @@ +# 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 top level domain, and an SRV record is used for backwards compatibility reasons. + +## 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. From ab7876cbef86ba669710c1a07aa4560764361cfc Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 09:55:58 -0700 Subject: [PATCH 0183/1250] Update 1831-srv-after-wellknown.md --- proposals/1831-srv-after-wellknown.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1831-srv-after-wellknown.md b/proposals/1831-srv-after-wellknown.md index 53f5ddac..f1b125f2 100644 --- a/proposals/1831-srv-after-wellknown.md +++ b/proposals/1831-srv-after-wellknown.md @@ -4,7 +4,7 @@ Currently there is a logistical error proposed by [MSC1708](https://github.com/m 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 top level domain, and an SRV record is used for backwards compatibility reasons. +the domain, and an SRV record is used for backwards compatibility reasons. ## Proposal From 2fe6b2cb5c1fc93088378ee86c639582acac1a95 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 10:53:06 -0700 Subject: [PATCH 0184/1250] Plagiarize from richvdh for a better explanation --- proposals/1831-srv-after-wellknown.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/proposals/1831-srv-after-wellknown.md b/proposals/1831-srv-after-wellknown.md index 53f5ddac..c0f8ef7a 100644 --- a/proposals/1831-srv-after-wellknown.md +++ b/proposals/1831-srv-after-wellknown.md @@ -6,6 +6,12 @@ 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 top level 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 From d2f012f4ea8f525ace16f75f7abaa5ce3351e3cd Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 11:17:56 -0700 Subject: [PATCH 0185/1250] Incorporate MSC1831 Original proposal: https://github.com/matrix-org/matrix-doc/pull/1831 Implementation proof: pending --- specification/server_server_api.rst | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index c88bd7ae..e680c792 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -112,14 +112,7 @@ The process overall is as follows: IP address on all requests. Requests must be made with a ``Host`` header containing the IP address, without port. -2. If the hostname is not an IP literal, a server is found by resolving - an SRV record for ``_matrix._tcp.``. This may result in - a hostname (to be resolved using AAAA or A records) and port. Requests - are made to the resolved IP address and port, using 8448 as a default - port, with a ``Host`` header of ````. A valid TLS certificate - for ```` must be provided by the target server on all requests. - -3. If the SRV record yielded no results, a ``/.well-known`` request is +2. If the hostname is not an IP literal, a ``/.well-known`` request is made to the hostname (using port 443 exclusively, ignoring the port provided in the server name). The target must present a valid TLS certificate for the hostname, and a ``Host`` header containing the @@ -156,12 +149,19 @@ The process overall is as follows: A valid TLS certificate for ```` must be provided by the target server. -4. If the `/.well-known` request was invalid or returned an error response, - and the SRV record was not found, an IP address is resolved using AAAA - and A records. Requests are made to the resolved IP address using port - 8448 and a ``Host`` header containing the ````. A valid TLS - certificate for ```` must be provided by the target server - on all requests. +3. If the `/.well-known` request returned an error response, a server is + found by resolving an SRV record for ``_matrix._tcp.``. This + may result in a hostname (to be resolved using AAAA or A records) and + port. Requests are made to the resolved IP address and port, using 8448 + as a default port, with a ``Host`` header of ````. A valid TLS + certificate for ```` must be provided by the target server on + all requests. + +4. If the `/.well-known` request returned an error response, and the SRV + record was not found, an IP address is resolved using AAAA and A records. + Requests are made to the resolved IP address using port 8448 and a ``Host`` + header containing the ````. A valid TLS certificate for + ```` must be provided by the target server on all requests. The TLS certificate provided by the target server must be present on all From 48e4d6e412077a48aeb39d374dae17e60f8e64df Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 12:27:09 -0700 Subject: [PATCH 0186/1250] Document domain reuse concerns Fixes https://github.com/matrix-org/matrix-doc/issues/1783 --- specification/server_server_api.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index a63bf0a6..b65060d9 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -1303,6 +1303,16 @@ Example code known hash functions like SHA-256 when none of the keys have been redacted]] +Security considerations +----------------------- + +When a domain's ownership changes, the new controller of the domain can masquerade +as the previous owner, receiving messages (similarly to email) and request past +messages from other servers. In the future, proposals like +`MSC1228 `_ will address this +issue. + + .. |/query/directory| replace:: ``/query/directory`` .. _/query/directory: #get-matrix-federation-v1-query-directory From b971bcee7d42e0a497c7476d3272ac80c16e4057 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 16:24:07 -0700 Subject: [PATCH 0187/1250] Accurately represent the 3 proposals and provide more detail --- specification/server_server_api.rst | 57 +++++++++++++++-------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index e680c792..380fe617 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -112,14 +112,22 @@ The process overall is as follows: IP address on all requests. Requests must be made with a ``Host`` header containing the IP address, without port. -2. If the hostname is not an IP literal, a ``/.well-known`` request is +2. If the hostname is not an IP literal, and has an explicit port given, + resolve the IP address using AAAA or A records. Requests are made to + the resolved IP address and given port with a ``Host`` header of the + original hostname (without port). A valid TLS certificate must be + provided by the target server for the hostname. + +3. If the hostname is not an IP literal, a ``/.well-known`` request is made to the hostname (using port 443 exclusively, ignoring the port - provided in the server name). The target must present a valid TLS - certificate for the hostname, and a ``Host`` header containing the - hostname is used to make the request. The schema of the ``/.well-known`` - request is later in this section. Assuming the response is valid, - the ``m.server`` property is parsed as ``[:]`` - and processed as follows: + provided in the server name). This is done as a plain HTTPS request + which follows 30x redirects, being careful to avoid redirect loops. + The schema of the ``/.well-known`` request is later in this section. + If the response is invalid (bad JSON, missing properties, etc), + attempts to connect to the target server are aborted - no connections + should be attempted. If the response is valid, the ``m.server`` property + is parsed as ``[:]`` and processed + as follows: * If ```` is an IP literal, then that IP address should be used together with the ```` or 8448 if no @@ -131,8 +139,8 @@ The process overall is as follows: is present, an IP address is disovered by looking up an AAAA or A record for ````. The resulting IP address is used, alongside the ````, to make requests with a - ``Host`` header of ````. A valid TLS certificate - must be provided by the target server for ````. + ``Host`` header of ``:``. A valid + TLS certificate must be provided by the target server for ````. * If ```` is not an IP literal and no ```` is present, an SRV record is looked up for @@ -143,36 +151,38 @@ The process overall is as follows: valid TLS certificate must be provided by the target server for the ````. - * If no SRV record is found, an IP address is resolved using AAAA - or A records. Requests are then made to the resolve IP address - and a port of 8448, using a ``Host`` header of ````. - A valid TLS certificate for ```` must be - provided by the target server. + * If no SRV record is found, an IP address is resolved using AAAA + or A records. Requests are then made to the resolve IP address + and a port of 8448, using a ``Host`` header of ````. + A valid TLS certificate for ```` must be + provided by the target server. -3. If the `/.well-known` request returned an error response, a server is - found by resolving an SRV record for ``_matrix._tcp.``. This +4. If the `/.well-known` request did not result in a 200 response, a server + is found by resolving an SRV record for ``_matrix._tcp.``. This may result in a hostname (to be resolved using AAAA or A records) and port. Requests are made to the resolved IP address and port, using 8448 as a default port, with a ``Host`` header of ````. A valid TLS certificate for ```` must be provided by the target server on all requests. -4. If the `/.well-known` request returned an error response, and the SRV +5. If the `/.well-known` request returned an error response, and the SRV record was not found, an IP address is resolved using AAAA and A records. Requests are made to the resolved IP address using port 8448 and a ``Host`` header containing the ````. A valid TLS certificate for ```` must be provided by the target server on all requests. -The TLS certificate provided by the target server must be present on all -requests made to the server. The TLS certificate must be signed by a known +The TLS certificate provided by the target server must be signed by a known Certificate Authority. Servers are ultimately responsible for determining the trusted Certificate Authorities, however are strongly encouraged to rely on the operating system's judgement. Servers can offer administrators a means to override the trusted authorities list. Servers can additionally skip the certificate validation for a given whitelist of domains or netmasks for the purposes of testing or in networks where verification is done -elsewhere, such as with ``.onion`` addresses. +elsewhere, such as with ``.onion`` addresses. Servers should respect SNI +when making requests where possible: a SNI should be sent for the certificate +which is expected, unless that certificate is expected to be an IP address in +which case SNI is not supported and should not be sent. Servers are encouraged to make use of the `Certificate Transparency `_ project. @@ -192,13 +202,6 @@ Retrieving server keys specification due to lack of significance. It may be reviewed `from the historical draft `_. -.. NOTE:: - Older drafts of this specification made use of a different style of key verification, - however for reasons discussed in `MSC1711 `_, - the approach was removed from the initial version of the specification. The older - draft may be reviewed `thanks to web.archive.org - `_. - Each homeserver publishes its public keys under ``/_matrix/key/v2/server/{keyId}``. Homeservers query for keys by either getting ``/_matrix/key/v2/server/{keyId}`` directly or by querying an intermediate notary server using a From 3c17a0e53bad28cc38f2df0828e83a71b2f8e1ac Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 16:29:07 -0700 Subject: [PATCH 0188/1250] Mention caching --- specification/server_server_api.rst | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 380fe617..a2672e92 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -122,12 +122,19 @@ The process overall is as follows: made to the hostname (using port 443 exclusively, ignoring the port provided in the server name). This is done as a plain HTTPS request which follows 30x redirects, being careful to avoid redirect loops. - The schema of the ``/.well-known`` request is later in this section. - If the response is invalid (bad JSON, missing properties, etc), - attempts to connect to the target server are aborted - no connections - should be attempted. If the response is valid, the ``m.server`` property - is parsed as ``[:]`` and processed - as follows: + Responses (successful or otherwise) to the ``/.well-known`` endpoint + should be cached by the requesting server. Servers should respect + the cache control headers present on the response, or use a sensible + default when headers are not present. The recommended sensible default + is 24 hours. Servers should additionally impose a maximum cache time + for responses: 48 hours is recommended. Errors are recommended to be + cached for up to an hour, and servers are encouraged to exponentially + back off for repeated failures. The schema of the ``/.well-known`` + request is later in this section. If the response is invalid (bad JSON, + missing properties, etc), attempts to connect to the target server are + aborted - no connections should be attempted. If the response is valid, + the ``m.server`` property is parsed as ``[:]`` + and processed as follows: * If ```` is an IP literal, then that IP address should be used together with the ```` or 8448 if no From 01556e5b179ab5fd9beaf1c07d6cc327d5fadde3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 16:44:24 -0700 Subject: [PATCH 0189/1250] Clarifications and bug fixes in how v3 rooms work --- api/server-server/definitions/pdu.yaml | 4 +- api/server-server/definitions/pdu_v3.yaml | 8 ++-- specification/index.rst | 2 +- specification/rooms/v3.rst | 47 +++++++++++++---------- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/api/server-server/definitions/pdu.yaml b/api/server-server/definitions/pdu.yaml index 93de20e6..87064c22 100644 --- a/api/server-server/definitions/pdu.yaml +++ b/api/server-server/definitions/pdu.yaml @@ -13,7 +13,7 @@ # limitations under the License. type: object title: Persistent Data Unit -description: A persistent data unit (event) +description: A persistent data unit (event) for room versions 1 and 2. example: $ref: "../examples/pdu.json" allOf: @@ -40,7 +40,7 @@ allOf: Signatures for the PDU, following the algorithm specified in `Signing Events`_. example: { "example.com": { - "ed25519:key_version:": "86BytesOfUnpaddedBase64ToCoverAllFieldsIncludingHashes" + "ed25519:key_version:": "86BytesOfSignatureOfTheRedactedEvent" } } additionalProperties: diff --git a/api/server-server/definitions/pdu_v3.yaml b/api/server-server/definitions/pdu_v3.yaml index 40093962..8d41fbda 100644 --- a/api/server-server/definitions/pdu_v3.yaml +++ b/api/server-server/definitions/pdu_v3.yaml @@ -13,7 +13,7 @@ # limitations under the License. type: object title: Persistent Data Unit -description: A persistent data unit (event) for room version 3. +description: A persistent data unit (event) for room version 3 and beyond. example: $ref: "../examples/pdu_v3.json" allOf: @@ -26,7 +26,7 @@ allOf: type: string description: Event ID. description: |- - Event IDs and reference hashes for the authorization events that would + Event IDs for the authorization events that would allow this event to be in the room. example: ["$base64EncodedHash", "$AnotherEvent"] prev_events: @@ -35,7 +35,7 @@ allOf: type: string description: Event ID. description: |- - Event IDs and reference hashes for the most recent events in the room + 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: @@ -58,7 +58,7 @@ allOf: Signatures for the PDU, following the algorithm specified in `Signing Events`_. example: { "example.com": { - "ed25519:key_version:": "86BytesOfUnpaddedBase64ToCoverAllFieldsIncludingHashes" + "ed25519:key_version:": "86BytesOfSignatureOfTheRedactedEvent" } } additionalProperties: diff --git a/specification/index.rst b/specification/index.rst index fa9ca3d6..05b85ab7 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -484,7 +484,7 @@ The available room versions are: * `Version 1 `_ - **Stable**. The current version of most rooms. * `Version 2 `_ - **Stable**. Implements State Resolution Version 2. -* `Version 3 `_ - **Stable**. Introduces a new event format. +* `Version 3 `_ - **Stable**. Introduces events whose IDs are the event's hash. Specification Versions ---------------------- diff --git a/specification/rooms/v3.rst b/specification/rooms/v3.rst index 22276ab3..3f383e7b 100644 --- a/specification/rooms/v3.rst +++ b/specification/rooms/v3.rst @@ -15,7 +15,7 @@ Room Version 3 ============== -This room version builds off of `version 2 `_ with an improved event format. +This room version builds on `version 2 `_ with an improved event format. .. note: All requirements listed in this room version specification are scoped to rooms @@ -49,29 +49,32 @@ Server implementation components Room version 3 uses the state resolution algorithm defined in `room version 2 `_, -and the event format defined here. Other event formats and applicable algorithms -may be used in other room versions. +and the event format defined here. Event IDs ~~~~~~~~~ -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. +.. admonition:: Rationale -The event ID must be a sha256 hash of the event, encoded using `Unpadded Base64`_ -and prefixed with `$`. For example, an event ID might be -``$CD66HAED5npg6074c6pDtLKalHjVfYb2q4Q3LZgrW6o``. + 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 hash itself is calculated the same as previous reference hashes are: +The event ID is calculated using the following algorithm. Note that the hashing +algorithm used is the same as in previous room versions. 1. Redact the event. 2. Remove the `signatures` field from the event. 3. Serialize the event into `Canonical JSON`_. 4. Compute the hash of the JSON bytes. +5. Encode the sha256 hash using `Unpadded Base64`_. +6. Use the resulting string as the event ID 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 @@ -91,11 +94,10 @@ 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 servers are not communicating the event ID over the wire to each other, -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. +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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -108,9 +110,12 @@ to the change in event format: domain. * Previously, redactions were allowed if the sender's domain matched the domain - in the event ID it was redacting, allowing self redaction. This check is removed - and redaction events are always accepted. Redaction events only take effect - when the original event is received, and the domain of the each event matches. + in the event ID it was redacting, allowing self redaction. Due to changes in + the event format, this check is now impossible to do. Instead, servers should + allow redactions from servers of the same origin to redact other events as a + self-redaction mechanism. The rules for allowing other servers to redact events + (as done by moderators) is unchanged. Redaction events only take effect when + the original event is received, and the domain of the each event matches. Servers should not send redactions down to clients until the redaction has taken effect. From ad64af3f016275d6f5e2f2acd954b5c7cbb7d6d8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 17:22:55 -0700 Subject: [PATCH 0190/1250] Clarify how reference hashes are done --- specification/rooms/v3.rst | 13 ++----------- specification/server_server_api.rst | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/specification/rooms/v3.rst b/specification/rooms/v3.rst index 3f383e7b..9efcc463 100644 --- a/specification/rooms/v3.rst +++ b/specification/rooms/v3.rst @@ -63,17 +63,8 @@ Event IDs 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 calculated using the following algorithm. Note that the hashing -algorithm used is the same as in previous room versions. - -1. Redact the event. -2. Remove the `signatures` field from the event. -3. Serialize the event into `Canonical JSON`_. -4. Compute the hash of the JSON bytes. -5. Encode the sha256 hash using `Unpadded Base64`_. -6. Use the resulting string as the event ID prefixed with ``$``. - -A resulting event ID using this approach should look similar to +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 diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 8f021e62..6eaf74e0 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -1050,6 +1050,22 @@ been given a redacted version of the event. To enforce this, the receiving server should use the redacted copy it calculated rather than the full copy it received. +Calculating the reference hash for an event +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The *reference hash* of an event covers the essential fields of an event, +includuing content hashes. It is calculated as follows. + +1. The event is put through the redaction algorithm. + +2. The ``signatures``, ``age_ts``, and ``unsigned`` properties are removed + from the event, if present. + +3. The event is converted into `Canonical JSON`_. + +4. A sha256 hash is calculed on the resulting JSON object. + + Calculating the content hash for an event ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 48912a73202121f86f1a8f971539df55eabea0d8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 17:35:25 -0700 Subject: [PATCH 0191/1250] Fix auth rules of redactions in v3 --- specification/rooms/v3.rst | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/specification/rooms/v3.rst b/specification/rooms/v3.rst index 9efcc463..040a7ff4 100644 --- a/specification/rooms/v3.rst +++ b/specification/rooms/v3.rst @@ -100,15 +100,17 @@ to the change in event format: is no domain in the event ID), but still needs to be signed by the sender's domain. -* Previously, redactions were allowed if the sender's domain matched the domain - in the event ID it was redacting, allowing self redaction. Due to changes in - the event format, this check is now impossible to do. Instead, servers should - allow redactions from servers of the same origin to redact other events as a - self-redaction mechanism. The rules for allowing other servers to redact events - (as done by moderators) is unchanged. Redaction events only take effect when - the original event is received, and the domain of the each event matches. - Servers should not send redactions down to clients until the redaction has - taken effect. +* 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 + origin sender's domains match, or the sender has the appropriate permissions per + the power levels. + The remaining rules are the same as room version 1. From a6243da03fef85e14bd8024c91914f138d218bb4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 17:58:42 -0700 Subject: [PATCH 0192/1250] Wording changes and links --- specification/rooms/v3.rst | 9 +++++---- specification/server_server_api.rst | 6 +++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/specification/rooms/v3.rst b/specification/rooms/v3.rst index 040a7ff4..e5b0c44c 100644 --- a/specification/rooms/v3.rst +++ b/specification/rooms/v3.rst @@ -63,7 +63,7 @@ Event IDs 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`_, +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``. @@ -108,13 +108,14 @@ to the change in event format: ``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 - origin sender's domains match, or the sender has the appropriate permissions per - the power levels. + 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. +The remaining rules are the same as `room version 1 `_. .. _`Unpadded Base64`: ../../appendices.html#unpadded-base64 .. _`Canonical JSON`: ../../appendices.html#canonical-json .. _`Signing Events`: ../../server_server/unstable.html#signing-events +.. _`reference hash`: ../../server_server/unstable.html#reference-hashes diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 6eaf74e0..f5831639 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -281,6 +281,8 @@ Transactions are limited in size; they can have at most 50 PDUs and 100 EDUs. {{transactions_ss_http_api}} +.. _`Persistent Data Unit schema`: + PDUs ---- @@ -1050,11 +1052,13 @@ been given a redacted version of the event. To enforce this, the receiving server should use the redacted copy it calculated rather than the full copy it received. +.. _`reference hashes`: + Calculating the reference hash for an event ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The *reference hash* of an event covers the essential fields of an event, -includuing content hashes. It is calculated as follows. +including content hashes. It is calculated as follows. 1. The event is put through the redaction algorithm. From 1c30f5eba986335635f1740b1689e9b011beefd1 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 21:15:47 -0700 Subject: [PATCH 0193/1250] Clarify certificate usage and ports --- specification/server_server_api.rst | 75 ++++++++++++++--------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index a2672e92..46a485af 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -107,76 +107,73 @@ The process overall is as follows: do so - just ensure that the result is the same! 1. If the hostname is an IP literal, then that IP address should be used, - together with the given port number, or 8448 if no port is given. A - valid TLS certificate must be provided by the target server for the - IP address on all requests. Requests must be made with a ``Host`` - header containing the IP address, without port. + together with the given port number, or 8448 if no port is given. The + target server must present a valid certificate for the IP address. + Requests must be made with a ``Host`` header containing the IP address, + without port. 2. If the hostname is not an IP literal, and has an explicit port given, resolve the IP address using AAAA or A records. Requests are made to the resolved IP address and given port with a ``Host`` header of the - original hostname (without port). A valid TLS certificate must be - provided by the target server for the hostname. - -3. If the hostname is not an IP literal, a ``/.well-known`` request is - made to the hostname (using port 443 exclusively, ignoring the port - provided in the server name). This is done as a plain HTTPS request - which follows 30x redirects, being careful to avoid redirect loops. - Responses (successful or otherwise) to the ``/.well-known`` endpoint - should be cached by the requesting server. Servers should respect - the cache control headers present on the response, or use a sensible - default when headers are not present. The recommended sensible default - is 24 hours. Servers should additionally impose a maximum cache time - for responses: 48 hours is recommended. Errors are recommended to be - cached for up to an hour, and servers are encouraged to exponentially - back off for repeated failures. The schema of the ``/.well-known`` - request is later in this section. If the response is invalid (bad JSON, - missing properties, etc), attempts to connect to the target server are - aborted - no connections should be attempted. If the response is valid, - the ``m.server`` property is parsed as ``[:]`` - and processed as follows: + original hostname (with port). The target server must present a valid + certificate for the hostname. + +3. If the hostname is not an IP literal, a regular HTTPS request is made + to ``https:///.well-known/matrix/server``, expecting the + schema defined later in this section. 30x redirects should be followed, + however redirection loops should be avoided. Responses (successful or + otherwise) to the ``/.well-known`` endpoint should be cached by the + requesting server. Servers should respect the cache control headers + present on the response, or use a sensible default when headers are not + present. The recommended sensible default is 24 hours. Servers should + additionally impose a maximum cache time for responses: 48 hours is + recommended. Errors are recommended to be cached for up to an hour, + and servers are encouraged to exponentially back off for repeated + failures. The schema of the ``/.well-known`` request is later in this + section. If the response is invalid (bad JSON, missing properties, etc), + attempts to connect to the target server are aborted - no connections + should be attempted. If the response is valid, the ``m.server`` property + is parsed as ``[:]`` and processed + as follows: * If ```` is an IP literal, then that IP address should be used together with the ```` or 8448 if no - port is provided. A valid TLS certificate must be provided by the - target server for that IP address. Requests must be made with a - ``Host`` header containing the IP address, without port. + port is provided. The target server must present a valid TLS certificate + for the IP address. Requests must be made with a ``Host`` header containing + the IP address, with port. * If ```` is not an IP literal, and ```` is present, an IP address is disovered by looking up an AAAA or A record for ````. The resulting IP address is used, alongside the ````, to make requests with a - ``Host`` header of ``:``. A valid - TLS certificate must be provided by the target server for ````. + ``Host`` header of ``:``. The + target server must present a valid certificate for ````. * If ```` is not an IP literal and no ```` is present, an SRV record is looked up for ``_matrix._tcp.``. This may result in another hostname (to be resolved using AAAA or A records) and port. Requests should be made to the resolved IP address and port with a ``Host`` - header containing the ````. Additionally, a - valid TLS certificate must be provided by the target server for the - ````. + header containing the ````. The target server + must present a valid certificate for ````. * If no SRV record is found, an IP address is resolved using AAAA or A records. Requests are then made to the resolve IP address and a port of 8448, using a ``Host`` header of ````. - A valid TLS certificate for ```` must be - provided by the target server. + The target server must present a valid certificate for ````. 4. If the `/.well-known` request did not result in a 200 response, a server is found by resolving an SRV record for ``_matrix._tcp.``. This may result in a hostname (to be resolved using AAAA or A records) and port. Requests are made to the resolved IP address and port, using 8448 - as a default port, with a ``Host`` header of ````. A valid TLS - certificate for ```` must be provided by the target server on - all requests. + as a default port, with a ``Host`` header of ````. The target + server must present a valid certificate for ````. 5. If the `/.well-known` request returned an error response, and the SRV record was not found, an IP address is resolved using AAAA and A records. Requests are made to the resolved IP address using port 8448 and a ``Host`` - header containing the ````. A valid TLS certificate for - ```` must be provided by the target server on all requests. + header containing the ````. The target server must present a + valid certificate for ````. The TLS certificate provided by the target server must be signed by a known From 39b71413be1f20d7071c2d8babe784b22b015537 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Fri, 1 Feb 2019 07:40:39 -0700 Subject: [PATCH 0194/1250] Update specification/server_server_api.rst Co-Authored-By: turt2live --- specification/server_server_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 46a485af..17f3e646 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -112,7 +112,7 @@ The process overall is as follows: Requests must be made with a ``Host`` header containing the IP address, without port. -2. If the hostname is not an IP literal, and has an explicit port given, +2. If the hostname is not an IP literal, and the server name includes an explicit port, resolve the IP address using AAAA or A records. Requests are made to the resolved IP address and given port with a ``Host`` header of the original hostname (with port). The target server must present a valid From 6421582bf2f29f766a151f93264126c3f69f4139 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 1 Feb 2019 08:18:12 -0700 Subject: [PATCH 0195/1250] Clarifications and alter the error handling of .well-known Note that MSC1831 changes the order, so the changes to MSC1708 might not make sense when combining all the proposals together. However, independently the change should make sense. --- proposals/1708-well-known-for-federation.md | 4 +- specification/server_server_api.rst | 51 ++++++++++----------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/proposals/1708-well-known-for-federation.md b/proposals/1708-well-known-for-federation.md index d23c0e2f..c9f90631 100644 --- a/proposals/1708-well-known-for-federation.md +++ b/proposals/1708-well-known-for-federation.md @@ -44,8 +44,8 @@ redirect loops). If the request does not return a 200, continue to step 4, otherwise: The response must be valid JSON which follows the structure documented -below. Otherwise, the request is aborted. It is NOT necessary for the response -to have a `Content-Type` of `application/json`. +below. Otherwise, continue to the next step in the discovery process. It is +NOT necessary for the response to have a `Content-Type` of `application/json`. If the response is valid, the `m.server` property is parsed as `[:]`, and processed as follows: diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 17f3e646..8de5ecc5 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -109,14 +109,14 @@ The process overall is as follows: 1. If the hostname is an IP literal, then that IP address should be used, together with the given port number, or 8448 if no port is given. The target server must present a valid certificate for the IP address. - Requests must be made with a ``Host`` header containing the IP address, - without port. + The ``Host`` header in the request should be set to the server name, + including the port if the server name included one. -2. If the hostname is not an IP literal, and the server name includes an explicit port, - resolve the IP address using AAAA or A records. Requests are made to - the resolved IP address and given port with a ``Host`` header of the - original hostname (with port). The target server must present a valid - certificate for the hostname. +2. If the hostname is not an IP literal, and the server name includes an + explicit port, resolve the IP address using AAAA or A records. Requests + are made to the resolved IP address and given port with a ``Host`` header + of the original server name (with port). The target server must present a + valid certificate for the hostname. 3. If the hostname is not an IP literal, a regular HTTPS request is made to ``https:///.well-known/matrix/server``, expecting the @@ -130,39 +130,38 @@ The process overall is as follows: recommended. Errors are recommended to be cached for up to an hour, and servers are encouraged to exponentially back off for repeated failures. The schema of the ``/.well-known`` request is later in this - section. If the response is invalid (bad JSON, missing properties, etc), - attempts to connect to the target server are aborted - no connections - should be attempted. If the response is valid, the ``m.server`` property - is parsed as ``[:]`` and processed - as follows: + section. If the response is invalid (bad JSON, missing properties, non-200 + response, etc), skip to step 4. If the response is valid, the ``m.server`` + property is parsed as ``[:]`` and + processed as follows: - * If ```` is an IP literal, then that IP address + * If ```` is an IP literal, then that IP address should be used together with the ```` or 8448 if no port is provided. The target server must present a valid TLS certificate for the IP address. Requests must be made with a ``Host`` header containing - the IP address, with port. + the IP address, including the port if one was provided. - * If ```` is not an IP literal, and ```` + * If ```` is not an IP literal, and ```` is present, an IP address is disovered by looking up an AAAA or A - record for ````. The resulting IP address is - used, alongside the ````, to make requests with a - ``Host`` header of ``:``. The - target server must present a valid certificate for ````. + record for ````. The resulting IP address is + used, alongside the ````. Requests must be made with a + ``Host`` header of ``:``. The + target server must present a valid certificate for ````. - * If ```` is not an IP literal and no + * If ```` is not an IP literal and no ```` is present, an SRV record is looked up for - ``_matrix._tcp.``. This may result in another + ``_matrix._tcp.``. This may result in another hostname (to be resolved using AAAA or A records) and port. Requests should be made to the resolved IP address and port with a ``Host`` - header containing the ````. The target server - must present a valid certificate for ````. + header containing the ````. The target server + must present a valid certificate for ````. * If no SRV record is found, an IP address is resolved using AAAA or A records. Requests are then made to the resolve IP address - and a port of 8448, using a ``Host`` header of ````. - The target server must present a valid certificate for ````. + and a port of 8448, using a ``Host`` header of ````. + The target server must present a valid certificate for ````. -4. If the `/.well-known` request did not result in a 200 response, a server +4. If the `/.well-known` request resulted in an error response, a server is found by resolving an SRV record for ``_matrix._tcp.``. This may result in a hostname (to be resolved using AAAA or A records) and port. Requests are made to the resolved IP address and port, using 8448 From 9b214ec16d1fe8db4f59100a35fcc9b5872da32c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 23:46:22 -0700 Subject: [PATCH 0196/1250] Make the backfill response aware of event format changes --- api/server-server/backfill.yaml | 29 +++++-------------- .../definitions/transaction.yaml | 15 ++++++++-- api/server-server/examples/transaction.json | 6 ++-- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/api/server-server/backfill.yaml b/api/server-server/backfill.yaml index b196d17c..738e6efc 100644 --- a/api/server-server/backfill.yaml +++ b/api/server-server/backfill.yaml @@ -65,22 +65,6 @@ paths: event(s), up to the given limit. schema: $ref: "definitions/transaction.yaml" - # Override the example to show the response of the request a bit better - examples: - application/json: { - "$ref": "examples/transaction.json", - "pdus": [ - { - "$ref": "pdu.json", - "room_id": "!SomeRoom:matrix.org", - "event_id": "$abc123:matrix.org" - }, - { - "$ref": "pdu.json", - "room_id": "!SomeRoom:matrix.org" - }, - ] - } "/get_missing_events/{roomId}": post: summary: Retrieves events that the sender is missing @@ -114,14 +98,14 @@ paths: earliest_events: type: array description: |- - The latest events that the sender already has. These are skipped when retrieving + The latest event IDs that the sender already has. These are skipped when retrieving the previous events of ``latest_events``. items: type: string example: ["$missing_event:example.org"] latest_events: type: array - description: The events to retrieve the previous events for. + description: The event IDs to retrieve the previous events for. items: type: string example: ["$event_that_has_the_missing_event_as_a_previous_event:example.org"] @@ -136,13 +120,16 @@ paths: properties: events: type: array - description: The missing events. + description: |- + The missing events. The event format varies depending on the room version - check + the `room version specification`_ for precise event formats. items: - $ref: definitions/pdu.yaml + type: object + title: PDU required: ['events'] examples: application/json: { "events": [ - {"$ref": "examples/pdu.json"} + {"see_room_version_spec": "The event format changes depending on the room version."} ] } diff --git a/api/server-server/definitions/transaction.yaml b/api/server-server/definitions/transaction.yaml index 9833f785..7ec9386e 100644 --- a/api/server-server/definitions/transaction.yaml +++ b/api/server-server/definitions/transaction.yaml @@ -26,12 +26,21 @@ properties: type: integer format: int64 description: |- - POSIX timestamp in milliseconds on originating homeserver when this + POSIX timestamp in milliseconds on originating homeserver when this transaction started. example: 1532991320875 pdus: type: array - description: List of persistent updates to rooms. Must not include more than 50 PDUs. + description: |- + List of persistent updates to rooms. Must not include more than 50 PDUs. Note that + events have a different version depending on the room version - check the + `room version specification`_ for precise event formats. items: - $ref: "pdu.yaml" + type: object + title: PDU + description: |- + The `PDUs <#pdus>`_ contained in the transaction. The event format varies depending + on the room version - check the `room version specification`_ for precise event formats. + properties: [] + example: {"see_room_version_spec": "The event format changes depending on the room version."} required: ['origin', 'origin_server_ts', 'pdus'] diff --git a/api/server-server/examples/transaction.json b/api/server-server/examples/transaction.json index bd8ac3dc..6d77f79e 100644 --- a/api/server-server/examples/transaction.json +++ b/api/server-server/examples/transaction.json @@ -1,5 +1,7 @@ { "origin": "matrix.org", "origin_server_ts": 1234567890, - "pdus": [{"$ref": "pdu.json"}] -} \ No newline at end of file + "pdus": [{ + "see_room_version_spec": "The event format changes depending on the room version." + }] +} From d94a70f49de4770ec84a700058737384938d7ce4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 31 Jan 2019 23:54:14 -0700 Subject: [PATCH 0197/1250] Warn clients about changes in event format --- specification/client_server_api.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 40ac5588..8f4a9a1d 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1267,7 +1267,21 @@ point in time:: [E0]->[E1]->[E2]->[E3]->[E4]->[E5] +.. WARNING:: + + The format of events can change depending on room version. Check the + `room version specification`_ for specific details on what to expect for + event formats. Examples contained within the client-server specification + are expected to be compatible with all specified room versions, however + some differences may still apply. + + For this version of the specification, clients only need to worry about + the event ID format being different depending on room version. Clients + should not be parsing the event ID, and instead be treating it as an + opaque string. No changes should be required to support the currently + available room versions. +.. _`room version specification`: ../index.html#room-versions Types of room events ~~~~~~~~~~~~~~~~~~~~ From 33406e4662a101eaa23f9b74612f18856b902b25 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 1 Feb 2019 10:08:30 -0700 Subject: [PATCH 0198/1250] Apply event format warnings to the remainder of the s2s spec --- api/server-server/backfill.yaml | 2 +- .../definitions/invite_event.yaml | 44 +-- .../definitions/transaction.yaml | 3 +- api/server-server/event_auth.yaml | 50 +++- api/server-server/events.yaml | 30 +- api/server-server/examples/minimal_pdu.json | 7 + api/server-server/examples/transaction.json | 2 +- api/server-server/invites-v1.yaml | 12 +- api/server-server/invites-v2.yaml | 12 +- api/server-server/joins.yaml | 266 ++++++++---------- api/server-server/leaving.yaml | 248 +++++++--------- api/server-server/transactions.yaml | 3 + 12 files changed, 316 insertions(+), 363 deletions(-) create mode 100644 api/server-server/examples/minimal_pdu.json diff --git a/api/server-server/backfill.yaml b/api/server-server/backfill.yaml index 738e6efc..0da0e234 100644 --- a/api/server-server/backfill.yaml +++ b/api/server-server/backfill.yaml @@ -130,6 +130,6 @@ paths: examples: application/json: { "events": [ - {"see_room_version_spec": "The event format changes depending on the room version."} + {"$ref": "examples/minimal_pdu.json"} ] } diff --git a/api/server-server/definitions/invite_event.yaml b/api/server-server/definitions/invite_event.yaml index d196339a..1f8b29d0 100644 --- a/api/server-server/definitions/invite_event.yaml +++ b/api/server-server/definitions/invite_event.yaml @@ -1,4 +1,4 @@ -# Copyright 2018 New Vector Ltd +# 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. @@ -13,15 +13,14 @@ # limitations under the License. type: object title: Invite Event -description: An invite event +description: |- + An invite event. Note that events have a different version depending on the + room version - check the `room version specification`_ for precise event formats. allOf: - - $ref: "pdu.yaml" - type: object properties: - # Note: we override a bunch of parameters to change their descriptions sender: type: string - # TODO: Verify/clarify this - it doesn't seem right, given this is a 'regular' invite description: |- The matrix ID of the user who sent the original ``m.room.third_party_invite``. example: "@someone:example.org" @@ -46,7 +45,7 @@ allOf: type: object title: Membership Event Content description: |- - The content of the event, matching what is available in the + The content of the event, matching what is available in the `Client-Server API`_. Must include a ``membership`` of ``invite``. example: {"membership": "invite"} properties: @@ -55,33 +54,10 @@ allOf: description: The value ``invite``. example: "invite" required: ['membership'] - auth_events: - type: array - description: |- - An event reference list containing the authorization events that would - allow the member to be invited to 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": "abase64encodedsha256hashshouldbe43byteslong" - } - properties: - sha256: - type: string - description: The event hash. - example: abase64encodedsha256hashshouldbe43byteslong - required: ['sha256'] - redacts: - type: string - description: Not used. required: - # Every other field is already flagged as required by the $ref - state_key + - sender + - origin + - origin_server_ts + - type + - content diff --git a/api/server-server/definitions/transaction.yaml b/api/server-server/definitions/transaction.yaml index 7ec9386e..a77f6f8a 100644 --- a/api/server-server/definitions/transaction.yaml +++ b/api/server-server/definitions/transaction.yaml @@ -42,5 +42,6 @@ properties: The `PDUs <#pdus>`_ contained in the transaction. The event format varies depending on the room version - check the `room version specification`_ for precise event formats. properties: [] - example: {"see_room_version_spec": "The event format changes depending on the room version."} + example: + $ref: "../examples/minimal_pdu.json" required: ['origin', 'origin_server_ts', 'pdus'] diff --git a/api/server-server/event_auth.yaml b/api/server-server/event_auth.yaml index 905b112f..262ea282 100644 --- a/api/server-server/event_auth.yaml +++ b/api/server-server/event_auth.yaml @@ -20,7 +20,7 @@ host: localhost:8448 schemes: - https basePath: /_matrix/federation/v1 -consumes: +consumes: - application/json produces: - application/json @@ -58,10 +58,19 @@ paths: type: array description: |- The full set of authorization events that make up the state of - the room, and their authorization events, recursively. + the room, and their authorization events, recursively. Note that + events have a different version depending on the room version - + check the `room version specification`_ for precise event formats. items: - $ref: "definitions/pdu.yaml" - example: [{"$ref": "examples/pdu.json"}] + type: object + title: PDU + description: |- + The `PDUs <#pdus>`_ contained in the auth chain. The event format + varies depending on the room version - check the `room version specification`_ + for precise event formats. + properties: [] + example: + $ref: "examples/minimal_pdu.json" required: ['auth_chain'] "/query_auth/{roomId}/{eventId}": post: @@ -98,10 +107,20 @@ paths: properties: auth_chain: type: array - description: The auth chain (the "remote auth"). + description: |- + The auth chain (the "remote auth"). Note that events have a different + version depending on the room version - check the `room version specification`_ + for precise event formats. items: - $ref: "definitions/pdu.yaml" - example: [{"$ref": "examples/pdu.json"}] + type: object + title: PDU + description: |- + The `PDUs <#pdus>`_ contained in the auth chain. The event format + varies depending on the room version - check the `room version specification`_ + for precise event formats. + properties: [] + example: + $ref: "examples/minimal_pdu.json" missing: type: array description: |- @@ -142,14 +161,23 @@ paths: type: array description: |- The auth chain the receiver has, and used to determine the auth - chain differences (the "local auth"). + chain differences (the "local auth"). Note that events have a different + version depending on the room version - check the `room version specification`_ + for precise event formats. items: - $ref: "definitions/pdu.yaml" - example: [{"$ref": "examples/pdu.json"}] + type: object + title: PDU + description: |- + The `PDUs <#pdus>`_ contained in the auth chain. The event format + varies depending on the room version - check the `room version specification`_ + for precise event formats. + properties: [] + example: + $ref: "examples/minimal_pdu.json" missing: type: array description: |- - The list of event IDs that the receiver believes it is missing, + The list of event IDs that the receiver believes it is missing, after comparing the "remote auth" and "local auth" chains. items: type: string diff --git a/api/server-server/events.yaml b/api/server-server/events.yaml index d23456d1..e7cb52cd 100644 --- a/api/server-server/events.yaml +++ b/api/server-server/events.yaml @@ -59,17 +59,35 @@ paths: type: array description: |- The full set of authorization events that make up the state - of the room, and their authorization events, recursively. + of the room, and their authorization events, recursively. Note that + events have a different version depending on the room version - + check the `room version specification`_ for precise event formats. items: - $ref: "definitions/pdu.yaml" - example: [{"$ref": "examples/pdu.json"}] + type: object + title: PDU + description: |- + The `PDUs <#pdus>`_ contained in the auth chain. The event format + varies depending on the room version - check the `room version specification`_ + for precise event formats. + properties: [] + example: + $ref: "examples/minimal_pdu.json" pdus: type: array description: |- - The fully resolved state of the room at the given event. + The fully resolved state of the room at the given event. Note that + events have a different version depending on the room version - + check the `room version specification`_ for precise event formats. items: - $ref: "definitions/pdu.yaml" - example: [{"$ref": "examples/pdu.json"}] + type: object + title: PDU + description: |- + The `PDUs <#pdus>`_ for the fully resolved state of the room. The event format + varies depending on the room version - check the `room version specification`_ + for precise event formats. + properties: [] + example: + $ref: "examples/minimal_pdu.json" required: ['auth_chain', 'pdus'] "/state_ids/{roomId}": get: diff --git a/api/server-server/examples/minimal_pdu.json b/api/server-server/examples/minimal_pdu.json new file mode 100644 index 00000000..f8b8efc3 --- /dev/null +++ b/api/server-server/examples/minimal_pdu.json @@ -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." + } +} diff --git a/api/server-server/examples/transaction.json b/api/server-server/examples/transaction.json index 6d77f79e..bbc661d9 100644 --- a/api/server-server/examples/transaction.json +++ b/api/server-server/examples/transaction.json @@ -2,6 +2,6 @@ "origin": "matrix.org", "origin_server_ts": 1234567890, "pdus": [{ - "see_room_version_spec": "The event format changes depending on the room version." + "$ref": "minimal_pdu.json" }] } diff --git a/api/server-server/invites-v1.yaml b/api/server-server/invites-v1.yaml index 44db1f8d..8daaabab 100644 --- a/api/server-server/invites-v1.yaml +++ b/api/server-server/invites-v1.yaml @@ -38,6 +38,11 @@ paths: Servers should prefer to use the v2 API for invites instead of the v1 API. Servers which receive a v1 invite request must assume that the room version is either ``"1"`` or ``"2"``. + + Note that events have a different version 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: sendInviteV1 security: - signedRequest: [] @@ -107,7 +112,7 @@ paths: } ] example: { - "$ref": "examples/pdu.json", + "$ref": "examples/minimal_pdu.json", "type": "m.room.member", "state_key": "@joe:elsewhere.com", "unsigned": { @@ -143,7 +148,8 @@ paths: 200: description: |- The event with the invited server's signature added. All other fields of the events - should remain untouched. + should remain untouched. Note that events have a different version depending on the + room version - check the `room version specification`_ for precise event formats. schema: type: array minItems: 2 @@ -164,7 +170,7 @@ paths: 200, { "event": { - "$ref": "examples/pdu.json", + "$ref": "examples/minimal_pdu.json", "type": "m.room.member", "state_key": "@someone:example.org", "unsigned": { diff --git a/api/server-server/invites-v2.yaml b/api/server-server/invites-v2.yaml index f8695195..91e95d7f 100644 --- a/api/server-server/invites-v2.yaml +++ b/api/server-server/invites-v2.yaml @@ -42,6 +42,11 @@ paths: 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 version 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: [] @@ -111,7 +116,7 @@ paths: example: { "room_version": "2", "event": { - "$ref": "examples/pdu.json", + "$ref": "examples/minimal_pdu.json", "type": "m.room.member", "state_key": "@joe:elsewhere.com", "content": { @@ -146,7 +151,8 @@ paths: 200: description: |- The event with the invited server's signature added. All other fields of the events - should remain untouched. + should remain untouched. Note that events have a different version 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. @@ -158,7 +164,7 @@ paths: examples: application/json: { "event": { - "$ref": "examples/pdu.json", + "$ref": "examples/minimal_pdu.json", "type": "m.room.member", "state_key": "@someone:example.org", "unsigned": { diff --git a/api/server-server/joins.yaml b/api/server-server/joins.yaml index 3c0ec48f..83f8d1c5 100644 --- a/api/server-server/joins.yaml +++ b/api/server-server/joins.yaml @@ -61,7 +61,11 @@ paths: responses: 200: description: |- - A template to be used for the rest of the `Joining Rooms`_ handshake. + A template to be used for the rest of the `Joining Rooms`_ handshake. Note that + events have a different version depending on the room version - check the + `room version specification`_ for precise event formats. **The response body + here describes the common event fields in more detail and may be missing other + required fields for a PDU.** schema: type: object properties: @@ -72,96 +76,61 @@ paths: the room version is assumed to be either "1" or "2". example: "2" event: - allOf: - - $ref: "definitions/unsigned_pdu.yaml" - - description: |- - An unsigned template event. + description: |- + An unsigned template event. Note that events have a different version + depending on the room version - check the `room version specification`_ + for precise event formats. + type: object + properties: + sender: + type: string + description: The user ID of the joining member. + example: "@someone:example.org" + origin: + type: string + description: The name of the resident homeserver. + example: "matrix.org" + origin_server_ts: + type: integer + format: int64 + description: A timestamp added by the resident homeserver. + example: 1234567890 + type: + type: string + description: The value ``m.room.member``. + example: "m.room.member" + state_key: + type: string + description: The user ID of the joining member. + example: "@someone:example.org" + content: type: object + title: Membership Event Content + description: The content of the event. + example: {"membership": "join"} properties: - # Note: we override a bunch of parameters to change their descriptions - sender: - type: string - description: The user ID of the joining member. - example: "@someone:example.org" - origin: - type: string - description: The name of the resident homeserver. - example: "matrix.org" - origin_server_ts: - type: integer - format: int64 - description: A timestamp added by the resident homeserver. - example: 1234567890 - type: - type: string - description: The value ``m.room.member``. - example: "m.room.member" - state_key: - type: string - description: The user ID of the joining member. - example: "@someone:example.org" - content: - type: object - title: Membership Event Content - description: The content of the event. - example: {"membership": "join"} - properties: - membership: - type: string - description: The value ``join``. - example: "join" - required: ['membership'] - depth: - type: integer - description: This field must be present but is ignored; it may be 0. - example: 12 - auth_events: - type: array - description: |- - An event reference list containing the authorization events that would - allow the member to join the room. This should normally be the - ``m.room.create``, ``m.room.power_levels``, and ``m.room.join_rules`` - events. - items: - type: array - maxItems: 2 - minItems: 2 - items: - - type: string - title: Event ID - example: "$abc123:matrix.org" - - type: object - title: Event Hash - example: { - "sha256": "abase64encodedsha256hashshouldbe43byteslong" - } - properties: - sha256: - type: string - description: The event hash. - example: abase64encodedsha256hashshouldbe43byteslong - required: ['sha256'] - redacts: + membership: type: string - description: Not used. - required: - # Every other field is already flagged as required by the $ref - - state_key + description: The value ``join``. + example: "join" + required: ['membership'] + required: + - state_key + - origin + - origin_server_ts + - type + - state_key + - content examples: application/json: { "room_version": "2", "event": { - "$ref": "examples/unsigned_pdu.json", + "$ref": "examples/minimal_pdu.json", "type": "m.room.member", "state_key": "@someone:example.org", "content": { "membership": "join" - }, - "auth_events": [ - ["$room_cre4te_3vent:matrix.org", {"sha256": "abase64encodedsha256hashshouldbe43byteslong"}], - ["$room_j0in_rul3s_3vent:matrix.org", {"sha256": "abase64encodedsha256hashshouldbe43byteslong"}], - ["$room_p0wer_l3vels_3vent:matrix.org", {"sha256": "abase64encodedsha256hashshouldbe43byteslong"}] - ] + } } } 400: @@ -193,7 +162,12 @@ paths: summary: Submit a signed join event to a resident server description: |- Submits a signed join event to the resident server for it - to accept it into the room's graph. + to accept it into the room's graph. Note that events have + a different version depending on the room version - check + the `room version specification`_ for precise event formats. + **The request and response body here describes the common + event fields in more detail and may be missing other required + fields for a PDU.** operationId: sendJoin security: - signedRequest: [] @@ -215,79 +189,50 @@ paths: type: object required: true schema: - allOf: - - $ref: "definitions/pdu.yaml" - - type: object + type: object + properties: + sender: + type: string + description: The user ID of the joining member. + example: "@someone:example.org" + origin: + type: string + description: The name of the joining homeserver. + example: "matrix.org" + origin_server_ts: + type: integer + format: int64 + description: A timestamp added by the joining homeserver. + example: 1234567890 + type: + type: string + description: The value ``m.room.member``. + example: "m.room.member" + state_key: + type: string + description: The user ID of the joining member. + example: "@someone:example.org" + content: + type: object + title: Membership Event Content + description: The content of the event. + example: {"membership": "join"} properties: - # Note: we override a bunch of parameters to change their descriptions - sender: + membership: type: string - description: The user ID of the joining member. - example: "@someone:example.org" - origin: - type: string - description: The name of the joining homeserver. - example: "matrix.org" - origin_server_ts: - type: integer - format: int64 - description: A timestamp added by the joining homeserver. - example: 1234567890 - type: - type: string - description: The value ``m.room.member``. - example: "m.room.member" - state_key: - type: string - description: The user ID of the joining member. - example: "@someone:example.org" - content: - type: object - title: Membership Event Content - description: The content of the event. - example: {"membership": "join"} - properties: - membership: - type: string - description: The value ``join``. - example: "join" - required: ['membership'] - depth: - type: integer - description: This field must be present but is ignored; it may be 0. - example: 12 - auth_events: - type: array - description: |- - An event reference list containing the authorization events that would - allow the member to join 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": "abase64encodedsha256hashshouldbe43byteslong" - } - properties: - sha256: - type: string - description: The event hash. - example: abase64encodedsha256hashshouldbe43byteslong - required: ['sha256'] - redacts: - type: string - description: Not used. - required: - # Every other field is already flagged as required by the $ref - - state_key + description: The value ``join``. + example: "join" + required: ['membership'] + required: + - state_key + - sender + - origin + - origin_server_ts + - type + - state_key + - content example: { - "$ref": "examples/pdu.json", + "$ref": "examples/minimal_pdu.json", "type": "m.room.member", "state_key": "@someone:example.org", "content": { @@ -315,11 +260,20 @@ paths: description: The resident server's DNS name. auth_chain: type: array - description: The auth chain. + description: |- + The auth chain. Note that events have a different version depending on + the room version - check the `room version specification`_ for precise + event formats. items: type: object - schema: - $ref: "definitions/pdu.yaml" + title: PDU + description: |- + The `PDUs <#pdus>`_ contained in the auth chain. The event format + varies depending on the room version - check the `room version specification`_ + for precise event formats. + properties: [] + example: + $ref: "examples/minimal_pdu.json" state: type: array description: The room state. @@ -333,7 +287,7 @@ paths: 200, { "origin": "matrix.org", - "auth_chain": [{"$ref": "examples/pdu.json"}], - "state": [{"$ref": "examples/pdu.json"}] + "auth_chain": [{"$ref": "examples/minimal_pdu.json"}], + "state": [{"$ref": "examples/minimal_pdu.json"}] } ] diff --git a/api/server-server/leaving.yaml b/api/server-server/leaving.yaml index 68ada9d7..1a112ad3 100644 --- a/api/server-server/leaving.yaml +++ b/api/server-server/leaving.yaml @@ -52,7 +52,11 @@ paths: responses: 200: description: |- - A template to be used to call ``/send_leave``. + A template to be used to call ``/send_leave``. Note that + events have a different version depending on the room version - check the + `room version specification`_ for precise event formats. **The response body + here describes the common event fields in more detail and may be missing other + required fields for a PDU.** schema: schema: type: object @@ -64,92 +68,62 @@ paths: the room version is assumed to be either "1" or "2". example: "2" event: - allOf: - - $ref: "definitions/unsigned_pdu.yaml" - - description: |- - An unsigned template event. + description: |- + An unsigned template event. Note that events have a different version + depending on the room version - check the `room version specification`_ + for precise event formats. + type: object + properties: + sender: + type: string + description: The user ID of the leaving member. + example: "@someone:example.org" + origin: + type: string + description: The name of the resident homeserver. + example: "matrix.org" + origin_server_ts: + type: integer + format: int64 + description: A timestamp added by the resident homeserver. + example: 1234567890 + type: + type: string + description: The value ``m.room.member``. + example: "m.room.member" + state_key: + type: string + description: The user ID of the leaving member. + example: "@someone:example.org" + content: type: object + title: Membership Event Content + description: The content of the event. + example: {"membership": "leave"} properties: - # Note: we override a bunch of parameters to change their descriptions - sender: - type: string - description: The user ID of the leaving member. - example: "@someone:example.org" - origin: - type: string - description: The name of the resident homeserver. - example: "matrix.org" - origin_server_ts: - type: integer - format: int64 - description: A timestamp added by the resident homeserver. - example: 1234567890 - type: - type: string - description: The value ``m.room.member``. - example: "m.room.member" - state_key: - type: string - description: The user ID of the leaving member. - example: "@someone:example.org" - content: - type: object - title: Membership Event Content - description: The content of the event. - example: {"membership": "leave"} - properties: - membership: - type: string - description: The value ``leave``. - example: "leave" - required: ['membership'] - auth_events: - type: array - description: |- - An event reference list containing the authorization events that would - allow the member to leave the room. This should normally be the - ``m.room.create``, ``m.room.power_levels``, and ``m.room.join_rules`` - events. - items: - type: array - maxItems: 2 - minItems: 2 - items: - - type: string - title: Event ID - example: "$abc123:matrix.org" - - type: object - title: Event Hash - example: { - "sha256": "abase64encodedsha256hashshouldbe43byteslong" - } - properties: - sha256: - type: string - description: The event hash. - example: abase64encodedsha256hashshouldbe43byteslong - required: ['sha256'] - redacts: + membership: type: string - description: Not used. - required: - # Every other field is already flagged as required by the $ref - - state_key + description: The value ``leave``. + example: "leave" + required: ['membership'] + required: + - state_key + - sender + - origin + - origin_server_ts + - type + - state_key + - content examples: application/json: { "room_version": "2", "event": { - "$ref": "examples/unsigned_pdu.json", + "$ref": "examples/minimal_pdu.json", "type": "m.room.member", "state_key": "@someone:example.org", "content": { "membership": "leave" - }, - "auth_events": [ - ["$room_cre4te_3vent:matrix.org", {"sha256": "abase64encodedsha256hashshouldbe43byteslong"}], - ["$room_j0in_rul3s_3vent:matrix.org", {"sha256": "abase64encodedsha256hashshouldbe43byteslong"}], - ["$room_p0wer_l3vels_3vent:matrix.org", {"sha256": "abase64encodedsha256hashshouldbe43byteslong"}] - ] + } } } 403: @@ -167,7 +141,12 @@ paths: summary: Submit a signed leave event to a resident server description: |- Submits a signed leave event to the resident server for it - to accept it into the room's graph. + to accept it into the room's graph. Note that events have + a different version depending on the room version - check + the `room version specification`_ for precise event formats. + **The request and response body here describes the common + event fields in more detail and may be missing other required + fields for a PDU.** operationId: sendLeave security: - signedRequest: [] @@ -189,79 +168,54 @@ paths: type: object required: true schema: - allOf: - - $ref: "definitions/pdu.yaml" - - type: object + type: object + properties: + sender: + type: string + description: The user ID of the leaving member. + example: "@someone:example.org" + origin: + type: string + description: The name of the leaving homeserver. + example: "matrix.org" + origin_server_ts: + type: integer + format: int64 + description: A timestamp added by the leaving homeserver. + example: 1234567890 + type: + type: string + description: The value ``m.room.member``. + example: "m.room.member" + state_key: + type: string + description: The user ID of the leaving member. + example: "@someone:example.org" + content: + type: object + title: Membership Event Content + description: The content of the event. + example: {"membership": "leave"} properties: - # Note: we override a bunch of parameters to change their descriptions - sender: - type: string - description: The user ID of the leaving member. - example: "@someone:example.org" - origin: - type: string - description: The name of the leaving homeserver. - example: "matrix.org" - origin_server_ts: - type: integer - format: int64 - description: A timestamp added by the leaving homeserver. - example: 1234567890 - type: - type: string - description: The value ``m.room.member``. - example: "m.room.member" - state_key: + membership: type: string - description: The user ID of the leaving member. - example: "@someone:example.org" - content: - type: object - title: Membership Event Content - description: The content of the event. - example: {"membership": "leave"} - properties: - membership: - type: string - description: The value ``leave``. - example: "leave" - required: ['membership'] - depth: - type: integer - description: This field must be present but is ignored; it may be 0. - example: 12 - auth_events: - type: array - description: |- - An event reference list containing the authorization events that would - allow the member to leave 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": "abase64encodedsha256hashshouldbe43byteslong" - } - properties: - sha256: - type: string - description: The event hash. - example: abase64encodedsha256hashshouldbe43byteslong - required: ['sha256'] - redacts: - type: string - description: Not used. - required: - # Every other field is already flagged as required by the $ref - - state_key + description: The value ``leave``. + example: "leave" + required: ['membership'] + depth: + type: integer + description: This field must be present but is ignored; it may be 0. + example: 12 + required: + - state_key + - sender + - origin + - origin_server_ts + - type + - state_key + - content example: { - "$ref": "examples/pdu.json", + "$ref": "examples/minimal_pdu.json", "type": "m.room.member", "state_key": "@someone:example.org", "content": { diff --git a/api/server-server/transactions.yaml b/api/server-server/transactions.yaml index 355be2c6..38073e40 100644 --- a/api/server-server/transactions.yaml +++ b/api/server-server/transactions.yaml @@ -37,6 +37,9 @@ paths: The sending server must wait and retry for a 200 OK response before sending a transaction with a different ``txnId`` to the receiving server. + + Note that events have a different version depending on the room version - check + the `room version specification`_ for precise event formats. operationId: sendTransaction security: - signedRequest: [] From 5d8fa65e6e5c06573f744e8656a9a7db9ed600aa Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 1 Feb 2019 10:11:39 -0700 Subject: [PATCH 0199/1250] De-duplicate state keys --- api/server-server/joins.yaml | 1 - api/server-server/leaving.yaml | 2 -- 2 files changed, 3 deletions(-) diff --git a/api/server-server/joins.yaml b/api/server-server/joins.yaml index 83f8d1c5..c3539297 100644 --- a/api/server-server/joins.yaml +++ b/api/server-server/joins.yaml @@ -119,7 +119,6 @@ paths: - origin - origin_server_ts - type - - state_key - content examples: application/json: { diff --git a/api/server-server/leaving.yaml b/api/server-server/leaving.yaml index 1a112ad3..556e0800 100644 --- a/api/server-server/leaving.yaml +++ b/api/server-server/leaving.yaml @@ -112,7 +112,6 @@ paths: - origin - origin_server_ts - type - - state_key - content examples: application/json: { @@ -212,7 +211,6 @@ paths: - origin - origin_server_ts - type - - state_key - content example: { "$ref": "examples/minimal_pdu.json", From 890fb1a01928dfa77a6ac86714c823e33460ae0a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 1 Feb 2019 10:15:32 -0700 Subject: [PATCH 0200/1250] Fix examples for new schema Fix missed example in make_join Fix state array in response of send_join Try removing examples from send_join? Try printing more information about the error Copy/paste known working examples Try schema definitions in the response? --- api/check_examples.py | 6 ++++++ api/server-server/invites-v1.yaml | 6 ++++++ api/server-server/invites-v2.yaml | 6 ++++++ api/server-server/joins.yaml | 29 ++++++++++++++++++++++------- api/server-server/leaving.yaml | 6 ++++++ 5 files changed, 46 insertions(+), 7 deletions(-) diff --git a/api/check_examples.py b/api/check_examples.py index 0fb275b1..94f3495e 100755 --- a/api/check_examples.py +++ b/api/check_examples.py @@ -75,6 +75,12 @@ def check_response(filepath, request, code, response): filepath, request, code )) check_schema(filepath, example, schema) + except jsonschema.SchemaError as error: + for suberror in sorted(error.context, key=lambda e: e.schema_path): + print(list(suberror.schema_path), suberror.message, sep=", ") + raise ValueError("Error validating JSON schema for %r %r" % ( + request, code + ), e) except Exception as e: raise ValueError("Error validating JSON schema for %r %r" % ( request, code diff --git a/api/server-server/invites-v1.yaml b/api/server-server/invites-v1.yaml index 8daaabab..f397fc91 100644 --- a/api/server-server/invites-v1.yaml +++ b/api/server-server/invites-v1.yaml @@ -115,6 +115,9 @@ paths: "$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", "unsigned": { "invite_room_state": [ { @@ -173,6 +176,9 @@ paths: "$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": [ { diff --git a/api/server-server/invites-v2.yaml b/api/server-server/invites-v2.yaml index 91e95d7f..d57a7ba2 100644 --- a/api/server-server/invites-v2.yaml +++ b/api/server-server/invites-v2.yaml @@ -119,6 +119,9 @@ paths: "$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" }, @@ -167,6 +170,9 @@ paths: "$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": [ { diff --git a/api/server-server/joins.yaml b/api/server-server/joins.yaml index c3539297..fca273b5 100644 --- a/api/server-server/joins.yaml +++ b/api/server-server/joins.yaml @@ -127,6 +127,9 @@ paths: "$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", "content": { "membership": "join" } @@ -228,12 +231,14 @@ paths: - origin - origin_server_ts - type - - state_key - content example: { "$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", "content": { "membership": "join" } @@ -267,19 +272,29 @@ paths: type: object title: PDU description: |- - The `PDUs <#pdus>`_ contained in the auth chain. The event format - varies depending on the room version - check the `room version specification`_ - for precise event formats. - properties: [] + The `PDUs <#pdus>`_ that make up the auth chain. The event format varies depending + on the room version - check the `room version specification`_ for precise event formats. + schema: + type: object + properties: [] example: $ref: "examples/minimal_pdu.json" state: type: array - description: The room state. + description: |- + The room state. The event format varies depending on the room version - + check the `room version specification`_ for precise event formats. items: type: object + title: PDU + description: |- + The `PDUs <#pdus>`_ for the fully resolved state of the room. The event format varies depending + on the room version - check the `room version specification`_ for precise event formats. schema: - $ref: "definitions/pdu.yaml" + type: object + properties: [] + example: + $ref: "examples/minimal_pdu.json" required: ["auth_chain", "state", "origin"] examples: application/json: [ diff --git a/api/server-server/leaving.yaml b/api/server-server/leaving.yaml index 556e0800..6c0d4959 100644 --- a/api/server-server/leaving.yaml +++ b/api/server-server/leaving.yaml @@ -120,6 +120,9 @@ paths: "$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", "content": { "membership": "leave" } @@ -216,6 +219,9 @@ paths: "$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", "content": { "membership": "leave" } From 82bed06d3f433dc9655246931e2553efb546c5e9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 1 Feb 2019 13:19:24 -0700 Subject: [PATCH 0201/1250] The event *format* changes, not the version --- api/server-server/definitions/invite_event.yaml | 2 +- api/server-server/definitions/transaction.yaml | 2 +- api/server-server/event_auth.yaml | 6 +++--- api/server-server/events.yaml | 4 ++-- api/server-server/invites-v1.yaml | 4 ++-- api/server-server/invites-v2.yaml | 4 ++-- api/server-server/joins.yaml | 8 ++++---- api/server-server/leaving.yaml | 6 +++--- api/server-server/transactions.yaml | 2 +- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/api/server-server/definitions/invite_event.yaml b/api/server-server/definitions/invite_event.yaml index 1f8b29d0..674ef2c9 100644 --- a/api/server-server/definitions/invite_event.yaml +++ b/api/server-server/definitions/invite_event.yaml @@ -14,7 +14,7 @@ type: object title: Invite Event description: |- - An invite event. Note that events have a different version depending on the + An invite event. Note that events have a different format depending on the room version - check the `room version specification`_ for precise event formats. allOf: - type: object diff --git a/api/server-server/definitions/transaction.yaml b/api/server-server/definitions/transaction.yaml index a77f6f8a..08f3738a 100644 --- a/api/server-server/definitions/transaction.yaml +++ b/api/server-server/definitions/transaction.yaml @@ -33,7 +33,7 @@ properties: type: array description: |- List of persistent updates to rooms. Must not include more than 50 PDUs. Note that - events have a different version depending on the room version - check the + events have a different format depending on the room version - check the `room version specification`_ for precise event formats. items: type: object diff --git a/api/server-server/event_auth.yaml b/api/server-server/event_auth.yaml index 262ea282..0db0d401 100644 --- a/api/server-server/event_auth.yaml +++ b/api/server-server/event_auth.yaml @@ -59,7 +59,7 @@ paths: description: |- The full set of authorization events that make up the state of the room, and their authorization events, recursively. Note that - events have a different version depending on the room version - + events have a different format depending on the room version - check the `room version specification`_ for precise event formats. items: type: object @@ -109,7 +109,7 @@ paths: type: array description: |- The auth chain (the "remote auth"). Note that events have a different - version depending on the room version - check the `room version specification`_ + format depending on the room version - check the `room version specification`_ for precise event formats. items: type: object @@ -162,7 +162,7 @@ paths: description: |- The auth chain the receiver has, and used to determine the auth chain differences (the "local auth"). Note that events have a different - version depending on the room version - check the `room version specification`_ + format depending on the room version - check the `room version specification`_ for precise event formats. items: type: object diff --git a/api/server-server/events.yaml b/api/server-server/events.yaml index e7cb52cd..1f1a802d 100644 --- a/api/server-server/events.yaml +++ b/api/server-server/events.yaml @@ -60,7 +60,7 @@ paths: description: |- The full set of authorization events that make up the state of the room, and their authorization events, recursively. Note that - events have a different version depending on the room version - + events have a different format depending on the room version - check the `room version specification`_ for precise event formats. items: type: object @@ -76,7 +76,7 @@ paths: type: array description: |- The fully resolved state of the room at the given event. Note that - events have a different version depending on the room version - + events have a different format depending on the room version - check the `room version specification`_ for precise event formats. items: type: object diff --git a/api/server-server/invites-v1.yaml b/api/server-server/invites-v1.yaml index f397fc91..2ad0f220 100644 --- a/api/server-server/invites-v1.yaml +++ b/api/server-server/invites-v1.yaml @@ -39,7 +39,7 @@ paths: which receive a v1 invite request must assume that the room version is either ``"1"`` or ``"2"``. - Note that events have a different version depending on the room version - check the + 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.** @@ -151,7 +151,7 @@ paths: 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 version depending on the + 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: array diff --git a/api/server-server/invites-v2.yaml b/api/server-server/invites-v2.yaml index d57a7ba2..c459a848 100644 --- a/api/server-server/invites-v2.yaml +++ b/api/server-server/invites-v2.yaml @@ -43,7 +43,7 @@ paths: 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 version depending on the room version - check the + 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.** @@ -154,7 +154,7 @@ paths: 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 version depending on the + 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 diff --git a/api/server-server/joins.yaml b/api/server-server/joins.yaml index fca273b5..ad033001 100644 --- a/api/server-server/joins.yaml +++ b/api/server-server/joins.yaml @@ -62,7 +62,7 @@ paths: 200: description: |- A template to be used for the rest of the `Joining Rooms`_ handshake. Note that - events have a different version depending on the room version - check the + events have a different format depending on the room version - check the `room version specification`_ for precise event formats. **The response body here describes the common event fields in more detail and may be missing other required fields for a PDU.** @@ -77,7 +77,7 @@ paths: example: "2" event: description: |- - An unsigned template event. Note that events have a different version + An unsigned template event. Note that events have a different format depending on the room version - check the `room version specification`_ for precise event formats. type: object @@ -165,7 +165,7 @@ paths: description: |- Submits a signed join event to the resident server for it to accept it into the room's graph. Note that events have - a different version depending on the room version - check + a different format depending on the room version - check the `room version specification`_ for precise event formats. **The request and response body here describes the common event fields in more detail and may be missing other required @@ -265,7 +265,7 @@ paths: auth_chain: type: array description: |- - The auth chain. Note that events have a different version depending on + The auth chain. Note that events have a different format depending on the room version - check the `room version specification`_ for precise event formats. items: diff --git a/api/server-server/leaving.yaml b/api/server-server/leaving.yaml index 6c0d4959..95ee6880 100644 --- a/api/server-server/leaving.yaml +++ b/api/server-server/leaving.yaml @@ -53,7 +53,7 @@ paths: 200: description: |- A template to be used to call ``/send_leave``. Note that - events have a different version depending on the room version - check the + events have a different format depending on the room version - check the `room version specification`_ for precise event formats. **The response body here describes the common event fields in more detail and may be missing other required fields for a PDU.** @@ -69,7 +69,7 @@ paths: example: "2" event: description: |- - An unsigned template event. Note that events have a different version + An unsigned template event. Note that events have a different format depending on the room version - check the `room version specification`_ for precise event formats. type: object @@ -144,7 +144,7 @@ paths: description: |- Submits a signed leave event to the resident server for it to accept it into the room's graph. Note that events have - a different version depending on the room version - check + a different format depending on the room version - check the `room version specification`_ for precise event formats. **The request and response body here describes the common event fields in more detail and may be missing other required diff --git a/api/server-server/transactions.yaml b/api/server-server/transactions.yaml index 38073e40..9cc8be75 100644 --- a/api/server-server/transactions.yaml +++ b/api/server-server/transactions.yaml @@ -38,7 +38,7 @@ paths: The sending server must wait and retry for a 200 OK response before sending a transaction with a different ``txnId`` to the receiving server. - Note that events have a different version depending on the room version - check + Note that events have a different format depending on the room version - check the `room version specification`_ for precise event formats. operationId: sendTransaction security: From 985d02d95e9c265a446e41c2c5765349817538ba Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 1 Feb 2019 13:35:38 -0700 Subject: [PATCH 0202/1250] Fix titles in schemas --- api/server-server/joins.yaml | 1 + api/server-server/leaving.yaml | 1 + api/server-server/third_party_invite.yaml | 1 + 3 files changed, 3 insertions(+) diff --git a/api/server-server/joins.yaml b/api/server-server/joins.yaml index ad033001..38586adb 100644 --- a/api/server-server/joins.yaml +++ b/api/server-server/joins.yaml @@ -81,6 +81,7 @@ paths: depending on the room version - check the `room version specification`_ for precise event formats. type: object + title: Event Template properties: sender: type: string diff --git a/api/server-server/leaving.yaml b/api/server-server/leaving.yaml index 95ee6880..0713da6f 100644 --- a/api/server-server/leaving.yaml +++ b/api/server-server/leaving.yaml @@ -73,6 +73,7 @@ paths: depending on the room version - check the `room version specification`_ for precise event formats. type: object + title: Event Template properties: sender: type: string diff --git a/api/server-server/third_party_invite.yaml b/api/server-server/third_party_invite.yaml index 37c3a189..a401ae1b 100644 --- a/api/server-server/third_party_invite.yaml +++ b/api/server-server/third_party_invite.yaml @@ -85,6 +85,7 @@ paths: third_party_invite: type: object description: The third party invite + title: Third Party Invite properties: display_name: type: string From 1d0156ad787776966436c12785684c9211486e0a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 1 Feb 2019 13:37:19 -0700 Subject: [PATCH 0203/1250] Fix more titles --- api/server-server/third_party_invite.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/api/server-server/third_party_invite.yaml b/api/server-server/third_party_invite.yaml index a401ae1b..0b7aac5b 100644 --- a/api/server-server/third_party_invite.yaml +++ b/api/server-server/third_party_invite.yaml @@ -98,6 +98,7 @@ paths: description: |- A block of content which has been signed, which servers can use to verify the event. + title: Invite Signatures properties: signatures: type: object From 222957157f5cadcaf095bc38f19dadd3e21d62ef Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 1 Feb 2019 13:56:30 -0700 Subject: [PATCH 0204/1250] Add missing required flags --- api/server-server/joins.yaml | 1 + api/server-server/leaving.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/api/server-server/joins.yaml b/api/server-server/joins.yaml index 38586adb..1b5f4632 100644 --- a/api/server-server/joins.yaml +++ b/api/server-server/joins.yaml @@ -121,6 +121,7 @@ paths: - origin_server_ts - type - content + - sender examples: application/json: { "room_version": "2", diff --git a/api/server-server/leaving.yaml b/api/server-server/leaving.yaml index 0713da6f..c088cb5d 100644 --- a/api/server-server/leaving.yaml +++ b/api/server-server/leaving.yaml @@ -215,6 +215,7 @@ paths: - origin - origin_server_ts - type + - depth - content example: { "$ref": "examples/minimal_pdu.json", From fe7f58223324d28559a460f60c1be8241456f318 Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Fri, 1 Feb 2019 16:42:49 -0600 Subject: [PATCH 0205/1250] Fix several spelling mistakes Signed-off-by: Aaron Raimist --- specification/appendices/base64.rst | 2 +- specification/appendices/identifier_grammar.rst | 2 +- specification/client_server_api.rst | 6 +++--- specification/index.rst | 2 +- specification/modules/account_data.rst | 2 +- specification/modules/end_to_end_encryption.rst | 4 ++-- specification/modules/mentions.rst | 2 +- specification/modules/tags.rst | 2 +- specification/modules/third_party_invites.rst | 2 +- specification/push_gateway.rst | 2 +- specification/rooms/v1.rst | 2 +- specification/rooms/v2.rst | 2 +- specification/server_server_api.rst | 8 ++++---- 13 files changed, 19 insertions(+), 19 deletions(-) diff --git a/specification/appendices/base64.rst b/specification/appendices/base64.rst index d046e0fc..a918c2f9 100644 --- a/specification/appendices/base64.rst +++ b/specification/appendices/base64.rst @@ -52,6 +52,6 @@ Examples of strings encoded using unpadded Base64:: UNPADDED_BASE64("foobar") = "Zm9vYmFy" When decoding Base64, implementations SHOULD accept input with or without -padding characters whereever possible, to ensure maximum interoperability. +padding characters wherever possible, to ensure maximum interoperability. .. _`RFC 4648`: https://tools.ietf.org/html/rfc4648 diff --git a/specification/appendices/identifier_grammar.rst b/specification/appendices/identifier_grammar.rst index b4678988..a0cdf298 100644 --- a/specification/appendices/identifier_grammar.rst +++ b/specification/appendices/identifier_grammar.rst @@ -203,7 +203,7 @@ a homeserver creating a user ID for a new user based on the username passed to Implementations are free to do this mapping however they choose. Since the user ID is opaque except to the implementation which created it, the only -requirement is that the implemention can perform the mapping +requirement is that the implementation can perform the mapping consistently. However, we suggest the following algorithm: 1. Encode character strings as UTF-8. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 8f4a9a1d..c506af4e 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -158,7 +158,7 @@ Other error codes the client might encounter are: Sent when the room alias given to the ``createRoom`` API is already in use. :``M_INVALID_ROOM_STATE``: - Sent when the intial state given to the ``createRoom`` API is invalid. + Sent when the initial state given to the ``createRoom`` API is invalid. :``M_THREEPID_IN_USE``: Sent when a threepid given to an API cannot be used because the same threepid is already in use. @@ -636,7 +636,7 @@ To use this authentication type, clients should submit an auth dict as follows: where the ``identifier`` property is a user identifier object, as described in `Identifier types`_. -For example, to authenticate using the user's Matrix ID, clients whould submit: +For example, to authenticate using the user's Matrix ID, clients would submit: .. code:: json @@ -928,7 +928,7 @@ Third-party ID :Type: ``m.id.thirdparty`` :Description: - The user is identified by a third-party identifer in canonicalised form. + The user is identified by a third-party identifier in canonicalised form. A client can identify a user using a 3pid associated with the user's account on the homeserver, where the 3pid was previously associated using the diff --git a/specification/index.rst b/specification/index.rst index 05b85ab7..aa4471c4 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -474,7 +474,7 @@ Room versions are divided into two distinct groups: stable and unstable. Stable room versions may be used by rooms safely. Unstable room versions are everything else which is either not listed in the specification or flagged as unstable for some other reason. Versions can switch between stable and unstable periodically -for a variety of reasons, including discovered security vulnerabilites and age. +for a variety of reasons, including discovered security vulnerabilities and age. Clients should not ask room administrators to upgrade their rooms if the room is running a stable version. Servers SHOULD use room version 1 as the default room diff --git a/specification/modules/account_data.rst b/specification/modules/account_data.rst index f0bf285f..a67e503a 100644 --- a/specification/modules/account_data.rst +++ b/specification/modules/account_data.rst @@ -27,7 +27,7 @@ The account_data may be either global or scoped to a particular rooms. Events ------ -The client recieves the account data as events in the ``account_data`` sections +The client receives the account data as events in the ``account_data`` sections of a ``/sync``. These events can also be received in a ``/events`` response or in the diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 72bfae35..a605875b 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -450,7 +450,7 @@ previously-received ``request`` message with the same ``request_id`` and .. NOTE:: Key sharing can be a big attack vector, thus it must be done very carefully. - A reasonable stategy is for a user's client to only send keys requested by the + A reasonable strategy is for a user's client to only send keys requested by the verified devices of the same user. Key exports @@ -696,7 +696,7 @@ An event encrypted using Megolm has the following format: "sender_key": "", "device_id": "", "session_id": "", - "ciphertext": "" + "ciphertext": "" } } diff --git a/specification/modules/mentions.rst b/specification/modules/mentions.rst index 4501b776..dc078f3b 100644 --- a/specification/modules/mentions.rst +++ b/specification/modules/mentions.rst @@ -44,7 +44,7 @@ In addition to using the appropriate ``matrix.to URI`` for the mention, clients should use the following guidelines when making mentions in events to be sent: -* When mentioning users, use the user's potentially ambigious display name for +* When mentioning users, use the user's potentially ambiguous display name for the anchor's text. If the user does not have a display name, use the user's ID. diff --git a/specification/modules/tags.rst b/specification/modules/tags.rst index 739ead2c..a4b0becf 100644 --- a/specification/modules/tags.rst +++ b/specification/modules/tags.rst @@ -48,7 +48,7 @@ The tag namespace is defined as follows: * The namespace ``u.*`` is reserved for user-defined tags. The portion of the string after the ``u.`` is defined to be the display name of this tag. No other semantics should be inferred from tags in this namespace. -* A client or app willing to use special tags for advanced functionnality should namespace them similarly to state keys: ``tld.name.*`` +* A client or app willing to use special tags for advanced functionality should namespace them similarly to state keys: ``tld.name.*`` * Any tag in the ``tld.name.*`` form but not matching the namespace of the current client should be ignored * Any tag not matching the above rules should be interpreted as a user tag from the ``u.*`` namespace, as if the name had already had ``u.`` stripped from the start (ie. the name of the tag is used as the diff --git a/specification/modules/third_party_invites.rst b/specification/modules/third_party_invites.rst index df71d215..3e11d929 100644 --- a/specification/modules/third_party_invites.rst +++ b/specification/modules/third_party_invites.rst @@ -229,7 +229,7 @@ verification must still be performed, so the attack surface here is minimized. Security considerations ----------------------- -There are a number of privary and trust implications to this module. +There are a number of privacy and trust implications to this module. It is important for user privacy that leaking the mapping between a matrix user ID and a third party identifier is hard. In particular, being able to look up diff --git a/specification/push_gateway.rst b/specification/push_gateway.rst index a77d43db..cba38b6c 100644 --- a/specification/push_gateway.rst +++ b/specification/push_gateway.rst @@ -84,7 +84,7 @@ This describes the format used by "HTTP" pushers to send notifications of events to Push Gateways. If the endpoint returns an HTTP error code, the homeserver SHOULD retry for a reasonable amount of time using exponential backoff. -When pushing notifications for events, the hoemserver is expected to include all of +When pushing notifications for events, the homeserver is expected to include all of the event-related fields in the ``/notify`` request. When the homeserver is performing a push where the ``format`` is ``"event_id_only"``, only the ``event_id``, ``room_id``, ``counts``, and ``devices`` are required to be populated. diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index e09420e4..d7939c61 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -275,7 +275,7 @@ The rules are as follows: Some consequences of these rules: * Unless you are a member of the room, the only permitted operations (apart - from the intial create/join) are: joining a public room; accepting or + 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 diff --git a/specification/rooms/v2.rst b/specification/rooms/v2.rst index d39a7caa..c95fc4c9 100644 --- a/specification/rooms/v2.rst +++ b/specification/rooms/v2.rst @@ -116,7 +116,7 @@ Mainline ordering 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 comparision relation + ordering, from smallest to largest, using the following comparison relation on events: for events :math:`x` and :math:`y`, :math:`x`` is not an IP literal, and ```` - is present, an IP address is disovered by looking up an AAAA or A + is present, an IP address is discovered by looking up an AAAA or A record for ````. The resulting IP address is used, alongside the ````. Requests must be made with a ``Host`` header of ``:``. The @@ -1125,7 +1125,7 @@ including content hashes. It is calculated as follows. 3. The event is converted into `Canonical JSON`_. -4. A sha256 hash is calculed on the resulting JSON object. +4. A sha256 hash is calculated on the resulting JSON object. Calculating the content hash for an event @@ -1170,7 +1170,7 @@ Example code # Keys under "unsigned" can be modified by other servers. # They are useful for conveying information like the age of an # event that will change in transit. - # Since they can be modifed we need to exclude them from the hash. + # Since they can be modified we need to exclude them from the hash. event_object.pop("unsigned", None) # Signatures will depend on the current value of the "hashes" key. @@ -1192,7 +1192,7 @@ Example code [[TODO(markjh): Since the ``hash`` object cannot be redacted a server shouldn't allow too many hashes to be listed, otherwise a server might embed - illict data within the ``hash`` object. + illicit data within the ``hash`` object. We might want to specify a maximum number of keys for the ``hash`` and we might want to specify the maximum output size of a hash]] From 9364787b9cedb641f9d268eb00bf2dac3098d0c8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 1 Feb 2019 12:12:34 -0700 Subject: [PATCH 0206/1250] Remove stability warning --- specification/server_server_api.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 30479b75..0c794ea5 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -16,10 +16,6 @@ Federation API ============== -.. WARNING:: - This API is unstable and will change without warning or discussion while - we work towards a r0 release (scheduled for August 2018). - Matrix homeservers use the Federation APIs (also known as server-server APIs) to communicate with each other. Homeservers use these APIs to push messages to each other in real-time, to retrieve historic messages from each other, and to From 8ace64bab719deb190cfb43b1fe1f896ab02e690 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 1 Feb 2019 12:36:35 -0700 Subject: [PATCH 0207/1250] r0.1.0 of the s2s specification --- changelogs/server_server.rst | 6 ++++++ specification/identity_service_api.rst | 2 +- specification/rooms/v1.rst | 4 ++-- specification/rooms/v2.rst | 2 +- specification/rooms/v3.rst | 4 ++-- specification/server_server_api.rst | 2 +- 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/changelogs/server_server.rst b/changelogs/server_server.rst index e69de29b..5dabc4ac 100644 --- a/changelogs/server_server.rst +++ b/changelogs/server_server.rst @@ -0,0 +1,6 @@ +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. diff --git a/specification/identity_service_api.rst b/specification/identity_service_api.rst index 1bcdeff0..ecd2c99f 100644 --- a/specification/identity_service_api.rst +++ b/specification/identity_service_api.rst @@ -279,4 +279,4 @@ this isn't possible. .. _`Unpadded Base64`: ../appendices.html#unpadded-base64 .. _`3PID Types`: ../appendices.html#pid-types .. _`Signing JSON`: ../appendices.html#signing-json -.. _`/3pid/onbind`: ../server_server/unstable.html#put-matrix-federation-v1-3pid-onbind +.. _`/3pid/onbind`: ../server_server/r0.1.0.html#put-matrix-federation-v1-3pid-onbind diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index d7939c61..63bb1d7a 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -290,5 +290,5 @@ Events in version 1 rooms have the following structure: {{definition_ss_pdu}} -.. _`auth events selection`: ../../server_server/unstable.html#auth-events-selection -.. _`Signing Events`: ../../server_server/unstable.html#signing-events +.. _`auth events selection`: ../../server_server/r0.1.0.html#auth-events-selection +.. _`Signing Events`: ../../server_server/r0.1.0.html#signing-events diff --git a/specification/rooms/v2.rst b/specification/rooms/v2.rst index c95fc4c9..b73662ea 100644 --- a/specification/rooms/v2.rst +++ b/specification/rooms/v2.rst @@ -159,7 +159,7 @@ The *resolution* of a set of states is obtained as follows: resolved state. -.. _`authorization rules`: ../server_server/unstable.html#authorization-rules +.. _`authorization rules`: ../server_server/r0.1.0.html#authorization-rules Rejected events +++++++++++++++ diff --git a/specification/rooms/v3.rst b/specification/rooms/v3.rst index e5b0c44c..36848519 100644 --- a/specification/rooms/v3.rst +++ b/specification/rooms/v3.rst @@ -117,5 +117,5 @@ The remaining rules are the same as `room version 1 `_: Includes all changes since the latest versioned release. +- `r0.1.0 `_ Server discovery ---------------- From 9631e4bcb1927bb69995346a02fb8183347c7527 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 1 Feb 2019 18:00:26 -0700 Subject: [PATCH 0208/1250] Add a bit of text to ensure that the intro page isn't missed --- specification/index.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/specification/index.rst b/specification/index.rst index aa4471c4..db6ff99f 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -40,10 +40,14 @@ The specification consists of the following parts: {{apis}} +Additionally, this introduction page is a valuable resource for all Matrix developers, +including the sections on `room versions <#room-versions>`_ and `overall architecture <#architecture>`_. + The `Appendices `_ contain supplemental information not specific to one of the above APIs. -The `Matrix Client-Server API Swagger Viewer `_ is useful for browsing the Client-Server API. +The `Matrix Client-Server API Swagger Viewer `_ +is useful for browsing the Client-Server API. Introduction to the Matrix APIs ------------------------------- From 1f5783b329f1d5b5e58206ff0a0f54d895868f10 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 1 Feb 2019 18:07:55 -0700 Subject: [PATCH 0209/1250] fix links and wording --- specification/index.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/specification/index.rst b/specification/index.rst index db6ff99f..d6176c93 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -40,8 +40,9 @@ The specification consists of the following parts: {{apis}} -Additionally, this introduction page is a valuable resource for all Matrix developers, -including the sections on `room versions <#room-versions>`_ and `overall architecture <#architecture>`_. +Additionally, this introduction page contains the key baseline information required to +understand the specific APIs, including the sections on `room versions`_ +and `overall architecture <#architecture>`_. The `Appendices `_ contain supplemental information not specific to one of the above APIs. @@ -132,6 +133,8 @@ To propose a change to the Matrix Spec, see the explanations at `Proposals for Spec Changes to Matrix `_. +.. _`architecture`: + Architecture ------------ @@ -422,6 +425,7 @@ dedicated API. The API is symmetrical to managing Profile data. Would it really be overengineered to use the same API for both profile & private user data, but with different ACLs? +.. _`room versions`: Room Versions ------------- From e9bac1b011957c87e3791b916b70755fbafa401e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 4 Feb 2019 13:49:29 -0700 Subject: [PATCH 0210/1250] Remove wrong references to TLS fingerprints Also fix some styling in the server discovery section - this didn't feel like it needed its own commit. --- specification/server_server_api.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 778a5819..d00ca135 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -157,14 +157,14 @@ The process overall is as follows: and a port of 8448, using a ``Host`` header of ````. The target server must present a valid certificate for ````. -4. If the `/.well-known` request resulted in an error response, a server +4. If the ``/.well-known`` request resulted in an error response, a server is found by resolving an SRV record for ``_matrix._tcp.``. This may result in a hostname (to be resolved using AAAA or A records) and port. Requests are made to the resolved IP address and port, using 8448 as a default port, with a ``Host`` header of ````. The target server must present a valid certificate for ````. -5. If the `/.well-known` request returned an error response, and the SRV +5. If the ``/.well-known`` request returned an error response, and the SRV record was not found, an IP address is resolved using AAAA and A records. Requests are made to the resolved IP address using port 8448 and a ``Host`` header containing the ````. The target server must present a @@ -220,12 +220,11 @@ server by querying other servers. Publishing Keys +++++++++++++++ -Homeservers publish the allowed TLS fingerprints and signing keys in a JSON +Homeservers publish their signing keys in a JSON object at ``/_matrix/key/v2/server/{key_id}``. The response contains a list of ``verify_keys`` that are valid for signing federation requests made by the homeserver and for signing events. It contains a list of ``old_verify_keys`` which -are only valid for signing events. Finally the response contains a list of TLS -certificate fingerprints to validate any connection made to the homeserver. +are only valid for signing events. {{keys_server_ss_http_api}} From 3dd0601a96be6f285753d72aa9fd212bb9ae3bc7 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 4 Feb 2019 13:52:20 -0700 Subject: [PATCH 0211/1250] Remove more TLS fingerprint talk --- api/server-server/keys_server.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/server-server/keys_server.yaml b/api/server-server/keys_server.yaml index 8734f2ed..69985ab7 100644 --- a/api/server-server/keys_server.yaml +++ b/api/server-server/keys_server.yaml @@ -27,7 +27,7 @@ paths: get: summary: Get the homeserver's public key(s) description: |- - Gets the homeserver's published TLS fingerprints and signing keys. + Gets the homeserver's published signing keys. The homeserver may have any number of active keys and may have a number of old keys. @@ -49,7 +49,7 @@ paths: type: string description: |- **Deprecated**. Servers should not use this parameter and instead - opt to return all keys, not just the requested one. The key ID to + opt to return all keys, not just the requested one. The key ID to look up. required: false x-example: "ed25519:abc123" From 6067a4ad3cfcfde21f812484162704728d144a96 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 4 Feb 2019 13:56:59 -0700 Subject: [PATCH 0212/1250] Use the real identity server version in the APIs table --- scripts/templating/matrix_templates/units.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index 721501ff..f697dbdf 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -774,7 +774,7 @@ class MatrixUnits(Units): "Privileged server plugins", ), TypeTableRow( "`Identity Service API `_", - "unstable", + is_ver, "Mapping of third party IDs to Matrix IDs", ), TypeTableRow( "`Push Gateway API `_", From f37a6d2ef554a4534ac6834e9c37fb5c1e008275 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 4 Feb 2019 14:00:34 -0700 Subject: [PATCH 0213/1250] Changelog --- changelogs/server_server/newsfragments/1844.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/server_server/newsfragments/1844.clarification diff --git a/changelogs/server_server/newsfragments/1844.clarification b/changelogs/server_server/newsfragments/1844.clarification new file mode 100644 index 00000000..f80eef51 --- /dev/null +++ b/changelogs/server_server/newsfragments/1844.clarification @@ -0,0 +1 @@ +Remove legacy references to TLS fingerprints. From 54ee861b5faf85bea35361cdbb89f28bae15711b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 4 Feb 2019 14:47:20 -0700 Subject: [PATCH 0214/1250] Fix changelog generation for non-default versions Currently if you generate a changelog for r0.1.1 of an API, you'd get "No significant changes" which is wrong. You should get a real changelog for the version. This is now handled by generating a "preferred" changelog which acts as the default for version variables in the RST. Using a specific version's changelog is still supported for the rare cases where that is desired. --- scripts/templating/matrix_templates/sections.py | 2 +- scripts/templating/matrix_templates/units.py | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/scripts/templating/matrix_templates/sections.py b/scripts/templating/matrix_templates/sections.py index af497674..4451d21d 100644 --- a/scripts/templating/matrix_templates/sections.py +++ b/scripts/templating/matrix_templates/sections.py @@ -41,7 +41,7 @@ class MatrixSections(Sections): version_var = "%s_%s" % (spec_var, version) logger.info("Rendering changelog for %s" % version_var) rendered[version_var] = changelog - if version == "unstable": + if version == "preferred": rendered[spec_var] = changelog return rendered diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index 721501ff..fd261838 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -903,9 +903,17 @@ class MatrixUnits(Units): return schema - def load_changelogs(self): + def load_changelogs(self, substitutions): changelogs = {} + preferred_versions = { + "server_server": substitutions.get("%SERVER_RELEASE_LABEL%", "unstable"), + "client_server": substitutions.get("%CLIENT_RELEASE_LABEL%", "unstable"), + "identity_service": substitutions.get("%IDENTITY_RELEASE_LABEL%", "unstable"), + "push_gateway": substitutions.get("%PUSH_GATEWAY_RELEASE_LABEL%", "unstable"), + "application_service": substitutions.get("%APPSERVICE_RELEASE_LABEL%", "unstable"), + } + # Changelog generation is a bit complicated. We rely on towncrier to # generate the unstable/current changelog, but otherwise use the RST # edition to record historical changelogs. This is done by prepending @@ -1007,6 +1015,10 @@ class MatrixUnits(Units): title_part = keyword_versions[title_part] changelog = "".join(changelog_lines) changelogs[name][title_part.replace("^[a-zA-Z0-9]", "_").lower()] = changelog + preferred_changelog = changelogs[name]["unstable"] + if name in preferred_versions: + preferred_changelog = changelogs[name][preferred_versions[name]] + changelogs[name]["preferred"] = preferred_changelog return changelogs From 3581368f1f9066bf0d2679f8909a921c83d5486c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 4 Feb 2019 14:48:31 -0700 Subject: [PATCH 0215/1250] Add the "please use latest.html" warning to the s2s spec Now that we have a release, we should be warning people who try and use the unstable spec as fact. --- specification/server_server_api.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 778a5819..0993cc14 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -16,6 +16,8 @@ Federation API ============== +{{unstable_warning_block_SERVER_RELEASE_LABEL}} + Matrix homeservers use the Federation APIs (also known as server-server APIs) to communicate with each other. Homeservers use these APIs to push messages to each other in real-time, to retrieve historic messages from each other, and to From 4ec3a43a8534a1f17d861e14271d5b51853f27dd Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 5 Feb 2019 12:58:11 +0000 Subject: [PATCH 0216/1250] Replace "3pid" with "3PID" --- specification/client_server_api.rst | 12 ++++++------ specification/identity_service_api.rst | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index c506af4e..1dce010c 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -650,7 +650,7 @@ For example, to authenticate using the user's Matrix ID, clients would submit: "session": "" } -Alternatively reply using a 3pid bound to the user's account on the homeserver +Alternatively reply using a 3PID bound to the user's account on the homeserver using the |/account/3pid|_ API rather then giving the ``user`` explicitly as follows: @@ -667,7 +667,7 @@ follows: "session": "" } -In the case that the homeserver does not know about the supplied 3pid, the +In the case that the homeserver does not know about the supplied 3PID, the homeserver must respond with 403 Forbidden. Google ReCaptcha @@ -930,8 +930,8 @@ Third-party ID :Description: The user is identified by a third-party identifier in canonicalised form. -A client can identify a user using a 3pid associated with the user's account on -the homeserver, where the 3pid was previously associated using the +A client can identify a user using a 3PID associated with the user's account on +the homeserver, where the 3PID was previously associated using the |/account/3pid|_ API. See the `3PID Types`_ Appendix for a list of Third-party ID media. @@ -987,7 +987,7 @@ request as follows: "password": "" } -Alternatively, a client can use a 3pid bound to the user's account on the +Alternatively, a client can use a 3PID bound to the user's account on the homeserver using the |/account/3pid|_ API rather then giving the ``user`` explicitly, as follows: @@ -1002,7 +1002,7 @@ explicitly, as follows: "password": "" } -In the case that the homeserver does not know about the supplied 3pid, the +In the case that the homeserver does not know about the supplied 3PID, the homeserver must respond with ``403 Forbidden``. To log in using a login token, clients should submit a ``/login`` request as diff --git a/specification/identity_service_api.rst b/specification/identity_service_api.rst index ecd2c99f..c6c0e5ec 100644 --- a/specification/identity_service_api.rst +++ b/specification/identity_service_api.rst @@ -22,10 +22,10 @@ Identity Service API The Matrix client-server and server-server APIs are largely expressed in Matrix user identifiers. From time to time, it is useful to refer to users by other -("third-party") identifiers, or "3pid"s, e.g. their email address or phone +("third-party") identifiers, or "3PID"s, e.g. their email address or phone number. This Identity Service Specification describes how mappings between third-party identifiers and Matrix user identifiers can be established, -validated, and used. This description technically may apply to any 3pid, but in +validated, and used. This description technically may apply to any 3PID, but in practice has only been applied specifically to email addresses and phone numbers. .. contents:: Table of Contents @@ -150,9 +150,9 @@ Identity is a privacy-sensitive issue. While the identity server exists to provide identity information, access should be restricted to avoid leaking potentially sensitive data. In particular, being able to construct large-scale connections between identities should be avoided. To this end, in general APIs -should allow a 3pid to be mapped to a Matrix user identity, but not in the other -direction (i.e. one should not be able to get all 3pids associated with a Matrix -user ID, or get all 3pids associated with a 3pid). +should allow a 3PID to be mapped to a Matrix user identity, but not in the other +direction (i.e. one should not be able to get all 3PIDs associated with a Matrix +user ID, or get all 3PIDs associated with a 3PID). Web browser clients ------------------- @@ -204,10 +204,10 @@ Establishing associations The flow for creating an association is session-based. -Within a session, one may prove that one has ownership of a 3pid. +Within a session, one may prove that one has ownership of a 3PID. Once this has been established, the user can form an association between that -3pid and a Matrix user ID. Note that this association is only proved one way; -a user can associate *any* Matrix user ID with a validated 3pid, +3PID and a Matrix user ID. Note that this association is only proved one way; +a user can associate *any* Matrix user ID with a validated 3PID, i.e. I can claim that any email address I own is associated with @billg:microsoft.com. @@ -255,11 +255,11 @@ General Invitation storage ------------------ -An identity server can store pending invitations to a user's 3pid, which will -be retrieved and can be either notified on or look up when the 3pid is +An identity server can store pending invitations to a user's 3PID, which will +be retrieved and can be either notified on or look up when the 3PID is associated with a Matrix user ID. -At a later point, if the owner of that particular 3pid binds it with a Matrix user +At a later point, if the owner of that particular 3PID binds it with a Matrix user ID, the identity server will attempt to make an HTTP POST to the Matrix user's homeserver via the `/3pid/onbind`_ endpoint. The request MUST be signed with a long-term private key for the identity server. From c8428b1f8bf38ec88a40f9ee38fbaead3bad052d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 5 Feb 2019 22:39:36 -0700 Subject: [PATCH 0217/1250] Fix contradiction in wellknown discovery for servers Fixes https://github.com/matrix-org/matrix-doc/issues/1854 --- api/server-server/wellknown.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/api/server-server/wellknown.yaml b/api/server-server/wellknown.yaml index 273da7eb..75676646 100644 --- a/api/server-server/wellknown.yaml +++ b/api/server-server/wellknown.yaml @@ -35,9 +35,8 @@ paths: 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 must result in server discovery failure (no - attempts should be made to continue finding an IP address/port number to connect - to). + 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" From c9b38cbe5310c8f0a8a637d4ac6ed57dcf1fb8e1 Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 6 Feb 2019 11:37:19 +0100 Subject: [PATCH 0218/1250] Key backup: add `PUT /room_keys/version/{version}` to allow matrix clients to add signatures to an existing backup --- .../1219-storing-megolm-keys-serverside.md | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 4d8e8f1c..4b121054 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -177,6 +177,42 @@ Error codes: - `M_NOT_FOUND`: No backup version has been created. +##### `PUT /room_keys/version/{version}` + +Update information about the given version, or the current version if `{version}` +is omitted. Only `signatures` in `auth_data` can be updated. + +Body parameters: + +- `algorithm` (string): Optional. Must be the same as in the body parameters for `GET + /room_keys/version`. +- `auth_data` (object): Required. algorithm-dependent data. For + `m.megolm_backup.v1.curve25519-aes-sha2`, see below for the definition of + this property. +- `version` (string): Optional. The backup version. Must be the same as the query parameter or must be the current version. + +Example: + +```javascript +{ + "auth_data": { + "public_key": "abcdefg", + "signatures": { + "something": { + "ed25519:something": "hijklmnop" + "ed25519:anotherthing": "abcdef" + } + } + } +} +``` + +On success, returns the empty JSON object. + +Error codes: + +- `M_NOT_FOUND`: No backup version has been created. + #### Storing keys ##### `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v` From e02b345c623210a718e13ac65afd66a120d90711 Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 6 Feb 2019 11:45:11 +0100 Subject: [PATCH 0219/1250] Revert "Key backup: add `PUT /room_keys/version/{version}` to allow matrix clients to add signatures to an existing backup" This reverts commit c9b38cbe5310c8f0a8a637d4ac6ed57dcf1fb8e1. --- .../1219-storing-megolm-keys-serverside.md | 36 ------------------- 1 file changed, 36 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 4b121054..4d8e8f1c 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -177,42 +177,6 @@ Error codes: - `M_NOT_FOUND`: No backup version has been created. -##### `PUT /room_keys/version/{version}` - -Update information about the given version, or the current version if `{version}` -is omitted. Only `signatures` in `auth_data` can be updated. - -Body parameters: - -- `algorithm` (string): Optional. Must be the same as in the body parameters for `GET - /room_keys/version`. -- `auth_data` (object): Required. algorithm-dependent data. For - `m.megolm_backup.v1.curve25519-aes-sha2`, see below for the definition of - this property. -- `version` (string): Optional. The backup version. Must be the same as the query parameter or must be the current version. - -Example: - -```javascript -{ - "auth_data": { - "public_key": "abcdefg", - "signatures": { - "something": { - "ed25519:something": "hijklmnop" - "ed25519:anotherthing": "abcdef" - } - } - } -} -``` - -On success, returns the empty JSON object. - -Error codes: - -- `M_NOT_FOUND`: No backup version has been created. - #### Storing keys ##### `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v` From 4b68b5c9392b44f72c7022686c766c408240d4dc Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 6 Feb 2019 12:20:56 -0700 Subject: [PATCH 0220/1250] Changelog --- changelogs/server_server/newsfragments/1855.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/server_server/newsfragments/1855.clarification diff --git a/changelogs/server_server/newsfragments/1855.clarification b/changelogs/server_server/newsfragments/1855.clarification new file mode 100644 index 00000000..e61e14c6 --- /dev/null +++ b/changelogs/server_server/newsfragments/1855.clarification @@ -0,0 +1 @@ +Clarify that servers should not fail to contact servers if ``/.well-known`` fails. From 8bd9ca4edd7a6f20da3a1d0e4a13854e70f03fa2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 6 Feb 2019 12:35:04 -0700 Subject: [PATCH 0221/1250] Prep for r0.1.1 of s2s --- changelogs/server_server.rst | 10 ++++++++++ .../server_server/newsfragments/1844.clarification | 1 - .../server_server/newsfragments/1855.clarification | 1 - specification/identity_service_api.rst | 2 +- specification/rooms/v1.rst | 4 ++-- specification/rooms/v2.rst | 2 +- specification/rooms/v3.rst | 4 ++-- specification/server_server_api.rst | 1 + 8 files changed, 17 insertions(+), 8 deletions(-) delete mode 100644 changelogs/server_server/newsfragments/1844.clarification delete mode 100644 changelogs/server_server/newsfragments/1855.clarification diff --git a/changelogs/server_server.rst b/changelogs/server_server.rst index 5dabc4ac..a21da177 100644 --- a/changelogs/server_server.rst +++ b/changelogs/server_server.rst @@ -1,3 +1,13 @@ +r0.1.1 +====== + +Spec Clarifications +------------------- + +- Remove legacy references to TLS fingerprints. (`#1844 `_) +- Clarify that servers should not fail to contact servers if ``/.well-known`` fails. (`#1855 `_) + + r0.1.0 ====== diff --git a/changelogs/server_server/newsfragments/1844.clarification b/changelogs/server_server/newsfragments/1844.clarification deleted file mode 100644 index f80eef51..00000000 --- a/changelogs/server_server/newsfragments/1844.clarification +++ /dev/null @@ -1 +0,0 @@ -Remove legacy references to TLS fingerprints. diff --git a/changelogs/server_server/newsfragments/1855.clarification b/changelogs/server_server/newsfragments/1855.clarification deleted file mode 100644 index e61e14c6..00000000 --- a/changelogs/server_server/newsfragments/1855.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that servers should not fail to contact servers if ``/.well-known`` fails. diff --git a/specification/identity_service_api.rst b/specification/identity_service_api.rst index ecd2c99f..e00cee81 100644 --- a/specification/identity_service_api.rst +++ b/specification/identity_service_api.rst @@ -279,4 +279,4 @@ this isn't possible. .. _`Unpadded Base64`: ../appendices.html#unpadded-base64 .. _`3PID Types`: ../appendices.html#pid-types .. _`Signing JSON`: ../appendices.html#signing-json -.. _`/3pid/onbind`: ../server_server/r0.1.0.html#put-matrix-federation-v1-3pid-onbind +.. _`/3pid/onbind`: ../server_server/r0.1.1.html#put-matrix-federation-v1-3pid-onbind diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index 63bb1d7a..f5013194 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -290,5 +290,5 @@ Events in version 1 rooms have the following structure: {{definition_ss_pdu}} -.. _`auth events selection`: ../../server_server/r0.1.0.html#auth-events-selection -.. _`Signing Events`: ../../server_server/r0.1.0.html#signing-events +.. _`auth events selection`: ../../server_server/r0.1.1.html#auth-events-selection +.. _`Signing Events`: ../../server_server/r0.1.1.html#signing-events diff --git a/specification/rooms/v2.rst b/specification/rooms/v2.rst index b73662ea..7ad7668c 100644 --- a/specification/rooms/v2.rst +++ b/specification/rooms/v2.rst @@ -159,7 +159,7 @@ The *resolution* of a set of states is obtained as follows: resolved state. -.. _`authorization rules`: ../server_server/r0.1.0.html#authorization-rules +.. _`authorization rules`: ../server_server/r0.1.1.html#authorization-rules Rejected events +++++++++++++++ diff --git a/specification/rooms/v3.rst b/specification/rooms/v3.rst index 36848519..0915d196 100644 --- a/specification/rooms/v3.rst +++ b/specification/rooms/v3.rst @@ -117,5 +117,5 @@ The remaining rules are the same as `room version 1 `_: Includes all changes since the latest versioned release. +- `r0.1.1 `_ - `r0.1.0 `_ Server discovery From 76946a8a7c6ba2bffb26ef91993e7b993bba03a9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 6 Feb 2019 22:02:21 -0700 Subject: [PATCH 0222/1250] Simplify changelog generation We don'e need `{{server_server_changelog_r0.1.0}}` (for example), so don't go through the hassle of generating it. Instead, we'll generate the changelog for the requested versions of each API and put that in place. In the future, we may wish to consider bringing back more complicated variables when/if we start generating released versions of the spec on the fly rather than manually. --- .../templating/matrix_templates/sections.py | 9 +- scripts/templating/matrix_templates/units.py | 181 +++++++++--------- 2 files changed, 92 insertions(+), 98 deletions(-) diff --git a/scripts/templating/matrix_templates/sections.py b/scripts/templating/matrix_templates/sections.py index 4451d21d..5961aa24 100644 --- a/scripts/templating/matrix_templates/sections.py +++ b/scripts/templating/matrix_templates/sections.py @@ -34,15 +34,10 @@ class MatrixSections(Sections): def render_changelogs(self): rendered = {} changelogs = self.units.get("changelogs") - for spec, versioned in changelogs.items(): + for spec, changelog_text in changelogs.items(): spec_var = "%s_changelog" % spec logger.info("Rendering changelog for spec: %s" % spec) - for version, changelog in versioned.items(): - version_var = "%s_%s" % (spec_var, version) - logger.info("Rendering changelog for %s" % version_var) - rendered[version_var] = changelog - if version == "preferred": - rendered[spec_var] = changelog + rendered[spec_var] = changelog_text return rendered def _render_events(self, filterFn, sortFn): diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index fd261838..0e3546cb 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -904,9 +904,20 @@ class MatrixUnits(Units): return schema def load_changelogs(self, substitutions): + """Loads the changelog unit for later rendering in a section. + + Args: + substitutions: dict of variable name to value. Provided by the gendoc script. + + Returns: + A dict of API name ("client_server", for example) to changelog. + """ changelogs = {} - preferred_versions = { + # The APIs and versions we'll prepare changelogs for. We use the substitutions + # to ensure that we pick up the right version for generated documentation. This + # defaults to "unstable" as a version for incremental generated documentation (CI). + prepare_versions = { "server_server": substitutions.get("%SERVER_RELEASE_LABEL%", "unstable"), "client_server": substitutions.get("%CLIENT_RELEASE_LABEL%", "unstable"), "identity_service": substitutions.get("%IDENTITY_RELEASE_LABEL%", "unstable"), @@ -914,112 +925,100 @@ class MatrixUnits(Units): "application_service": substitutions.get("%APPSERVICE_RELEASE_LABEL%", "unstable"), } - # Changelog generation is a bit complicated. We rely on towncrier to - # generate the unstable/current changelog, but otherwise use the RST - # edition to record historical changelogs. This is done by prepending - # the towncrier output to the RST in memory, then parsing the RST by - # hand. We parse the entire changelog to create a changelog for each - # version which may be of use in some APIs. - - # Map specific headers to specific keys that'll be used eventually - # in variables. Things not listed here will get lowercased and formatted - # such that characters not [a-z0-9] will be replaced with an underscore. - keyword_versions = { - "Unreleased Changes": "unstable" - } - - # Only generate changelogs for things that have an RST document - for f in os.listdir(CHANGELOG_DIR): - if not f.endswith(".rst"): - continue - path = os.path.join(CHANGELOG_DIR, f) - name = f[:-4] # take off ".rst" - - # If there's a directory with the same name, we'll try to generate - # a towncrier changelog and prepend it to the general changelog. - tc_path = os.path.join(CHANGELOG_DIR, name) - tc_lines = [] - if os.path.isdir(tc_path): - logger.info("Generating towncrier changelog for: %s" % name) - p = subprocess.Popen( - ['towncrier', '--version', 'Unreleased Changes', '--name', name, '--draft'], - cwd=tc_path, - stderr=subprocess.PIPE, - stdout=subprocess.PIPE, - ) - stdout, stderr = p.communicate() - if p.returncode != 0: - # Something broke - dump as much information as we can - logger.error("Towncrier exited with code %s" % p.returncode) - logger.error(stdout.decode('UTF-8')) - logger.error(stderr.decode('UTF-8')) - raw_log = "" - else: - raw_log = stdout.decode('UTF-8') - - # This is a bit of a hack, but it does mean that the log at least gets *something* - # to tell us it broke - if not raw_log.startswith("Unreleased Changes"): - logger.error("Towncrier appears to have failed to generate a changelog") - logger.error(raw_log) - raw_log = "" - tc_lines = raw_log.splitlines() + # Changelogs are split into two places: towncrier for the unstable changelog and + # the RST file for historical versions. If the prepare_versions dict above has + # a version other than "unstable" specified for an API, we'll use the historical + # changelog and otherwise generate the towncrier log in-memory. - title_part = None + for api_name, target_version in prepare_versions.items(): + logger.info("Generating changelog for %s at %s" % (api_name, target_version,)) changelog_lines = [] - with open(path, "r", encoding="utf-8") as f: - lines = f.readlines() + if target_version == 'unstable': + # generate towncrier log + tc_path = os.path.join(CHANGELOG_DIR, api_name) + if os.path.isdir(tc_path): + logger.info("Generating towncrier changelog for: %s" % api_name) + p = subprocess.Popen( + ['towncrier', '--version', 'unstable', '--name', api_name, '--draft'], + cwd=tc_path, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + ) + stdout, stderr = p.communicate() + if p.returncode != 0: + # Something broke - dump as much information as we can + logger.error("Towncrier exited with code %s" % p.returncode) + logger.error(stdout.decode('UTF-8')) + logger.error(stderr.decode('UTF-8')) + raw_log = "" + else: + raw_log = stdout.decode('UTF-8') + + # This is a bit of a hack, but it does mean that the log at least gets *something* + # to tell us it broke + if not raw_log.startswith("unstable"): + logger.error("Towncrier appears to have failed to generate a changelog") + logger.error(raw_log) + raw_log = "" + changelog_lines = raw_log.splitlines() + else: + # read in the existing RST changelog + logger.info("Reading changelog RST for %s" % api_name) + rst_path = os.path.join(CHANGELOG_DIR, "%s.rst" % api_name) + with open(rst_path, 'r', encoding="utf-8") as f: + changelog_lines = f.readlines() + + # Parse the changelog lines to find the header we're looking for and therefore + # the changelog body. prev_line = None - for line in (tc_lines + lines): + title_part = None + changelog_body_lines = [] + have_changelog = False + for line in changelog_lines: if prev_line is None: prev_line = line continue if not title_part: - # find the title underline (at least 3 =) + # Titles we care about are underlined with at least 3 equal signs if re.match("^[=]{3,}$", line.strip()): - title_part = prev_line + logger.info("Found header %s" % prev_line) + title_part = prev_line.strip() continue prev_line = line - else: # have title, get body (stop on next title or EOF) + else: + # we have a title, start parsing the body if re.match("^[=]{3,}$", line.strip()): - # we hit another title, so pop the last line of - # the changelog and record the changelog - new_title = changelog_lines.pop() - if name not in changelogs: - changelogs[name] = {} - if title_part in keyword_versions: - title_part = keyword_versions[title_part] - title_part = title_part.strip().replace("^[a-zA-Z0-9]", "_").lower() - changelog = "".join(changelog_lines) - changelogs[name][title_part] = changelog - - # reset for the next version - changelog_lines = [] - title_part = new_title.strip() + # we hit another title. prev_line will be the new section's header. + # do a check to see if the section we just read is the one we want - if + # it is, use that changelog and move on. If it isn't, keep reading. + if title_part == target_version: + changelogs[api_name] = "".join(changelog_body_lines) + have_changelog = True + break + # not the section we want - start the next section + title_part = changelog_body_lines.pop().strip() + changelog_body_lines = [] continue - # Don't generate subheadings (we'll keep the title though) if re.match("^[-]{3,}$", line.strip()): - continue - if line.strip().startswith(".. version: "): - # The changelog is directing us to use a different title - # for the changelog. - title_part = line.strip()[len(".. version: "):] + # the last line is a subheading - drop this line because it's the underline + # and that causes problems with rendering. We'll keep the header text though. continue if line.strip().startswith(".. "): - continue # skip comments - changelog_lines.append(" " + line + '\n') - if len(changelog_lines) > 0 and title_part is not None: - if name not in changelogs: - changelogs[name] = {} - if title_part in keyword_versions: - title_part = keyword_versions[title_part] - changelog = "".join(changelog_lines) - changelogs[name][title_part.replace("^[a-zA-Z0-9]", "_").lower()] = changelog - preferred_changelog = changelogs[name]["unstable"] - if name in preferred_versions: - preferred_changelog = changelogs[name][preferred_versions[name]] - changelogs[name]["preferred"] = preferred_changelog + # skip comments + continue + # if we made it this far, append the line to the changelog body. We indent it so + # that it renders correctly in the section. We also add newlines so that there's + # intentionally blank lines that make rst2html happy. + changelog_body_lines.append(" " + line + '\n') + # do some quick checks to see if the last read section is our changelog + if not have_changelog: + logger.info("No changelog - testing %s == %s" % (target_version, title_part,)) + if title_part == target_version and len(changelog_body_lines) > 0: + changelogs[api_name] = "".join(changelog_body_lines) + else: + raise ValueError("No changelog for %s at %s" % (api_name, target_version,)) + # return our `dict[api_name] => changelog` as the last step. return changelogs def load_unstable_warnings(self, substitutions): From 375104127cc25fc5cb3d46456e4b7d08623f490c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 6 Feb 2019 22:03:16 -0700 Subject: [PATCH 0223/1250] Fix spec release process to match new changelog stuff Also while we're here, make it accurate. Fixes https://github.com/matrix-org/matrix-doc/issues/1858 --- meta/releasing_a_spec.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/meta/releasing_a_spec.md b/meta/releasing_a_spec.md index 2d9cd34e..1d7aaea7 100644 --- a/meta/releasing_a_spec.md +++ b/meta/releasing_a_spec.md @@ -18,16 +18,18 @@ The remainder of the process is as follows: 1. Activate your Python 3 virtual environment. 1. Having checked out the new release branch, navigate your way over to `./changelogs`. 1. Follow the release instructions provided in the README.md located there. -1. Update the changelog section of the specification you're releasing to make a reference - to the new version. 1. Update any version/link references across all specifications. -1. Ensure the `targets.yml` file lists the version correctly. -1. Commit the changes and PR them to master. -1. Tag the release with the format `client_server/r0.4.0`. -1. Add the changes to the matrix-org/matrix.org repository (for historic tracking). +1. Generate the specification using `./scripts/gendoc.py -c r0.4.0`, specifying all the + API versions at the time of generation. +1. PR the changes to the matrix-org/matrix.org repository (for historic tracking). * This is done by making a PR to the `unstyled_docs/spec` folder for the version and specification you're releasing. * Don't forget to symlink the new release as `latest`. + * For the client-server API, don't forget to generate the swagger JSON by using + `./scripts/dump-swagger.py -c r0.4.0`. This will also need symlinking to `latest`. +1. Commit the changes and PR them to master. **Wait for review from the spec core team.** + * Link to your matrix-org/matrix.org so both can be reviewed at the same time. +1. Tag the release with the format `client_server/r0.4.0`. 1. Perform a release on GitHub to tag the release. 1. Yell from the mountaintop to the world about the new release. From cf11965a8ee6c9bbe2de6e107b9291ecf666b8aa Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 6 Feb 2019 22:15:13 -0700 Subject: [PATCH 0224/1250] Change notice about room v2's scope to represent reality Fixes https://github.com/matrix-org/matrix-doc/issues/1851 --- specification/rooms/v2.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/specification/rooms/v2.rst b/specification/rooms/v2.rst index 7ad7668c..6188966a 100644 --- a/specification/rooms/v2.rst +++ b/specification/rooms/v2.rst @@ -27,9 +27,8 @@ Server implementation components details contained here, and can safely ignore their presence. -The algorithms defined here should only apply to version 2 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. +Room version 2 uses the base compoennts of `room version 1 `_, changing +only the state resolution algorithm. State resolution From 85578f984240b3eda83b074f0ee286175806e5a6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 6 Feb 2019 22:18:56 -0700 Subject: [PATCH 0225/1250] Fix spelling mistake: endponts -> endpoints Fixes https://github.com/matrix-org/matrix-doc/issues/1677 --- changelogs/client_server/newsfragments/1838.clarification | 1 + changelogs/client_server/newsfragments/1860.clarification | 1 + specification/client_server_api.rst | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/1838.clarification create mode 100644 changelogs/client_server/newsfragments/1860.clarification diff --git a/changelogs/client_server/newsfragments/1838.clarification b/changelogs/client_server/newsfragments/1838.clarification new file mode 100644 index 00000000..b0f05203 --- /dev/null +++ b/changelogs/client_server/newsfragments/1838.clarification @@ -0,0 +1 @@ +Fix various spelling mistakes throughout the specification. diff --git a/changelogs/client_server/newsfragments/1860.clarification b/changelogs/client_server/newsfragments/1860.clarification new file mode 100644 index 00000000..b0f05203 --- /dev/null +++ b/changelogs/client_server/newsfragments/1860.clarification @@ -0,0 +1 @@ +Fix various spelling mistakes throughout the specification. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index c506af4e..b41c3460 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -73,7 +73,7 @@ MUST be encoded as UTF-8. Clients are authenticated using opaque ``access_token`` strings (see `Client Authentication`_ for details), passed as a query string parameter on all requests. -The names of the API endponts for the HTTP transport follow a convention of +The names of the API endpoints for the HTTP transport follow a convention of using underscores to separate words (for example ``/delete_devices``). The key names in JSON objects passed over the API also follow this convention. From 772ba8dc2af8c9236aa2947603ae270c78f99c9b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 6 Feb 2019 22:26:41 -0700 Subject: [PATCH 0226/1250] Add a table of contents to each room version spec Fixes https://github.com/matrix-org/matrix-doc/issues/1852 We get clickable headers for free by doing this. --- specification/rooms/v1.rst | 3 +++ specification/rooms/v2.rst | 3 +++ specification/rooms/v3.rst | 3 +++ 3 files changed, 9 insertions(+) diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index f5013194..1c7a56c4 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -18,6 +18,9 @@ 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 -------------------------------- diff --git a/specification/rooms/v2.rst b/specification/rooms/v2.rst index 7ad7668c..b262f47f 100644 --- a/specification/rooms/v2.rst +++ b/specification/rooms/v2.rst @@ -18,6 +18,9 @@ Room Version 2 This room version builds off of `version 1 `_ with an improved state resolution algorithm. +.. contents:: Table of Contents +.. sectnum:: + Server implementation components -------------------------------- diff --git a/specification/rooms/v3.rst b/specification/rooms/v3.rst index 0915d196..863f1c3a 100644 --- a/specification/rooms/v3.rst +++ b/specification/rooms/v3.rst @@ -24,6 +24,9 @@ This room version builds on `version 2 `_ with an improved event format 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 --------------------- From 0ed0fee26147af548d2684f25ed8aa06028fdc59 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 7 Feb 2019 08:09:35 -0700 Subject: [PATCH 0227/1250] Update specification/rooms/v2.rst Co-Authored-By: turt2live --- specification/rooms/v2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/rooms/v2.rst b/specification/rooms/v2.rst index 6188966a..1ff2d3fc 100644 --- a/specification/rooms/v2.rst +++ b/specification/rooms/v2.rst @@ -27,7 +27,7 @@ Server implementation components details contained here, and can safely ignore their presence. -Room version 2 uses the base compoennts of `room version 1 `_, changing +Room version 2 uses the base components of `room version 1 `_, changing only the state resolution algorithm. From 2099308d4cf1b733b88976f535590932f9b0eafb Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 6 Feb 2019 11:50:47 +0100 Subject: [PATCH 0228/1250] Key backup: add `PUT /room_keys/version/{version}` to allow matrix clients to add signatures to an existing backup --- .../1219-storing-megolm-keys-serverside.md | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 4d8e8f1c..ae361d3a 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -177,6 +177,42 @@ Error codes: - `M_NOT_FOUND`: No backup version has been created. +##### `PUT /room_keys/version/{version}` + +Update information about the given version, or the current version if `{version}` +is omitted. Only `auth_data` can be updated. + +Body parameters: + +- `algorithm` (string): Optional. Must be the same as in the body parameters for `GET + /room_keys/version`. +- `auth_data` (object): Required. algorithm-dependent data. For + `m.megolm_backup.v1.curve25519-aes-sha2`, see below for the definition of + this property. +- `version` (string): Optional. The backup version. Must be the same as the query parameter or must be the current version. + +Example: + +```javascript +{ + "auth_data": { + "public_key": "abcdefg", + "signatures": { + "something": { + "ed25519:something": "hijklmnop" + "ed25519:anotherthing": "abcdef" + } + } + } +} +``` + +On success, returns the empty JSON object. + +Error codes: + +- `M_NOT_FOUND`: No backup version found. + #### Storing keys ##### `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v` From d43b595b5e4ec966508b09af010c3273336f10cf Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 7 Feb 2019 10:36:34 +0100 Subject: [PATCH 0229/1250] Key backup: Fix PR remarks on `PUT /room_keys/version/{version}` --- proposals/1219-storing-megolm-keys-serverside.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index ae361d3a..f4f45827 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -179,17 +179,16 @@ Error codes: ##### `PUT /room_keys/version/{version}` -Update information about the given version, or the current version if `{version}` -is omitted. Only `auth_data` can be updated. +Update information about the given version. Only `auth_data` can be updated. Body parameters: -- `algorithm` (string): Optional. Must be the same as in the body parameters for `GET +- `algorithm` (string): Required. Must be the same as in the body parameters for `GET /room_keys/version`. - `auth_data` (object): Required. algorithm-dependent data. For `m.megolm_backup.v1.curve25519-aes-sha2`, see below for the definition of this property. -- `version` (string): Optional. The backup version. Must be the same as the query parameter or must be the current version. +- `version` (string): Required. The backup version. Must be the same as the query parameter or must be the current version. Example: From e7f792602348f06f3c726f72902a127df0d7269e Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 7 Feb 2019 23:29:11 -0500 Subject: [PATCH 0230/1250] add algorithm and version to the example since they're marked as required --- proposals/1219-storing-megolm-keys-serverside.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index f4f45827..74a148a2 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -194,6 +194,7 @@ Example: ```javascript { + "algorithm": "m.megolm_backup.v1.curve25519-aes-sha2", "auth_data": { "public_key": "abcdefg", "signatures": { @@ -202,7 +203,8 @@ Example: "ed25519:anotherthing": "abcdef" } } - } + }, + "version": "42" } ``` From ed945d67444a5c011bd55d6cfbcf39ee3812e8bd Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 6 Feb 2019 12:03:44 +0100 Subject: [PATCH 0231/1250] Key backup: Expose the number of keys stored in the backup so that matrix clients can compare it with the number of keys they have locally. --- proposals/1219-storing-megolm-keys-serverside.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 74a148a2..1f33fb45 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -172,6 +172,7 @@ On success, returns a JSON object with keys: - `auth_data` (object): Required. Same as in the body parameters for `POST /room_keys/version`. - `version` (string): Required. The backup version. +- `count` (number): Required. The number of keys stored in the backup. Error codes: From 82ff866b5890e1e7132c5bdfc603c79ce92d7964 Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 6 Feb 2019 12:30:21 +0100 Subject: [PATCH 0232/1250] Key backup: Add `hash` to represent stored keys so that a matrix client A can check it is synchronised with the backup. If not, that means that another client B has pushed keys client A does not have locally. Client A should then propose to the end user to retrieve keys from the backup. --- .../1219-storing-megolm-keys-serverside.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 1f33fb45..22e57968 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -172,6 +172,7 @@ On success, returns a JSON object with keys: - `auth_data` (object): Required. Same as in the body parameters for `POST /room_keys/version`. - `version` (string): Required. The backup version. +- `hash` (string): Required. A hash value representing stored keys. - `count` (number): Required. The number of keys stored in the backup. Error codes: @@ -240,7 +241,9 @@ Body parameters: `m.megolm_backup.v1.curve25519-aes-sha2`, see below for the definition of this property. -On success, returns the empty JSON object. +On success, returns a JSON object with keys: + +- `hash` (string): Required. The new hash value representing stored keys. Error codes: @@ -267,8 +270,11 @@ Example: Result: ```javascript -{} +{ + "hash": "abcdefghi" +} ``` + ##### `PUT /room_keys/keys/${roomId}?version=$v` Store several keys for the given room, using the given backup version. @@ -308,8 +314,11 @@ Example: Result: ```javascript -{} +{ + "hash": "abcdefghi" +} ``` + ##### `PUT /room_keys/keys?version=$v` Store several keys, using the given backup version. @@ -353,7 +362,9 @@ Example: Result: ```javascript -{} +{ + "hash": "abcdefghi" +} ``` #### Retrieving keys From 7cde3193e535aa3510fc008fb8ce55617815a194 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 7 Feb 2019 10:29:30 +0100 Subject: [PATCH 0233/1250] Key backup: Explain `hash` better --- proposals/1219-storing-megolm-keys-serverside.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 22e57968..069021c8 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -172,7 +172,10 @@ On success, returns a JSON object with keys: - `auth_data` (object): Required. Same as in the body parameters for `POST /room_keys/version`. - `version` (string): Required. The backup version. -- `hash` (string): Required. A hash value representing stored keys. +- `hash` (string): Required. The hash value which is an opaque string + representing stored keys in the backup. Client can compare it with the `hash` + value they received in the response of their last key storage request. + If not equal, another matrix client pushed new keys to the backup. - `count` (number): Required. The number of keys stored in the backup. Error codes: @@ -243,7 +246,8 @@ Body parameters: On success, returns a JSON object with keys: -- `hash` (string): Required. The new hash value representing stored keys. +- `hash` (string): Required. The new hash value representing stored keys. See +`GET /room_keys/version/{version}` for more details. Error codes: From 0051c6a377ca9fa724f0848b6d2cb58dd1680660 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 7 Feb 2019 22:54:53 +0100 Subject: [PATCH 0234/1250] Key backup: Return {hash, count} for key upload requests This is this tuple that allows the client to check if it has locally all keys of the backup --- proposals/1219-storing-megolm-keys-serverside.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 069021c8..05c68520 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -248,6 +248,7 @@ On success, returns a JSON object with keys: - `hash` (string): Required. The new hash value representing stored keys. See `GET /room_keys/version/{version}` for more details. +- `count` (number): Required. The new count of keys stored in the backup. Error codes: @@ -275,7 +276,8 @@ Result: ```javascript { - "hash": "abcdefghi" + "hash": "abcdefghi", + "count": 10 } ``` @@ -319,7 +321,8 @@ Result: ```javascript { - "hash": "abcdefghi" + "hash": "abcdefghi", + "count": 10 } ``` @@ -367,7 +370,8 @@ Result: ```javascript { - "hash": "abcdefghi" + "hash": "abcdefghi", + "count": 10 } ``` From 7eb8b5d7f3992c4e5bcf295e1e672eff0f1ce0c7 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 8 Feb 2019 14:36:12 +0000 Subject: [PATCH 0235/1250] Add proposal for invite error code --- .../1866-invite-unsupported-version-error-code.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 proposals/1866-invite-unsupported-version-error-code.md diff --git a/proposals/1866-invite-unsupported-version-error-code.md b/proposals/1866-invite-unsupported-version-error-code.md new file mode 100644 index 00000000..98098637 --- /dev/null +++ b/proposals/1866-invite-unsupported-version-error-code.md @@ -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. From 6bbf22cd04733c1a0fc04ef1f05aab708068aed7 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 10 Feb 2019 17:07:42 -0700 Subject: [PATCH 0236/1250] Add routes for retrieving account data Original proposal: https://github.com/matrix-org/matrix-doc/issues/1339 This contains no known differences to what was ultimately decided upon and implemented. --- api/client-server/account-data.yaml | 87 +++++++++++++++++-- .../client_server/newsfragments/1873.new | 1 + 2 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 changelogs/client_server/newsfragments/1873.new diff --git a/api/client-server/account-data.yaml b/api/client-server/account-data.yaml index 76b2b156..ae845b25 100644 --- a/api/client-server/account-data.yaml +++ b/api/client-server/account-data.yaml @@ -43,8 +43,8 @@ paths: name: userId required: true description: |- - The id of the user to set account_data for. The access token must be - authorized to make requests for this user id. + The ID of the user to set account_data for. The access token must be + authorized to make requests for this user ID. x-example: "@alice:example.com" - in: path type: string @@ -69,6 +69,41 @@ paths: The account_data was successfully added. tags: - User data + get: + summary: Get some account_data for the user. + description: |- + Get some account_data for the client. This config is only visible to the user + that set the account_data. + operationId: getAccountData + security: + - accessToken: [] + parameters: + - in: path + type: string + name: userId + required: true + description: |- + The ID of the user to get account_data for. The access token must be + authorized to make requests for this user ID. + x-example: "@alice:example.com" + - in: path + type: string + name: type + required: true + description: |- + The event type of the account_data to get. Custom types should be + namespaced to avoid clashes. + x-example: "org.example.custom.config" + responses: + 200: + description: + The account data content for the given type. + schema: + type: object + example: { + "custom_account_data_key": "custom_config_value"} + tags: + - User data "/user/{userId}/rooms/{roomId}/account_data/{type}": put: summary: Set some account_data for the user. @@ -85,15 +120,15 @@ paths: name: userId required: true description: |- - The id of the user to set account_data for. The access token must be - authorized to make requests for this user id. + The ID of the user to set account_data for. The access token must be + authorized to make requests for this user ID. x-example: "@alice:example.com" - in: path type: string name: roomId required: true description: |- - The id of the room to set account_data on. + The ID of the room to set account_data on. x-example: "!726s6s6q:example.com" - in: path type: string @@ -118,3 +153,45 @@ paths: The account_data was successfully added. tags: - User data + get: + summary: Get some account_data for the user. + 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. + operationId: getAccountDataPerRoom + security: + - accessToken: [] + parameters: + - in: path + type: string + name: userId + required: true + description: |- + The ID of the user to set account_data for. The access token must be + authorized to make requests for this user ID. + x-example: "@alice:example.com" + - in: path + type: string + name: roomId + required: true + description: |- + The ID of the room to get account_data for. + x-example: "!726s6s6q:example.com" + - in: path + type: string + name: type + required: true + description: |- + The event type of the account_data to get. Custom types should be + namespaced to avoid clashes. + x-example: "org.example.custom.room.config" + responses: + 200: + description: + The account data content for the given type. + schema: + type: object + example: { + "custom_account_data_key": "custom_config_value"} + tags: + - User data diff --git a/changelogs/client_server/newsfragments/1873.new b/changelogs/client_server/newsfragments/1873.new new file mode 100644 index 00000000..724a4308 --- /dev/null +++ b/changelogs/client_server/newsfragments/1873.new @@ -0,0 +1 @@ +``GET /account_data`` routes. From 5721712eae1ea6e039d8452c5539bb08f358b76e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 10 Feb 2019 17:47:17 -0700 Subject: [PATCH 0237/1250] Add M_RESOURCE_LIMIT_EXCEEDED Original proposal: https://github.com/matrix-org/matrix-doc/issues/1504 No changes from the original proposal or implementations have been made intentionally here. --- changelogs/client_server/newsfragments/1874.feature | 1 + specification/client_server_api.rst | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/1874.feature diff --git a/changelogs/client_server/newsfragments/1874.feature b/changelogs/client_server/newsfragments/1874.feature new file mode 100644 index 00000000..03b891e2 --- /dev/null +++ b/changelogs/client_server/newsfragments/1874.feature @@ -0,0 +1 @@ +Add `M_RESOURCE_LIMIT_EXCEEDED` as an error code for when homeservers exceed limits imposed on them. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index b41c3460..618fdc10 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -210,10 +210,18 @@ Other error codes the client might encounter are: The resource being requested is reserved by an application service, or the application service making the request has not created the resource. +:``M_RESOURCE_LIMIT_EXCEEDED``: + The request cannot be completed because the homeserver has reached a resource + limit imposed on it. For example, a homeserver held in a shared hosting environment + may reach a resource limit if it starts using too much memory or disk space. The + error MUST have an ``admin_contact`` field to provide the user receiving the error + a place to reach out to. Typically, this error will appear on routes which attempt + to modify state (eg: sending messages, account data, etc) and not routes which only + read state (eg: ``/sync``, get account data, etc). + .. TODO: More error codes (covered by other issues) .. * M_CONSENT_NOT_GIVEN - GDPR: https://github.com/matrix-org/matrix-doc/issues/1512 .. * M_CANNOT_LEAVE_SERVER_NOTICE_ROOM - GDPR: https://github.com/matrix-org/matrix-doc/issues/1254 -.. * M_RESOURCE_LIMIT_EXCEEDED - Limits: https://github.com/matrix-org/matrix-doc/issues/1504 .. _sect:txn_ids: From b1689a3036878cbf152e2e4de45f1ac28a08d5ee Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 10 Feb 2019 18:03:17 -0700 Subject: [PATCH 0238/1250] Misc improvements --- meta/releasing_a_spec.md | 4 +- scripts/templating/matrix_templates/units.py | 120 +++++++++---------- 2 files changed, 56 insertions(+), 68 deletions(-) diff --git a/meta/releasing_a_spec.md b/meta/releasing_a_spec.md index 1d7aaea7..f186c4be 100644 --- a/meta/releasing_a_spec.md +++ b/meta/releasing_a_spec.md @@ -19,8 +19,8 @@ The remainder of the process is as follows: 1. Having checked out the new release branch, navigate your way over to `./changelogs`. 1. Follow the release instructions provided in the README.md located there. 1. Update any version/link references across all specifications. -1. Generate the specification using `./scripts/gendoc.py -c r0.4.0`, specifying all the - API versions at the time of generation. +1. Generate the specification using `./scripts/gendoc.py`, specifying all the + API versions at the time of generation. For example: `./scripts/gendoc.py -c r0.4.0 -s r0.1.0 -i r0.1.0 #etc` 1. PR the changes to the matrix-org/matrix.org repository (for historic tracking). * This is done by making a PR to the `unstyled_docs/spec` folder for the version and specification you're releasing. diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index a061c693..c1755119 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -935,92 +935,80 @@ class MatrixUnits(Units): changelog_lines = [] if target_version == 'unstable': # generate towncrier log - tc_path = os.path.join(CHANGELOG_DIR, api_name) - if os.path.isdir(tc_path): - logger.info("Generating towncrier changelog for: %s" % api_name) - p = subprocess.Popen( - ['towncrier', '--version', 'unstable', '--name', api_name, '--draft'], - cwd=tc_path, - stderr=subprocess.PIPE, - stdout=subprocess.PIPE, - ) - stdout, stderr = p.communicate() - if p.returncode != 0: - # Something broke - dump as much information as we can - logger.error("Towncrier exited with code %s" % p.returncode) - logger.error(stdout.decode('UTF-8')) - logger.error(stderr.decode('UTF-8')) - raw_log = "" - else: - raw_log = stdout.decode('UTF-8') - - # This is a bit of a hack, but it does mean that the log at least gets *something* - # to tell us it broke - if not raw_log.startswith("unstable"): - logger.error("Towncrier appears to have failed to generate a changelog") - logger.error(raw_log) - raw_log = "" - changelog_lines = raw_log.splitlines() + changelog_lines = self._read_towncrier_changelog(api_name) else: # read in the existing RST changelog - logger.info("Reading changelog RST for %s" % api_name) - rst_path = os.path.join(CHANGELOG_DIR, "%s.rst" % api_name) - with open(rst_path, 'r', encoding="utf-8") as f: - changelog_lines = f.readlines() + changelog_lines = self._read_rst_changelog(api_name) # Parse the changelog lines to find the header we're looking for and therefore # the changelog body. prev_line = None title_part = None changelog_body_lines = [] - have_changelog = False for line in changelog_lines: if prev_line is None: prev_line = line continue - if not title_part: - # Titles we care about are underlined with at least 3 equal signs - if re.match("^[=]{3,}$", line.strip()): - logger.info("Found header %s" % prev_line) - title_part = prev_line.strip() - continue - prev_line = line - else: - # we have a title, start parsing the body - if re.match("^[=]{3,}$", line.strip()): - # we hit another title. prev_line will be the new section's header. - # do a check to see if the section we just read is the one we want - if - # it is, use that changelog and move on. If it isn't, keep reading. - if title_part == target_version: - changelogs[api_name] = "".join(changelog_body_lines) - have_changelog = True - break - # not the section we want - start the next section - title_part = changelog_body_lines.pop().strip() - changelog_body_lines = [] - continue - if re.match("^[-]{3,}$", line.strip()): - # the last line is a subheading - drop this line because it's the underline - # and that causes problems with rendering. We'll keep the header text though. - continue - if line.strip().startswith(".. "): - # skip comments - continue + if re.match("^[=]{3,}$", line.strip()): + # the last line was a header - use that as our new title_part + title_part = prev_line.strip() + continue + if re.match("^[-]{3,}$", line.strip()): + # the last line is a subheading - drop this line because it's the underline + # and that causes problems with rendering. We'll keep the header text though. + continue + if line.strip().startswith(".. "): + # skip comments + continue + if title_part == target_version: # if we made it this far, append the line to the changelog body. We indent it so # that it renders correctly in the section. We also add newlines so that there's # intentionally blank lines that make rst2html happy. changelog_body_lines.append(" " + line + '\n') - # do some quick checks to see if the last read section is our changelog - if not have_changelog: - logger.info("No changelog - testing %s == %s" % (target_version, title_part,)) - if title_part == target_version and len(changelog_body_lines) > 0: - changelogs[api_name] = "".join(changelog_body_lines) - else: - raise ValueError("No changelog for %s at %s" % (api_name, target_version,)) + + if len(changelog_body_lines) > 0: + changelogs[api_name] = "".join(changelog_body_lines) + else: + raise ValueError("No changelog for %s at %s" % (api_name, target_version,)) # return our `dict[api_name] => changelog` as the last step. return changelogs + def _read_towncrier_changelog(self, api_name): + tc_path = os.path.join(CHANGELOG_DIR, api_name) + if os.path.isdir(tc_path): + logger.info("Generating towncrier changelog for: %s" % api_name) + p = subprocess.Popen( + ['towncrier', '--version', 'unstable', '--name', api_name, '--draft'], + cwd=tc_path, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + ) + stdout, stderr = p.communicate() + if p.returncode != 0: + # Something broke - dump as much information as we can + logger.error("Towncrier exited with code %s" % p.returncode) + logger.error(stdout.decode('UTF-8')) + logger.error(stderr.decode('UTF-8')) + raw_log = "" + else: + raw_log = stdout.decode('UTF-8') + + # This is a bit of a hack, but it does mean that the log at least gets *something* + # to tell us it broke + if not raw_log.startswith("unstable"): + logger.error("Towncrier appears to have failed to generate a changelog") + logger.error(raw_log) + raw_log = "" + return raw_log.splitlines() + return [] + + def _read_rst_changelog(self, api_name): + logger.info("Reading changelog RST for %s" % api_name) + rst_path = os.path.join(CHANGELOG_DIR, "%s.rst" % api_name) + with open(rst_path, 'r', encoding="utf-8") as f: + return f.readlines() + def load_unstable_warnings(self, substitutions): warning = """ .. WARNING:: From ef13aef8c3751166032907ab2041fb1386fd7077 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 10 Feb 2019 19:31:25 -0700 Subject: [PATCH 0239/1250] Clarify the recommendations for "transferable state" Fixes https://github.com/matrix-org/matrix-doc/issues/1843 --- api/client-server/room_upgrades.yaml | 4 +--- specification/modules/room_upgrades.rst | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/api/client-server/room_upgrades.yaml b/api/client-server/room_upgrades.yaml index 6511d9fc..55ee14dc 100644 --- a/api/client-server/room_upgrades.yaml +++ b/api/client-server/room_upgrades.yaml @@ -31,9 +31,7 @@ paths: post: summary: Upgrades a room to a new room version. description: |- - Upgrades the given room to a particular room version, migrating as much - data as possible over to the new room. See the `room_upgrades <#room-upgrades>`_ - module for more information on what this entails. + Upgrades the given room to a particular room version. operationId: upgradeRoom security: - accessToken: [] diff --git a/specification/modules/room_upgrades.rst b/specification/modules/room_upgrades.rst index 49ff4414..20efbabd 100644 --- a/specification/modules/room_upgrades.rst +++ b/specification/modules/room_upgrades.rst @@ -47,9 +47,21 @@ 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 the power levels, privacy, topic, and other transferable state events to - the new room. This generally excludes membership events but may include client-specified - events and other presentation details. +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`` + + Membership events should not be transferred to the new room. + 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. @@ -57,5 +69,5 @@ When the client requests to upgrade a known room to a known version, the server: 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 may wish to automatically transfer/replicate -some of the user's personalized settings such as notifications, tags, etc. +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. From f67782230a6e26792b4a05f0cb5d63d7a54bd277 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 10 Feb 2019 19:35:23 -0700 Subject: [PATCH 0240/1250] changelog --- changelogs/client_server/newsfragments/1791.feature | 2 +- changelogs/client_server/newsfragments/1817.deprecation | 2 +- changelogs/client_server/newsfragments/1875.feature | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/1875.feature diff --git a/changelogs/client_server/newsfragments/1791.feature b/changelogs/client_server/newsfragments/1791.feature index ae961ad3..0a854c8f 100644 --- a/changelogs/client_server/newsfragments/1791.feature +++ b/changelogs/client_server/newsfragments/1791.feature @@ -1 +1 @@ -Add room version upgrades +Add room version upgrades. diff --git a/changelogs/client_server/newsfragments/1817.deprecation b/changelogs/client_server/newsfragments/1817.deprecation index 9a888e85..2c52d198 100644 --- a/changelogs/client_server/newsfragments/1817.deprecation +++ b/changelogs/client_server/newsfragments/1817.deprecation @@ -1 +1 @@ -Remove references to presence lists +Remove references to presence lists. diff --git a/changelogs/client_server/newsfragments/1875.feature b/changelogs/client_server/newsfragments/1875.feature new file mode 100644 index 00000000..0a854c8f --- /dev/null +++ b/changelogs/client_server/newsfragments/1875.feature @@ -0,0 +1 @@ +Add room version upgrades. From f058a0f40a404d8a2711b168e183724285787bf6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 10 Feb 2019 19:36:33 -0700 Subject: [PATCH 0241/1250] also power levels --- specification/modules/room_upgrades.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/specification/modules/room_upgrades.rst b/specification/modules/room_upgrades.rst index 20efbabd..889c1068 100644 --- a/specification/modules/room_upgrades.rst +++ b/specification/modules/room_upgrades.rst @@ -59,6 +59,7 @@ When the client requests to upgrade a known room to a known version, the server: * ``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. From 946acbf380a4fc510737886f3a94ec024d39f227 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 10 Feb 2019 19:49:55 -0700 Subject: [PATCH 0242/1250] Clarify v3 event representation in identifier grammar Fixes https://github.com/matrix-org/matrix-doc/issues/1870 Fixes https://github.com/matrix-org/matrix-doc/issues/1869 Fixes https://github.com/matrix-org/matrix-doc/issues/1867 --- specification/appendices/identifier_grammar.rst | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/specification/appendices/identifier_grammar.rst b/specification/appendices/identifier_grammar.rst index a0cdf298..e1034803 100644 --- a/specification/appendices/identifier_grammar.rst +++ b/specification/appendices/identifier_grammar.rst @@ -19,7 +19,7 @@ Identifier Grammar Some identifiers are specific to given room versions, please refer to the `room versions specification`_ for more information. -.. _`room versions specification`: ../index.html#room-versions +.. _`room versions specification`: index.html#room-versions Server Name @@ -234,18 +234,17 @@ A room has exactly one room ID. A room ID has the format:: !opaque_id:domain -An event has exactly one event ID. An event ID has the format:: +An event has exactly one event ID. The format of an event ID depends upon the +`room version specification `_. - $opaque_id:domain - -The ``domain`` of a room/event ID is the `server name`_ of the homeserver which +The ``domain`` of a room ID is the `server name`_ of the homeserver which created the room/event. The domain is used only for namespacing to avoid the risk of clashes of identifiers between different homeservers. There is no implication that the room or event in question is still available at the corresponding homeserver. Event IDs and Room IDs are case-sensitive. They are not meant to be human -readable. +readable. They are intended to be treated as fully opaque strings by clients. .. TODO-spec What is the grammar for the opaque part? https://matrix.org/jira/browse/SPEC-389 @@ -333,6 +332,10 @@ Examples of matrix.to URIs are: * User: ``https://matrix.to/#/@alice:example.org`` * Group: ``https://matrix.to/#/+example:example.org`` +.. Note:: + Event IDs have the potential to contain slashes in some `room versions `_. + No component of the URI should be URL encoded. + .. Note:: Room ID permalinks are unroutable as there is no reliable domain to send requests to upon receipt of the permalink. Clients should do their best route Room IDs to From 22188ebfebb291ffb30a879045499aef12a9fef1 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 10 Feb 2019 19:54:20 -0700 Subject: [PATCH 0243/1250] Further clarify why membership events are not to be transferred --- specification/modules/room_upgrades.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/specification/modules/room_upgrades.rst b/specification/modules/room_upgrades.rst index 889c1068..f1861f72 100644 --- a/specification/modules/room_upgrades.rst +++ b/specification/modules/room_upgrades.rst @@ -61,7 +61,11 @@ When the client requests to upgrade a known room to a known version, the server: * ``m.room.join_rules`` * ``m.room.power_levels`` - Membership events should not be transferred to the new room. + 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 From d31d2f5e57c58903d0fdbdba8d215d1e1e10d2df Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 11 Feb 2019 20:31:48 -0700 Subject: [PATCH 0244/1250] Correctly nest the capabilities response object Everything is contained in a "capabilities" property, which is not represented by the schema. The example was correct. --- api/client-server/capabilities.yaml | 68 ++++++++++--------- .../client_server/newsfragments/1879.feature | 1 + 2 files changed, 37 insertions(+), 32 deletions(-) create mode 100644 changelogs/client_server/newsfragments/1879.feature diff --git a/api/client-server/capabilities.yaml b/api/client-server/capabilities.yaml index 63a3ea91..a50908f7 100644 --- a/api/client-server/capabilities.yaml +++ b/api/client-server/capabilities.yaml @@ -62,44 +62,48 @@ paths: schema: type: object required: ["capabilities"] - additionalProperties: - type: object - description: |- - The custom capabilities the server supports, using the - Java package naming convention. properties: - "m.change_password": + capabilities: type: object + title: Capabilities description: |- - Capability to indicate if the user can change their password. - title: ChangePasswordCapability + The custom capabilities the server supports, using the + Java package naming convention. + additionalProperties: + type: object 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: + "m.change_password": 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'] + 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: diff --git a/changelogs/client_server/newsfragments/1879.feature b/changelogs/client_server/newsfragments/1879.feature new file mode 100644 index 00000000..107291f3 --- /dev/null +++ b/changelogs/client_server/newsfragments/1879.feature @@ -0,0 +1 @@ +Support optional features by having clients query for capabilities. From ca7aa8b0baca2d8b598449b9ab2d33e7a79a2ad8 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 12 Feb 2019 20:12:17 -0500 Subject: [PATCH 0245/1250] fill in more details, including federation bits --- proposals/1756-cross-signing.md | 37 +++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index f3c13f01..6d5ddd40 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -69,6 +69,8 @@ use cases. ### API description +#### Uploading signing keys + Public keys for the self-signing and user-signing keys are uploaded to the servers using `/keys/device_signing/upload`. This endpoint requires [UI Auth](https://matrix.org/docs/spec/client_server/r0.4.0.html#user-interactive-authentication-api). @@ -99,6 +101,18 @@ Auth](https://matrix.org/docs/spec/client_server/r0.4.0.html#user-interactive-au } ``` +Self-signing and user-signing keys are JSON objects with the following +properties: + +* `user_id` (string): The user who owns the key +* `usage` ([string]): Allowed uses for the key. Must be `["self_signing"]` for + self-signing keys, and `["user_signing"]` for user-signing keys. +* `keys` ({string: string}): an object that must have one entry, whose name is + "`ed25519:`" followed by the unpadded base64 encoding of the public key, and + whose value is the unpadded base64 encoding of the public key. +* `signatures` ({string: {stringg: string}}): signatures of the key. A + user-signing key must be signed by the self-signing key. + In order to ensure that there will be no collisions in the `signatures` property, the server must respond with an error (FIXME: what error?) if any of the uploaded public keys match an existing device ID for the user. Similarly, @@ -113,8 +127,6 @@ a `replaces` property whose value is the previous public self-signing key. Otherwise the server must respond with an error (FIXME: what error?). The new self-signing key may also be signed with the old self-signing key. -FIXME: document `usage` property - After uploading self-signing and user-signing keys, they will be included under the `/keys/query` endpoint under the `self_signing_key` and `user_signing_key` properties, respectively. The `user_signing_key` will only be included when a @@ -153,10 +165,22 @@ response: } ``` +Similarly, the federation endpoints `GET /user/keys/query` and +`POST /user/devices/{userId}` will include the self-signing key. + +In addition, Alice's homeserver will send a `m.signing_key_update` EDU to +servers that have users who share encrypted rooms with Alice. The `content` of +that EDU has the following properties: + +* `user_id` (string): Required. The user ID who owns the signing key +* `self_signing_key` (object): Required. The self-signing key, as above. + After uploading self-signing and user-signing keys, the user will show up in the `changed` property of the `device_lists` field of the sync result of any others users who share an encrypted room with that user. +#### Uploading signatures + Signatures of keys can be uploaded using `/keys/signatures/upload`. For example, Alice signs one of her devices (HIJKLMN), and Bob's self-signing key. @@ -258,6 +282,13 @@ response: } ``` +Similarly, the federation endpoints `GET /user/keys/query` and +`POST /user/devices/{userId}` will include the new signature. + +In addition, Alice's server will send an `m.device_list_update` EDU to servers +that have users who share encrypted rooms with Alice, updating her device to +include her new signature. + After Alice uploads a signature for Bob's user-signing key, her signature will be included in the results of the `/keys/query` request when Alice requests Bob's key: @@ -289,8 +320,6 @@ Bob's key: } ``` -FIXME: s2s stuff - ## Comparison with MSC1680 MSC1680 suffers from the fact that the attestation graph may be arbitrarily From 82258fc0fc90c8f2cc5d96967229a029335b1b7e Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 13 Feb 2019 23:11:14 +0000 Subject: [PATCH 0246/1250] Proposal for changing event ids. Again. --- .../1884-replace-slashes-in-event_ids.md | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 proposals/1884-replace-slashes-in-event_ids.md diff --git a/proposals/1884-replace-slashes-in-event_ids.md b/proposals/1884-replace-slashes-in-event_ids.md new file mode 100644 index 00000000..5d9d0bc2 --- /dev/null +++ b/proposals/1884-replace-slashes-in-event_ids.md @@ -0,0 +1,91 @@ +# MSC1884: Proposal to replace slashes in event IDs + +[MSC1659](https://github.com/matrix-org/matrix-doc/pull/1659) mandated that, +starting in version 3 rooms, event IDs must be calculated as a base64-encoding +of a hash. This implies that event IDs may contain any character in the +standard Base64 alphabet, which notably includes the slash character, `/`. + +Event IDs are often embedded in URI paths, and since the slash character is +used as a separator in URI paths, this presents a problem. The immediate +solution is to ensure that event IDs are URL-encoded, so that `/` is instead +represented as `%2F`. However, this is not entirely satisfactory for a number +of reasons: + + * There exist a number of client (and possibly server) implementations which + do not currently URL-encode such parameters; these are therefore broken by + such event IDs and must be updated. Furthermore, all future client + implementers must remember to do the encoding correctly. + + * Even if client implementations do rembember to URL-encode their parameters, + they may not do it correctly: many URL-encoding implementations may be + intended to encode parameters in the query-string (which can of course + contain literal slashes) rather tha the path component. + + * Some proxy software may treat `%2F` specially: for instance, Apache, when + configured as a reverse-proxy, will reject requests for a path containing + `%2F` unless it is also configured with `nocanon`. Again this means that + existing setups will be broken by this change, and it is a trap for new + users of the software. + +## Proposal + +This MSC proposes that we should introduce a new room version, in which event +IDs are encoded using the [URL-safe Base64 +encoding](https://tools.ietf.org/html/rfc4648#section-5) (which uses `-` and +`_` as the 62nd and 63rd characters instead of `+` and `/`). + +## Counterarguments + +1. Inconsistency. Base64 encoding is used heavily elsewhere in the matrix + protocol and in all cases the standard encoding is used (though with some + variation as to the inclusion of padding characters). Further, SHA256 hashes + are used in a number of places and are universally included with standard, + unpadded Base64. + + Changing event IDs alone would therefore leave us with a confusing mix of + encodings. + + A potential extension would be to change *all* Base64 encodings to be + URL-safe. This would address the inconsistency. However, it feels like a + large job which would span the entire matrix ecosystem (far larger than + updating clients to URL-encode their URL prarameters), and again the + situation would be confusing while the transition was in progress. + +2. Incompleteness. Event IDs are certainly not the only identifier which can + contain slashes - Room aliases, Room IDs, Group IDs, User IDs [1], and state + keys can all contain slashes, as well as a number of identifiers whose + grammars are currently underspecified (eg transaction ids, event types, + device IDs). (Indeed, there was nothing preventing Event IDs from containing + slashes before room v3 - it just happened that Synapse used an algorithm + which didn't generate them). + + All of these other identifiers can appear in URLs in either or both the + client-server or server-server APIs, and all have the potential to cause + misbehaviour if software does not correctly URL-encode them. + + It can be argued that it is better for software to fail 50% of the time [2] + so that it can be fixed than it is to fail only on edge-cases or, worse, + when deliberately provoked by a malicious or "curious" actor. + + Of course, an alternative is to modify the grammars of all of these + identifiers to forbid slashes. + +[1] Discussion remains open as to whether allowing slashes in User IDs was a +good idea. + +[2] 48% of random 32-byte sequences will contain a slash when Base64-encoded. + +## Alternatives + +An alternative would be to modify all REST endpoints to use query or body +parameters instead of path parameters. This would of course be a significant +and incompatible change, but it would also bring the benefit of solving a +common problem where forgetting to use `nocanon` in a reverse-proxy +configuration [breaks +federation](https://github.com/matrix-org/synapse/issues/3294) (though other +solutions to that are also possible). + +## Conclusion + +It's unclear to me that changing the format of event IDs alone solves any +problems. From 2de7ef9a3d1305edffd7774fe22ea140b9903966 Mon Sep 17 00:00:00 2001 From: Anatoly Sablin Date: Fri, 15 Feb 2019 23:23:38 +0300 Subject: [PATCH 0247/1250] #1865 Add the m.push_rules schema. --- event-schemas/examples/m.push_rules | 192 ++++++++++++++++++ .../schema/core-event-schema/push_rule.yaml | 85 ++++++++ event-schemas/schema/m.push_rules | 59 ++++++ specification/modules/push.rst | 2 + 4 files changed, 338 insertions(+) create mode 100644 event-schemas/examples/m.push_rules create mode 100644 event-schemas/schema/core-event-schema/push_rule.yaml create mode 100644 event-schemas/schema/m.push_rules diff --git a/event-schemas/examples/m.push_rules b/event-schemas/examples/m.push_rules new file mode 100644 index 00000000..9785da25 --- /dev/null +++ b/event-schemas/examples/m.push_rules @@ -0,0 +1,192 @@ +{ + "$ref": "core/state_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" + } + ] + } + } +} diff --git a/event-schemas/schema/core-event-schema/push_rule.yaml b/event-schemas/schema/core-event-schema/push_rule.yaml new file mode 100644 index 00000000..a7626bbe --- /dev/null +++ b/event-schemas/schema/core-event-schema/push_rule.yaml @@ -0,0 +1,85 @@ +# Copyright 2016 OpenMarket Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +title: PushRule +type: object +properties: + actions: + items: + type: + - object + - string + type: array + description: |- + The actions to perform when this rule is matched. + default: + type: boolean + description: |- + Whether this is a default rule, or has been set explicitly. + enabled: + type: boolean + description: |- + Whether the push rule is enabled or not. + rule_id: + type: string + description: |- + The ID of this rule. + conditions: + type: array + items: + title: PushCondition + type: object + properties: + kind: + enum: + - event_match + - contains_display_name + - room_member_count + type: string + key: + type: string + description: |- + Required for ``event_match`` conditions. The dot-separated field of the + event to match. + x-example: content.body + pattern: + type: string + description: |- + Required for ``event_match`` conditions. The glob-style pattern to + match against. Patterns with no special glob characters should be + treated as having asterisks prepended and appended when testing the + condition. + is: + type: string + description: |- + Required for ``room_member_count`` conditions. A decimal integer + optionally prefixed by one of, ==, <, >, >= or <=. A prefix of < matches + rooms where the member count is strictly less than the given number and + so forth. If no prefix is present, this parameter defaults to ==. + required: + - kind + description: |- + The conditions that must hold true for an event in order for a rule to be + applied to an event. A rule with no conditions always matches. Only + applicable to ``underride`` and ``override`` rules. + pattern: + type: string + description: |- + The glob-style pattern to match against. Only applicable to ``content`` + rules. +required: + - actions + - default + - enabled + - rule_id diff --git a/event-schemas/schema/m.push_rules b/event-schemas/schema/m.push_rules new file mode 100644 index 00000000..b487a6f5 --- /dev/null +++ b/event-schemas/schema/m.push_rules @@ -0,0 +1,59 @@ +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: Describes all push rules for this user. +properties: + content: + properties: + global: + type: object + title: Ruleset + description: The global ruleset + properties: + content: + items: + allOf: + - $ref: core-event-schema/push_rule.yaml + title: PushRule + type: object + type: array + override: + items: + allOf: + - $ref: core-event-schema/push_rule.yaml + title: PushRule + type: object + type: array + room: + items: + allOf: + - $ref: core-event-schema/push_rule.yaml + title: PushRule + type: object + type: array + sender: + items: + allOf: + - $ref: core-event-schema/push_rule.yaml + title: PushRule + type: object + type: array + underride: + items: + allOf: + - $ref: core-event-schema/push_rule.yaml + title: PushRule + type: object + type: array + type: object + state_key: + description: A zero-length string. + pattern: '^$' + type: string + type: + enum: + - m.push_rules + type: string +title: Push rules +type: object + diff --git a/specification/modules/push.rst b/specification/modules/push.rst index 008eaa8b..9830729a 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -660,6 +660,8 @@ When a user changes their push rules a ``m.push_rules`` event is sent to all clients in the ``account_data`` section of their next ``/sync`` request. The content of the event is the current push rules for the user. +{{m_push_rules_event}} + Examples ++++++++ From d4b4d92b827a41ec1fcda1e799dd2a3f67edf8bb Mon Sep 17 00:00:00 2001 From: Anatoly Sablin Date: Sat, 16 Feb 2019 00:24:26 +0300 Subject: [PATCH 0248/1250] Fix the m.push_rules type (switch from the state event to the common event). --- event-schemas/examples/m.push_rules | 2 +- event-schemas/schema/m.push_rules | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/event-schemas/examples/m.push_rules b/event-schemas/examples/m.push_rules index 9785da25..e4f0a959 100644 --- a/event-schemas/examples/m.push_rules +++ b/event-schemas/examples/m.push_rules @@ -1,5 +1,5 @@ { - "$ref": "core/state_event.json", + "$ref": "core/event.json", "type": "m.push_rules", "content": { "global": { diff --git a/event-schemas/schema/m.push_rules b/event-schemas/schema/m.push_rules index b487a6f5..ededb33e 100644 --- a/event-schemas/schema/m.push_rules +++ b/event-schemas/schema/m.push_rules @@ -1,6 +1,6 @@ --- allOf: - - $ref: core-event-schema/state_event.yaml + - $ref: core-event-schema/event.yaml description: Describes all push rules for this user. properties: content: @@ -46,10 +46,6 @@ properties: type: object type: array type: object - state_key: - description: A zero-length string. - pattern: '^$' - type: string type: enum: - m.push_rules From 17420c537a8a12199e7447f9610ba9bb0058232f Mon Sep 17 00:00:00 2001 From: Anatoly Sablin Date: Sat, 16 Feb 2019 08:56:02 +0300 Subject: [PATCH 0249/1250] Fix links. --- specification/rooms/v3.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/specification/rooms/v3.rst b/specification/rooms/v3.rst index 863f1c3a..c17c0fe0 100644 --- a/specification/rooms/v3.rst +++ b/specification/rooms/v3.rst @@ -118,7 +118,7 @@ to the change in event format: The remaining rules are the same as `room version 1 `_. -.. _`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 +.. _`Unpadded Base64`: ../../spec/appendices.html#unpadded-base64 +.. _`Canonical JSON`: ../../spec/appendices.html#canonical-json +.. _`Signing Events`: ../../spec/server_server/r0.1.1.html#signing-events +.. _`reference hash`: ../../spec/server_server/r0.1.1.html#reference-hashes From befd76f8533d3bdd1af82490893af6d6f66d46e5 Mon Sep 17 00:00:00 2001 From: Anatoly Sablin Date: Sat, 16 Feb 2019 10:38:51 +0300 Subject: [PATCH 0250/1250] Fix links. --- specification/rooms/v3.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/specification/rooms/v3.rst b/specification/rooms/v3.rst index c17c0fe0..733c6984 100644 --- a/specification/rooms/v3.rst +++ b/specification/rooms/v3.rst @@ -118,7 +118,7 @@ to the change in event format: The remaining rules are the same as `room version 1 `_. -.. _`Unpadded Base64`: ../../spec/appendices.html#unpadded-base64 -.. _`Canonical JSON`: ../../spec/appendices.html#canonical-json -.. _`Signing Events`: ../../spec/server_server/r0.1.1.html#signing-events -.. _`reference hash`: ../../spec/server_server/r0.1.1.html#reference-hashes +.. _`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 From 989d7ff192cc2414606fea061255f55df31ac1be Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sat, 16 Feb 2019 18:49:13 +0900 Subject: [PATCH 0251/1250] Remove extended text about life without transaction IDs Signed-off-by: Kitsune Ral --- specification/modules/instant_messaging.rst | 27 ++++++--------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/specification/modules/instant_messaging.rst b/specification/modules/instant_messaging.rst index 2adade5e..86daa700 100644 --- a/specification/modules/instant_messaging.rst +++ b/specification/modules/instant_messaging.rst @@ -185,25 +185,14 @@ reduced through clients making use of the transaction ID they used to send a particular event. The transaction ID used will be included in the event's ``unsigned`` data as ``transaction_id`` when it arrives through the event stream. -Clients unable to make use of the transaction ID are more likely to experience -flickering due to the following two scenarios, however the effect can be mitigated -to a degree: - -- The client sends a message and the remote echo arrives on the event stream - *after* the request to send the message completes. -- The client sends a message and the remote echo arrives on the event stream - *before* the request to send the message completes. - -In the first scenario, the client will receive an event ID when the request to -send the message completes. This ID can be used to identify the duplicate event -when it arrives on the event stream. However, in the second scenario, the event -arrives before the client has obtained an event ID. This makes it impossible to -identify it as a duplicate event. This results in the client displaying the -message twice for a fraction of a second before the the original request to send -the message completes. Once it completes, the client can take remedial actions -to remove the duplicate event by looking for duplicate event IDs. A future version -of the client-server API will resolve this by attaching the transaction ID of the -sending request to the event itself. +Clients unable to make use of the transaction ID are likely to experience +flickering when the remote echo arrives on the event stream *before* +the request to send the message completes. In that case the event +arrives before the client has obtained an event ID, making it impossible to +identify it as a remote echo. This results in the client displaying the message +twice for some time (depending on the server responsiveness) before the original +request to send the message completes. Once it completes, the client can take +remedial actions to remove the duplicate event by looking for duplicate event IDs. Calculating the display name for a user From e825224b5b9649cdf3e3a71f3eb4b45e846abb3a Mon Sep 17 00:00:00 2001 From: Hristo Venev Date: Thu, 21 Feb 2019 21:27:21 +0000 Subject: [PATCH 0252/1250] Restrict identifier port numbers to 5 digits. --- specification/appendices/identifier_grammar.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/appendices/identifier_grammar.rst b/specification/appendices/identifier_grammar.rst index a0cdf298..b0d4f6f7 100644 --- a/specification/appendices/identifier_grammar.rst +++ b/specification/appendices/identifier_grammar.rst @@ -34,7 +34,7 @@ following grammar:: server_name = hostname [ ":" port ] - port = *DIGIT + port = 1*5DIGIT hostname = IPv4address / "[" IPv6address "]" / dns-name From 4bec3d6dd866e9ba4843a7f55dd87f841d50f1e9 Mon Sep 17 00:00:00 2001 From: Anatoly Sablin Date: Sun, 24 Feb 2019 19:43:03 +0300 Subject: [PATCH 0253/1250] Avoid duplicates. --- .../schema/core-event-schema/push_rule.yaml | 85 ------------------- event-schemas/schema/m.push_rules | 38 +-------- 2 files changed, 2 insertions(+), 121 deletions(-) delete mode 100644 event-schemas/schema/core-event-schema/push_rule.yaml diff --git a/event-schemas/schema/core-event-schema/push_rule.yaml b/event-schemas/schema/core-event-schema/push_rule.yaml deleted file mode 100644 index a7626bbe..00000000 --- a/event-schemas/schema/core-event-schema/push_rule.yaml +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright 2016 OpenMarket Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -title: PushRule -type: object -properties: - actions: - items: - type: - - object - - string - type: array - description: |- - The actions to perform when this rule is matched. - default: - type: boolean - description: |- - Whether this is a default rule, or has been set explicitly. - enabled: - type: boolean - description: |- - Whether the push rule is enabled or not. - rule_id: - type: string - description: |- - The ID of this rule. - conditions: - type: array - items: - title: PushCondition - type: object - properties: - kind: - enum: - - event_match - - contains_display_name - - room_member_count - type: string - key: - type: string - description: |- - Required for ``event_match`` conditions. The dot-separated field of the - event to match. - x-example: content.body - pattern: - type: string - description: |- - Required for ``event_match`` conditions. The glob-style pattern to - match against. Patterns with no special glob characters should be - treated as having asterisks prepended and appended when testing the - condition. - is: - type: string - description: |- - Required for ``room_member_count`` conditions. A decimal integer - optionally prefixed by one of, ==, <, >, >= or <=. A prefix of < matches - rooms where the member count is strictly less than the given number and - so forth. If no prefix is present, this parameter defaults to ==. - required: - - kind - description: |- - The conditions that must hold true for an event in order for a rule to be - applied to an event. A rule with no conditions always matches. Only - applicable to ``underride`` and ``override`` rules. - pattern: - type: string - description: |- - The glob-style pattern to match against. Only applicable to ``content`` - rules. -required: - - actions - - default - - enabled - - rule_id diff --git a/event-schemas/schema/m.push_rules b/event-schemas/schema/m.push_rules index ededb33e..6fde9e14 100644 --- a/event-schemas/schema/m.push_rules +++ b/event-schemas/schema/m.push_rules @@ -9,42 +9,8 @@ properties: type: object title: Ruleset description: The global ruleset - properties: - content: - items: - allOf: - - $ref: core-event-schema/push_rule.yaml - title: PushRule - type: object - type: array - override: - items: - allOf: - - $ref: core-event-schema/push_rule.yaml - title: PushRule - type: object - type: array - room: - items: - allOf: - - $ref: core-event-schema/push_rule.yaml - title: PushRule - type: object - type: array - sender: - items: - allOf: - - $ref: core-event-schema/push_rule.yaml - title: PushRule - type: object - type: array - underride: - items: - allOf: - - $ref: core-event-schema/push_rule.yaml - title: PushRule - type: object - type: array + allOf: + - $ref: ../../api/client-server/definitions/push_ruleset.yaml type: object type: enum: From d52918a8923acc65acb91ddfc7d064bf7b88e7a1 Mon Sep 17 00:00:00 2001 From: Anatoly Sablin Date: Sun, 24 Feb 2019 22:26:32 +0300 Subject: [PATCH 0254/1250] Fix #1904. --- api/server-server/openid.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/server-server/openid.yaml b/api/server-server/openid.yaml index 0eac48c8..0761618d 100644 --- a/api/server-server/openid.yaml +++ b/api/server-server/openid.yaml @@ -33,7 +33,7 @@ paths: User ID of the owner. operationId: exchangeOpenIdToken parameters: - - in: path + - in: query name: access_token type: string description: |- From 060c5c7b21243ef737cb9ec6d537a0e3ab7674df Mon Sep 17 00:00:00 2001 From: Anatoly Sablin Date: Sun, 24 Feb 2019 23:01:01 +0300 Subject: [PATCH 0255/1250] Add clarification changelog entry. --- changelogs/server_server/newsfragments/1904.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/server_server/newsfragments/1904.clarification diff --git a/changelogs/server_server/newsfragments/1904.clarification b/changelogs/server_server/newsfragments/1904.clarification new file mode 100644 index 00000000..94174ebd --- /dev/null +++ b/changelogs/server_server/newsfragments/1904.clarification @@ -0,0 +1 @@ +Fix the `access_token` parameter in the open_id endpoint. From baf8948eb5b3be04f06bba0fce87153834bda16f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 24 Feb 2019 21:53:50 -0700 Subject: [PATCH 0256/1250] Describe M_UNSUPPORTED_ROOM_VERSION on invite and createRoom endpoints Spec for MSC1866: https://github.com/matrix-org/matrix-doc/pull/1866 --- api/client-server/create_room.yaml | 6 ++++++ api/client-server/inviting.yaml | 14 ++++++++++++++ .../client_server/newsfragments/1903.feature | 1 + 3 files changed, 21 insertions(+) create mode 100644 changelogs/client_server/newsfragments/1903.feature diff --git a/api/client-server/create_room.yaml b/api/client-server/create_room.yaml index d361d973..bce61aad 100644 --- a/api/client-server/create_room.yaml +++ b/api/client-server/create_room.yaml @@ -244,6 +244,12 @@ paths: invalid: for example, the user's ``power_level`` is set below that necessary to set the room name (``errcode`` set to ``M_INVALID_ROOM_STATE``). + + - The homeserver doesn't support the requested room version, or + one or more users being invited to the new room are residents + of a homeserver which does not support the requested room version. + The ``errcode`` will be ``M_UNSUPPORTED_ROOM_VERSION`` in these + cases. schema: "$ref": "definitions/errors/error.yaml" tags: diff --git a/api/client-server/inviting.yaml b/api/client-server/inviting.yaml index f312d5ce..dfa66b9b 100644 --- a/api/client-server/inviting.yaml +++ b/api/client-server/inviting.yaml @@ -82,6 +82,20 @@ paths: } schema: type: object + 400: + description: |- + + The request is invalid. A meaningful ``errcode`` and description + error text will be returned. Example reasons for rejection include: + + - The request body is malformed (``errcode`` set to ``M_BAD_JSON`` + or ``M_NOT_JSON``). + + - One or more users being invited to the room are residents of a + homeserver which does not support the requested room version. The + ``errcode`` will be ``M_UNSUPPORTED_ROOM_VERSION`` in these cases. + schema: + "$ref": "definitions/errors/error.yaml" 403: description: |- You do not have permission to invite the user to the room. A meaningful ``errcode`` and description error text will be returned. Example reasons for rejections are: diff --git a/changelogs/client_server/newsfragments/1903.feature b/changelogs/client_server/newsfragments/1903.feature new file mode 100644 index 00000000..1c64d826 --- /dev/null +++ b/changelogs/client_server/newsfragments/1903.feature @@ -0,0 +1 @@ +Emit ``M_UNSUPPORTED_ROOM_VERSION`` error codes where applicable on ``/createRoom`` and ``/invite`` APIs. From adb721bc0b101bcf458a17275792eec20fe96e63 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 24 Feb 2019 21:55:57 -0700 Subject: [PATCH 0257/1250] Fix unrelated changelog entry's RST representation --- changelogs/client_server/newsfragments/1874.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/client_server/newsfragments/1874.feature b/changelogs/client_server/newsfragments/1874.feature index 03b891e2..bdab5464 100644 --- a/changelogs/client_server/newsfragments/1874.feature +++ b/changelogs/client_server/newsfragments/1874.feature @@ -1 +1 @@ -Add `M_RESOURCE_LIMIT_EXCEEDED` as an error code for when homeservers exceed limits imposed on them. +Add ``M_RESOURCE_LIMIT_EXCEEDED`` as an error code for when homeservers exceed limits imposed on them. From 4049ca92085b98b29d19eb24323ebaab41765529 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 25 Feb 2019 09:47:19 +0000 Subject: [PATCH 0258/1250] Specify news fragments must be done in RST. --- CONTRIBUTING.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 0666c579..7a6c6be2 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -98,8 +98,10 @@ the ``newsfragments`` directory. The ``type`` can be one of the following: * ``deprecation`` - Used when deprecating something -All news fragments must have a brief summary explaining the change in the contents -of the file. The summary must end in a full stop to be in line with the style guide. +All news fragments must have a brief summary explaining the change in the +contents of the file. The summary must end in a full stop to be in line with +the style guide and and formatting must be done using `Restructured Text +`_. Changes that do not change the spec, such as changes to the build script, formatting, CSS, etc should not get a news fragment. From 99405418c9408004ce099cf21b01a7838d97b51e Mon Sep 17 00:00:00 2001 From: Ben Parsons Date: Tue, 26 Feb 2019 18:11:02 +0000 Subject: [PATCH 0259/1250] in the appendices, thanks earfolds --- specification/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/index.rst b/specification/index.rst index d6176c93..19c5ad22 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -196,7 +196,7 @@ allocated the account and has the form:: @localpart:domain -See `'Identifier Grammar' the appendices `_ for full details of +See `'Identifier Grammar' in the appendices `_ for full details of the structure of user IDs. Devices From 5303ba54b72a926e029528a9e96c7fb75925d51a Mon Sep 17 00:00:00 2001 From: Anatoly Sablin Date: Thu, 28 Feb 2019 21:04:23 +0300 Subject: [PATCH 0260/1250] Add a clarification changelog. --- changelogs/client_server/newsfragments/1889.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/1889.clarification diff --git a/changelogs/client_server/newsfragments/1889.clarification b/changelogs/client_server/newsfragments/1889.clarification new file mode 100644 index 00000000..5026dab3 --- /dev/null +++ b/changelogs/client_server/newsfragments/1889.clarification @@ -0,0 +1 @@ +Add the missing `m.push_rules` event schema. From f92925ed456d51c71dd064ee30b93bad40f1fe44 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Wed, 6 Mar 2019 11:32:28 +0000 Subject: [PATCH 0261/1250] Add a 3PID unbind API --- .../1915-unbind-identity-server-param.md | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 proposals/1915-unbind-identity-server-param.md diff --git a/proposals/1915-unbind-identity-server-param.md b/proposals/1915-unbind-identity-server-param.md new file mode 100644 index 00000000..f018d261 --- /dev/null +++ b/proposals/1915-unbind-identity-server-param.md @@ -0,0 +1,97 @@ +# 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. + + +## New APIs + +### Client-Server API + +Add `POST /_matrix/client/r0/account/3pid/delete` API, which expects a JSON body +with `medium`, `address` and `id_server` fields (as per existing APIs). + +The `id_server` parameter is optional and if missing the server will attempt to +unbind from a suitable identity server (e.g. its default identity server or the +server used when originally binding the 3pid). + +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. + +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" +} +``` + + +### Identity Server 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 accept any request to unbind a 3PID for a `user_id` from +the homeserver controlling that user ID. + +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. From ee6513d608cf8004f67a9fbae1b69d02477719dd Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Thu, 7 Mar 2019 16:52:58 +0000 Subject: [PATCH 0262/1250] Add alternative sid/client_secret authentication --- proposals/1915-unbind-identity-server-param.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/proposals/1915-unbind-identity-server-param.md b/proposals/1915-unbind-identity-server-param.md index f018d261..1dc2d833 100644 --- a/proposals/1915-unbind-identity-server-param.md +++ b/proposals/1915-unbind-identity-server-param.md @@ -57,8 +57,11 @@ 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 accept any request to unbind a 3PID for a `user_id` from -the homeserver controlling that user ID. +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_server` params (as per `/bind`), + which proves ownership of the given 3PID. Example: From 77110b46df7000d0ea78f2cdd4778c2122b7de73 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 8 Mar 2019 12:14:08 +0000 Subject: [PATCH 0263/1250] Update proposals/1915-unbind-identity-server-param.md Co-Authored-By: erikjohnston --- proposals/1915-unbind-identity-server-param.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1915-unbind-identity-server-param.md b/proposals/1915-unbind-identity-server-param.md index 1dc2d833..9ffb99b3 100644 --- a/proposals/1915-unbind-identity-server-param.md +++ b/proposals/1915-unbind-identity-server-param.md @@ -60,7 +60,7 @@ it returns a specific matrix error response (i.e. the body is a JSON object with 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_server` params (as per `/bind`), +2. The request includes the `sid` and `client_secret` params (as per `/bind`), which proves ownership of the given 3PID. Example: From 60f1cf79de80221029234949483b0643f246df43 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 12 Mar 2019 14:20:37 +0000 Subject: [PATCH 0264/1250] Update wording and add deactivate account API --- .../1915-unbind-identity-server-param.md | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/proposals/1915-unbind-identity-server-param.md b/proposals/1915-unbind-identity-server-param.md index 9ffb99b3..8dbfe2e6 100644 --- a/proposals/1915-unbind-identity-server-param.md +++ b/proposals/1915-unbind-identity-server-param.md @@ -13,16 +13,16 @@ This is meant as a simple extension to the current APIs, and so this explicitly does not try and solve any existing usability concerns. -## New APIs +## API Changes -### Client-Server API +### Client-Server 3PID Delete API -Add `POST /_matrix/client/r0/account/3pid/delete` API, which expects a JSON body -with `medium`, `address` and `id_server` fields (as per existing APIs). +Add an `id_server` param to `POST /_matrix/client/r0/account/3pid/delete` API, +which matches the 3PID creation APIs. -The `id_server` parameter is optional and if missing the server will attempt to -unbind from a suitable identity server (e.g. its default identity server or the -server used when originally binding the 3pid). +The new `id_server` parameter is optional and if missing the server will attempt +to unbind from a suitable identity server (e.g. its default identity server or +the server used when originally binding the 3pid). 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 @@ -45,8 +45,14 @@ HTTP/1.1 200 OK } ``` +### Client-Server Deactivate account API -### Identity Server 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 From f9a00fc943d9ae49ae32845a7a971578ff84c4a0 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 13 Mar 2019 23:25:11 -0400 Subject: [PATCH 0265/1250] clarify that not understanding a verification method should not auto-cancel --- proposals/1717-key_verification.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/proposals/1717-key_verification.md b/proposals/1717-key_verification.md index b536be0e..10ccf785 100644 --- a/proposals/1717-key_verification.md +++ b/proposals/1717-key_verification.md @@ -28,7 +28,10 @@ appropriate `m.key.verification.cancel` message is received. If Bob chooses to reject the key verification request, Bob's client should send a `m.key.verification.cancel` message to Alice's device. If Bob's client does not understand any of the methods offered, it should display a message to Bob -saying so. +saying so. However, it should not send a `m.key.verification.cancel` message +to Alice's device unless Bob chooses to reject the verification request, as Bob +may have another device that is capable of verifying using one of the given +methods. To initiate a key verification process, Bob's device sends a `to_device` event to one of Alice's devices with the `type` set to `m.key.verification.start`. From 4842a718d8ab3c4000e86270d3ef3aea6cf42154 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 13 Mar 2019 23:39:00 -0400 Subject: [PATCH 0266/1250] fill in some of the other sections --- proposals/1717-key_verification.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/proposals/1717-key_verification.md b/proposals/1717-key_verification.md index 10ccf785..9296cf40 100644 --- a/proposals/1717-key_verification.md +++ b/proposals/1717-key_verification.md @@ -132,10 +132,18 @@ convention. ## Tradeoffs -## Potential issues +Rather than broadcasting verification requests to Bob's devices, Alice could +simply send an `m.key.verification.start` request to a single device. However, +this would require Alice to choose the right device to send to, which may be +hard for Alice to do if, for example, Bob has many devices, or if his devices +have similar names. ## Security considerations +An attacker could try to spam a user with verification requests. Clients +should take care that such requests do not interfere with a user's use of the +client. + ## Conclusion This proposal presents common event definitions for use by key verification From 1749a91344786815ecbae43a53e19fb53157c307 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 13 Mar 2019 23:41:43 -0400 Subject: [PATCH 0267/1250] make MSC mentions into links --- proposals/1717-key_verification.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/proposals/1717-key_verification.md b/proposals/1717-key_verification.md index 9296cf40..02018ef9 100644 --- a/proposals/1717-key_verification.md +++ b/proposals/1717-key_verification.md @@ -2,8 +2,10 @@ Key verification is an essential part of ensuring that end-to-end encrypted messages are secure. Matrix may support multiple verification methods that -require sending events; in fact, two such methods (such as MSC1267 and MSC1543) -have already been proposed. +require sending events; in fact, two such methods (such as [MSC +1267](https://github.com/matrix-org/matrix-doc/issues/1267) and [MSC +1543](https://github.com/matrix-org/matrix-doc/issues/1543)) have already been +proposed. This proposal tries to present a common framework for verification methods to use, and presents a way to request key verification. From 87824c1c963f13dfe6072e76fe372eb18c81d65c Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Fri, 15 Mar 2019 13:38:19 -0400 Subject: [PATCH 0268/1250] Update proposals/1219-storing-megolm-keys-serverside.md Co-Authored-By: uhoreg --- proposals/1219-storing-megolm-keys-serverside.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 05c68520..0863bc8d 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -4,7 +4,7 @@ Storing megolm keys serverside Background ---------- -A user who uses end-to-end encyrption will usually have many inbound group session +A user who uses end-to-end encryption will usually have many inbound group session keys. Users who log into new devices and want to read old messages will need a convenient way to transfer the session keys from one device to another. While users can currently export their keys from one device and import them to From 1c4262e556108d0b1ada17c722659a6d010e5dff Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Fri, 15 Mar 2019 13:40:44 -0400 Subject: [PATCH 0269/1250] Apply suggestions from code review Co-Authored-By: uhoreg --- proposals/1219-storing-megolm-keys-serverside.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 0863bc8d..09ded1cd 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -162,7 +162,7 @@ On success, returns a JSON object with keys: ##### `GET /room_keys/version/{version}` -Get information about the given version, or the current version if `{version}` +Get information about the given version, or the current version if `/{version}` is omitted. On success, returns a JSON object with keys: @@ -448,7 +448,7 @@ On success, returns the empty JSON object. The `auth_data` property for the backup versions endpoints for `m.megolm_backup.v1.curve25519-aes-sha2` is a signedjson object with the -followin keys: +following keys: - `public_key` (string): the curve25519 public key used to encrypt the backups - `signatures` (object): signatures of the public key From 0e07a6d243f2fc11c1ce95504e842d2f96f24c00 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 15 Mar 2019 13:32:38 -0600 Subject: [PATCH 0270/1250] Proposal to have a push rule for m.room.tombstone events --- proposals/1930-tombstone-notifications.md | 40 +++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 proposals/1930-tombstone-notifications.md diff --git a/proposals/1930-tombstone-notifications.md b/proposals/1930-tombstone-notifications.md new file mode 100644 index 00000000..715921aa --- /dev/null +++ b/proposals/1930-tombstone-notifications.md @@ -0,0 +1,40 @@ +# Proposal to add a default push rule for m.room.tombstone events + +Currently users are unaware of when a room becomes upgraded, leaving them potentially in the old room +without knowing until they visit the room again. By having a notification for when the room is upgraded, +users are able to ensure they are able to stay relevant in rooms by joining the upgraded room. + + +## Proposal + +A new default override rule is to be added which is similar to `@room` notifications: + +```json +{ + "rule_id": ".m.rule.tombstone", + "default": true, + "enabled": true, + "conditions": [ + { + "kind": "event_match", + "key": "type", + "pattern": "m.room.tombstone" + } + ], + "actions": [ + "notify", + { + "set_tweak": "highlight", + "value": true + } + ] +} +``` + + +## Tradeoffs + +Clients could calculate this on their own and show some sort of "room upgraded" notification instead, +however by doing it this way it means that all clients would need to be aware of room upgrades. Having +a default push rule means that clients get this notification for free. Clients which want a more diverse +UX can still do so by ignoring this push rule locally. From bd4fab7a15e9086473714fd9d54656b396212467 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Mon, 18 Mar 2019 09:28:46 +0000 Subject: [PATCH 0271/1250] Be more explicit identity server selection and errors --- proposals/1915-unbind-identity-server-param.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/proposals/1915-unbind-identity-server-param.md b/proposals/1915-unbind-identity-server-param.md index 8dbfe2e6..438dfa44 100644 --- a/proposals/1915-unbind-identity-server-param.md +++ b/proposals/1915-unbind-identity-server-param.md @@ -21,12 +21,13 @@ 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 a suitable identity server (e.g. its default identity server or -the server used when originally binding the 3pid). +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. +identity server (IS) does not support unbinding 3PIDs directly. If the identity +server returns an error than that should be returned to the client. Example: From 410a5dbbff6dc37132ee22ce2e0bf4df3aaa51a6 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 18 Mar 2019 09:36:01 +0000 Subject: [PATCH 0272/1250] Update proposals/1915-unbind-identity-server-param.md Co-Authored-By: erikjohnston --- proposals/1915-unbind-identity-server-param.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1915-unbind-identity-server-param.md b/proposals/1915-unbind-identity-server-param.md index 438dfa44..053552f6 100644 --- a/proposals/1915-unbind-identity-server-param.md +++ b/proposals/1915-unbind-identity-server-param.md @@ -27,7 +27,7 @@ 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 than that should be returned to the client. +server returns an error then that should be returned to the client. Example: From 1a739ec97b54faa3e8719c1fdb271c0d3388f15a Mon Sep 17 00:00:00 2001 From: Vikingat-RAGE Date: Mon, 18 Mar 2019 21:16:52 +0000 Subject: [PATCH 0273/1250] E2E typo fix in spec --- specification/modules/end_to_end_encryption.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index a605875b..76b36c4f 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -291,8 +291,8 @@ v string **Required.** Version of the encrypted attachments ========= ========= ============================================================ Parameter Type Description ========= ========= ============================================================ -key string **Required.** Key type. Must be ``oct``. -key_opts [string] **Required.** Key operations. Must at least contain +kty string **Required.** Key type. Must be ``oct``. +key_ops [string] **Required.** Key operations. Must at least contain ``encrypt`` and ``decrypt``. alg string **Required.** Algorithm. Must be ``A256CTR``. k string **Required.** The key, encoded as urlsafe unpadded base64. From 76ee13b9bb4c65a8af1eaaba22e443c4648c8500 Mon Sep 17 00:00:00 2001 From: Vikingat-RAGE Date: Mon, 18 Mar 2019 21:54:56 +0000 Subject: [PATCH 0274/1250] Fixed bad spacing. --- changelogs/client_server/newsfragments/1933.clarification | 1 + specification/modules/end_to_end_encryption.rst | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/1933.clarification diff --git a/changelogs/client_server/newsfragments/1933.clarification b/changelogs/client_server/newsfragments/1933.clarification new file mode 100644 index 00000000..b0f05203 --- /dev/null +++ b/changelogs/client_server/newsfragments/1933.clarification @@ -0,0 +1 @@ +Fix various spelling mistakes throughout the specification. diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 76b36c4f..3b5bd4d9 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -292,7 +292,7 @@ v string **Required.** Version of the encrypted attachments Parameter Type Description ========= ========= ============================================================ kty string **Required.** Key type. Must be ``oct``. -key_ops [string] **Required.** Key operations. Must at least contain +key_ops [string] **Required.** Key operations. Must at least contain ``encrypt`` and ``decrypt``. alg string **Required.** Algorithm. Must be ``A256CTR``. k string **Required.** The key, encoded as urlsafe unpadded base64. From 42cf72c60f9f5fe6036fc32f65c0cd5d2ed73b6e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 20 Mar 2019 14:43:16 -0600 Subject: [PATCH 0275/1250] URL encode matrix.to URIs --- .../appendices/identifier_grammar.rst | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/specification/appendices/identifier_grammar.rst b/specification/appendices/identifier_grammar.rst index e1034803..17c557d9 100644 --- a/specification/appendices/identifier_grammar.rst +++ b/specification/appendices/identifier_grammar.rst @@ -323,18 +323,27 @@ and instead should perform some sort of action within the client. For example, i the user were to click on a matrix.to URI for a room alias, the client may open a view for the user to participate in the room. +The components of the matrix.to URI (```` and ````) +are to be percent-encoded as per RFC 3986. + Examples of matrix.to URIs are: -* Room alias: ``https://matrix.to/#/#somewhere:example.org`` -* Room: ``https://matrix.to/#/!somewhere:example.org`` -* Permalink by room: ``https://matrix.to/#/!somewhere:example.org/$event:example.org`` +* Room alias: ``https://matrix.to/#/%23somewhere%3Aexample.org`` +* Room: ``https://matrix.to/#/!somewhere%3Aexample.org`` +* Permalink by room: ``https://matrix.to/#/!somewhere%3Aexample.org/%24event%3Aexample.org`` * Permalink by room alias: ``https://matrix.to/#/#somewhere:example.org/$event:example.org`` * User: ``https://matrix.to/#/@alice:example.org`` * Group: ``https://matrix.to/#/+example:example.org`` .. Note:: - Event IDs have the potential to contain slashes in some `room versions `_. - No component of the URI should be URL encoded. + Historically, clients have not produced URIs which are fully encoded. Clients should + try to interpret these cases to the best of their ability. For example, an unencoded + room alias should still work within the client if possible. + +.. Note:: + Clients should be aware that decoding a matrix.to URI may result in extra slashes + appearing due to some `room versions `_. These slashes + should normally be encoded when producing matrix.to URIs, however. .. Note:: Room ID permalinks are unroutable as there is no reliable domain to send requests From 0ec34039e85e777c2b50b532dac9c594513174fe Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 20 Mar 2019 14:44:54 -0600 Subject: [PATCH 0276/1250] URL encode all the things --- specification/appendices/identifier_grammar.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/specification/appendices/identifier_grammar.rst b/specification/appendices/identifier_grammar.rst index 17c557d9..ad0794bd 100644 --- a/specification/appendices/identifier_grammar.rst +++ b/specification/appendices/identifier_grammar.rst @@ -331,9 +331,9 @@ Examples of matrix.to URIs are: * Room alias: ``https://matrix.to/#/%23somewhere%3Aexample.org`` * Room: ``https://matrix.to/#/!somewhere%3Aexample.org`` * Permalink by room: ``https://matrix.to/#/!somewhere%3Aexample.org/%24event%3Aexample.org`` -* Permalink by room alias: ``https://matrix.to/#/#somewhere:example.org/$event:example.org`` -* User: ``https://matrix.to/#/@alice:example.org`` -* Group: ``https://matrix.to/#/+example:example.org`` +* Permalink by room alias: ``https://matrix.to/#/#somewhere:example.org/%24event%3Aexample.org`` +* User: ``https://matrix.to/#/%40alice%3Aexample.org`` +* Group: ``https://matrix.to/#/%2Bexample%3Aexample.org`` .. Note:: Historically, clients have not produced URIs which are fully encoded. Clients should From d224c4ff715456cb1d65fbac0c82e1e2eaf39801 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 25 Mar 2019 18:13:14 -0400 Subject: [PATCH 0277/1250] fix some errors in key export format - empirically, we don't acatually wrap the array in an object - fix an incorrect type --- specification/modules/end_to_end_encryption.rst | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 3b5bd4d9..59d241b6 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -496,18 +496,9 @@ passphrase, and is created as follows: Key export format <<<<<<<<<<<<<<<<< -The exported sessions are formatted as a JSON object of type ``ExportData`` +The exported sessions are formatted as a JSON array of ``SessionData`` objects described as follows: -``ExportData`` - -=============== ================= ============================================== -Parameter Type Description -=============== ================= ============================================== -sessions ``[SessionData]`` Required. The sessions that are being - exported. -=============== ================= ============================================== - ``SessionData`` .. table:: @@ -529,7 +520,7 @@ sessions ``[SessionData]`` Required. The sessions that are being device which initiated the session originally. sender_claimed_keys {string: Required. The Ed25519 key of the - integer} device which initiated the session + string} device which initiated the session originally. session_id string Required. The ID of the session. session_key string Required. The key for the session. From 696e568fb2101480826d873fac83897ae904472a Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 26 Mar 2019 15:10:14 -0400 Subject: [PATCH 0278/1250] add some clarifications --- proposals/1717-key_verification.md | 46 +++++++++++++++++++----------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/proposals/1717-key_verification.md b/proposals/1717-key_verification.md index 02018ef9..6c9e2341 100644 --- a/proposals/1717-key_verification.md +++ b/proposals/1717-key_verification.md @@ -19,26 +19,40 @@ Java package naming convention. If Alice wants to verify keys with Bob, Alice's device may send `to_device` events to Bob's devices with the `type` set to `m.key.verification.request`, as -described below. The event lists the verification methods that Alice's device -supports. Upon receipt of this message, Bob's client should prompt him to -verify keys with Alice using one of the applicable methods. In order to avoid -displaying stale key verification prompts, if Bob does not interact with the -prompt, it should be automatically hidden 10 minutes after the message is sent -(according to the `timestamp` field), or 2 minutes after the client receives -the message, whichever comes first. The prompt should also be hidden if an -appropriate `m.key.verification.cancel` message is received. If Bob chooses to -reject the key verification request, Bob's client should send a -`m.key.verification.cancel` message to Alice's device. If Bob's client does -not understand any of the methods offered, it should display a message to Bob -saying so. However, it should not send a `m.key.verification.cancel` message -to Alice's device unless Bob chooses to reject the verification request, as Bob -may have another device that is capable of verifying using one of the given -methods. +described below. The `m.key.verification.request` messages should all have the +same `transaction_id`, and are considered to be a single request. Thus, for +example, if Bob rejects the request on one device, then the entire request +should be considered as rejected across all of his devices. Similarly, if Bob +accepts the request on one device, that device is now in charge of completing +the key verification, and Bob's other devices no longer need to be involved. + +The `m.key.verification.request` event lists the verification methods that +Alice's device supports, and upon receipt of this message, Bob's client should +prompt him to verify keys with Alice using one of the applicable methods. In +order to avoid displaying stale key verification prompts, if Bob does not +interact with the prompt, it should be automatically hidden 10 minutes after +the message is sent (according to the `timestamp` field), or 2 minutes after +the client receives the message, whichever comes first. The prompt should also +be hidden if an appropriate `m.key.verification.cancel` message is received. + +If Bob chooses to reject the key verification request, Bob's client should send +a `m.key.verification.cancel` message to Alice's device. This indicates to +Alice that Bob does not wish to verify keys with her. In this case, Alice's +device should send an `m.key.verification.cancel` message to all of Bob's +devices to notify them that the request has been rejected. + +If one of Bob's clients does not understand any of the methods offered, it +should display a message to Bob saying so. However, it should not send a +`m.key.verification.cancel` message to Alice's device unless Bob chooses to +reject the verification request, as Bob may have another device that is capable +of verifying using one of the given methods. To initiate a key verification process, Bob's device sends a `to_device` event to one of Alice's devices with the `type` set to `m.key.verification.start`. This may either be done in response to an `m.key.verification.request` message, -or can be done independently. If Alice's device receives an +or can be done independently. If it is done in response to an +`m.key.verification.request` messsage, it should use the same `transaction_id` +as the `m.key.verification.request` message. If Alice's device receives an `m.key.verification.start` message in response to an `m.key.verification.request` message, it should send an `m.key.verification.cancel` message to Bob's other devices that it had From 4e95f8062a8a493cb07a89fc53b5dfad9399507f Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 26 Mar 2019 16:51:46 -0400 Subject: [PATCH 0279/1250] add examples for federation endpoints --- proposals/1756-cross-signing.md | 52 +++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 6d5ddd40..68143b87 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -168,6 +168,58 @@ response: Similarly, the federation endpoints `GET /user/keys/query` and `POST /user/devices/{userId}` will include the self-signing key. +`POST /keys/query` + +``` json +{ + "device_keys": { + "@alice:example.com": [] + } +} +``` + +response: + +``` json +{ + "device_keys": { + "@alice:example.com": { + // ... + } + }, + "self_signing_keys": { + "@alice:example.com": { + "user_id": "@alice:example.com", + "usage": ["self_signing"], + "keys": { + "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key" + } + } + } +} +``` + +`GET /user/devices/%40alice%3Aexample.com` + +response: + +``` json +{ + "user_id": "@alice:example.com", + "stream_id": 5, + "devices": [ + // ... + ], + "self_signing_keys": { + "user_id": "@alice:example.com", + "usage": ["self_signing"], + "keys": { + "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key" + } + } +} +``` + In addition, Alice's homeserver will send a `m.signing_key_update` EDU to servers that have users who share encrypted rooms with Alice. The `content` of that EDU has the following properties: From 63c6d030fdbcee336e7df03e89d96a63c10fa205 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 27 Mar 2019 21:48:12 -0400 Subject: [PATCH 0280/1250] draft of secure server-side storage --- proposals/xxxx-secure_server-side_storage.md | 144 +++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 proposals/xxxx-secure_server-side_storage.md diff --git a/proposals/xxxx-secure_server-side_storage.md b/proposals/xxxx-secure_server-side_storage.md new file mode 100644 index 00000000..603fe64e --- /dev/null +++ b/proposals/xxxx-secure_server-side_storage.md @@ -0,0 +1,144 @@ +# Secure Server-side Storage + +Some features may require clients to store encrypted data on the server so that +it can be shared securely between clients. For example, key backups (MSC-1219) +can store the decryption key for the backups on the server, or cross-signing +(MSC-1756) can store the signing keys. This proposal presents a standardized +way of storing such data. + +## Proposal + +A user can have multiple keys used for encrypting data. This allows the user +to selectively decrypt data. For example, the user could have one key that can +decrypt everything, and another key that can only decrypt their user-signing +key for cross-signing. Each key has an ID, and a discription of the key is +stored in the user's `account_data` using the `type` `m.secure_storage.key.[key +ID]`. The contents of the account data for the key will include an `algorithm` +property, which indicates the encryption algorithm used, as well as a `name` +property, which is a human-readable name. Other properties depend on the +encryption algorithm, and are described below. + +Encrypted data can be stored using the `account_data` API. The `type` for the +`account_data` is defined by the feature that uses the data. For example, +decryption keys for key backups could be stored under the type +`m.megolm_backup.v1.recovery_key`, or the self-signing key for cross-signing +could be stored under the type `m.signing_key.self_signing`. + +Data will be stored using using the following format: + +```json +{ + "encrypted": { + [key ID]: { + "ciphertext": "base64+encoded+encrypted+data", + "mac": "base64+encoded+mac" + } + } +} +``` + +The `encrypted` property is map from key ID to an object. The algorithm for +the given key defines how the other properties are interpreted, though it's +expected that most encryption schemes would have `ciphertext` and `mac` +properties, where the `ciphertext` property is the unpadded base64-encoded +ciphertext, and the `mac` is used to ensure the integrity of the data. + +FIXME: the key format was chosen so that existing backups could be easily +migrated by just copying the configuration from the backup config to the key +description. However, we need a way of signalling that the key for the backup +is the same as the key for decrypting the other bits. Maybe a special flag in +the account data? Or special case backups somehow, say, have clients inspect +the backup's `auth_data` to see of the key config is the same? + +### Encryption algorithms + +#### `m.secure_storage.v1.curve25519-aes-sha2` + +The data is encrypted and MACed as follows: + +1. Generate an ephemeral curve25519 key, and perform an ECDH with the ephemeral + key and the backup's public key to generate a shared secret. The public + half of the ephemeral key, encoded using base64, becomes the `ephemeral` + property. +2. Using the shared secret, generate 80 bytes by performing an HKDF using + SHA-256 as the hash, with a salt of 32 bytes of 0, and with the empty string + as the info. The first 32 bytes are used as the AES key, the next 32 bytes + are used as the MAC key, and the last 16 bytes are used as the AES + initialization vector. +4. Encrypt the data using AES-CBC-256 with PKCS#7 padding. This encrypted + data, encoded using base64, becomes the `ciphertext` property. +5. Pass the raw encrypted data (prior to base64 encoding) through HMAC-SHA-256 + using the MAC key generated above. The first 8 bytes of the resulting MAC + are base64-encoded, and become the `mac` property. + +(The key HKDF, AES, and HMAC steps are the same as what are used for encryption +in olm and megolm.) + +FIXME: add an example of `m.secure_storage.key.*`, and of encrypted data. + +##### Keys + +When a user is given a raw key for `m.secure_storage.v1.curve25519-aes-sha2`, +it will be encoded as follows (this is the same as what is proposed in MSC1703): + +* prepend the two bytes 0x8b and 0x01 to the key +* compute a parity byte by XORing all bytes of the resulting string, and append + the parity byte to the string +* base58-encode the resulting byte string with the alphabet + '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'. +* format the resulting ASCII string into groups of 4 characters separated by + spaces. + +When decoding a raw key, the process should be reversed, with the exception +that whitespace is insignificant in the user's ASCII input. + +##### Passphrase + +A user may wish to use a chosen passphrase rather than a randomly generated +key. In this case, information on how to generate the key from a passphrase +will be stored in the `passphrase` property of the `m.secure_storage.key.[key +ID]` account-data: + +```json +{ + "passphrase": { + "algorithm": "m.pbkdf2", + "salt": "MmMsAlty", + "rounds": 100000 + }, + ... +} +``` + +###### `m.pbkdf2` + +The key is generated using PBKDF2 using the salt given in the `salt` +parameter, and the number of rounds given in the `rounds` parameter. + +## Tradeoffs + +Rather than encrypting data on the server using a static key, clients can +exchange data by sending to_device messages encrypted using Olm. This allows +clients to share data securely without requiring the user to enter keys or +passphrases. However, users who have only one device and lose it will still +need a way to, for example, recover their key backup, so we must provide a way +for the data to be stored on the server. + +Currently, only a public/private key mechanism is defined. It may be useful to +also define a secret key mechanism. + +## Potential issues + +Keeping all the data and keys in account data means that it may clutter up the +`/sync`. However, clients can filter out the data that they are not interested +in. One possibility for addressing this would be to add a flag to the account +data to indicate whether it should come down the `/sync` or not. + +## Security considerations + +Yes. + +## Conclusion + +This proposal presents a common way for bits of encrypted data to be stored on +a user's homeserver for use by various features. From 979827bad3ba422b01edaaa1bc49d54e0d0c5f1b Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 27 Mar 2019 21:57:13 -0400 Subject: [PATCH 0281/1250] rename to match MSC number --- ..._server-side_storage.md => 1946-secure_server-side_storage.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/{xxxx-secure_server-side_storage.md => 1946-secure_server-side_storage.md} (100%) diff --git a/proposals/xxxx-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md similarity index 100% rename from proposals/xxxx-secure_server-side_storage.md rename to proposals/1946-secure_server-side_storage.md From 207d6cf8512231eb121d9696369b1d1d01449673 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 30 Mar 2019 13:12:18 +0000 Subject: [PATCH 0282/1250] update MSC1884 to reflect new conclusions following discussion on the PR --- .../1884-replace-slashes-in-event_ids.md | 80 ++++++++++++++++++- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/proposals/1884-replace-slashes-in-event_ids.md b/proposals/1884-replace-slashes-in-event_ids.md index 5d9d0bc2..9c3b7ea7 100644 --- a/proposals/1884-replace-slashes-in-event_ids.md +++ b/proposals/1884-replace-slashes-in-event_ids.md @@ -11,12 +11,20 @@ solution is to ensure that event IDs are URL-encoded, so that `/` is instead represented as `%2F`. However, this is not entirely satisfactory for a number of reasons: + * The act of escaping and unescaping slash characters when doing casual + development and ops work becomes an constant and annoying chore which + is entirely avoidable. Whenever using tools like `curl` and `grep` or + manipulating SQL, developers will have to constantly keep in mind whether + they are dealing with escaped or unescaped IDs, and manually convert between + the two as needed. This will only get worse with further keys-as-IDs + landing with MSC1228. + * There exist a number of client (and possibly server) implementations which do not currently URL-encode such parameters; these are therefore broken by such event IDs and must be updated. Furthermore, all future client implementers must remember to do the encoding correctly. - * Even if client implementations do rembember to URL-encode their parameters, + * Even if client implementations do remember to URL-encode their parameters, they may not do it correctly: many URL-encoding implementations may be intended to encode parameters in the query-string (which can of course contain literal slashes) rather tha the path component. @@ -27,6 +35,14 @@ of reasons: existing setups will be broken by this change, and it is a trap for new users of the software. + * Cosmetically, URL-escaping base64 in otherwise-constant-length IDs results + in variable length IDs, making it harder to visually scan lists of IDs and + manipulate them in columnar form when doing devops work. + + * Those developing against the CS API might reasonably expect us to use + URL-safe identifiers in URLs where available, rather than deliberately + choosing non-URL-safe IDs, which could be seen as developer-unfriendly. + ## Proposal This MSC proposes that we should introduce a new room version, in which event @@ -34,6 +50,22 @@ IDs are encoded using the [URL-safe Base64 encoding](https://tools.ietf.org/html/rfc4648#section-5) (which uses `-` and `_` as the 62nd and 63rd characters instead of `+` and `/`). +URL-safe Base64 encoding is then used consistently for encoding binary +identifiers in the CS API - particularly in upcoming MSC1228 IDs for rooms and +users, such that typical CS API developers should be able to safely assume +that for all common cases they should use URL-safe Base64 when decoding base64 +strings. + +The exception would be for E2EE data (device keys and signatures etc) which +currently use normal Base64 with no easy mechanism to migrate to a new encoding. +Given E2EE development is rare and requires expert skills, it seems acceptable +to expect E2EE developers to be able to use the right encoding without tripping +up significantly. + +Similarly, the S2S API could continue to use standard base64-encoded hashes and +signatures, given they are only exposed to S2S API developers who are necessarily +expert and should be able to correctly pick the right encoding. + ## Counterarguments 1. Inconsistency. Base64 encoding is used heavily elsewhere in the matrix @@ -45,6 +77,14 @@ encoding](https://tools.ietf.org/html/rfc4648#section-5) (which uses `-` and Changing event IDs alone would therefore leave us with a confusing mix of encodings. + However, the current uses of standard Base64 encodings are not exposed to + common CS API developers, and so whilst this might be slightly confusing + for the minority of expert homeserver developers, the confusion does not + exist today for client developers. Therefore it seems safe to standardise + on URL-safe Base64 for identifiers exposed to the client developers, who + form by far the majority of the Matrix ecosystem today, and expect as + simple an API as possible. + A potential extension would be to change *all* Base64 encodings to be URL-safe. This would address the inconsistency. However, it feels like a large job which would span the entire matrix ecosystem (far larger than @@ -70,6 +110,16 @@ encoding](https://tools.ietf.org/html/rfc4648#section-5) (which uses `-` and Of course, an alternative is to modify the grammars of all of these identifiers to forbid slashes. + The counter-counterargument to this is that it is of course best practice + for implementations is to URL-escape any IDs used in URLs, and human-selected + IDs such as Room aliases, Group IDs, Matrix user IDs etc apply an adequate + forcing function already to remind developers to do this. However, + it doesn't follow that we should then also deliberately pick URL-unsafe + encodings for machine-selected IDs - the argument that it is better for software + to fail 50% of the time to force a fix is irrelevant when the possibility + exists for the software to fail 0% of the time in the first place by picking + an identifier format which cannot fail. + [1] Discussion remains open as to whether allowing slashes in User IDs was a good idea. @@ -87,5 +137,29 @@ solutions to that are also possible). ## Conclusion -It's unclear to me that changing the format of event IDs alone solves any -problems. +There are two main questions here: + + 1. Whether it's worth forcing casual CS API developers to juggle escaping of + machine-selected IDs in order to remind them to escape all variables in + their URIs correctly. + + 2. Whether it's a significant problem for E2EE & SS API developers to have to + handle strings which are a mix of standard Base64 and URL-safe Base64 + encodings. + +Both of these are a subjective judgement call. + +Given we wish the CS API particularly to be as easy for casual developers to +use as possible, it feels that we should find another way to encourage +developers to escape variables in their URLs in general - e.g. by recommending +that developers test their clients against a 'torture room' full of exotic IDs +and data, or by improving warnings in the spec... rather than (ab)using +machine-selected IDs as a reminder. + +Meanwhile, given we have many more CS API developers than SS or E2EE developers, +and we wish to make the CS API particularly easy for casual developers to use, +it feels we should not prioritise consistency of encodings for SS/E2EE developers +over the usability of the CS API. + +Therefore, on balance, it seems plausible that changing the format of event IDs +does solve sufficient problems to make it desirable. \ No newline at end of file From 9dcf2d6a2805e4c81b5c04af71034a10cb68282a Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 1 Apr 2019 00:43:31 +0100 Subject: [PATCH 0283/1250] Update proposals/1884-replace-slashes-in-event_ids.md Co-Authored-By: ara4n --- proposals/1884-replace-slashes-in-event_ids.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1884-replace-slashes-in-event_ids.md b/proposals/1884-replace-slashes-in-event_ids.md index 9c3b7ea7..ae2c0e94 100644 --- a/proposals/1884-replace-slashes-in-event_ids.md +++ b/proposals/1884-replace-slashes-in-event_ids.md @@ -27,7 +27,7 @@ of reasons: * Even if client implementations do remember to URL-encode their parameters, they may not do it correctly: many URL-encoding implementations may be intended to encode parameters in the query-string (which can of course - contain literal slashes) rather tha the path component. + contain literal slashes) rather than the path component. * Some proxy software may treat `%2F` specially: for instance, Apache, when configured as a reverse-proxy, will reject requests for a path containing @@ -162,4 +162,4 @@ it feels we should not prioritise consistency of encodings for SS/E2EE developer over the usability of the CS API. Therefore, on balance, it seems plausible that changing the format of event IDs -does solve sufficient problems to make it desirable. \ No newline at end of file +does solve sufficient problems to make it desirable. From 417f3a3e8b1b0510513306139ba1fd05f39e295e Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 1 Apr 2019 00:58:10 +0100 Subject: [PATCH 0284/1250] incorporate further feedback from vdh --- .../1884-replace-slashes-in-event_ids.md | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/proposals/1884-replace-slashes-in-event_ids.md b/proposals/1884-replace-slashes-in-event_ids.md index ae2c0e94..9f1a2ad0 100644 --- a/proposals/1884-replace-slashes-in-event_ids.md +++ b/proposals/1884-replace-slashes-in-event_ids.md @@ -11,8 +11,8 @@ solution is to ensure that event IDs are URL-encoded, so that `/` is instead represented as `%2F`. However, this is not entirely satisfactory for a number of reasons: - * The act of escaping and unescaping slash characters when doing casual - development and ops work becomes an constant and annoying chore which + * The act of escaping and unescaping slash characters when manually calling + the API during devops work becomes an constant and annoying chore which is entirely avoidable. Whenever using tools like `curl` and `grep` or manipulating SQL, developers will have to constantly keep in mind whether they are dealing with escaped or unescaped IDs, and manually convert between @@ -50,11 +50,10 @@ IDs are encoded using the [URL-safe Base64 encoding](https://tools.ietf.org/html/rfc4648#section-5) (which uses `-` and `_` as the 62nd and 63rd characters instead of `+` and `/`). -URL-safe Base64 encoding is then used consistently for encoding binary -identifiers in the CS API - particularly in upcoming MSC1228 IDs for rooms and -users, such that typical CS API developers should be able to safely assume -that for all common cases they should use URL-safe Base64 when decoding base64 -strings. +We will then aim to use URL-safe Base64 encoding across Matrix in future, +such that typical CS API developers should be able to safely assume +that for all common cases (including upcoming MSC1228 identifiers) they should +use URL-safe Base64 when decoding base64 strings. The exception would be for E2EE data (device keys and signatures etc) which currently use normal Base64 with no easy mechanism to migrate to a new encoding. @@ -63,8 +62,9 @@ to expect E2EE developers to be able to use the right encoding without tripping up significantly. Similarly, the S2S API could continue to use standard base64-encoded hashes and -signatures, given they are only exposed to S2S API developers who are necessarily -expert and should be able to correctly pick the right encoding. +signatures in the places it does today, given they are only exposed to S2S API +developers who are necessarily expert and should be able to correctly pick the +right encoding. ## Counterarguments @@ -81,9 +81,9 @@ expert and should be able to correctly pick the right encoding. common CS API developers, and so whilst this might be slightly confusing for the minority of expert homeserver developers, the confusion does not exist today for client developers. Therefore it seems safe to standardise - on URL-safe Base64 for identifiers exposed to the client developers, who - form by far the majority of the Matrix ecosystem today, and expect as - simple an API as possible. + (except those implementing E2EE) on URL-safe Base64 for identifiers exposed + to the client developers, who form by far the majority of the Matrix + ecosystem today, and expect as simple an API as possible. A potential extension would be to change *all* Base64 encodings to be URL-safe. This would address the inconsistency. However, it feels like a @@ -139,7 +139,7 @@ solutions to that are also possible). There are two main questions here: - 1. Whether it's worth forcing casual CS API developers to juggle escaping of + 1. Whether it's worth forcing manual CS API users to juggle escaping of machine-selected IDs in order to remind them to escape all variables in their URIs correctly. @@ -149,17 +149,17 @@ There are two main questions here: Both of these are a subjective judgement call. -Given we wish the CS API particularly to be as easy for casual developers to -use as possible, it feels that we should find another way to encourage -developers to escape variables in their URLs in general - e.g. by recommending -that developers test their clients against a 'torture room' full of exotic IDs -and data, or by improving warnings in the spec... rather than (ab)using +Given we wish the CS API particularly to be as easy as possible for manual +use, it feels that we should find another way to encourage developers to +escape variables in their URLs in general - e.g. by recommending that +developers test their clients against a 'torture room' full of exotic IDs and +data, or by improving warnings in the spec... rather than (ab)using machine-selected IDs as a reminder. -Meanwhile, given we have many more CS API developers than SS or E2EE developers, -and we wish to make the CS API particularly easy for casual developers to use, -it feels we should not prioritise consistency of encodings for SS/E2EE developers -over the usability of the CS API. +Meanwhile, given we have many more CS API developers than SS or E2EE +developers, and we wish to make the CS API particularly easy for developers to +manually invoke, it feels we should not prioritise consistency of encodings +for SS/E2EE developers over the usability of the CS API. Therefore, on balance, it seems plausible that changing the format of event IDs does solve sufficient problems to make it desirable. From 88f533f0db33518e48c489872d8cbc68a204ab2c Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 1 Apr 2019 10:27:30 +0100 Subject: [PATCH 0285/1250] incorporate further feedback --- .../1884-replace-slashes-in-event_ids.md | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/proposals/1884-replace-slashes-in-event_ids.md b/proposals/1884-replace-slashes-in-event_ids.md index 9f1a2ad0..bec8d7ad 100644 --- a/proposals/1884-replace-slashes-in-event_ids.md +++ b/proposals/1884-replace-slashes-in-event_ids.md @@ -80,10 +80,10 @@ right encoding. However, the current uses of standard Base64 encodings are not exposed to common CS API developers, and so whilst this might be slightly confusing for the minority of expert homeserver developers, the confusion does not - exist today for client developers. Therefore it seems safe to standardise - (except those implementing E2EE) on URL-safe Base64 for identifiers exposed - to the client developers, who form by far the majority of the Matrix - ecosystem today, and expect as simple an API as possible. + exist today for client developers (except those implementing E2EE). + Therefore it seems safe to standardise on URL-safe Base64 for identifiers + exposed to the client developers, who form by far the majority of the + Matrix ecosystem today, and expect as simple an API as possible. A potential extension would be to change *all* Base64 encodings to be URL-safe. This would address the inconsistency. However, it feels like a @@ -139,9 +139,9 @@ solutions to that are also possible). There are two main questions here: - 1. Whether it's worth forcing manual CS API users to juggle escaping of - machine-selected IDs in order to remind them to escape all variables in - their URIs correctly. + 1. Whether it's worth forcing CS API developers to juggle escaping of + machine-selected IDs during manual use of the API in order to remind them + to escape all variables in their URIs correctly when writing code. 2. Whether it's a significant problem for E2EE & SS API developers to have to handle strings which are a mix of standard Base64 and URL-safe Base64 @@ -156,10 +156,11 @@ developers test their clients against a 'torture room' full of exotic IDs and data, or by improving warnings in the spec... rather than (ab)using machine-selected IDs as a reminder. -Meanwhile, given we have many more CS API developers than SS or E2EE -developers, and we wish to make the CS API particularly easy for developers to -manually invoke, it feels we should not prioritise consistency of encodings -for SS/E2EE developers over the usability of the CS API. +Meanwhile, given we have many more people manually invoking the CS API than +developing on the SS or E2EE APIs, and we wish to make the CS API particularly +easy for developers to manually invoke, it feels we should not prioritise +consistency of encodings for SS/E2EE developers over the usability of the CS +API. Therefore, on balance, it seems plausible that changing the format of event IDs does solve sufficient problems to make it desirable. From 743eeca27a821b0939780d4fd3713c3f514b3660 Mon Sep 17 00:00:00 2001 From: Neil Johnson Date: Fri, 5 Apr 2019 15:19:22 +0100 Subject: [PATCH 0286/1250] MSC to remove prev_content from the essential keys list --- ...ove-prev_event-from-essential-keys-list.md | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 proposals/1954-remove-prev_event-from-essential-keys-list.md diff --git a/proposals/1954-remove-prev_event-from-essential-keys-list.md b/proposals/1954-remove-prev_event-from-essential-keys-list.md new file mode 100644 index 00000000..992b3e80 --- /dev/null +++ b/proposals/1954-remove-prev_event-from-essential-keys-list.md @@ -0,0 +1,64 @@ +# Remove prev_content from the essential keys list + +Matrix supports the concept of event redaction. The ability to redact rather +than delete is necessary because some events e.g. membership events are +essential to the protocol and _cannot_ be deleted. Therefore we do not delete +events outright and instead redact them. This involves removing all keys from +an event that are not required by the protocol. The stripped down event is +thereafter returned anytime a client or remote server requests it. + + +## Proposal + +[The redaction algorithm](https://matrix.org/docs/spec/client_server/r0.4.0.html#redactions) +defines which keys must be retained through a redaction. Currently it lists +```prev_content``` as a key to retain, though in practice there is no need to +do so at the protocol level. + +The proposal is simply to remove ```prev_content``` from the essential keys +list. + +Note: the inclusion of ```prev_content``` in the essential keys list was +unintentional and should be considered a spec bug. Synapse (and other server +implementations) have not implemented the bug and already omit +```prev_content``` from redacted events. + + +## Tradeoffs + +When sending events over federation the events are [hashed and +signed](https://matrix.org/docs/spec/server_server/unstable.html#adding-hashes-and-signatures-to-outgoing-events), +this involves operating not only on the original event but also the redacted +form of the event. The redacted hash and redacted signed event are necessary if +the event is ever redacted in future. As a result, any change of the essential +keys list must be managed carefully. If disparate servers implement different +versions of the redaction algorithm (for a given event) attempts to send the +event over federation will fail. + +We _could_ manage this change via room versioning and create a new room +version that implements this MSC. However, because the federation already +omits the ```prev_content``` key by convention, implementing this MSC only in +the new room version would mean that the entire existing federation would not +be spec compliant. + +As a result it seems pragmatic to have the spec reflect reality, acknowledge +that the spec and federation have deviated and instead update the spec +retrospectively to describe the de-facto redaction algorithm. + +## Potential issues + +It is theoretically possible that a closed federation could exist whose servers +do follow the spec as is. This MSC would render those servers uncompliant with +the spec. On balance this seems unlikely and in the worst case those +implementors could add the change to a subsequent room version, eventually +reaching spec consistency as older room versions are deprecated. + +## Security considerations + +I am unaware of any security issues related to this proposal, but can certainly +see issues with a precedent that the federation deviates from the spec. + +## Conclusions +Removing ```prev_content``` is pragmatic response to the current situation. It +alligns the federation and the spec, and does so in a way that removes +unecessary overhead. From 8ad82ce3c0783cacb29f0730546f738acaacd92a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 5 Apr 2019 16:24:51 -0600 Subject: [PATCH 0287/1250] Add permalink routing through ?via parameters on matrix.to URIs Spec for [MSC1704](https://github.com/matrix-org/matrix-doc/pull/1704) Reference implementations: * Original: https://github.com/matrix-org/matrix-react-sdk/pull/2250 * Modern recommendations: https://github.com/matrix-org/matrix-react-sdk/blob/2ca281f6b7b735bc96945370584c5cb1b5f7e1f1/src/matrix-to.js#L29-L70 The only deviation from the original MSC is the recommendation for which servers to pick. The original MSC failed to consider server ACLs and IP addresses correctly, and during implementation it was realized that both of these cases should be handled. The core principles of the original MSC are left unaltered. --- .../appendices/identifier_grammar.rst | 61 +++++++++++++++++-- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/specification/appendices/identifier_grammar.rst b/specification/appendices/identifier_grammar.rst index 729246d0..ea805955 100644 --- a/specification/appendices/identifier_grammar.rst +++ b/specification/appendices/identifier_grammar.rst @@ -311,13 +311,16 @@ in the room's history (a permalink). A matrix.to URI has the following format, based upon the specification defined in RFC 3986: - https://matrix.to/#// + https://matrix.to/#//? The identifier may be a room ID, room alias, user ID, or group ID. The extra parameter is only used in the case of permalinks where an event ID is referenced. The matrix.to URI, when referenced, must always start with ``https://matrix.to/#/`` followed by the identifier. +The ```` and the preceeding question mark are optional and +only apply in certain circumstances, documented below. + Clients should not rely on matrix.to URIs falling back to a web server if accessed and instead should perform some sort of action within the client. For example, if the user were to click on a matrix.to URI for a room alias, the client may open @@ -331,7 +334,7 @@ Examples of matrix.to URIs are: * Room alias: ``https://matrix.to/#/%23somewhere%3Aexample.org`` * Room: ``https://matrix.to/#/!somewhere%3Aexample.org`` * Permalink by room: ``https://matrix.to/#/!somewhere%3Aexample.org/%24event%3Aexample.org`` -* Permalink by room alias: ``https://matrix.to/#/#somewhere:example.org/%24event%3Aexample.org`` +* Permalink by room alias: ``https://matrix.to/#/%23somewhere:example.org/%24event%3Aexample.org`` * User: ``https://matrix.to/#/%40alice%3Aexample.org`` * Group: ``https://matrix.to/#/%2Bexample%3Aexample.org`` @@ -345,7 +348,53 @@ Examples of matrix.to URIs are: appearing due to some `room versions `_. These slashes should normally be encoded when producing matrix.to URIs, however. -.. Note:: - Room ID permalinks are unroutable as there is no reliable domain to send requests - to upon receipt of the permalink. Clients should do their best route Room IDs to - where they need to go, however they should also be aware of `issue #1579 `_. +Routing +<<<<<<< + +Room IDs are not routable on their own as there is no reliable domain to send requests +to. This is partially mitigated with the addition of a ``via`` argument on a matrix.to +URI, however the problem of routability is still present. Clients should do their best +to route Room IDs to where they need to go, however they should also be aware of +`issue #1579 `_. + +A room (or room permalink) which isn't using a room alias should supply at least one +server using ``via`` in the ````, like so: +``https://matrix.to/!somewhere%3Aexample.org?via=example.org&via=alt.example.org``. The +parameter can be supplied multiple times to specify multiple servers to try. + +The values of ``via`` are intended to be passed along as the ``server_name`` parameters +on the Client Server ``/join`` API. + +When generating room links and permalinks, the application should pick servers which +have a high probability of being in the room in the distant future. How these servers +are picked is left as an implementation detail, however the current recommendation is +to pick 3 unique servers based on the following criteria: + +* The first server should be the server of the highest power level user in the room, + provided they are at least power level 50. If no user meets this criteria, pick the + most popular server in the room (most joined users). The rationale for not picking + users with power levels under 50 is that they are unlikely to be around into the + distant future while higher ranking users (and therefore servers) are less likely + to give up their power and move somewhere else. Most rooms in the public federation + have a power level 100 user and have not deviated from the default structure where + power level 50 users have moderator-style privileges. + +* The second server should be the next highest server by population, or the first + highest by population if the first server was based on a user's power level. The + rationale for picking popular servers is that the server is unlikely to be removed + as the room naturally grows in membership due to that server joining users. The + server could be refused participation in the future due to server ACLs or similar, + however the chance of that happening to a server which is organically joining the + room is unlikely. + +* The third server should be the next highest server by population. + +* Servers which are blocked due to server ACLs should never be chosen. + +* Servers which are IP addresses should never be chosen. Servers which use a domain + name are less likely to be unroutable in the future whereas IP addresses cannot be + pointed to a different location and therefore higher risk options. + +* All 3 servers should be unique from each other. If the room does not have enough users + to supply 3 servers, the application should only specify the servers it can. For example, + a room with only 2 users in it would result in maximum 2 ``via`` parameters. From 99cd064f2623ce762319f571c10b79912db3bc68 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 5 Apr 2019 16:37:27 -0600 Subject: [PATCH 0288/1250] Update original MSC as per proposal guidelines --- proposals/1704-matrix.to-permalinks.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/proposals/1704-matrix.to-permalinks.md b/proposals/1704-matrix.to-permalinks.md index 1430565c..7e1a2b28 100644 --- a/proposals/1704-matrix.to-permalinks.md +++ b/proposals/1704-matrix.to-permalinks.md @@ -33,4 +33,7 @@ is to pick up to 3 unique servers where the first one is that of the user with t highest power level in the room, provided that power level is 50 or higher. The other 2 servers should be the most popular servers in the room based on the number of joined users. This same heuristic should apply to the first server if no user meets the power -level requirements. +level requirements. Servers blocked by server ACLs should not be picked because they +are unlikely to continue being residents of the room. Similarly, IP addresses should +not be picked because they cannot be redirected to another location like domain names +can, making them a higher risk option. From 29a9982447a946e7338749031a68e1fa7937df0f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 7 Apr 2019 21:04:52 -0600 Subject: [PATCH 0289/1250] Proposal for integration manager discovery --- proposals/0000-integrations-discovery.md | 133 +++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 proposals/0000-integrations-discovery.md diff --git a/proposals/0000-integrations-discovery.md b/proposals/0000-integrations-discovery.md new file mode 100644 index 00000000..c09551a8 --- /dev/null +++ b/proposals/0000-integrations-discovery.md @@ -0,0 +1,133 @@ +# MSC0000: Integration manager discovery + +*Note*: This is a required component of [MSC1956 - Integrations API](https://github.com/matrix-org/matrix-doc/pull/1956) + +Users should have the freedom to choose which integration manager they want to use in their client, while +also accepting suggestions from their homeserver and client. Clients need to know where to find the different +integration managers and how to contact them. + + +## Proposal + +A single logged in user may be influenced by zero or more integration managers at any given time. Managers +are sourced from the client's own configuration, homeserver discovery information, and the user's personal +account data in the form of widgets. Clients should support users using more than one integration manager +at a given time, although the rules for how this can be handled are defined later in this proposal. + +#### Client-configured integration managers + +This is left as an implementation detail. In the case of Riot, this is likely to be part of the existing +`config.json` options, although liekly modified to support multiple managers instead of one. + +#### Homeserver-configured integration managers + +The integration managers suggested by a homeserver are done through the existing +[.well-known](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-well-known-matrix-client) discovery +mechanism. The added optional fields, which should not affect a client's ability to log a user in, are: +```json +{ + "m.integrations": { + "managers": [ + { + "api_url": "https://integrations.example.org", + "ui_url": "https://integrations.example.org/ui" + }, + { + "api_url": "https://bots.example.org" + } + ] + } +} +``` + +As shown, the homeserver is able to suggest multiple integration managers through this method. Each manager +must have an `api_url` which must be an `http` or `https` URL. The `ui_url` is optional and if not provided +is the same as the `api_url`. Like the `api_url`, the `ui_url` must be `http` or `https` if supplied. + +The `ui_url` is ultimately treated the same as a widget, except that the custom `data` is not present and +must not be templated here. Variables like `$matrix_display_name` are able to function, however. Integration +managers should never use the `$matrix_user_id` as authoritative and instead seek other ways to determine the +user ID. This is covered by other proposals. + +The `api_url` is the URL clients will use when *not* embedding the integration manager, and instead showing +its own purpose-built interface. + +#### User-configured integration managers + +Users can specify integration managers in the form of account widgets. The `type` is to be `m.integration_manager` +and the content would look something similar to: +```json +{ + "url": "https://integrations.example.org/ui?displayName=$matrix_display_name", + "data": { + "api_url": "https://integrations.example.org" + } +} +``` + +The `api_url` in the `data` object is required and has the same meaning as the homeserver-defined `api_url`. +The `url` of the widget is analogous to the `ui_url` from the homeserver configuration above, however normal +widget rules apply here. + +The user is able to have multiple integration managers through use of multiple widgets. + +#### Display order of integration managers + +Clients which have support for integration managers should display at least 1 manager, but may decide +to display multiple via something like tabs. Clients must prefer to display the user's configured +integration managers over any defaults, and if only displaying one manager must pick the first +manager after sorting the `state_key`s in lexicographical order. Clients may additionally display +default managers if they so wish, and should preserve the order defined in the various defaults. +If the user has no configured integration managers, the client must prefer to display one or more +of the managers suggested by the homeserver over the managers recommended by the client. + +The client may optionally support a way to entirely disable integration manager support, even if the +user and homeserver have managers defined. + +The rationale for having the client prefer to use the user's integration managers first is so that +the user can tailor their experience within Matrix if desired. Similarly, a homeserver may wish to +subject all of their users to the same common integration manager as would be common in some organizations. +The client's own preference is a last ditch effort to have an integration manager available to the +user so they don't get left out. + +#### Displaying integration managers + +Clients simply open the `ui_url` (or equivalent) in an `iframe` or similar. In the current ecosystem, +integration managers would receive a `scalar_token` to idenitify the user - this is no longer the case +and instead integration managers must seek other avenues for determining the user ID. Other proposals +cover how to do this in the context of the integrations API. + +Integration managers shown in this way must be treated like widgets, regardless of source. In practice +this means exposing the Widget API to the manager and applying necessary scoping to keep the manager +as an account widget rather than a room widget. + + +## Tradeoffs + +We could limit the user (and by extension, the homeserver and client) to exactly 1 integration manager +and not worry about tabs or other concepts, however this restricts a user's access to integrations. +In a scenario where the user wants to use widgets from Service A and bots from Service B, they'd +end up switching accounts or clients to gain access to either service, or potentially just give up +and walk away from the problem. Instead of having the user switch between clients, we might as well +support this use case, even if it is moderately rare. + +We could also define the integration managers in a custom account data event rather than defining them +as a widget. Doing so just adds clutter to the account data and risks duplicating code in clients as +using widgets gets us URL templating for free (see the section later on in this proposal about account +widgets for more information). + + +## Future extensions + +Some things which may be desirable in the future are: +* Avatars for the different managers +* Human-readable names for the different managers +* Supporting `ui_url`s targeting specific clients for a more consistent design + + +## Security considerations + +When displaying integration managers, clients should not trust that the input is sanitary. Integration +managers may only be at HTTP(S) endpoints and may still have malicious intent. Ensure any sandboxing +on the manager is appropriate such that it can communicate with the client, but cannot perform unauthorized +actions. From cc10444d4b3dceac24ae15648e2ab0f078fa99a2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 7 Apr 2019 21:06:42 -0600 Subject: [PATCH 0290/1250] Assign MSC number --- proposals/0000-integrations-discovery.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/0000-integrations-discovery.md b/proposals/0000-integrations-discovery.md index c09551a8..7672e024 100644 --- a/proposals/0000-integrations-discovery.md +++ b/proposals/0000-integrations-discovery.md @@ -1,4 +1,4 @@ -# MSC0000: Integration manager discovery +# MSC1957: Integration manager discovery *Note*: This is a required component of [MSC1956 - Integrations API](https://github.com/matrix-org/matrix-doc/pull/1956) From dffe19bb76226f956d35d79e6e67c256e4b9a896 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 7 Apr 2019 21:07:46 -0600 Subject: [PATCH 0291/1250] Rename file to match MSC number --- ...0-integrations-discovery.md => 1957-integrations-discovery.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/{0000-integrations-discovery.md => 1957-integrations-discovery.md} (100%) diff --git a/proposals/0000-integrations-discovery.md b/proposals/1957-integrations-discovery.md similarity index 100% rename from proposals/0000-integrations-discovery.md rename to proposals/1957-integrations-discovery.md From 2dcda7d564d9e45538b95a08f5183c1628aff05a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 7 Apr 2019 21:17:14 -0600 Subject: [PATCH 0292/1250] Add a mention that clients should re-query .well-known --- proposals/1957-integrations-discovery.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/proposals/1957-integrations-discovery.md b/proposals/1957-integrations-discovery.md index 7672e024..2eca300b 100644 --- a/proposals/1957-integrations-discovery.md +++ b/proposals/1957-integrations-discovery.md @@ -52,6 +52,11 @@ user ID. This is covered by other proposals. The `api_url` is the URL clients will use when *not* embedding the integration manager, and instead showing its own purpose-built interface. +Clients should query the `.well-known` information for the homeserver periodically to update the integration +manager settings for that homeserver. The client is not expected to validate or use any other information +contained in the response. Current recommendations are to query the configuration when the client starts up +and every 8 hours after that. + #### User-configured integration managers Users can specify integration managers in the form of account widgets. The `type` is to be `m.integration_manager` From 13d63685d379b68b4bb356822a64d78526ca65b1 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Mon, 8 Apr 2019 07:05:38 -0600 Subject: [PATCH 0293/1250] Spelling Co-Authored-By: turt2live --- proposals/1957-integrations-discovery.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1957-integrations-discovery.md b/proposals/1957-integrations-discovery.md index 2eca300b..fd6bc8f9 100644 --- a/proposals/1957-integrations-discovery.md +++ b/proposals/1957-integrations-discovery.md @@ -17,7 +17,7 @@ at a given time, although the rules for how this can be handled are defined late #### Client-configured integration managers This is left as an implementation detail. In the case of Riot, this is likely to be part of the existing -`config.json` options, although liekly modified to support multiple managers instead of one. +`config.json` options, although likely modified to support multiple managers instead of one. #### Homeserver-configured integration managers From e8de1423b12c93cb53fcc4b1999aebc7369272da Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 8 Apr 2019 21:22:55 -0600 Subject: [PATCH 0294/1250] Proposal for OpenID information exchange with widgets --- proposals/0000-integrations-openid.md | 83 +++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 proposals/0000-integrations-openid.md diff --git a/proposals/0000-integrations-openid.md b/proposals/0000-integrations-openid.md new file mode 100644 index 00000000..8658e828 --- /dev/null +++ b/proposals/0000-integrations-openid.md @@ -0,0 +1,83 @@ +# MSC0000: OpenID information exchange for widgets + +With the various integrations API proposals, widgets are left with no options to verify the +requesting user's ID if they need it. Widgets like the sticker picker must know who is making +the request and as such need a way to get accurate information about who is contacting them. + +This proposal introduces a way for widgets (room and account) to do so over the `fromWidget` +API proposed by [MSC1236](https://github.com/matrix-org/matrix-doc/issues/1236). + + +## Proposal + +Room and account widgets may request a new OpenID object from the user so they can log in/register with +the backing integration manager or other application. This is largely based on the prior art available +[here (riot-web#7153)](https://github.com/vector-im/riot-web/issues/7153). The rationale for such an +API is so that widgets can load things like a user's sticker packs or other information without having +to rely on secret strings. For example, a room could be used to let a user create custom sticker packs +via a common widget - it would be nice if that widget could auth the user without asking them to enter +their username and password into an iframe. + +Widgets can request OpenID credentials from the user by sending a `fromWidget` action of `get_openid` +to intiate the token exchange process. The client should respond with an acknowledgement of +`{"state":"request"}` (or `{"state":"blocked"}` if the client/user doesn't think the widget is safe). +The client should then prompt the user if the widget should be allowed to get details about the user, +optionally providing a way for the user to always accept/deny the widget. If the user agrees, the +client sends a `toWidget` action of `openid_credentials` with `data` holding the raw OpenID credentials +object returned from the homeserver, and a `success: true` parameter. If the user denies the widget, +just `success: false` is returned in the `data` property. To lessen the number of requests, a client may +also respond to the original `get_openid` request with a `state` of `"allowed"`, `success: true`, and +the OpenID object (just like in the data for `openid_credentials`). The widget should not request OpenID +credentials until after it has exchanged capabilities with the client, however this is not required. The +widget should acknowledge the `openid_credentials` request with an empty response object. + +A full sequence diagram for this flow is as follows: + +``` ++-------+ +---------+ +---------+ +| User | | Client | | Widget | ++-------+ +---------+ +---------+ + | | | + | | Capabilities negotiation | + | |<-----------------------------------------| + | | | + | | Capabilities negotiation | + | |----------------------------------------->| + | | | + | | fromWidget get_openid request | + | |<-----------------------------------------| + | | | + | | ack with state "request" | + | |----------------------------------------->| + | | | + | Ask if the widget can have information | | + |<--------------------------------------------| | + | | | + | Approve | | + |-------------------------------------------->| | + | | | + | | toWidget openid_credentials request | + | |----------------------------------------->| + | | | + | | acknowledge request (empty response) | + | |<-----------------------------------------| +``` + +Prior to this proposal, widgets could use an undocumented `scalar_token` parameter if the client chose to +send it to the widget. Clients typically chose to send it if the widget's URL matched a whitelist for URLs +the client trusts. Widgets are now not able to rely on this behaviour with this proposal, although clients +may wish to still support it until adoption is complete. Widgets may wish to look into cookies and other +storage techniques to avoid continously requesting credentials. + +A proof of concept for this system is demonstrated [here](https://github.com/matrix-org/matrix-react-sdk/pull/2781). + +The widget is left responsible for dealing with the OpenID object it receives, likely handing it off to +the integration manager it is backed by to exchange it for a long-lived Bearer token. + +## Security considerations + +The user is explicitly kept in the loop to avoid automatic and silent harvesting of private information. +Clients must ask the user for permission to send OpenID information to a widget, but may optionally allow +the user to always allow/deny the widget access. Clients are encouraged to notify the user when future +requests are automatically handled due to the user's prior selection (eg: an unobtrusive popup saying +"hey, your sticker picker asked for your information. [Block future requests]"). From bd0211be127c4807c3527583ea9556cd68473473 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 8 Apr 2019 21:24:57 -0600 Subject: [PATCH 0295/1250] Assign MSC number --- ...{0000-integrations-openid.md => 1960-integrations-openid.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename proposals/{0000-integrations-openid.md => 1960-integrations-openid.md} (99%) diff --git a/proposals/0000-integrations-openid.md b/proposals/1960-integrations-openid.md similarity index 99% rename from proposals/0000-integrations-openid.md rename to proposals/1960-integrations-openid.md index 8658e828..edc34a0b 100644 --- a/proposals/0000-integrations-openid.md +++ b/proposals/1960-integrations-openid.md @@ -1,4 +1,4 @@ -# MSC0000: OpenID information exchange for widgets +# MSC1960: OpenID information exchange for widgets With the various integrations API proposals, widgets are left with no options to verify the requesting user's ID if they need it. Widgets like the sticker picker must know who is making From d6d0f9780dc3948f25bac7880adea6602650ec4e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 8 Apr 2019 21:36:16 -0600 Subject: [PATCH 0296/1250] Proposal for basic integration manager authentication APIs --- proposals/0000-integrations-auth.md | 69 +++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 proposals/0000-integrations-auth.md diff --git a/proposals/0000-integrations-auth.md b/proposals/0000-integrations-auth.md new file mode 100644 index 00000000..1a491790 --- /dev/null +++ b/proposals/0000-integrations-auth.md @@ -0,0 +1,69 @@ +# MSC0000: Integration manager authentication + +A set of common APIs needs to be defined for clients to be able to interact with an integration +manager. This proposal covers the authentication portion of that API. + + +## Proposal + +All specified APIs (except `/register`) will take an `Authorization` header with a `Bearer` token returned +from a call to `/register`. This token is used to authorize the request and to identify who is making the +request. + +#### POST /_matrix/integrations/v1/account/register + +Exchanges an OpenID object for a token which can be used to authorize future requests to the manager. + +Request body is an OpenID object as returned by `/_matrix/client/r0/user/:userId/openid/request_token`. + +Response is: +```json +{ + "token": "OpaqueString" +} +``` + +The token should consist of URL-safe base64 characters. Integration managers should be careful to validate +the OpenID object by ensuring the `/_matrix/federation/v1/openid/userinfo` response has a `sub` which belongs +to the `matrix_server_name` provided in the original OpenID object. + +Applications which register for a token are responsible for tracking which integration manager they are for. +This can usually be done by tracking the hostname of the integration manager and matching a token with it. + +#### GET /_matrix/integrations/v1/account + +Gets information about the token's owner, such as the user ID for which it belongs. + +Besides a token, no other information is required for the request. + +Response is: +```json +{ + "user_id": "@alice:example.org" +} +``` + +The `user_id` is the user ID which was represented in the OpenID object provided to `/register`. Integration +managers may be interested in also supplying information about the user's credit balance for paid integrations +here. Preferably, custom information is stored under a namespaced key like so: +```json +{ + "user_id": "@alice:example.org", + "org.example.paid.integrations": { + "credit": 20000 + } +} +``` + +#### POST /_matrix/integrations/v1/account/logout + +Logs the token out, rendering it useless for future requests. + +Request body is an empty object. Response body is also an empty object if successful. + + +## Security considerations + +Clients should be sure to call `/logout` where possible when the user is logging out or no longer needs access +to a given manager. Clients should additionally be cautious about which managers they register for tokens with, +as some integration managers may be untrusted. From 0bab70c14e84ff71146cc9a8dce7071e1021d75f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 8 Apr 2019 21:37:35 -0600 Subject: [PATCH 0297/1250] Assign MSC number --- .../{0000-integrations-auth.md => 1961-integrations-auth.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename proposals/{0000-integrations-auth.md => 1961-integrations-auth.md} (98%) diff --git a/proposals/0000-integrations-auth.md b/proposals/1961-integrations-auth.md similarity index 98% rename from proposals/0000-integrations-auth.md rename to proposals/1961-integrations-auth.md index 1a491790..863ea325 100644 --- a/proposals/0000-integrations-auth.md +++ b/proposals/1961-integrations-auth.md @@ -1,4 +1,4 @@ -# MSC0000: Integration manager authentication +# MSC1961: Integration manager authentication A set of common APIs needs to be defined for clients to be able to interact with an integration manager. This proposal covers the authentication portion of that API. From b41fbc86b6d07a93c10f074c97befe9fe7e4733e Mon Sep 17 00:00:00 2001 From: Neil Johnson Date: Tue, 9 Apr 2019 13:56:45 +0100 Subject: [PATCH 0298/1250] add further potential issues and security concerns --- ...emove-prev_event-from-essential-keys-list.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/proposals/1954-remove-prev_event-from-essential-keys-list.md b/proposals/1954-remove-prev_event-from-essential-keys-list.md index 992b3e80..1cd0fd36 100644 --- a/proposals/1954-remove-prev_event-from-essential-keys-list.md +++ b/proposals/1954-remove-prev_event-from-essential-keys-list.md @@ -53,10 +53,23 @@ the spec. On balance this seems unlikely and in the worst case those implementors could add the change to a subsequent room version, eventually reaching spec consistency as older room versions are deprecated. +Another scenario is that a client may redact events according to the spec as is +and persist prev_content through the redaction, thereby diverting from that on +the server(s). Client authors will have to update their code to drop +```prev_content``` - however, given that prev_content should not be used in +important calculations and/or visualisations, this ought to be relatively +uninvaisive change. + + ## Security considerations -I am unaware of any security issues related to this proposal, but can certainly -see issues with a precedent that the federation deviates from the spec. +A further reason to support removal of ```prev_content``` is the case where a +malicious user adds illegal or abusive content into a state event and then +overwrites that state event. The content would then be preserved through the +redaction. + +Additionally, there are plenty of reasons to have security concerns over a +precedent that the federation can deviate from the spec. ## Conclusions Removing ```prev_content``` is pragmatic response to the current situation. It From 24e0ec4bcecee55e34d54bd8a747f619b57384b5 Mon Sep 17 00:00:00 2001 From: aqtusia <47819902+aqtusia@users.noreply.github.com> Date: Sun, 14 Apr 2019 18:17:44 +0200 Subject: [PATCH 0299/1250] Replace /bind with /3pid/bind --- api/identity/associations.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/identity/associations.yaml b/api/identity/associations.yaml index edd43f5d..152a0a9b 100644 --- a/api/identity/associations.yaml +++ b/api/identity/associations.yaml @@ -90,7 +90,7 @@ paths: } schema: $ref: "../client-server/definitions/errors/error.yaml" - "/bind": + "/3pid/bind": post: summary: Publish an association between a session and a Matrix user ID. description: |- From 2eb9708f7fcdead5e21ad22bd8a054e1ae4bfd31 Mon Sep 17 00:00:00 2001 From: aqtusia <47819902+aqtusia@users.noreply.github.com> Date: Sun, 14 Apr 2019 18:21:59 +0200 Subject: [PATCH 0300/1250] Replace /unbind with /3pid/unbind --- proposals/1915-unbind-identity-server-param.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/1915-unbind-identity-server-param.md b/proposals/1915-unbind-identity-server-param.md index 053552f6..6817ece3 100644 --- a/proposals/1915-unbind-identity-server-param.md +++ b/proposals/1915-unbind-identity-server-param.md @@ -55,12 +55,12 @@ from the given identity server. ### Identity Server 3PID Unbind API -Add `POST /_matrix/identity/api/v1/unbind` with `mxid` and `threepid` fields. +Add `POST /_matrix/identity/api/v1/3pid/unbind` with `mxid` and `threepid` fields. The `mxid` is the user's `user_id` and `threepid` is a dict with the usual `medium` and `address` fields. If the server returns a 400, 404 or 501 HTTP error code then the homeserver -should assume that the identity server doesn't support the `/unbind` API, unless +should assume that the identity server doesn't support the `/3pid/unbind` API, unless it returns a specific matrix error response (i.e. the body is a JSON object with `error` and `errcode` fields). @@ -73,7 +73,7 @@ The identity server should authenticate the request in one of two ways: Example: ``` -POST /_matrix/identity/api/v1/unbind HTTP/1.1 +POST /_matrix/identity/api/v1/3pid/unbind HTTP/1.1 { "mxid": "@foobar:example.com", From 911fb94ea0d7213ea363293c1db39ca4391669f7 Mon Sep 17 00:00:00 2001 From: Neil Johnson Date: Mon, 15 Apr 2019 17:08:09 +0100 Subject: [PATCH 0301/1250] typos --- .../1954-remove-prev_event-from-essential-keys-list.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/1954-remove-prev_event-from-essential-keys-list.md b/proposals/1954-remove-prev_event-from-essential-keys-list.md index 1cd0fd36..735fac01 100644 --- a/proposals/1954-remove-prev_event-from-essential-keys-list.md +++ b/proposals/1954-remove-prev_event-from-essential-keys-list.md @@ -48,7 +48,7 @@ retrospectively to describe the de-facto redaction algorithm. ## Potential issues It is theoretically possible that a closed federation could exist whose servers -do follow the spec as is. This MSC would render those servers uncompliant with +do follow the spec as is. This MSC would render those servers non-compliant with the spec. On balance this seems unlikely and in the worst case those implementors could add the change to a subsequent room version, eventually reaching spec consistency as older room versions are deprecated. @@ -57,8 +57,8 @@ Another scenario is that a client may redact events according to the spec as is and persist prev_content through the redaction, thereby diverting from that on the server(s). Client authors will have to update their code to drop ```prev_content``` - however, given that prev_content should not be used in -important calculations and/or visualisations, this ought to be relatively -uninvaisive change. +important calculations and/or visualisations, this ought to be a relatively +non-invasive change. ## Security considerations From 043dddc49061f4a8837a0b9d5dc0fb0c0d79f85d Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Sat, 20 Apr 2019 21:56:43 +0200 Subject: [PATCH 0302/1250] Fix a typo in m.call.invite --- event-schemas/schema/m.call.invite | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event-schemas/schema/m.call.invite b/event-schemas/schema/m.call.invite index ebf09267..65796e1e 100644 --- a/event-schemas/schema/m.call.invite +++ b/event-schemas/schema/m.call.invite @@ -10,7 +10,7 @@ "properties": { "call_id": { "type": "string", - "description": "A unique identifer for the call." + "description": "A unique identifier for the call." }, "offer": { "type": "object", From 2ae122903f1338ca82362dd89e196168164143e2 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Thu, 25 Apr 2019 20:49:58 -0400 Subject: [PATCH 0303/1250] Use the right name Co-Authored-By: uhoreg --- proposals/1756-cross-signing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 68143b87..17721055 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -48,7 +48,7 @@ key by using the new user-signing key. Otherwise, they will need to re-verify the other users. If a user's self-signing key is compromised, then the user will need to issue -both a new self-signing key and a new device-signing key. The user may sign +both a new self-signing key and a new user-signing key. The user may sign their new self-signing key with their old self-signing key, allowing other users who have verified the old self-signing key to automatically trust the new self-signing key if they wish to. Otherwise, the users will need to re-verify From 14715468bb6aa157601fa271bd3a57507f90b8dd Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 26 Apr 2019 14:41:19 +0100 Subject: [PATCH 0304/1250] Make thumbnail dimensions mandatory Fixes #1883 --- api/client-server/content-repo.yaml | 2 ++ changelogs/client_server/newsfragments/1975.clarification | 1 + 2 files changed, 3 insertions(+) create mode 100644 changelogs/client_server/newsfragments/1975.clarification diff --git a/api/client-server/content-repo.yaml b/api/client-server/content-repo.yaml index 5f4e9111..07df18fe 100644 --- a/api/client-server/content-repo.yaml +++ b/api/client-server/content-repo.yaml @@ -202,6 +202,7 @@ paths: type: integer x-example: 64 name: width + required: true description: |- The *desired* width of the thumbnail. The actual thumbnail may not match the size specified. @@ -209,6 +210,7 @@ paths: type: integer x-example: 64 name: height + required: true description: |- The *desired* height of the thumbnail. The actual thumbnail may not match the size specified. diff --git a/changelogs/client_server/newsfragments/1975.clarification b/changelogs/client_server/newsfragments/1975.clarification new file mode 100644 index 00000000..03a9b754 --- /dev/null +++ b/changelogs/client_server/newsfragments/1975.clarification @@ -0,0 +1 @@ +Clarify that ``width`` and ``height`` are required parameters on ``/_matrix/media/r0/thumbnail/{serverName}/{mediaId}``. It is somewhat meaningless to request a thumbnail without specifying a desired size, and Synapse has never permitted such requests. \ No newline at end of file From 6cdc8982fa84fc25b6ea9d20d241df8e2795b643 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 26 Apr 2019 15:58:31 +0100 Subject: [PATCH 0305/1250] jenkins is dead, long live buildkite --- .buildkite/pipeline.yaml | 11 +++++++++++ jenkins.sh | 3 --- scripts/requirements.txt | 8 ++++++-- 3 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 .buildkite/pipeline.yaml delete mode 100755 jenkins.sh diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml new file mode 100644 index 00000000..e98d7026 --- /dev/null +++ b/.buildkite/pipeline.yaml @@ -0,0 +1,11 @@ +steps: + - label: ":books: Build spec" + command: + - python3 -m venv env + - env/bin/pip install -r scripts/requirements.txt + - ". env/bin/activate; scripts/generate-matrix-org-assets" + artifact_paths: + - assets.tar.gz + plugins: + - docker#v3.0.1: + image: "python:3.6" diff --git a/jenkins.sh b/jenkins.sh deleted file mode 100755 index 79b77acb..00000000 --- a/jenkins.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -exec ./scripts/test-and-build.sh diff --git a/scripts/requirements.txt b/scripts/requirements.txt index 2a7d7ff8..66027f91 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -4,8 +4,12 @@ docutils >= 0.14 pygments >= 2.2.0 Jinja2 >= 2.9.6 -jsonschema >= 2.6.0 + +# jsonschema 3.0.0 objects to the $refs in our schema file. TODO: figure out +# why. +jsonschema >= 2.6.0, < 3.0.0 + PyYAML >= 3.12 requests >= 2.18.4 towncrier == 18.6.0 -six >= 1.11.0 \ No newline at end of file +six >= 1.11.0 From 661d69858edde5d543a0eaa1503f0383b2ea2b92 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Mon, 29 Apr 2019 10:24:46 +0100 Subject: [PATCH 0306/1250] Add fallback --- proposals/1802-standardised-federation-response-format.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/1802-standardised-federation-response-format.md b/proposals/1802-standardised-federation-response-format.md index f4cefc8f..da18c254 100644 --- a/proposals/1802-standardised-federation-response-format.md +++ b/proposals/1802-standardised-federation-response-format.md @@ -41,6 +41,10 @@ This proposal doesn't address the `PUT [MSC1794](https://github.com/matrix-org/matrix-doc/pull/1794) already takes care of it. +If a call to any of the `v2` endpoints described in this proposal results in an +unrecognised request exception, then the sending server should retry the request +with the `v1` API. + ## Alternative solutions An alternative solution would be to make the change in the `v1` fedration API, From 4e9dc2098ff65acda435797b8d824653289f0e8b Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 30 Apr 2019 17:43:21 +0100 Subject: [PATCH 0307/1250] Fix comments which refer to jenkins. (#1981) * Fix comments which refer to jenkins. * Spelling Co-Authored-By: turt2live --- scripts/test-and-build.sh | 2 +- specification/proposals.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/test-and-build.sh b/scripts/test-and-build.sh index 710b03dd..f45e2da6 100755 --- a/scripts/test-and-build.sh +++ b/scripts/test-and-build.sh @@ -30,5 +30,5 @@ go get gopkg.in/fsnotify/fsnotify.v1 # build the spec for matrix.org. # (we don't actually use it on travis, but it's still useful to check we -# can build it. On Jenkins, this is then used to deploy to matrix.org). +# can build it. On Buildkite, this is then used to deploy to matrix.org). ./scripts/generate-matrix-org-assets diff --git a/specification/proposals.rst b/specification/proposals.rst index 371850ab..94878f80 100644 --- a/specification/proposals.rst +++ b/specification/proposals.rst @@ -1,6 +1,6 @@ Tables of Tracked Proposals --------------------------- -This file is autogenerated by a jenkins build process +This file is generated by an automated process on our build server. -View the current live version `at https://matrix.org/docs/spec/proposals `_ +View the current live version `at https://matrix.org/docs/spec/proposals `_. From 97786da4ad9038a29c545315b10de4d305313aab Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 30 Apr 2019 15:13:28 -0600 Subject: [PATCH 0308/1250] Create 0000-leave-reasons.md --- proposals/0000-leave-reasons.md | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 proposals/0000-leave-reasons.md diff --git a/proposals/0000-leave-reasons.md b/proposals/0000-leave-reasons.md new file mode 100644 index 00000000..8e0710b8 --- /dev/null +++ b/proposals/0000-leave-reasons.md @@ -0,0 +1,39 @@ +# Proposal to add reasons for leaving a room + +This proposal intends to solve [#1295](https://github.com/matrix-org/matrix-doc/issues/1295). Currently +people can be kicked from a room for a human-readable reason, but when voluntarily leaving the `reason` +is not considered. + +## Proposal + +Like when kicking someone, `m.room.member` events with `membership: leave` can have a string `reason`. +The reason is a human-readable string of text which clients should display to users of the room, providing +users with the ability to leave a room for a reason of their choosing. The field is optional. + +Having such a field gives Matrix better compatibility with other networks such as IRC which use the leave +reason to communicate connection problems ("ping timeout", etc). Although Matrix doesn't have a need for a +persistent connection to remain in the room, having a reason can improve the bridge experience. + +An example of a partial leave event with reason would be: +```json +{ + "type": "m.room.member", + "sender": "@travis:t2l.io", + "state_key": "@travis:t2l.io", + "content": { + "membership": "leave", + "reason": "I'm in too many rooms and never talk here" + } +} +``` + + +## Potential issues + +There is a chance that quality of communication may deteriorate as a result of adding this field. Arguments +in rooms may result in the leave reason having personal attacks against other room members or rude remarks. +Moderators would be expected to handle these situations for these cases, including redacting the state event +if needed. + +This also opens up an avenue for spam by having a very large reason for leaving. Clients are encouraged to +trim/hide the reason at a reasonable length. From 62748a026d6688df514c7e0aad544648b8ce1a15 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 30 Apr 2019 15:14:54 -0600 Subject: [PATCH 0309/1250] Rename 0000-leave-reasons.md to 1983-leave-reasons.md --- proposals/{0000-leave-reasons.md => 1983-leave-reasons.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/{0000-leave-reasons.md => 1983-leave-reasons.md} (100%) diff --git a/proposals/0000-leave-reasons.md b/proposals/1983-leave-reasons.md similarity index 100% rename from proposals/0000-leave-reasons.md rename to proposals/1983-leave-reasons.md From e71b3ac754963910ef76e39e29178ad3e40aab9f Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Wed, 1 May 2019 16:53:29 +0100 Subject: [PATCH 0310/1250] Add details to what an unrecognised request is --- proposals/1802-standardised-federation-response-format.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1802-standardised-federation-response-format.md b/proposals/1802-standardised-federation-response-format.md index da18c254..bd8b1189 100644 --- a/proposals/1802-standardised-federation-response-format.md +++ b/proposals/1802-standardised-federation-response-format.md @@ -42,8 +42,8 @@ This proposal doesn't address the `PUT of it. If a call to any of the `v2` endpoints described in this proposal results in an -unrecognised request exception, then the sending server should retry the request -with the `v1` API. +unrecognised request exception (i.e. in a response with a 400 or a 404 status +code), then the sending server should retry the request with the `v1` API. ## Alternative solutions From 7c7bc677fb485d3df0e2dcb52554eb1bf2bd7f28 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 7 May 2019 00:11:14 +0100 Subject: [PATCH 0311/1250] Trigger matrix.org rebuild --- .buildkite/pipeline.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index e98d7026..6e595120 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -9,3 +9,8 @@ steps: plugins: - docker#v3.0.1: image: "python:3.6" + + - label: "rebuild matrix.org" + trigger: "matrix-dot-org" + async: true + branches: "master" From da82a423084d4bd5a209e73548001fb89024aa35 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 7 May 2019 15:40:39 -0700 Subject: [PATCH 0312/1250] fix grammatical error --- specification/modules/end_to_end_encryption.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 59d241b6..8d8a2d06 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -182,7 +182,7 @@ process: field as the ``from`` parameter. If the client is tracking the device list of any of the users listed in the response, it marks them as outdated. It combines this list with those already flagged as outdated, and initiates a - |/keys/query|_ requests for all of them. + |/keys/query|_ request for all of them. .. Warning:: From c233535de00e8c66d80fa807535b68f3e9ec291b Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 7 May 2019 15:51:32 -0700 Subject: [PATCH 0313/1250] fix typo --- specification/modules/end_to_end_encryption.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 59d241b6..9ad80a12 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -460,7 +460,7 @@ Keys can be manually exported from one device to an encrypted file, copied to another device, and imported. The file is encrypted using a user-supplied passphrase, and is created as follows: -1. Encode the sessions a JSON object, formatted as described in `Key export +1. Encode the sessions as a JSON object, formatted as described in `Key export format`_. 2. Generate a 512-bit key from the user-entered passphrase by computing `PBKDF2`_\(HMAC-SHA-512, passphrase, S, N, 512), where S is a 128-bit From 40482f76163951aaf95a2ccef848fc43789ec3f9 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 7 May 2019 15:55:07 -0700 Subject: [PATCH 0314/1250] Add missing period --- specification/appendices/signing_json.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/appendices/signing_json.rst b/specification/appendices/signing_json.rst index 795d6669..8036950e 100644 --- a/specification/appendices/signing_json.rst +++ b/specification/appendices/signing_json.rst @@ -59,7 +59,7 @@ Grammar +++++++ Adapted from the grammar in http://tools.ietf.org/html/rfc7159 removing -insignificant whitespace, fractions, exponents and redundant character escapes +insignificant whitespace, fractions, exponents and redundant character escapes. .. code:: From 3c62b90dfbf58a4ff99c4e7fc403d8737816dc2b Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 7 May 2019 16:59:10 -0700 Subject: [PATCH 0315/1250] Add missing punctuation --- api/client-server/keys.yaml | 2 +- api/server-server/user_keys.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/client-server/keys.yaml b/api/client-server/keys.yaml index 55f8a5a5..718703fd 100644 --- a/api/client-server/keys.yaml +++ b/api/client-server/keys.yaml @@ -253,7 +253,7 @@ paths: responses: 200: description: - The claimed keys + The claimed keys. schema: type: object properties: diff --git a/api/server-server/user_keys.yaml b/api/server-server/user_keys.yaml index 63c74d20..3c59cf81 100644 --- a/api/server-server/user_keys.yaml +++ b/api/server-server/user_keys.yaml @@ -63,7 +63,7 @@ paths: - one_time_keys responses: 200: - description: The claimed keys + description: The claimed keys. schema: type: object properties: From 57cf1aaa96f9767444f42a32f0f7c7d21b92062e Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 7 May 2019 19:37:25 -0700 Subject: [PATCH 0316/1250] Add missing period --- specification/modules/send_to_device.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/send_to_device.rst b/specification/modules/send_to_device.rst index 86288546..cca0338a 100644 --- a/specification/modules/send_to_device.rst +++ b/specification/modules/send_to_device.rst @@ -108,7 +108,7 @@ to_device ToDevice Optional. Information on the send-to-device messages ========= ========= ============================================= Parameter Type Description ========= ========= ============================================= -events [Event] List of send-to-device messages +events [Event] List of send-to-device messages. ========= ========= ============================================= ``Event`` From 20d2fdc288e3e79909db449f99895f1a2ad77764 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 7 May 2019 19:51:11 -0700 Subject: [PATCH 0317/1250] Add changelog --- changelogs/client_server/newsfragments/1988.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/1988.clarification diff --git a/changelogs/client_server/newsfragments/1988.clarification b/changelogs/client_server/newsfragments/1988.clarification new file mode 100644 index 00000000..b0f05203 --- /dev/null +++ b/changelogs/client_server/newsfragments/1988.clarification @@ -0,0 +1 @@ +Fix various spelling mistakes throughout the specification. From abd770419b6169510293e963c373625bfefd0646 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 7 May 2019 19:52:38 -0700 Subject: [PATCH 0318/1250] Add changelog --- changelogs/client_server/newsfragments/1989.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/1989.clarification diff --git a/changelogs/client_server/newsfragments/1989.clarification b/changelogs/client_server/newsfragments/1989.clarification new file mode 100644 index 00000000..b0f05203 --- /dev/null +++ b/changelogs/client_server/newsfragments/1989.clarification @@ -0,0 +1 @@ +Fix various spelling mistakes throughout the specification. From 713e4401b47ff71da6aad21ce2bd781281f48007 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 7 May 2019 19:54:38 -0700 Subject: [PATCH 0319/1250] Add changelogs --- changelogs/client_server/newsfragments/1991.clarification | 1 + changelogs/server_server/newsfragments/1991.clarification | 1 + 2 files changed, 2 insertions(+) create mode 100644 changelogs/client_server/newsfragments/1991.clarification create mode 100644 changelogs/server_server/newsfragments/1991.clarification diff --git a/changelogs/client_server/newsfragments/1991.clarification b/changelogs/client_server/newsfragments/1991.clarification new file mode 100644 index 00000000..b0f05203 --- /dev/null +++ b/changelogs/client_server/newsfragments/1991.clarification @@ -0,0 +1 @@ +Fix various spelling mistakes throughout the specification. diff --git a/changelogs/server_server/newsfragments/1991.clarification b/changelogs/server_server/newsfragments/1991.clarification new file mode 100644 index 00000000..b0f05203 --- /dev/null +++ b/changelogs/server_server/newsfragments/1991.clarification @@ -0,0 +1 @@ +Fix various spelling mistakes throughout the specification. From 00b7b70c062e78c8bdbce060a56d099540654f9e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 7 May 2019 23:09:39 -0600 Subject: [PATCH 0320/1250] Create 1992.clarification --- changelogs/client_server/newsfragments/1992.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/1992.clarification diff --git a/changelogs/client_server/newsfragments/1992.clarification b/changelogs/client_server/newsfragments/1992.clarification new file mode 100644 index 00000000..b0f05203 --- /dev/null +++ b/changelogs/client_server/newsfragments/1992.clarification @@ -0,0 +1 @@ +Fix various spelling mistakes throughout the specification. From 383e02835e5c9e60d0f574e69cf7cd6fa2cae262 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 May 2019 18:07:58 +0100 Subject: [PATCH 0321/1250] Words on using m.login.dummy for disambiguation Add some text on how m.login.dummy can be used to distinguish a flow that would otherwise be a subset of other flows. --- specification/client_server_api.rst | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index f9f815f7..b2ff3dbd 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -789,7 +789,14 @@ Dummy Auth :Description: Dummy authentication always succeeds and requires no extra parameters. Its purpose is to allow servers to not require any form of User-Interactive - Authentication to perform a request. + Authentication to perform a request. It can also be used to differentiate + flows where otherwise one flow would be a subset of another flow. eg. if + a server offers flows ``m.login.recaptcha`` and ``m.login.recaptcha, + m.login.email.identity`` and the client completes the recaptcha stage first, + the auth would succeed with the former flow, even if the client was intending + to then complete the email auth stage. A server can instead send flows + ``m.login.recaptcha, m.login.dummy`` and ``m.login.recaptcha, + m.login.email.identity`` to fix the ambiguity. To use this authentication type, clients should submit an auth dict with just the type and session, if provided: From c38581fb868c0d198297d82932d2b8117264bad3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 May 2019 19:20:01 +0100 Subject: [PATCH 0322/1250] Too many spaces Co-Authored-By: Travis Ralston --- specification/client_server_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index b2ff3dbd..6f65ebb1 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -790,7 +790,7 @@ Dummy Auth Dummy authentication always succeeds and requires no extra parameters. Its purpose is to allow servers to not require any form of User-Interactive Authentication to perform a request. It can also be used to differentiate - flows where otherwise one flow would be a subset of another flow. eg. if + flows where otherwise one flow would be a subset of another flow. eg. if a server offers flows ``m.login.recaptcha`` and ``m.login.recaptcha, m.login.email.identity`` and the client completes the recaptcha stage first, the auth would succeed with the former flow, even if the client was intending From 37871106c6fc6013c17b5711fb93853fff140267 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 21 May 2019 16:21:47 +0100 Subject: [PATCH 0323/1250] MSC2002: Proposal for adopting MSC1884 as v4 rooms (#2002) --- proposals/2002-rooms-v4.md | 54 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 proposals/2002-rooms-v4.md diff --git a/proposals/2002-rooms-v4.md b/proposals/2002-rooms-v4.md new file mode 100644 index 00000000..defacee1 --- /dev/null +++ b/proposals/2002-rooms-v4.md @@ -0,0 +1,54 @@ +# MSC 2002 - Rooms V4 + +This MSC proposes creating a new room version named v4 to allow servers to switch +event ID grammar to that proposed in MSC1884. + +## Proposal + +The new room version is called "4". The only difference between v4 and v3 is +that v4 rooms use the grammar for defining event IDs as proposed in MSC1884 - +expressing event IDs as url-safe base64 rather than plain base64 for the +convenience of client implementors. + +It is not proposed that servers change the default room version used when +creating new rooms, and it is not proposed that servers recommend upgrading +existing rooms to v4. + +## Rationale and Context + +We would like to default to creating rooms with a reasonably secure room +algorithm in upcoming Matrix 1.0. We do not want to default to creating v3 +rooms due to the inconvenience the v3 event ID grammar might cause, so instead +we are proposing favouring v4. + +Ideally we would also include other room algorithm changes in v4 (e.g. +honouring server signing key validity periods, as per +https://github.com/matrix-org/synapse/issues/4364), but as spec & +implementation work is still ongoing there, we are proposing using v4 as a +room version which can be supported in the wild before Matrix 1.0 and then +used as the initial default for creating rooms. The expectation is for the +versions of the spec which coincide with 1.0 to also support v5 rooms, but in +practice v5 will not be marked as default until it has sufficient adoption on +the public network. + +The expectation is never to recommend upgrading existing +rooms to v4, but instead v5 (once ready), to avoid overburdening room admins +with upgrade notifications. + +To conclude, the proposed plan is: + 1. Define room v4 as MSC1884 + 2. Introduce servers with v4 support into the public network as rapidly as possible + 3. Wait for enough servers to speak v4. Meanwhile: + 1. Define an MSC for honouring server signing key validity periods + 2. Implement this MSC + 3. Define room v5 as this MSC + 4. Release Matrix 1.0, defining room v4 as the new default for creating rooms, + but also shipping support for room v5 for the first time. + 5. Wait for enough servers to speak v5 rooms. + 6. Define room v5 as the new default for creating rooms. + 7. Define room versions prior to v5 as unsafe, thus prompting users to upgrade their + rooms to v5. + +The reason we don't wait for v5 to be widespread before releasing 1.0 is to avoid +delaying the 1.0 yet further. It is good enough for 1.0 to support v5 without it +also being the default for creating rooms. From 7bad359b0dd774aa8f41f117782d1c65c733a27d Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 20 May 2019 21:03:48 -0400 Subject: [PATCH 0324/1250] switch to the 3-key system, and some wording improvements --- proposals/1756-cross-signing.md | 221 +++++++++++++++++---------- proposals/images/1756-graph2.dot | 12 +- proposals/images/1756-graph2.dot.png | Bin 49417 -> 60244 bytes 3 files changed, 152 insertions(+), 81 deletions(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 17721055..5595b2b4 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -19,49 +19,51 @@ MSC1680 is presented below. ## Proposal -Each user has a self-signing key pair that is used to sign their own devices, -and a user-signing key pair that is used to sign other users' signing keys. A -user's user-signing key is also signed by their own self-signing key. When one -user (e.g. Alice) verifies another user's (Bob's) identity, Alice will sign -Bob's self-signing key with her user-signing key. (This will mean that +Each user has three sets of key pairs: + +- a master cross-signing key pair that is used to identify themselves and to + sign their other cross-signing keys, +- a self-signing key pair that is used to sign their own devices, and +- a user-signing key pair that is used to sign other users' master keys. + +When one user (e.g. Alice) verifies another user's (Bob's) identity, Alice will +sign Bob's self-signing key with her user-signing key. (This will mean that verification methods will need to be modified to pass along the self-signing identity key.) Alice's device will trust Bob's device if: -- Alice's device is using a self-signing key that has signed her user-signing key, -- Alice's user-signing key has signed Bob's self-signing key, and +- Alice's device is using a master key that has signed her user-signing key, +- Alice's user-signing key has signed Bob's master key, +- Bob's master key has signed Bob's self-signing key, and - Bob's self-signing key has signed Bob's device key. ### Key security -A user's private half of their user-signing key pair may be kept unlocked on a -device, but their self-signing key should not; the private half of the -self-signing key pair should only be stored encrypted, requiring a passphrase -to access. By keeping the user-signing key unlocked, Alice can verify Bob's -identity and distribute signatures to all her devices without needing to enter -a passphrase to decrypt the key. - -If a user's device is compromised, they can issue a new user-signing key, -signed by their self-signing key, rendering the old user-signing key useless. -If they are certain that the old user-signing key has not yet been used by an -attacker, then they may also reissue signatures made by the old user-signing -key by using the new user-signing key. Otherwise, they will need to re-verify -the other users. - -If a user's self-signing key is compromised, then the user will need to issue -both a new self-signing key and a new user-signing key. The user may sign -their new self-signing key with their old self-signing key, allowing other -users who have verified the old self-signing key to automatically trust the new -self-signing key if they wish to. Otherwise, the users will need to re-verify -each other. - -The private halves of the user-signing key pair and self-signing key pair may -be stored encrypted on the server (possibly along with the megolm key backup) -so that they may be retrieved by new devices. FIXME: explain how to do this +A user's master key could allow an attacker to impersonate that user to other +users, or other users to that user. Thus clients must ensure that the private +part of the master key is treated securely. If clients do not have a secure +means of storing the master key (such as an secret storage system provided by +the operating system), then clients must not store the private part. If a user +changes their master key, clients of users that they communicate with must +notify their users about the change. + +A user's user-signing and self-signing keys are intended to be easily +replaceable if they are compromised by re-issuing a new key signed by the +user's master key and possibly by re-verifying devices or users. However, +doing so relies on the user being able to notice when their keys have been +compromised, and it involves extra work for the user, and so although clients +do not have to treat the private parts as sensitively as the master key, +clients should still make efforts to store the private part securely, or not +store it at all. Clients will need to balance the security of the keys with +the usability of signing users and devices when performing key verification. + +The private halves of a user's cross-signing keys be stored encrypted on the +server so that they may be retrieved by new devices. FIXME: explain how to do +this via MSC 1946 ### Signature distribution -Currently, users will only be allowed to see signatures made by their own -self-signing or user-signing keys, or signatures made by other users' +Currently, users will only be allowed to see signatures made by her own master, +self-signing or user-signing keys, or signatures made by other users' master or self-signing keys about their own devices. This is done in order to preserve the privacy of social connections. Future proposals may define mechanisms for distributing signatures to other users in order to allow for other web-of-trust @@ -71,19 +73,31 @@ use cases. #### Uploading signing keys -Public keys for the self-signing and user-signing keys are uploaded to the -servers using `/keys/device_signing/upload`. This endpoint requires [UI +Public keys for the cross-signing keys are uploaded to the servers using +`/keys/device_signing/upload`. This endpoint requires [UI Auth](https://matrix.org/docs/spec/client_server/r0.4.0.html#user-interactive-authentication-api). `POST /keys/device_signing/upload` ``` json { + "master_key": { + "user_id": "@alice:example.com", + "usage": ["master"], + "keys": { + "ed25519:base64+master+public+key": "base64+self+master+key", + } + }, "self_signing_key": { "user_id": "@alice:example.com", "usage": ["self_signing"], "keys": { "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key", + }, + "signatures": { + "@alice:example.com": { + "ed25519:base64+master+public+key": "base64+signature" + } } }, "user_signing_key": { @@ -94,24 +108,25 @@ Auth](https://matrix.org/docs/spec/client_server/r0.4.0.html#user-interactive-au "usage": ["user_signing"], "signatures": { "@alice:example.com": { - "ed25519:base64+self+signing+public+key": "base64+signature" + "ed25519:base64+master+public+key": "base64+signature" } } } } ``` -Self-signing and user-signing keys are JSON objects with the following +Cross-signing keys are JSON objects with the following properties: * `user_id` (string): The user who owns the key -* `usage` ([string]): Allowed uses for the key. Must be `["self_signing"]` for - self-signing keys, and `["user_signing"]` for user-signing keys. +* `usage` ([string]): Allowed uses for the key. Must contain `"master"` for + master keys, `"self_signing"` for self-signing keys, and `"user_signing"` + for user-signing keys. * `keys` ({string: string}): an object that must have one entry, whose name is "`ed25519:`" followed by the unpadded base64 encoding of the public key, and whose value is the unpadded base64 encoding of the public key. -* `signatures` ({string: {stringg: string}}): signatures of the key. A - user-signing key must be signed by the self-signing key. +* `signatures` ({string: {string: string}}): signatures of the key. A + self-signing or user-signing key must be signed by the master key. In order to ensure that there will be no collisions in the `signatures` property, the server must respond with an error (FIXME: what error?) if any of @@ -119,18 +134,14 @@ the uploaded public keys match an existing device ID for the user. Similarly, if a user attempts to log in specifying a device ID matching one of the signing keys, the server must respond with an error (FIXME: what error?). -If a user-signing key is uploaded, it must be signed by the current -self-signing key (or the self-signing key that is included in the request) +If a self-signing or user-signing key is uploaded, it must be signed by the +master key that is included in the request, or the current master key if no +master key is included. -If a previous self-signing key exists, then the new self-signing key must have -a `replaces` property whose value is the previous public self-signing key. -Otherwise the server must respond with an error (FIXME: what error?). The new -self-signing key may also be signed with the old self-signing key. - -After uploading self-signing and user-signing keys, they will be included under -the `/keys/query` endpoint under the `self_signing_key` and `user_signing_key` -properties, respectively. The `user_signing_key` will only be included when a -user requests their own keys. +After uploading cross-signing keys, they will be included under the +`/keys/query` endpoint under the `master_keys`, `self_signing_keys` and +`user_signing_keys` properties. The `user_signing_keys` property will only be +included when a user requests their own keys. `POST /keys/query` @@ -153,12 +164,26 @@ response: // ... } }, + "master_keys": { + "@alice:example.com": { + "user_id": "@alice:example.com", + "usage": ["master"], + "keys": { + "ed25519:base64+master+public+key": "base64+master+public+key" + } + } + }, "self_signing_keys": { "@alice:example.com": { "user_id": "@alice:example.com", "usage": ["self_signing"], "keys": { "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key" + }, + "signatures": { + "@alice:example.com": { + "ed25519:base64+master+public+key": "base64+signature" + } } } } @@ -166,7 +191,9 @@ response: ``` Similarly, the federation endpoints `GET /user/keys/query` and -`POST /user/devices/{userId}` will include the self-signing key. +`POST /user/devices/{userId}` will include the master and self-signing keys. +(It will not include the user-signing key because it is not intended to be +visible to other users.) `POST /keys/query` @@ -187,12 +214,26 @@ response: // ... } }, + "master_keys": { + "@alice:example.com": { + "user_id": "@alice:example.com", + "usage": ["master"], + "keys": { + "ed25519:base64+master+public+key": "base64+master+public+key" + } + } + }, "self_signing_keys": { "@alice:example.com": { "user_id": "@alice:example.com", "usage": ["self_signing"], "keys": { "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key" + }, + "signatures": { + "@alice:example.com": { + "ed25519:base64+master+public+key": "base64+signature" + } } } } @@ -210,11 +251,23 @@ response: "devices": [ // ... ], - "self_signing_keys": { + "master_key": { + "user_id": "@alice:example.com", + "usage": ["master"], + "keys": { + "ed25519:base64+master+public+key": "base64+master+public+key" + } + }, + "self_signing_key": { "user_id": "@alice:example.com", "usage": ["self_signing"], "keys": { "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key" + }, + "signatures": { + "@alice:example.com": { + "ed25519:base64+master+public+key": "base64+signature" + } } } } @@ -225,7 +278,8 @@ servers that have users who share encrypted rooms with Alice. The `content` of that EDU has the following properties: * `user_id` (string): Required. The user ID who owns the signing key -* `self_signing_key` (object): Required. The self-signing key, as above. +* `master_key` (object): The master key, as above. +* `self_signing_key` (object): The self-signing key, as above. After uploading self-signing and user-signing keys, the user will show up in the `changed` property of the `device_lists` field of the sync result of any @@ -235,7 +289,8 @@ others users who share an encrypted room with that user. Signatures of keys can be uploaded using `/keys/signatures/upload`. -For example, Alice signs one of her devices (HIJKLMN), and Bob's self-signing key. +For example, Alice signs one of her devices (HIJKLMN) (using her self-signing +key), and signs Bob's master key (using her user-signing key). `POST /keys/signatures/upload` @@ -255,7 +310,7 @@ For example, Alice signs one of her devices (HIJKLMN), and Bob's self-signing ke }, "signatures": { "@alice:example.com": { - "ed25519:base64+user+signing+public+key": "base64+signature+of+HIJKLMN" + "ed25519:base64+self+signing+public+key": "base64+signature+of+HIJKLMN" } } } @@ -264,12 +319,12 @@ For example, Alice signs one of her devices (HIJKLMN), and Bob's self-signing ke "bobs+base64+self+signing+public+key": { "user_id": "@bob:example.com", "keys": { - "ed25519:bobs+base64+self+signing+public+key": "bobs+base64+self+signing+public+key" + "ed25519:bobs+base64+master+public+key": "bobs+base64+master+public+key" }, - "usage": ["self_signing"], + "usage": ["master"], "signatures": { "@alice:example.com": { - "ed25519:base64+user+signing+public+key": "base64+signature+of+bobs+self+signing+key" + "ed25519:base64+user+signing+public+key": "base64+signature+of+bobs+master+key" } } } @@ -313,7 +368,7 @@ response: "signatures": { "@alice:example.com": { "ed25519:HIJKLMN": "base64+self+signature", - "ed25519:base64+user+signing+public+key": "base64+signature+of+HIJKLMN" + "ed25519:base64+self+signing+public+key": "base64+signature+of+HIJKLMN" } }, "unsigned": { @@ -322,12 +377,22 @@ response: } } }, - "self_signing_keys": { - "@alice:example.com": { - "user_id": "@alice:example.com", - "usage": ["self_signing"], - "keys": { - "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key", + "master_key": { + "user_id": "@alice:example.com", + "usage": ["master"], + "keys": { + "ed25519:base64+master+public+key": "base64+master+public+key" + } + }, + "self_signing_key": { + "user_id": "@alice:example.com", + "usage": ["self_signing"], + "keys": { + "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key" + }, + "signatures": { + "@alice:example.com": { + "ed25519:base64+master+public+key": "base64+signature" } } } @@ -343,7 +408,7 @@ include her new signature. After Alice uploads a signature for Bob's user-signing key, her signature will be included in the results of the `/keys/query` request when Alice requests -Bob's key: +Bob's key, but will not be included when anyone else requests Bob's key: `GET /keys/query` @@ -355,16 +420,16 @@ Bob's key: // ... } }, - "self_signing_keys": { + "master_keys": { "@bob:example.com": { "user_id": "@bob:example.com", "keys": { - "ed25519:bobs+base64+self+signing+public+key": "bobs+base64+self+signing+public+key" + "ed25519:bobs+base64+master+public+key": "bobs+base64+master+public+key" }, - "usage": ["self_signing"], + "usage": ["master"], "signatures": { "@alice:example.com": { - "ed25519:base64+user+signing+public+key": "base64+signature+of+bobs+self+signing+key" + "ed25519:base64+user+signing+public+key": "base64+signature+of+bobs+master+key" } } } @@ -414,11 +479,13 @@ user-signing key must be re-issued. ## Security considerations -This proposal relies on servers to communicate when self-signing or -user-signing keys are deleted and replaced. An attacker who is able to both -steal a user's device and control their homeserver could prevent that device -from being marked as untrusted. +This proposal relies on servers to communicate when cross-signing keys are +deleted and replaced. An attacker who is able to both steal a user's device +and control their homeserver could prevent that device from being marked as +untrusted. ## Conclusion -This proposal presents an alternative cross-signing mechanism to MSC1680. +This proposal presents an alternative cross-signing mechanism to MSC1680, +allowing users to trust another user's devices without needing to verify each +one individually. diff --git a/proposals/images/1756-graph2.dot b/proposals/images/1756-graph2.dot index 8eaa1df8..a8074125 100644 --- a/proposals/images/1756-graph2.dot +++ b/proposals/images/1756-graph2.dot @@ -1,18 +1,22 @@ digraph { A1 [label="A's PDP-11"] A2 [label="A's Osborne 2"] +AM [label="A's master key"] AS [label="A's self-signing key"] AU [label="A's user-signing key"] +BM [label="B's master key"] BU [label="B's user-signing key"] BS [label="B's self-signing key"] B1 [label="B's Dynabook"] B2 [label="B's VAX"] AS -> A1 AS -> A2 -AS -> AU -AU -> BS -BS -> BU -BU -> AS +AM -> AS +AM -> AU +AU -> BM +BM -> BS +BM -> BU +BU -> AM BS -> B1 BS -> B2 } diff --git a/proposals/images/1756-graph2.dot.png b/proposals/images/1756-graph2.dot.png index 3af9270f094b2361858930630945b05e40b2c6fd..e7591f0471c22dda586767c61b87eeab2c0c8f89 100644 GIT binary patch literal 60244 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 ep|aT?kR{vPe-SB^6H$>(D literal 49417 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 GQu0Bt7+ePe1W@TYUs^3Vjg81* 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

uud2Zki_XHF3;Vjc|~P{e<3QC2?#Q= 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 ZwJnJord#H| Date: Wed, 22 May 2019 14:46:31 +0200 Subject: [PATCH 0325/1250] add spoiler msc --- proposals/2010-spoilers.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 proposals/2010-spoilers.md diff --git a/proposals/2010-spoilers.md b/proposals/2010-spoilers.md new file mode 100644 index 00000000..bec895b7 --- /dev/null +++ b/proposals/2010-spoilers.md @@ -0,0 +1,25 @@ +# MSC 2010: Proposal to add client-side spoilers +Sometimes you are talking about e.g. a new movie and want to discuss the plot without spoiling others. Or you are talking in e.g. some mental health community where, due to triggers, some content shouldn't be immediately visible to everybody. For this the content is hidden and then revealed once interacted somehow (e.g. a click / hover). + +## Proposal +This proposal adds a new attribute, `data-mx-spoiler`, to the `` tag. If the attribute is present the contents of the span tag should be rendered as a spoiler. Optionally, you can specify a reason for the spoiler by setting the attribute string. + +For example: +`Hello there, the movie was awesome` for a spoiler without reason and `Hey the movie was awesome` for a spoiler with the reason "movie". + +The plain-text fallback could be rendered as `(Spoiler: )` and `(Spoiler for : )` respectively. + +For example: +`Hi there` would have as fallback `Hi (Spoiler: there)` +`Hi there` would have as fallback `Hi (Spoiler for greeting: there)` + +## Tradeoffs +Instead of making this an attribute, an entirely new tag could be introduced (e.g. ``), however that wouldn't be HTML-compliant. + +Instead of limiting the proposed `data-mx-spoiler` attribute only to the ``-tag it could be added to all tags, however it might make implementations for clients more complicated. + +## Potential issues +Depending on context it might make sense to put other events, such as `m.image`, into spoilers, too. This MSC doesn't address that at all. Using `` seems rather sub-optimal for that. + +## Security considerations +The spoiler reason needs to be properly escaped when rendered. From d750115fdc30ce29ed7281c24bbfff65fff0af95 Mon Sep 17 00:00:00 2001 From: Sorunome Date: Wed, 22 May 2019 15:20:30 +0200 Subject: [PATCH 0326/1250] fix up some things --- proposals/2010-spoilers.md | 39 ++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/proposals/2010-spoilers.md b/proposals/2010-spoilers.md index bec895b7..d47b058f 100644 --- a/proposals/2010-spoilers.md +++ b/proposals/2010-spoilers.md @@ -1,25 +1,48 @@ # MSC 2010: Proposal to add client-side spoilers -Sometimes you are talking about e.g. a new movie and want to discuss the plot without spoiling others. Or you are talking in e.g. some mental health community where, due to triggers, some content shouldn't be immediately visible to everybody. For this the content is hidden and then revealed once interacted somehow (e.g. a click / hover). +Sometimes, while you want to put text into a spoiler to not have people accidentally read things that they don't want to see. +For example, when discussing a new movie or a TV series, not everyone might have watched it yet. In such cases it would make sense to add a spoiler so that only those who have seen the movie or don't mind spoilers read the content. +Another example would be e.g. in mental health communities where certain people have certain triggers. People could put talking about abuse or thelike into a spoiler, to not accidentally trigger anyone just reading along the conversation. +Furthermore this is helpful for bridging to other networks that already have a spoiler feature. -## Proposal -This proposal adds a new attribute, `data-mx-spoiler`, to the `` tag. If the attribute is present the contents of the span tag should be rendered as a spoiler. Optionally, you can specify a reason for the spoiler by setting the attribute string. +To render the spoiler the content is hidden and then revealed once interacted somehow (e.g. a click / hover). -For example: -`Hello there, the movie was awesome` for a spoiler without reason and `Hey the movie was awesome` for a spoiler with the reason "movie". +## Proposal +This proposal is about adding a new attribute to the `formatted_body` of messages with type `m.room.message` and msgtype `m.text`. +It adds a new attribute, `data-mx-spoiler`, to the `` tag. If the attribute is present the contents of the span tag should be rendered as a spoiler. Optionally, you can specify a reason for the spoiler by setting the attribute string. The plain-text fallback could be rendered as `(Spoiler: )` and `(Spoiler for : )` respectively. -For example: -`Hi there` would have as fallback `Hi (Spoiler: there)` -`Hi there` would have as fallback `Hi (Spoiler for greeting: there)` +### Example +Without reason: +``` +{ + "msgtype": "m.text", + "format": "org.matrix.custom.html", + "body": "Hello there, the movie was (Spoiler: awesome)", + "formatted_body": "Hello there, the movie was awesome" +} +``` +With reason: +``` +{ + "msgtype": "m.text", + "format": "org.matrix.custom.html", + "body": "Hey (Spoiler for movie: the movie was awesome)", + "formatted_body": "Hey the movie was awesome" +} +``` ## Tradeoffs Instead of making this an attribute, an entirely new tag could be introduced (e.g. ``), however that wouldn't be HTML-compliant. Instead of limiting the proposed `data-mx-spoiler` attribute only to the ``-tag it could be added to all tags, however it might make implementations for clients more complicated. +Clients would have to come up with a way how to input spoilers. This could be done, for example, by adding a custom markdown tag (like discord does), so that you do `Text ||spoiler||`, however that doesn't take a spoiler reason into account. + ## Potential issues Depending on context it might make sense to put other events, such as `m.image`, into spoilers, too. This MSC doesn't address that at all. Using `` seems rather sub-optimal for that. +This MSC doesn't take HTML block elements into account. + ## Security considerations The spoiler reason needs to be properly escaped when rendered. From ebb1351a9f27bb335cebf6e2cd92deedcd0dabaf Mon Sep 17 00:00:00 2001 From: Sorunome Date: Wed, 22 May 2019 15:22:22 +0200 Subject: [PATCH 0327/1250] linebreak consistency --- proposals/2010-spoilers.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/proposals/2010-spoilers.md b/proposals/2010-spoilers.md index d47b058f..739bfe2e 100644 --- a/proposals/2010-spoilers.md +++ b/proposals/2010-spoilers.md @@ -1,5 +1,6 @@ # MSC 2010: Proposal to add client-side spoilers -Sometimes, while you want to put text into a spoiler to not have people accidentally read things that they don't want to see. +Sometimes, while you want to put text into a spoiler to not have people accidentally read things that they don't want to see. + For example, when discussing a new movie or a TV series, not everyone might have watched it yet. In such cases it would make sense to add a spoiler so that only those who have seen the movie or don't mind spoilers read the content. Another example would be e.g. in mental health communities where certain people have certain triggers. People could put talking about abuse or thelike into a spoiler, to not accidentally trigger anyone just reading along the conversation. Furthermore this is helpful for bridging to other networks that already have a spoiler feature. @@ -7,7 +8,8 @@ Furthermore this is helpful for bridging to other networks that already have a s To render the spoiler the content is hidden and then revealed once interacted somehow (e.g. a click / hover). ## Proposal -This proposal is about adding a new attribute to the `formatted_body` of messages with type `m.room.message` and msgtype `m.text`. +This proposal is about adding a new attribute to the `formatted_body` of messages with type `m.room.message` and msgtype `m.text`. + It adds a new attribute, `data-mx-spoiler`, to the `` tag. If the attribute is present the contents of the span tag should be rendered as a spoiler. Optionally, you can specify a reason for the spoiler by setting the attribute string. The plain-text fallback could be rendered as `(Spoiler: )` and `(Spoiler for : )` respectively. From 6f3bcb56d34364de1cc6d1c7dc1ad8ca281ef806 Mon Sep 17 00:00:00 2001 From: Sorunome Date: Wed, 22 May 2019 15:35:32 +0200 Subject: [PATCH 0328/1250] add rendering idea --- proposals/2010-spoilers.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/2010-spoilers.md b/proposals/2010-spoilers.md index 739bfe2e..d4128de4 100644 --- a/proposals/2010-spoilers.md +++ b/proposals/2010-spoilers.md @@ -10,7 +10,9 @@ To render the spoiler the content is hidden and then revealed once interacted so ## Proposal This proposal is about adding a new attribute to the `formatted_body` of messages with type `m.room.message` and msgtype `m.text`. -It adds a new attribute, `data-mx-spoiler`, to the `` tag. If the attribute is present the contents of the span tag should be rendered as a spoiler. Optionally, you can specify a reason for the spoiler by setting the attribute string. +It adds a new attribute, `data-mx-spoiler`, to the `` tag. If the attribute is present the contents of the span tag should be rendered as a spoiler. Optionally, you can specify a reason for the spoiler by setting the attribute string. It could be rendered, for example, similar to this: + +![Spoiler rendering idea](https://user-images.githubusercontent.com/2433620/58178745-082c1480-7ca7-11e9-901b-13b147cfd157.png) The plain-text fallback could be rendered as `(Spoiler: )` and `(Spoiler for : )` respectively. From 273af2a2e0eb3351ad58bf39c1e2472a3c96881d Mon Sep 17 00:00:00 2001 From: Sorunome Date: Wed, 22 May 2019 17:30:18 +0200 Subject: [PATCH 0329/1250] wrap long lines --- proposals/2010-spoilers.md | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/proposals/2010-spoilers.md b/proposals/2010-spoilers.md index d4128de4..366f4a3e 100644 --- a/proposals/2010-spoilers.md +++ b/proposals/2010-spoilers.md @@ -1,20 +1,29 @@ # MSC 2010: Proposal to add client-side spoilers Sometimes, while you want to put text into a spoiler to not have people accidentally read things that they don't want to see. -For example, when discussing a new movie or a TV series, not everyone might have watched it yet. In such cases it would make sense to add a spoiler so that only those who have seen the movie or don't mind spoilers read the content. -Another example would be e.g. in mental health communities where certain people have certain triggers. People could put talking about abuse or thelike into a spoiler, to not accidentally trigger anyone just reading along the conversation. +For example, when discussing a new movie or a TV series, not everyone might have watched it yet. +In such cases it would make sense to add a spoiler so that only those who have seen the movie or +don't mind spoilers read the content. +Another example would be e.g. in mental health communities where certain people have certain +triggers. People could put talking about abuse or thelike into a spoiler, to not accidentally +trigger anyone just reading along the conversation. Furthermore this is helpful for bridging to other networks that already have a spoiler feature. -To render the spoiler the content is hidden and then revealed once interacted somehow (e.g. a click / hover). +To render the spoiler the content is hidden and then revealed once interacted somehow +(e.g. a click / hover). ## Proposal -This proposal is about adding a new attribute to the `formatted_body` of messages with type `m.room.message` and msgtype `m.text`. +This proposal is about adding a new attribute to the `formatted_body` of messages with type +`m.room.message` and msgtype `m.text`. -It adds a new attribute, `data-mx-spoiler`, to the `` tag. If the attribute is present the contents of the span tag should be rendered as a spoiler. Optionally, you can specify a reason for the spoiler by setting the attribute string. It could be rendered, for example, similar to this: +It adds a new attribute, `data-mx-spoiler`, to the `` tag. If the attribute is present the +contents of the span tag should be rendered as a spoiler. Optionally, you can specify a reason for +the spoiler by setting the attribute string. It could be rendered, for example, similar to this: ![Spoiler rendering idea](https://user-images.githubusercontent.com/2433620/58178745-082c1480-7ca7-11e9-901b-13b147cfd157.png) -The plain-text fallback could be rendered as `(Spoiler: )` and `(Spoiler for : )` respectively. +The plain-text fallback could be rendered as `(Spoiler: )` and +`(Spoiler for : )` respectively. ### Example Without reason: @@ -37,14 +46,20 @@ With reason: ``` ## Tradeoffs -Instead of making this an attribute, an entirely new tag could be introduced (e.g. ``), however that wouldn't be HTML-compliant. +Instead of making this an attribute, an entirely new tag could be introduced (e.g. ``), +however that wouldn't be HTML-compliant. -Instead of limiting the proposed `data-mx-spoiler` attribute only to the ``-tag it could be added to all tags, however it might make implementations for clients more complicated. +Instead of limiting the proposed `data-mx-spoiler` attribute only to the ``-tag it could be +added to all tags, however it might make implementations for clients more complicated. -Clients would have to come up with a way how to input spoilers. This could be done, for example, by adding a custom markdown tag (like discord does), so that you do `Text ||spoiler||`, however that doesn't take a spoiler reason into account. +Clients would have to come up with a way how to input spoilers. This could be done, for example, +by adding a custom markdown tag (like discord does), so that you do `Text ||spoiler||`, however +that doesn't take a spoiler reason into account. ## Potential issues -Depending on context it might make sense to put other events, such as `m.image`, into spoilers, too. This MSC doesn't address that at all. Using `` seems rather sub-optimal for that. +Depending on context it might make sense to put other events, such as `m.image`, into spoilers, +too. This MSC doesn't address that at all. Using +`` seems rather sub-optimal for that. This MSC doesn't take HTML block elements into account. From 77050062601cad901623660de151081608fb5ca3 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 22 May 2019 12:43:43 -0400 Subject: [PATCH 0330/1250] 1 hour seems to be fine --- proposals/1719-olm_unwedging.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/1719-olm_unwedging.md b/proposals/1719-olm_unwedging.md index e696c1e2..50b6f0e6 100644 --- a/proposals/1719-olm_unwedging.md +++ b/proposals/1719-olm_unwedging.md @@ -16,8 +16,7 @@ empty contents. In order to avoid creating too many extra sessions, a client should rate-limit the number of new sessions it creates per device that it receives a message from; the client should not create a new session with another device if it has -already created one for that given device in the past 1 hour. (TODO: is 1 hour -the right amount of time?) +already created one for that given device in the past 1 hour. Clients may wish to ask the sender of the undecryptable messages to re-send the message. For exampe, if the undecryptable message was a megolm session, then From d39baba21b64c0dfe3b57e2bbbe8b9609fb69f2d Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 22 May 2019 12:44:04 -0400 Subject: [PATCH 0331/1250] add a security note --- proposals/1719-olm_unwedging.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/1719-olm_unwedging.md b/proposals/1719-olm_unwedging.md index 50b6f0e6..3e0ce35d 100644 --- a/proposals/1719-olm_unwedging.md +++ b/proposals/1719-olm_unwedging.md @@ -45,6 +45,10 @@ time of the session. The spec will be changed to read: ## Security considerations +An attacker could use this to create a new session on a device that they are +able to read. However, this would require the attacker to have compromised the +device's keys. + ## Conclusion This proposal outlines how wedged olm sessions can be replaced by a new From dd74baa5d0fb6c2f15878a929c1a70e2edf69e62 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 22 May 2019 12:54:01 -0400 Subject: [PATCH 0332/1250] clarify wording --- proposals/1719-olm_unwedging.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/1719-olm_unwedging.md b/proposals/1719-olm_unwedging.md index 3e0ce35d..67bd6010 100644 --- a/proposals/1719-olm_unwedging.md +++ b/proposals/1719-olm_unwedging.md @@ -36,8 +36,7 @@ time of the session. The spec will be changed to read: > If a client has multiple sessions established with another device, it should > use the session from which it last received and successfully decrypted a > message. For these purposes, a session that has not received any messages -> should consider its creation time to be the time that it last received a -> message. +> should use its creation time as the time that it last received a message. ## Tradeoffs From ac08c8461240e2fc9f88bc59c34263d8add4115f Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 23 May 2019 14:39:46 -0400 Subject: [PATCH 0333/1250] remove duplicate consideration Co-Authored-By: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- proposals/1719-olm_unwedging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1719-olm_unwedging.md b/proposals/1719-olm_unwedging.md index 67bd6010..c181e3f7 100644 --- a/proposals/1719-olm_unwedging.md +++ b/proposals/1719-olm_unwedging.md @@ -29,7 +29,7 @@ another device, it should use the session from which it last received a message." (the last paragraph of the [`m.olm.v1.curve25519-aes-sha2` section](https://matrix.org/docs/spec/client_server/r0.4.0.html#m-olm-v1-curve25519-aes-sha2)). When comparing the time of the last received message for each session, the -client should consider only consider messages that were successfully decrypted, +client should only consider messages that were successfully decrypted, and for sessions that have never received a message, it should use the creation time of the session. The spec will be changed to read: From 9c2a789d34da6a465ace23875d9d9e89ff7ced48 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 23 May 2019 22:13:57 -0600 Subject: [PATCH 0334/1250] Add missing changelogs and make existing ones match conventions The conventions are not set in stone, however the changelog should not be a mixed bag of voices. --- changelogs/application_service/newsfragments/1650.clarification | 1 + changelogs/client_server/newsfragments/1650.clarification | 1 + changelogs/client_server/newsfragments/1656.clarification | 1 + changelogs/client_server/newsfragments/1701.feature | 2 +- changelogs/client_server/newsfragments/1744.clarification | 2 +- changelogs/client_server/newsfragments/1889.clarification | 2 +- changelogs/client_server/newsfragments/1891.clarification | 1 + changelogs/client_server/newsfragments/1969.clarification | 1 + changelogs/client_server/newsfragments/1975.clarification | 2 +- changelogs/client_server/newsfragments/1999.clarification | 1 + changelogs/identity_service/newsfragments/1967.clarification | 1 + changelogs/server_server/newsfragments/1650.clarification | 1 + 12 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 changelogs/application_service/newsfragments/1650.clarification create mode 100644 changelogs/client_server/newsfragments/1650.clarification create mode 100644 changelogs/client_server/newsfragments/1656.clarification create mode 100644 changelogs/client_server/newsfragments/1891.clarification create mode 100644 changelogs/client_server/newsfragments/1969.clarification create mode 100644 changelogs/client_server/newsfragments/1999.clarification create mode 100644 changelogs/identity_service/newsfragments/1967.clarification create mode 100644 changelogs/server_server/newsfragments/1650.clarification diff --git a/changelogs/application_service/newsfragments/1650.clarification b/changelogs/application_service/newsfragments/1650.clarification new file mode 100644 index 00000000..617b7ab6 --- /dev/null +++ b/changelogs/application_service/newsfragments/1650.clarification @@ -0,0 +1 @@ +Change examples to use example.org instead of a real domain. diff --git a/changelogs/client_server/newsfragments/1650.clarification b/changelogs/client_server/newsfragments/1650.clarification new file mode 100644 index 00000000..617b7ab6 --- /dev/null +++ b/changelogs/client_server/newsfragments/1650.clarification @@ -0,0 +1 @@ +Change examples to use example.org instead of a real domain. diff --git a/changelogs/client_server/newsfragments/1656.clarification b/changelogs/client_server/newsfragments/1656.clarification new file mode 100644 index 00000000..0c8f4ad0 --- /dev/null +++ b/changelogs/client_server/newsfragments/1656.clarification @@ -0,0 +1 @@ +Clarify that ``state_default`` in ``m.room.power_levels`` always defaults to 50. diff --git a/changelogs/client_server/newsfragments/1701.feature b/changelogs/client_server/newsfragments/1701.feature index 39c22dd7..cf6084ae 100644 --- a/changelogs/client_server/newsfragments/1701.feature +++ b/changelogs/client_server/newsfragments/1701.feature @@ -1 +1 @@ -Documented megolm session export format. \ No newline at end of file +Add megolm session export format. diff --git a/changelogs/client_server/newsfragments/1744.clarification b/changelogs/client_server/newsfragments/1744.clarification index dc103920..dfe838f1 100644 --- a/changelogs/client_server/newsfragments/1744.clarification +++ b/changelogs/client_server/newsfragments/1744.clarification @@ -1 +1 @@ -Add missing status_msg to m.presence schema. +Add missing ``status_msg`` to ``m.presence`` schema. diff --git a/changelogs/client_server/newsfragments/1889.clarification b/changelogs/client_server/newsfragments/1889.clarification index 5026dab3..2737a7ee 100644 --- a/changelogs/client_server/newsfragments/1889.clarification +++ b/changelogs/client_server/newsfragments/1889.clarification @@ -1 +1 @@ -Add the missing `m.push_rules` event schema. +Add the missing ``m.push_rules`` event schema. diff --git a/changelogs/client_server/newsfragments/1891.clarification b/changelogs/client_server/newsfragments/1891.clarification new file mode 100644 index 00000000..ef4edfb4 --- /dev/null +++ b/changelogs/client_server/newsfragments/1891.clarification @@ -0,0 +1 @@ +Clarify how modern day local echo is meant to be solved by clients. diff --git a/changelogs/client_server/newsfragments/1969.clarification b/changelogs/client_server/newsfragments/1969.clarification new file mode 100644 index 00000000..b0f05203 --- /dev/null +++ b/changelogs/client_server/newsfragments/1969.clarification @@ -0,0 +1 @@ +Fix various spelling mistakes throughout the specification. diff --git a/changelogs/client_server/newsfragments/1975.clarification b/changelogs/client_server/newsfragments/1975.clarification index 03a9b754..ac118bfd 100644 --- a/changelogs/client_server/newsfragments/1975.clarification +++ b/changelogs/client_server/newsfragments/1975.clarification @@ -1 +1 @@ -Clarify that ``width`` and ``height`` are required parameters on ``/_matrix/media/r0/thumbnail/{serverName}/{mediaId}``. It is somewhat meaningless to request a thumbnail without specifying a desired size, and Synapse has never permitted such requests. \ No newline at end of file +Clarify that ``width`` and ``height`` are required parameters on ``/_matrix/media/r0/thumbnail/{serverName}/{mediaId}``. diff --git a/changelogs/client_server/newsfragments/1999.clarification b/changelogs/client_server/newsfragments/1999.clarification new file mode 100644 index 00000000..748c55f2 --- /dev/null +++ b/changelogs/client_server/newsfragments/1999.clarification @@ -0,0 +1 @@ +Clarify how ``m.login.dummy`` can be used to disambiguate login flows. diff --git a/changelogs/identity_service/newsfragments/1967.clarification b/changelogs/identity_service/newsfragments/1967.clarification new file mode 100644 index 00000000..b080caeb --- /dev/null +++ b/changelogs/identity_service/newsfragments/1967.clarification @@ -0,0 +1 @@ +Fix route for ``/3pid/bind``. diff --git a/changelogs/server_server/newsfragments/1650.clarification b/changelogs/server_server/newsfragments/1650.clarification new file mode 100644 index 00000000..617b7ab6 --- /dev/null +++ b/changelogs/server_server/newsfragments/1650.clarification @@ -0,0 +1 @@ +Change examples to use example.org instead of a real domain. From 3c38956510511d97dc770c0ec0be4d681b382af0 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 24 May 2019 11:57:22 -0600 Subject: [PATCH 0335/1250] Remove prev_content from the redaction essential keys list As per [MSC1954](https://github.com/matrix-org/matrix-doc/pull/1954) No known changes since the proposal was accepted. --- changelogs/client_server/newsfragments/2016.clarification | 1 + specification/client_server_api.rst | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/2016.clarification diff --git a/changelogs/client_server/newsfragments/2016.clarification b/changelogs/client_server/newsfragments/2016.clarification new file mode 100644 index 00000000..77ea0d4c --- /dev/null +++ b/changelogs/client_server/newsfragments/2016.clarification @@ -0,0 +1 @@ +Remove ``prev_content`` from the redaction algorithm's essential keys list. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 6f65ebb1..604c2b1c 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1500,7 +1500,6 @@ the following list: - ``room_id`` - ``sender`` - ``state_key`` -- ``prev_content`` - ``content`` - ``hashes`` - ``signatures`` From 3b0e194ff7a5a4b6e20bbf1572337738904feda5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 24 May 2019 15:50:05 -0600 Subject: [PATCH 0336/1250] Add version 4 rooms to the spec As per [MSC1884](https://github.com/matrix-org/matrix-doc/pull/1884) and [MSC2002](https://github.com/matrix-org/matrix-doc/pull/2002). No known changes since the proposals were accepted. Due to being in the area: This fixes https://github.com/matrix-org/matrix-doc/issues/1863 --- api/server-server/definitions/pdu_v3.yaml | 4 ++ api/server-server/definitions/pdu_v4.yaml | 47 ++++++++++++++ api/server-server/examples/pdu_v3.json | 3 +- api/server-server/examples/pdu_v4.json | 12 ++++ specification/index.rst | 1 + specification/rooms/v4.rst | 76 +++++++++++++++++++++++ specification/targets.yaml | 4 ++ 7 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 api/server-server/definitions/pdu_v4.yaml create mode 100644 api/server-server/examples/pdu_v4.json create mode 100644 specification/rooms/v4.rst diff --git a/api/server-server/definitions/pdu_v3.yaml b/api/server-server/definitions/pdu_v3.yaml index 8d41fbda..38105098 100644 --- a/api/server-server/definitions/pdu_v3.yaml +++ b/api/server-server/definitions/pdu_v3.yaml @@ -20,6 +20,10 @@ allOf: - $ref: "unsigned_pdu_base.yaml" - type: object properties: + redacts: + type: string + description: For redaction events, the ID of the event being redacted. + example: "$def/456+oldevent" auth_events: type: array items: diff --git a/api/server-server/definitions/pdu_v4.yaml b/api/server-server/definitions/pdu_v4.yaml new file mode 100644 index 00000000..55b1c26f --- /dev/null +++ b/api/server-server/definitions/pdu_v4.yaml @@ -0,0 +1,47 @@ +# Copyright 2019 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: Persistent Data Unit +description: A persistent data unit (event) for room version 3 and beyond. +example: + $ref: "../examples/pdu_v4.json" +allOf: + - $ref: "pdu_v3.yaml" + - type: object + properties: + redacts: + type: string + description: For redaction events, the ID of the event being redacted. + example: "$def_456-oldevent" + 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: ["$URLsafe-base64EncodedHash", "$Another_Event"] + 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: ["$URLsafe-base64EncodedHash", "$Another_Event"] + required: + - auth_events + - prev_events diff --git a/api/server-server/examples/pdu_v3.json b/api/server-server/examples/pdu_v3.json index 6a454b4e..acffdf26 100644 --- a/api/server-server/examples/pdu_v3.json +++ b/api/server-server/examples/pdu_v3.json @@ -15,5 +15,6 @@ "prev_events": [ "$base64encodedeventid", "$adifferenteventid" - ] + ], + "redacts": "$some/old+event" } diff --git a/api/server-server/examples/pdu_v4.json b/api/server-server/examples/pdu_v4.json new file mode 100644 index 00000000..3c2f0e22 --- /dev/null +++ b/api/server-server/examples/pdu_v4.json @@ -0,0 +1,12 @@ +{ + "$ref": "pdu_v3.json", + "auth_events": [ + "$urlsafe_base64_encoded_eventid", + "$a-different-event-id" + ], + "prev_events": [ + "$urlsafe_base64_encoded_eventid", + "$a-different-event-id" + ], + "redacts": "$some-old_event" +} diff --git a/specification/index.rst b/specification/index.rst index 19c5ad22..33dff5a3 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -493,6 +493,7 @@ The available room versions are: * `Version 1 `_ - **Stable**. The current version of most rooms. * `Version 2 `_ - **Stable**. Implements State Resolution Version 2. * `Version 3 `_ - **Stable**. Introduces events whose IDs are the event's hash. +* `Version 4 `_ - **Stable**. Builds on v3 by using URL-safe base64 for event IDs. Specification Versions ---------------------- diff --git a/specification/rooms/v4.rst b/specification/rooms/v4.rst new file mode 100644 index 00000000..8d2cc59b --- /dev/null +++ b/specification/rooms/v4.rst @@ -0,0 +1,76 @@ +.. Copyright 2019 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. + +Room Version 4 +============== + +This room version builds on `version 3 `_ using a different encoding for +event IDs. + +.. contents:: Table of Contents +.. sectnum:: + + +Client considerations +--------------------- + +This room version changes the format form event IDs sent to clients. Clients should +already be treating event IDs as opaque identifiers, and should not be concerned with +the format of them. Clients should still encode the event ID when including it in a +request path. + +Clients should expect to see event IDs changed from the format of ``$randomstring:example.org`` +to something like ``$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg`` (note the lack of domain). + + +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 4 uses the same algorithms defined in `room version 3 `_, however +using URL-safe base64 to generate the event ID. + +Event IDs +~~~~~~~~~ + +.. admonition:: Rationale + + Room version 3 generated event IDs that were difficult for client implementations + which were not encoding the event ID to function in those rooms. It additionally + raised concern due to the ``/`` character being interpretted differently by some + reverse proxy software, and generally made administration harder. + +The event ID is the `reference hash`_ of the event encoded using a variation of +`Unpadded Base64`_ which replaces the 62nd and 63rd characters with ``-`` and ``_`` +instead of using ``+`` and ``/``. This matches `RFC4648's definition of URL-safe base64 +`_. Event IDs are still prefixed +with ``$`` and may result in looking like ``$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg``. + +Just like in room version 3, 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. Room version 3 also changes the format +of ``auth_events`` and ``prev_events`` in a PDU. + +{{definition_ss_pdu_v4}} + +.. _`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 diff --git a/specification/targets.yaml b/specification/targets.yaml index 830449ae..be4a063a 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -38,6 +38,10 @@ targets: files: - rooms/v3.rst version_label: v3 + rooms@v4: # this is translated to be rooms/v4.html + files: + - rooms/v4.rst + version_label: v4 appendices: files: - appendices.rst From ceaccffdf7244e79aa91e3916811f93881be9bca Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 24 May 2019 17:14:23 -0600 Subject: [PATCH 0337/1250] Add a .m.rule.tombstone default push rule for room upgrades As per [MSC1930](https://github.com/matrix-org/matrix-doc/pull/1930) There are no known changes to this proposal since it was accepted. --- .../client_server/newsfragments/2020.feature | 1 + specification/modules/push.rst | 35 +++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2020.feature diff --git a/changelogs/client_server/newsfragments/2020.feature b/changelogs/client_server/newsfragments/2020.feature new file mode 100644 index 00000000..0d7c7eb8 --- /dev/null +++ b/changelogs/client_server/newsfragments/2020.feature @@ -0,0 +1 @@ +Add a ``.m.rule.tombstone`` default push rule for room ugprade notifications. diff --git a/specification/modules/push.rst b/specification/modules/push.rst index 9830729a..1bac0c2e 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -177,7 +177,7 @@ notification is delivered for a matching event. The following actions are define This prevents each matching event from generating a notification ``coalesce`` This enables notifications for matching events but activates homeserver - specific behaviour to intelligently coalesce multiple events into a single + specific behaviour to intelligently coalesce multiple events into a single notification. Not all homeservers may support this. Those that do not support it should treat it as the ``notify`` action. ``set_tweak`` @@ -369,6 +369,37 @@ Definition: } +``.m.rule.tombstone`` +````````````````````` +Matches any event whose type is ``m.room.tombstone``. This is intended +to notify users of a room when it is upgraded, similar to what an +``@room`` notification would accomplish. + +Definition: + +.. code:: json + + { + "rule_id": ".m.rule.tombstone", + "default": true, + "enabled": true, + "conditions": [ + { + "kind": "event_match", + "key": "type", + "pattern": "m.room.tombstone" + } + ], + "actions": [ + "notify", + { + "set_tweak": "highlight", + "value": true + } + ] + } + + ``.m.rule.roomnotif`` ````````````````````` Matches any message whose content is unencrypted and contains the @@ -599,7 +630,7 @@ Definition: Conditions ++++++++++ -Override, Underride and Default Rules MAY have a list of 'conditions'. +Override, Underride and Default Rules MAY have a list of 'conditions'. All conditions must hold true for an event in order to apply the ``action`` for the event. A rule with no conditions always matches. Room, Sender, User and Content rules do not have conditions in the same way, but instead have From 2b96d73305328188f584070f550ce1591d08bbff Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 26 May 2019 15:39:35 -0600 Subject: [PATCH 0338/1250] Fix third party signed definitions for join APIs Fixes https://github.com/matrix-org/matrix-doc/issues/1978 --- .../definitions/third_party_signed.yaml | 41 +++++++++++ api/client-server/joining.yaml | 69 +------------------ specification/modules/third_party_invites.rst | 3 +- 3 files changed, 45 insertions(+), 68 deletions(-) create mode 100644 api/client-server/definitions/third_party_signed.yaml diff --git a/api/client-server/definitions/third_party_signed.yaml b/api/client-server/definitions/third_party_signed.yaml new file mode 100644 index 00000000..c9c761a1 --- /dev/null +++ b/api/client-server/definitions/third_party_signed.yaml @@ -0,0 +1,41 @@ +# Copyright 2019 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: Third Party Signed +description: |- + A signature of an ``m.third_party_invite`` token to prove that this user + owns a third party identity which has been invited to the room. +properties: + sender: + type: string + description: The Matrix ID of the user who issued the invite. + example: "@alice:example.org" + mxid: + type: string + description: The Matrix ID of the invitee. + example: "@bob:example.org" + token: + type: string + description: The state key of the m.third_party_invite event. + example: "random8nonce" + signatures: + type: object + description: A signatures object containing a signature of the entire signed object. + title: Signatures + example: { + "example.org": { + "ed25519:0": "some9signature" + } + } +required: ["sender", "mxid", "token", "signatures"] diff --git a/api/client-server/joining.yaml b/api/client-server/joining.yaml index 1dcf769f..af38d6f9 100644 --- a/api/client-server/joining.yaml +++ b/api/client-server/joining.yaml @@ -58,38 +58,9 @@ paths: name: third_party_signed schema: type: object - example: { - "third_party_signed": { - "sender": "@cat:the.hat", - "mxid": "@green:eggs.ham", - "token": "random8nonce", - "signatures": { - "horton.hears": { - "ed25519:0": "some9signature" - } - } - } - } properties: third_party_signed: - type: object - title: ThirdPartySigned - description: A signature of an ``m.third_party_invite`` token to prove that this user owns a third party identity which has been invited to the room. - properties: - sender: - type: string - description: The Matrix ID of the user who issued the invite. - mxid: - type: string - description: The Matrix ID of the invitee. - token: - type: string - description: The state key of the m.third_party_invite event. - signatures: - type: object - description: A signatures object containing a signature of the entire signed object. - title: Signatures - required: ["sender", "mxid", "token", "signatures"] + $ref: "definitions/third_party_signed.yaml" responses: 200: description: |- @@ -163,45 +134,9 @@ paths: name: third_party_signed schema: type: object - example: { - "third_party_signed": { - "signed": { - "sender": "@cat:the.hat", - "mxid": "@green:eggs.ham", - "token": "random8nonce", - "signatures": { - "horton.hears": { - "ed25519:0": "some9signature" - } - } - } - } - } properties: third_party_signed: - type: object - title: ThirdPartySigned - description: A signature of an ``m.third_party_invite`` token to prove that this user owns a third party identity which has been invited to the room. - properties: - signed: - type: object - title: Signed - properties: - sender: - type: string - description: The Matrix ID of the user who issued the invite. - mxid: - type: string - description: The Matrix ID of the invitee. - token: - type: string - description: The state key of the m.third_party_invite event. - signatures: - type: object - description: A signatures object containing a signature of the entire signed object. - title: Signatures - required: ["sender", "mxid", "token", "signatures"] - required: ["signed"] + $ref: "definitions/third_party_signed.yaml" responses: 200: description: |- diff --git a/specification/modules/third_party_invites.rst b/specification/modules/third_party_invites.rst index 3e11d929..b8ab9657 100644 --- a/specification/modules/third_party_invites.rst +++ b/specification/modules/third_party_invites.rst @@ -38,7 +38,8 @@ When the invitee's homeserver receives the notification of the binding, it should insert an ``m.room.member`` event into the room's graph for that user, with ``content.membership`` = ``invite``, as well as a ``content.third_party_invite`` property which contains proof that the invitee -does indeed own that third party identifier. +does indeed own that third party identifier. See the `m.room.member <#m-room-member>`_ +schema for more information. Events From 17a9524cad8774c9cfe12157742d0f196391de44 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 26 May 2019 15:40:29 -0600 Subject: [PATCH 0339/1250] changelog --- changelogs/client_server/newsfragments/2025.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2025.clarification diff --git a/changelogs/client_server/newsfragments/2025.clarification b/changelogs/client_server/newsfragments/2025.clarification new file mode 100644 index 00000000..9e99b23d --- /dev/null +++ b/changelogs/client_server/newsfragments/2025.clarification @@ -0,0 +1 @@ +Fix the ``third_party_signed`` definitions for the join APIs. From 5eea4a477f98d79371791ab153bdaae91883f4b8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 26 May 2019 20:42:21 -0600 Subject: [PATCH 0340/1250] Add server notices support As per [MSC1452](https://github.com/matrix-org/matrix-doc/issues/1452) Fixes https://github.com/matrix-org/matrix-doc/issues/1254 Although MSC1452 focuses on just the warnings part of the server notices, the base for notices has not been established in the spec. This commit adds the needed support to be able to handle notices. No intentional divergences from the proposal are included in this changeset. There are a few additions which are used in practice although not defined in the proposal, such as who is responsible for aesthetics, sending notices, and other misc rules. --- .../client_server/newsfragments/2026.feature | 1 + .../examples/m.room.message#m.server_notice | 11 +++ .../schema/m.room.message#m.server_notice | 39 ++++++++++ .../templating/matrix_templates/sections.py | 15 +++- .../matrix_templates/templates/events.tmpl | 7 ++ scripts/templating/matrix_templates/units.py | 2 + specification/client_server_api.rst | 5 +- specification/modules/server_notices.rst | 78 +++++++++++++++++++ specification/targets.yaml | 1 + 9 files changed, 154 insertions(+), 5 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2026.feature create mode 100644 event-schemas/examples/m.room.message#m.server_notice create mode 100644 event-schemas/schema/m.room.message#m.server_notice create mode 100644 specification/modules/server_notices.rst diff --git a/changelogs/client_server/newsfragments/2026.feature b/changelogs/client_server/newsfragments/2026.feature new file mode 100644 index 00000000..f82b9aea --- /dev/null +++ b/changelogs/client_server/newsfragments/2026.feature @@ -0,0 +1 @@ +Add support for sending server notices to clients. diff --git a/event-schemas/examples/m.room.message#m.server_notice b/event-schemas/examples/m.room.message#m.server_notice new file mode 100644 index 00000000..0eb44ea7 --- /dev/null +++ b/event-schemas/examples/m.room.message#m.server_notice @@ -0,0 +1,11 @@ +{ + "$ref": "core/room_event.json", + "type": "m.room.message", + "content": { + "body": "Human-readable message to explain the notice", + "msgtype": "m.server_notice", + "server_notice_type": "m.server_notice.usage_limit_reached", + "admin_contact": "mailto:server.admin@example.org", + "limit_type": "monthly_active_user" + } +} diff --git a/event-schemas/schema/m.room.message#m.server_notice b/event-schemas/schema/m.room.message#m.server_notice new file mode 100644 index 00000000..f1848821 --- /dev/null +++ b/event-schemas/schema/m.room.message#m.server_notice @@ -0,0 +1,39 @@ +--- +allOf: + - $ref: core-event-schema/room_event.yaml +description: Represents a server notice for a user. +properties: + content: + properties: + body: + description: A human-readable description of the notice. + type: string + msgtype: + enum: + - m.server_notice + type: string + server_notice_type: + description: |- + The type of notice being represented. + type: string + admin_contact: + description: |- + A URI giving a contact method for the server administrator. Required if the + notice type is ``m.server_notice.usage_limit_reached``. + type: string + limit_type: + description: |- + The kind of usage limit the server has exceeded. Required if the notice type is + ``m.server_notice.usage_limit_reached``. + type: string + required: + - msgtype + - body + - server_notice_type + type: object + type: + enum: + - m.room.message + type: string +title: ServerNoticeMessage +type: object diff --git a/scripts/templating/matrix_templates/sections.py b/scripts/templating/matrix_templates/sections.py index 5961aa24..92afa5ff 100644 --- a/scripts/templating/matrix_templates/sections.py +++ b/scripts/templating/matrix_templates/sections.py @@ -110,12 +110,13 @@ class MatrixSections(Sections): # Special function: Returning a dict will specify multiple sections where # the key is the section name and the value is the value of the section def render_group_events(self): - # map all event schemata to the form $EVENTTYPE_event with s/./_/g - # e.g. m_room_topic_event + # map all event schemata to the form $EVENTTYPE_event with s/.#/_/g + # e.g. m_room_topic_event or m_room_message_m_text_event schemas = self.units.get("event_schemas") renders = {} for event_type in schemas: - renders[event_type.replace(".", "_") + "_event"] = self._render_events( + underscored_event_type = event_type.replace(".", "_").replace("#", "_") + renders[underscored_event_type + "_event"] = self._render_events( lambda x: x == event_type, sorted ) return renders @@ -141,9 +142,15 @@ class MatrixSections(Sections): "m.room.message#m.notice", "m.room.message#m.image", "m.room.message#m.file" ] + excluded_types = [ + # We exclude server notices from here because we handle them in a + # dedicated module. We do not want to confuse developers this early + # in the spec. + "m.room.message#m.server_notice", + ] other_msgtypes = [ k for k in schemas.keys() if k.startswith("m.room.message#") and - k not in msgtype_order + k not in msgtype_order and k not in excluded_types ] for event_name in (msgtype_order + other_msgtypes): if not event_name.startswith("m.room.message#m."): diff --git a/scripts/templating/matrix_templates/templates/events.tmpl b/scripts/templating/matrix_templates/templates/events.tmpl index 0955cf4c..f55be73f 100644 --- a/scripts/templating/matrix_templates/templates/events.tmpl +++ b/scripts/templating/matrix_templates/templates/events.tmpl @@ -1,7 +1,14 @@ {% import 'tables.tmpl' as tables -%} +{% if (event.type_with_msgtype) %} +``{{event.type_with_msgtype}}`` +{{(4 + event.type_with_msgtype | length) * title_kind}} +{% endif -%} + +{% if (not event.type_with_msgtype) %} ``{{event.type}}`` {{(4 + event.type | length) * title_kind}} +{% endif -%} {% if (event.typeof | length) %} *{{event.typeof}}* diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index c1755119..466110f8 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -846,6 +846,7 @@ class MatrixUnits(Units): "title": None, "desc": None, "msgtype": None, + "type_with_msgtype": None, # for the template's sake "content_fields": [ # ] @@ -884,6 +885,7 @@ class MatrixUnits(Units): ) if msgtype: schema["msgtype"] = msgtype[0] # enum prop + schema["type_with_msgtype"] = schema["type"] + " (" + msgtype[0] + ")" # link to msgtypes for m.room.message if schema["type"] == "m.room.message" and not msgtype: diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 604c2b1c..a8bbfca0 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -219,9 +219,12 @@ Other error codes the client might encounter are: to modify state (eg: sending messages, account data, etc) and not routes which only read state (eg: ``/sync``, get account data, etc). +:``M_CANNOT_LEAVE_SERVER_NOTICE_ROOM``: + The user is unable to reject an invite to join the server notices room. See the + `Server Notices <#server-notices>`_ module for more information. + .. TODO: More error codes (covered by other issues) .. * M_CONSENT_NOT_GIVEN - GDPR: https://github.com/matrix-org/matrix-doc/issues/1512 -.. * M_CANNOT_LEAVE_SERVER_NOTICE_ROOM - GDPR: https://github.com/matrix-org/matrix-doc/issues/1254 .. _sect:txn_ids: diff --git a/specification/modules/server_notices.rst b/specification/modules/server_notices.rst new file mode 100644 index 00000000..63b7bfc5 --- /dev/null +++ b/specification/modules/server_notices.rst @@ -0,0 +1,78 @@ +.. Copyright 2019 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. + +Server Notices +============== + +.. _module:server-notices: + +Homeserver hosts often want to send messages to users in an official capacity, +or have resource limits which affect a user's ability to use the homeserver. +For example, the homeserver may be limited to a certain number of active users +per month and has exceeded that limit. To communicate this failure to users, +the homeserver would use the Server Notices room. + +The aesthetics of the room (name, topic, avatar, etc) are left as an implementation +detail. It is recommended that the homeserver decorate the room such that it looks +like an official room to users. + +Events +------ +Notices are sent to the client as normal ``m.room.message`` events with a +``msgtype`` of ``m.server_notice`` in the server notices room. Events with +a ``m.server_notice`` ``msgtype`` outside of the server notice room must +be ignored by clients. + +The specified values for ``server_notice_type`` are: + +:``m.server_notice.usage_limit_reached``: + The server has exceeded some limit which requires the server administrator + to intervene. The ``limit_type`` describes the kind of limit reached. + The specified values for ``limit_type`` are: + + :``monthly_active_user``: + The server's number of active users in the last 30 days has exceeded the + maximum. New connections are being refused by the server. What defines + "active" is left as an implementation detail, however servers are encouraged + to treat syncing users as "active". + + +{{m_room_message_m_server_notice_event}} + +Client behaviour +---------------- +Clients can identify the server notices room by the ``m.server_notice`` tag +on the room. Active notices are represented by the `pinned events <#m-room-pinned-events>`_ +in the server notices room. Server notice events pinned in that room should +be shown to the user through special UI and not through the normal pinned +events interface in the client. For example, clients may show warning banners +or bring up dialogs to get the user's attention. Events which are not server +notice events and are pinned in the server notices room should be shown just +like any other pinned event in a room. + +The client must not expect to be able to reject an invite to join the server +notices room. Attempting to reject the invite must result in a +``M_CANNOT_LEAVE_SERVER_NOTICE_ROOM`` error. Servers should not prevent the user +leaving the room after joining the server notices room, however the same error +code must be used if the server will prevent leaving the room. + +Server behaviour +---------------- +Servers should manage exactly 1 server notices room per user. Servers must +identify this room to clients with the ``m.server_notice`` tag. Servers should +invite the target user rather than automatically join them to the server notice +room. + +How servers send notices to clients, and which user they use to send the events, +is left as an implementation detail for the server. diff --git a/specification/targets.yaml b/specification/targets.yaml index 830449ae..aa53e9c3 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -83,6 +83,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/server_acls.rst - modules/mentions.rst - modules/room_upgrades.rst + - modules/server_notices.rst title_styles: ["=", "-", "~", "+", "^", "`", "@", ":"] From 1d33adf62d8d56d1bfb88a0ff13da7e00fb0cc60 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 26 May 2019 21:20:04 -0600 Subject: [PATCH 0341/1250] Add rationale for UIA on change password, and how access tokens behave Fixes https://github.com/matrix-org/matrix-doc/issues/680 --- api/client-server/registration.yaml | 8 ++++++-- changelogs/client_server/newsfragments/2027.clarification | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2027.clarification diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index e2d35d2c..3195ab41 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -326,13 +326,17 @@ paths: description: |- Changes the password for an account on this homeserver. - This API endpoint uses the `User-Interactive Authentication API`_. + This API endpoint uses the `User-Interactive Authentication API`_ to + ensure the user changing the password is actually the owner of the + account. An access token should be submitted to this endpoint if the client has an active session. The homeserver may change the flows available depending on whether a - valid access token is provided. + valid access token is provided. The homeserver SHOULD NOT revoke the + access token provided in the request, however all other access tokens + for the user should be revoked if the request succeeds. security: - accessToken: [] operationId: changePassword diff --git a/changelogs/client_server/newsfragments/2027.clarification b/changelogs/client_server/newsfragments/2027.clarification new file mode 100644 index 00000000..db74ea56 --- /dev/null +++ b/changelogs/client_server/newsfragments/2027.clarification @@ -0,0 +1 @@ +Clarify why User Interactive Auth is used on password changes and how access tokens are handled. From 221d9f24fd5699c78072feeab335c9a389a4de41 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 26 May 2019 21:30:55 -0600 Subject: [PATCH 0342/1250] Clarify that logging out deletes devices too Fixes https://github.com/matrix-org/matrix-doc/issues/1651 --- api/client-server/logout.yaml | 5 +++-- changelogs/client_server/newsfragments/2028.clarification | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2028.clarification diff --git a/api/client-server/logout.yaml b/api/client-server/logout.yaml index 2dfd6d97..8451f739 100644 --- a/api/client-server/logout.yaml +++ b/api/client-server/logout.yaml @@ -32,7 +32,7 @@ paths: summary: Invalidates a user access token description: |- Invalidates an existing access token, so that it can no longer be used for - authorization. + authorization. The device associated with the access token is also deleted. operationId: logout security: - accessToken: [] @@ -49,7 +49,8 @@ paths: summary: Invalidates all access tokens for a user description: |- Invalidates all access tokens for a user, so that they can no longer be used for - authorization. This includes the access token that made this request. + authorization. This includes the access token that made this request. All devices + for the user are also deleted. This endpoint does not require UI authorization because UI authorization is designed to protect against attacks where the someone gets hold of a single access diff --git a/changelogs/client_server/newsfragments/2028.clarification b/changelogs/client_server/newsfragments/2028.clarification new file mode 100644 index 00000000..75e21e74 --- /dev/null +++ b/changelogs/client_server/newsfragments/2028.clarification @@ -0,0 +1 @@ +Clarify that devices are deleted upon logout. From d52fcdacfa7a98e6ab56916dd7d331e53d94ab77 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 26 May 2019 21:36:31 -0600 Subject: [PATCH 0343/1250] Add M_NOT_FOUND definition for deleting non-existent aliases Fixes https://github.com/matrix-org/matrix-doc/issues/1675 --- api/client-server/directory.yaml | 9 +++++++++ .../client_server/newsfragments/2029.clarification | 1 + 2 files changed, 10 insertions(+) create mode 100644 changelogs/client_server/newsfragments/2029.clarification diff --git a/api/client-server/directory.yaml b/api/client-server/directory.yaml index 78ddfa29..2c7c8386 100644 --- a/api/client-server/directory.yaml +++ b/api/client-server/directory.yaml @@ -148,5 +148,14 @@ paths: } schema: type: object + 404: + description: There is no mapped room ID for this room alias. + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "Room alias #monkeys:example.org not found." + } + schema: + "$ref": "definitions/errors/error.yaml" tags: - Room directory diff --git a/changelogs/client_server/newsfragments/2029.clarification b/changelogs/client_server/newsfragments/2029.clarification new file mode 100644 index 00000000..95b65481 --- /dev/null +++ b/changelogs/client_server/newsfragments/2029.clarification @@ -0,0 +1 @@ +Add ``M_NOT_FOUND`` error definition for deleting room aliases. From a30dbc590da00727e71920af0df7f5e140783aba Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 26 May 2019 21:39:09 -0600 Subject: [PATCH 0344/1250] Clarify that e2e keys are also obliterated --- api/client-server/logout.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/client-server/logout.yaml b/api/client-server/logout.yaml index 8451f739..75a3ec87 100644 --- a/api/client-server/logout.yaml +++ b/api/client-server/logout.yaml @@ -33,6 +33,7 @@ paths: description: |- Invalidates an existing access token, so that it can no longer be used for authorization. The device associated with the access token is also deleted. + `Device keys <#device-keys>`_ for the device are deleted alongside the device. operationId: logout security: - accessToken: [] @@ -50,7 +51,8 @@ paths: description: |- Invalidates all access tokens for a user, so that they can no longer be used for authorization. This includes the access token that made this request. All devices - for the user are also deleted. + for the user are also deleted. `Device keys <#device-keys>`_ for the device are + deleted alongside the device. This endpoint does not require UI authorization because UI authorization is designed to protect against attacks where the someone gets hold of a single access From 1bda3fe2b20427be2e129ac2a91d7dc9bbd72215 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 26 May 2019 21:49:46 -0600 Subject: [PATCH 0345/1250] Spec MSISDN UIA support Fixes https://github.com/matrix-org/matrix-doc/issues/1702 1702 describes the lack of `bind_msisdn` parameter, however the whole login type was missing from UIA. --- api/client-server/registration.yaml | 6 ++++ .../client_server/newsfragments/2030.feature | 1 + specification/client_server_api.rst | 29 +++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 changelogs/client_server/newsfragments/2030.feature diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index e2d35d2c..741008bb 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -94,6 +94,12 @@ paths: If true, the server binds the email used for authentication to the Matrix ID with the identity server. example: false + bind_msisdn: + type: boolean + description: |- + If true, the server binds the phone number used for authentication + to the Matrix ID with the identity server. + example: false username: type: string description: |- diff --git a/changelogs/client_server/newsfragments/2030.feature b/changelogs/client_server/newsfragments/2030.feature new file mode 100644 index 00000000..b5975a73 --- /dev/null +++ b/changelogs/client_server/newsfragments/2030.feature @@ -0,0 +1 @@ +Add MSISDN (phone number) support to User-Interactive Authentication. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 604c2b1c..a40d463c 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -618,6 +618,7 @@ This specification defines the following auth types: - ``m.login.recaptcha`` - ``m.login.oauth2`` - ``m.login.email.identity`` + - ``m.login.msisdn`` - ``m.login.token`` - ``m.login.dummy`` @@ -782,6 +783,34 @@ To use this authentication type, clients should submit an auth dict as follows: "session": "" } +Phone number/MSISDN-based (identity server) +<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +:Type: + ``m.login.msisdn`` +:Description: + Authentication is supported by authorising a phone number with an identity + server. + +Prior to submitting this, the client should authenticate with an identity +server. After authenticating, the session information should be submitted to +the homeserver. + +To use this authentication type, clients should submit an auth dict as follows: + +.. code:: json + + { + "type": "m.login.msisdn", + "threepidCreds": [ + { + "sid": "", + "client_secret": "", + "id_server": "" + } + ], + "session": "" + } + Dummy Auth <<<<<<<<<< :Type: From 00f97636a22b28de26ffaafd674e1014374210e0 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 26 May 2019 22:08:04 -0600 Subject: [PATCH 0346/1250] Add missing reason property to m.call.hangup Fixes https://github.com/matrix-org/matrix-doc/issues/1689 --- .../client_server/newsfragments/2031.clarification | 1 + event-schemas/schema/m.call.hangup | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/2031.clarification diff --git a/changelogs/client_server/newsfragments/2031.clarification b/changelogs/client_server/newsfragments/2031.clarification new file mode 100644 index 00000000..9bed3bcc --- /dev/null +++ b/changelogs/client_server/newsfragments/2031.clarification @@ -0,0 +1 @@ +Add missing ``reason`` to ``m.call.hangup``. diff --git a/event-schemas/schema/m.call.hangup b/event-schemas/schema/m.call.hangup index 9d45d179..0328e03a 100644 --- a/event-schemas/schema/m.call.hangup +++ b/event-schemas/schema/m.call.hangup @@ -1,6 +1,6 @@ { "type": "object", - "description": "Sent by either party to signal their termination of the call. This can be sent either once the call has has been established or before to abort the call.", + "description": "Sent by either party to signal their termination of the call. This can be sent either once the call has has been established or before to abort the call. The ``reason`` for the hangup is expected to be provided when there was an error in the call negotiation, such as ``ice_failed`` for when ICE negotiation fails or ``invite_timeout`` for when the other party did not answer in time.", "allOf": [{ "$ref": "core-event-schema/room_event.yaml" }], @@ -15,6 +15,14 @@ "version": { "type": "integer", "description": "The version of the VoIP specification this message adheres to. This specification is version 0." + }, + "reason": { + "type": "string", + "description": "Optional error reason for the hangup. This should not be provided when the user naturally ends or rejects the call.", + "enum": [ + "ice_failed", + "invite_timeout" + ] } }, "required": ["call_id", "version"] From 23ab1c527a4864f632ce07d80d80fa23eae81ed6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 26 May 2019 22:16:12 -0600 Subject: [PATCH 0347/1250] Clarify how redactions affect room state Fixes https://github.com/matrix-org/matrix-doc/issues/1726 --- .../client_server/newsfragments/2032.clarification | 1 + specification/client_server_api.rst | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 changelogs/client_server/newsfragments/2032.clarification diff --git a/changelogs/client_server/newsfragments/2032.clarification b/changelogs/client_server/newsfragments/2032.clarification new file mode 100644 index 00000000..e497b8be --- /dev/null +++ b/changelogs/client_server/newsfragments/2032.clarification @@ -0,0 +1 @@ +Clarify how redactions affect room state. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 604c2b1c..a254a85d 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1531,6 +1531,15 @@ property of the redacted event, under the ``redacted_because`` key. When a client receives a redaction event it should change the redacted event in the same way a server does. +.. NOTE:: + + Redacted events can still affect the state of the room. For example, a + redacted ``join`` event will still result in the user being considered + joined. Similarly, a redacted topic does not necessarily cause the topic + to revert to what is was prior to the event - it causes the topic to be + removed from the room. + + Events ++++++ From df51acd7ae43cac76f61397d21378ed549e5b548 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 12:14:21 -0600 Subject: [PATCH 0348/1250] Proposal for adding a device_id to /account/whoami --- proposals/2033-whoami-device-id.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 proposals/2033-whoami-device-id.md diff --git a/proposals/2033-whoami-device-id.md b/proposals/2033-whoami-device-id.md new file mode 100644 index 00000000..2dd408eb --- /dev/null +++ b/proposals/2033-whoami-device-id.md @@ -0,0 +1,30 @@ +# Proposal to include device IDs in `/account/whoami` + +There are some use cases (namely using +[Pantalaimon with bots](https://github.com/matrix-org/pantalaimon/issues/14)) +which could benefit from knowing the `device_id` associated with a token. + + +## Proposal + +The `/account/whoami` endpoint receives an additional optional field for the `device_id` +associated with the access token. The field is optional because appservice users may not +have a real device associated with them. Non-appservice users should always have a device +associated with them. + +Access tokens are already associated with at most 1 device, and devices are associated with +exactly 1 access token. Because of this, we do not need to worry about multiple devices +causing problems. For more information, see +https://matrix.org/docs/spec/client_server/r0.4.0.html#relationship-between-access-tokens-and-devices + +*Note*: Pantalaimon would likely require a `device_id` be returned and error requests +otherwise. This should be considered expected behaviour by Pantalaimon in the MSC author's +opinion. + + +## Tradeoffs + +We could introduce a `/device/whoami` endpoint, however that is a less superior option. Most +calls to `/device/whoami` would additionally need to call `/account/whoami` to determine the +user ID of the account. We had might as well bundle the two pieces of information into the +same request. From f4ff8e5467d2acad1f154df8a44d287766f8cf22 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 12:20:26 -0600 Subject: [PATCH 0349/1250] Clarify where the field appears --- proposals/2033-whoami-device-id.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2033-whoami-device-id.md b/proposals/2033-whoami-device-id.md index 2dd408eb..bac804c1 100644 --- a/proposals/2033-whoami-device-id.md +++ b/proposals/2033-whoami-device-id.md @@ -7,7 +7,7 @@ which could benefit from knowing the `device_id` associated with a token. ## Proposal -The `/account/whoami` endpoint receives an additional optional field for the `device_id` +The `/account/whoami` endpoint receives an additional response field for the `device_id` associated with the access token. The field is optional because appservice users may not have a real device associated with them. Non-appservice users should always have a device associated with them. From e7ed8a23ce1e2e4c11484e1ffcda728730c56b22 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 14:42:00 -0600 Subject: [PATCH 0350/1250] Move lazy loading filter options to event filter The options also work on /messages --- .../definitions/room_event_filter.yaml | 25 ++++++++++++++++ .../definitions/sync_filter.yaml | 29 +------------------ 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/api/client-server/definitions/room_event_filter.yaml b/api/client-server/definitions/room_event_filter.yaml index aa217d2b..fd399913 100644 --- a/api/client-server/definitions/room_event_filter.yaml +++ b/api/client-server/definitions/room_event_filter.yaml @@ -16,6 +16,31 @@ allOf: - type: object title: RoomEventFilter properties: + lazy_load_members: + type: boolean + description: |- + If ``true``, the only ``m.room.member`` events returned in + the ``state`` section of the ``/sync`` response are those + which are definitely necessary for a client to display + the ``sender`` of the timeline events in that response. + If ``false``, ``m.room.member`` events are not filtered. + By default, servers should suppress duplicate redundant + lazy-loaded ``m.room.member`` events from being sent to a given + client across multiple calls to ``/sync``, given that most clients + cache membership events (see ``include_redundant_members`` + to change this behaviour). + include_redundant_members: + type: boolean + description: |- + If ``true``, the ``state`` section of the ``/sync`` response will + always contain the ``m.room.member`` events required to display + the ``sender`` of the timeline events in that response, assuming + ``lazy_load_members`` is enabled. This means that redundant + duplicate member events may be returned across multiple calls to + ``/sync``. This is useful for naive clients who never track + membership data. If ``false``, duplicate ``m.room.member`` events + may be suppressed by the server across multiple calls to ``/sync``. + If ``lazy_load_members`` is ``false`` this field is ignored. 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'`` diff --git a/api/client-server/definitions/sync_filter.yaml b/api/client-server/definitions/sync_filter.yaml index 65b18ba6..45a269c7 100644 --- a/api/client-server/definitions/sync_filter.yaml +++ b/api/client-server/definitions/sync_filter.yaml @@ -47,7 +47,7 @@ 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. This filter is applied before the filters in ``ephemeral``, + filter. This filter is applied before the filters in ``ephemeral``, ``state``, ``timeline`` or ``account_data`` items: type: string @@ -73,33 +73,6 @@ properties: allOf: - $ref: room_event_filter.yaml description: The state events to include for rooms. - properties: - lazy_load_members: - type: boolean - description: |- - If ``true``, the only ``m.room.member`` events returned in - the ``state`` section of the ``/sync`` response are those - which are definitely necessary for a client to display - the ``sender`` of the timeline events in that response. - If ``false``, ``m.room.member`` events are not filtered. - By default, servers should suppress duplicate redundant - lazy-loaded ``m.room.member`` events from being sent to a given - client across multiple calls to ``/sync``, given that most clients - cache membership events (see ``include_redundant_members`` - to change this behaviour). - include_redundant_members: - type: boolean - description: |- - If ``true``, the ``state`` section of the ``/sync`` response will - always contain the ``m.room.member`` events required to display - the ``sender`` of the timeline events in that response, assuming - ``lazy_load_members`` is enabled. This means that redundant - duplicate member events may be returned across multiple calls to - ``/sync``. This is useful for naive clients who never track - membership data. If ``false``, duplicate ``m.room.member`` events - may be suppressed by the server across multiple calls to ``/sync``. - If ``lazy_load_members`` is ``false`` this field is ignored. - timeline: allOf: - $ref: room_event_filter.yaml From d56df3238c58abde17ca28165baa9b904cb743c0 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 14:35:37 -0600 Subject: [PATCH 0351/1250] Generalize wording to fit /messages and /sync --- .../definitions/room_event_filter.yaml | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/api/client-server/definitions/room_event_filter.yaml b/api/client-server/definitions/room_event_filter.yaml index fd399913..5258ea30 100644 --- a/api/client-server/definitions/room_event_filter.yaml +++ b/api/client-server/definitions/room_event_filter.yaml @@ -19,28 +19,32 @@ allOf: lazy_load_members: type: boolean description: |- - If ``true``, the only ``m.room.member`` events returned in - the ``state`` section of the ``/sync`` response are those - which are definitely necessary for a client to display - the ``sender`` of the timeline events in that response. + If ``true``, the only ``m.room.member`` events returned + are those which are definitely necessary for a client to + display the ``sender`` of the timeline events in the response. If ``false``, ``m.room.member`` events are not filtered. By default, servers should suppress duplicate redundant lazy-loaded ``m.room.member`` events from being sent to a given - client across multiple calls to ``/sync``, given that most clients + client across multiple calls, given that most clients cache membership events (see ``include_redundant_members`` to change this behaviour). + + Only applicable when filtering state events, such as the + ``state`` section of a ``/sync`` or ``/messages``. include_redundant_members: type: boolean description: |- - If ``true``, the ``state`` section of the ``/sync`` response will - always contain the ``m.room.member`` events required to display - the ``sender`` of the timeline events in that response, assuming - ``lazy_load_members`` is enabled. This means that redundant - duplicate member events may be returned across multiple calls to - ``/sync``. This is useful for naive clients who never track + If ``true``, response will always contain the ``m.room.member`` + events required to display the ``sender`` of the timeline events + in that response, assuming ``lazy_load_members`` is enabled. This + means that redundant duplicate member events may be returned across + multiple calls to. This is useful for naive clients who never track membership data. If ``false``, duplicate ``m.room.member`` events - may be suppressed by the server across multiple calls to ``/sync``. - If ``lazy_load_members`` is ``false`` this field is ignored. + may be suppressed by the server across multiple calls. If + ``lazy_load_members`` is ``false`` this field is ignored. + + Only applicable when filtering state events, such as the + ``state`` section of a ``/sync`` or ``/messages``. 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'`` From 34d6c1f4ad60d7d753ac703613034a8756662ae8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 14:46:59 -0600 Subject: [PATCH 0352/1250] Clarify wording further for how to handle redundant members Note: This makes assumptions on what the TODO comment in Synapse means: https://github.com/matrix-org/synapse/blob/e26e6b3230f0b55376f0f3bf823dd789ac7064d0/synapse/handlers/pagination.py#L262 Due to lack of implementation, it is assumed that using the same filter across multiple calls to /sync OR /messages will result in the redundant members being excluded in the next request. For example, calling /sync, then /messages which returns some members, then /sync again will exclude the members due to them being in /messages. --- .../definitions/room_event_filter.yaml | 25 ++++++++++--------- api/client-server/message_pagination.yaml | 17 +++++++++++++ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/api/client-server/definitions/room_event_filter.yaml b/api/client-server/definitions/room_event_filter.yaml index 5258ea30..35b3edf9 100644 --- a/api/client-server/definitions/room_event_filter.yaml +++ b/api/client-server/definitions/room_event_filter.yaml @@ -24,27 +24,28 @@ allOf: display the ``sender`` of the timeline events in the response. If ``false``, ``m.room.member`` events are not filtered. By default, servers should suppress duplicate redundant - lazy-loaded ``m.room.member`` events from being sent to a given - client across multiple calls, given that most clients - cache membership events (see ``include_redundant_members`` - to change this behaviour). + lazy-loaded ``m.room.member`` events from being sent to a + given client in a previous request using the same filter, + given that most clients cache membership events (see + ``include_redundant_members`` to change this behaviour). Only applicable when filtering state events, such as the - ``state`` section of a ``/sync`` or ``/messages``. + ``state`` section of a ``/sync`` or ``/messages`` response. include_redundant_members: type: boolean description: |- If ``true``, response will always contain the ``m.room.member`` events required to display the ``sender`` of the timeline events - in that response, assuming ``lazy_load_members`` is enabled. This - means that redundant duplicate member events may be returned across - multiple calls to. This is useful for naive clients who never track - membership data. If ``false``, duplicate ``m.room.member`` events - may be suppressed by the server across multiple calls. If - ``lazy_load_members`` is ``false`` this field is ignored. + in that response, assuming ``lazy_load_members`` is enabled. + This means that redundant duplicate member events will be returned + across multiple calls using the same filter. This is useful for + naive clients who never track membership data. If ``false`` or + not provided, duplicate ``m.room.member`` events should be + suppressed by the server across multiple calls. If ``lazy_load_members`` + is ``false`` this field is ignored. Only applicable when filtering state events, such as the - ``state`` section of a ``/sync`` or ``/messages``. + ``state`` section of a ``/sync`` or ``/messages`` response. 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'`` diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index 941e61fb..ff6d970d 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -108,6 +108,23 @@ paths: type: object title: RoomEvent "$ref": "definitions/event-schemas/schema/core-event-schema/room_event.yaml" + state: + type: array + description: |- + A list of state events relevant to showing the ``chunk``. For example, if + lazy-loading members is enabled in the filter then this will contain any + applicable membership events. Servers should be careful to not exclude + membership events which are older than ones already sent to the client. + Likewise, clients should be cautious and avoid using older membership + events as the current membership event when paginating backwards. + + Unless ``include_redundant_members`` is ``true``, the server should remove + redundant members which would have already been sent to clients in prior calls + to ``/messages`` or ``/sync`` with the same filter. + items: + type: object + title: RoomStateEvent + $ref: "definitions/event-schemas/schema/core-event-schema/state_event.yaml" examples: application/json: { "start": "t47429-4392820_219380_26003_2265", From b67161cf97badda0c37ccaa482634e5c5fa4093b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 14:59:59 -0600 Subject: [PATCH 0353/1250] List the endpoints which are lazy-loading aware --- api/client-server/definitions/room_event_filter.yaml | 9 +++++++-- api/client-server/event_context.yaml | 3 +++ api/client-server/message_pagination.yaml | 5 ++++- api/client-server/sync.yaml | 3 +++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/api/client-server/definitions/room_event_filter.yaml b/api/client-server/definitions/room_event_filter.yaml index 35b3edf9..4790643e 100644 --- a/api/client-server/definitions/room_event_filter.yaml +++ b/api/client-server/definitions/room_event_filter.yaml @@ -30,7 +30,12 @@ allOf: ``include_redundant_members`` to change this behaviour). Only applicable when filtering state events, such as the - ``state`` section of a ``/sync`` or ``/messages`` response. + ``state`` section of a lazy-loading aware endpoint. + + The endpoints which support lazy-loading are: + `/sync <#get-matrix-client-%CLIENT_RELEASE_LABEL%-sync>`_, + `/messages <#get-matrix-client-%CLIENT_RELEASE_LABEL%-rooms-roomid-messages>`_, + and `/context <#get-matrix-client-%CLIENT_RELEASE_LABEL%-rooms-roomid-context-eventid>`_. include_redundant_members: type: boolean description: |- @@ -45,7 +50,7 @@ allOf: is ``false`` this field is ignored. Only applicable when filtering state events, such as the - ``state`` section of a ``/sync`` or ``/messages`` response. + ``state`` section of a lazy-loading aware endpoint. 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'`` diff --git a/api/client-server/event_context.yaml b/api/client-server/event_context.yaml index 91da3cf4..c0f391e5 100644 --- a/api/client-server/event_context.yaml +++ b/api/client-server/event_context.yaml @@ -34,6 +34,9 @@ paths: This API returns a number of events that happened just before and after the specified event. This allows clients to get the context surrounding an event. + + *Note*: this endpoint supports lazy-loading. See `Filtering <#filtering>`_ + for more information. operationId: getEventContext security: - accessToken: [] diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index ff6d970d..716afb65 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -33,6 +33,9 @@ paths: description: |- This API returns a list of message and state events for a room. It uses pagination query parameters to paginate history in the room. + + *Note*: this endpoint supports lazy-loading. See `Filtering <#filtering>`_ + for more information. operationId: getRoomEvents security: - accessToken: [] @@ -120,7 +123,7 @@ paths: Unless ``include_redundant_members`` is ``true``, the server should remove redundant members which would have already been sent to clients in prior calls - to ``/messages`` or ``/sync`` with the same filter. + to lazy-loading aware endpoints with the same filter. items: type: object title: RoomStateEvent diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index f204152a..87e7bf74 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -34,6 +34,9 @@ paths: Clients use this API when they first log in to get an initial snapshot of the state on the server, and then continue to call this API to get incremental deltas to the state, and to receive new messages. + + *Note*: this endpoint supports lazy-loading. See `Filtering <#filtering>`_ + for more information. operationId: sync security: - accessToken: [] From ba520df004eafdf3fc58d051a567708d7419fe14 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 17:38:04 -0600 Subject: [PATCH 0354/1250] Move lazy loading to a section in Filtering --- .../definitions/room_event_filter.yaml | 36 ++++--------------- api/client-server/sync.yaml | 3 +- specification/client_server_api.rst | 33 +++++++++++++++++ 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/api/client-server/definitions/room_event_filter.yaml b/api/client-server/definitions/room_event_filter.yaml index 4790643e..0659be8e 100644 --- a/api/client-server/definitions/room_event_filter.yaml +++ b/api/client-server/definitions/room_event_filter.yaml @@ -19,38 +19,16 @@ allOf: lazy_load_members: type: boolean description: |- - If ``true``, the only ``m.room.member`` events returned - are those which are definitely necessary for a client to - display the ``sender`` of the timeline events in the response. - If ``false``, ``m.room.member`` events are not filtered. - By default, servers should suppress duplicate redundant - lazy-loaded ``m.room.member`` events from being sent to a - given client in a previous request using the same filter, - given that most clients cache membership events (see - ``include_redundant_members`` to change this behaviour). - - Only applicable when filtering state events, such as the - ``state`` section of a lazy-loading aware endpoint. - - The endpoints which support lazy-loading are: - `/sync <#get-matrix-client-%CLIENT_RELEASE_LABEL%-sync>`_, - `/messages <#get-matrix-client-%CLIENT_RELEASE_LABEL%-rooms-roomid-messages>`_, - and `/context <#get-matrix-client-%CLIENT_RELEASE_LABEL%-rooms-roomid-context-eventid>`_. + If ``true``, enables lazy-loading of membership events. See + `Lazy-loading room members <#lazy-loading-room-members>`_ + for more information. Defaults to ``false``. include_redundant_members: type: boolean description: |- - If ``true``, response will always contain the ``m.room.member`` - events required to display the ``sender`` of the timeline events - in that response, assuming ``lazy_load_members`` is enabled. - This means that redundant duplicate member events will be returned - across multiple calls using the same filter. This is useful for - naive clients who never track membership data. If ``false`` or - not provided, duplicate ``m.room.member`` events should be - suppressed by the server across multiple calls. If ``lazy_load_members`` - is ``false`` this field is ignored. - - Only applicable when filtering state events, such as the - ``state`` section of a lazy-loading aware endpoint. + If ``true``, enables redudant membership events. Does not + apply unless ``lazy_load_members`` is ``true``. See + `Lazy-loading room members <#lazy-loading-room-members>`_ + for more information. Defaults to ``false``. 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'`` diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 87e7bf74..bd659369 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -36,7 +36,8 @@ paths: incremental deltas to the state, and to receive new messages. *Note*: this endpoint supports lazy-loading. See `Filtering <#filtering>`_ - for more information. + for more information. Lazy-loading members is only supported on a ``StateFilter`` + for this endpoint. operationId: sync security: - accessToken: [] diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 604c2b1c..a4b8dd5c 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1268,6 +1268,39 @@ Filters can be created on the server and can be passed as as a parameter to APIs which return events. These filters alter the data returned from those APIs. Not all APIs accept filters. +Lazy-loading room members +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Membership events often take significant resources for clients to track. In an +effort to reduce the number of resources used, clients can enable "lazy-loading" +for room members. By doing this, servers will only ever send membership events +which are relevant to the client. + +In terms of filters, this means enabling ``lazy_load_members`` on a ``StateFilter`` +or ``RoomEventFilter``. When enabled, lazy-loading aware endpoints (see below) +will only include membership events for the ``sender`` of events being included +in the response. For example, if a client makes a ``/sync`` request with lazy-loading +enabled, the server will only return membership events for the ``sender`` of events +in the timeline, not all members of a room. + +Repeated calls to lazy-loading aware endpoints will result in redundant membership +events being excluded by default. Clients often track which membership events they +already have, therefore making the extra information not as useful to the client. +Clients can always request redundant members by setting ``include_redundant_members`` +to true in the filter. + +Servers should be cautious about which events they consider redundant. Membership +events can change over time, and should be included as relevant to maintain the +historical record. Likewise, clients should be cautious about treating an older event +as the current membership event for a user. + +.. Note:: + Repeated calls using the same filter to *any* lazy-loading aware endpoint may + result in redundant members being excluded from future calls. For example, a + request to ``/sync`` followed by a request to ``/messages`` may result in a + future call to ``/sync`` excluding members included by the ``/messages`` call. + + {{filter_cs_http_api}} Events From 7b266b33da0cdabcfa6e2d2fdf4d3fc36f83ed0f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 19:26:26 -0600 Subject: [PATCH 0355/1250] Add membership params Fixes https://github.com/matrix-org/matrix-doc/issues/1945 --- api/client-server/rooms.yaml | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/api/client-server/rooms.yaml b/api/client-server/rooms.yaml index cc1f2bf7..acddf891 100644 --- a/api/client-server/rooms.yaml +++ b/api/client-server/rooms.yaml @@ -288,6 +288,44 @@ paths: description: The room to get the member events for. required: true x-example: "!636q39766251:example.com" + - in: query + name: at + type: string + description: |- + The point in time (pagination token) to return members for in the room. + This token can be obtained from a ``prev_batch`` token returned for + each room by the sync API. Defaults to the current state of the room, + as determined by the server. + x-example: "YWxsCgpOb25lLDM1ODcwOA" + # XXX: As mentioned in MSC1227, replacing `[not_]membership` with a JSON + # filter might be a better alternative. + # See https://github.com/matrix-org/matrix-doc/issues/1337 + - in: query + name: membership + type: string + enum: + - join + - invite + - leave + - ban + description: |- + The kind of membership to filter for. Defaults to no filtering if + unspecified. When specified alongside ``not_membership``, the two + parameters create an 'or' condition: either the membership *is* + the same as ``membership`` **or** *is not* the same as ``not_membership``. + x-example: "join" + - in: query + name: not_membership + type: string + enum: + - join + - invite + - leave + - ban + description: |- + The kind of membership to exclude from the results. Defaults to no + filtering if unspecified. + x-example: leave security: - accessToken: [] responses: From b3d86f99b9d21ad98e26b37cf6afcc73d7064964 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 20:20:00 -0600 Subject: [PATCH 0356/1250] Add room summary spec --- api/client-server/sync.yaml | 52 +++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index bd659369..2c504295 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -129,6 +129,50 @@ paths: title: Joined Room type: object properties: + summary: + title: RoomSummary + type: object + description: |- + Information about the room which clients may need to + correctly render it to users. + properties: + "m.heroes": + type: array + description: |- + The users which can be used to generate a room name + if the room does not have one. Required if the room + does not have a ``m.room.name`` or ``m.room.canonical_alias`` + state event with non-empty content. + + This should be the first 5 members of the room, ordered + by stream ordering, which are joined or invited. The + list must never include the client's own user ID. When + no joined or invited members are available, this should + consist of the banned and left users. More than 5 members + may be provided, however less than 5 should only be provided + when there are less than 5 members to represent. + + When lazy-loading room members is enabled, the membership + events for the heroes MUST be included in the ``state``, + unless they are redundant. When the list of users changes, + the server notifies the client by sending a fresh list of + heroes. If there are no changes since the last sync, this + field may be omitted. + items: + type: string + "m.joined_member_count": + type: integer + description: |- + The number of users with ``membership`` of ``join``, + including the client's own user ID. If this field has + not changed since the last sync, it may be omitted. + Required otherwise. + "m.invited_member_count": + type: integer + description: |- + The number of users with ``membership`` of ``invite``. + If this field has not changed since the last sync, it + may be omitted. Required otherwise. state: title: State type: object @@ -334,6 +378,14 @@ paths: "rooms": { "join": { "!726s6s6q:example.com": { + "summary": { + "m.heroes": [ + "@alice:example.com", + "@bob:example.com" + ], + "m.joined_member_count": 2, + "m.invited_member_count": 0 + }, "state": { "events": [ { From 8330810e957bf33991274b9fad6cd258deaf670d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 20:47:03 -0600 Subject: [PATCH 0357/1250] Specify the new room naming scheme --- specification/modules/instant_messaging.rst | 98 ++++++++------------- 1 file changed, 35 insertions(+), 63 deletions(-) diff --git a/specification/modules/instant_messaging.rst b/specification/modules/instant_messaging.rst index 86daa700..dd3e9c6c 100644 --- a/specification/modules/instant_messaging.rst +++ b/specification/modules/instant_messaging.rst @@ -278,70 +278,42 @@ choose a name: #. If the room has an `m.room.canonical_alias`_ state event with a non-empty ``alias`` field, use the alias given by that field as the name. -#. If neither of the above conditions are met, a name should be composed based - on the members of the room. Clients should consider `m.room.member`_ events - for users other than the logged-in user, with ``membership: join`` or - ``membership: invite``. - - .. _active_members: - - i. If there is only one such event, the display name for the room should be - the `disambiguated display name`_ of the corresponding user. - - #. If there are two such events, they should be lexicographically sorted by - their ``state_key`` (i.e. the corresponding user IDs), and the display - name for the room should be the `disambiguated display name`_ of both - users: " and ", or a localised variant thereof. - - #. If there are three or more such events, the display name for the room - should be based on the disambiguated display name of the user - corresponding to the first such event, under a lexicographical sorting - according to their ``state_key``. The display name should be in the - format " and others" (or a localised variant thereof), where N - is the number of `m.room.member`_ events with ``membership: join`` or - ``membership: invite``, excluding the logged-in user and "user1". - - For example, if Alice joins a room, where Bob (whose user id is - ``@superuser:example.com``), Carol (user id ``@carol:example.com``) and - Dan (user id ``@dan:matrix.org``) are in conversation, Alice's - client should show the room name as "Carol and 2 others". - - .. TODO-spec - Sorting by user_id certainly isn't ideal, as IDs at the start of the - alphabet will end up dominating room names: they will all be called - "Arathorn and 15 others". Furthermore - user_ids are not necessarily - ASCII, which means we need to either specify a collation order, or specify - how to choose one. - - Ideally we might sort by the time when the user was first invited to, or - first joined the room. But we don't have this information. - - See https://matrix.org/jira/browse/SPEC-267 for further discussion. - -#. If the room has no valid ``m.room.name`` or ``m.room.canonical_alias`` - event, and no active members other than the current user, clients should - consider ``m.room.member`` events with ``membership: leave``. If such events - exist, a display name such as "Empty room (was and others)" (or - a localised variant thereof) should be used, following similar rules as for - active members (see `above `_). - -#. A complete absence of room name, canonical alias, and room members is likely - to indicate a problem with creating the room or synchronising the state - table; however clients should still handle this situation. A display name - such as "Empty room" (or a localised variant thereof) should be used in this - situation. - -.. _`disambiguated display name`: `Calculating the display name for a user`_ - -Clients SHOULD NOT use `m.room.aliases`_ events as a source for room names, as -it is difficult for clients to agree on the best alias to use, and aliases can -change unexpectedly. - -.. TODO-spec - How can we make this less painful for clients to implement, without forcing - an English-language implementation on them all? See - https://matrix.org/jira/browse/SPEC-425. +#. If neither of the above conditions are met, the client can optionally guess + an alias from the ``m.room.alias`` events in the room. This is a temporary + measure while clients do not promote canonical aliases as prominently. This + step may be removed in a future version of the specification. +#. If none of the above conditions are met, a name should be composed based + on the members of the room. Clients should consider `m.room.member`_ events + for users other than the logged-in user, as defined below. + + i. If the ``m.heroes`` for the room are greater or equal to + ``m.joined_member_count + m.invited_member_count - 1``, then use the + membership events for the heroes to calculate display names for the + users (`disambiguating them if required`_) and concatenating them. For + example, the client may choose to show "Alice, Bob, and Charlie + (@charlie:example.org)" as the room name. The client may optionally + limit the number + + #. If there are fewer heroes than ``m.joined_member_count + m.invited_member_count + - 1``, and ``m.joined_member_count + m.invited_member_count`` is greater + than 1, the client should use the heroes to calculate display names for + the users (`disambiguating them if required`_) and concatenating them + alongside a count of the remaining users. For example, "Alice, Bob, and + 1234 others". + + #. If ``m.joined_member_count + m.invited_member_count`` is less than or + equal to 1 (indicating the member is alone), the client should use the + rules above to indicate that the room was empty. For example, "Empty + Room (was Alice)", "Empty Room (was Alice and 1234 others)", or + "Empty Room" if there are no heroes. + +Clients SHOULD internationalise the room name to the user's language when using +the ``m.heroes`` to calculate the name. Clients SHOULD use minimum 5 heroes to +calculate room names where possible, but may use more or less to fit better with +their user experience. + +.. _`disambiguating them if required`: `Calculating the display name for a user`_ Forming relationships between events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From b1dccda49ddae41ec67e193b7da1f0bd1f345360 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 20:47:53 -0600 Subject: [PATCH 0358/1250] changelog --- changelogs/client_server/newsfragments/2035.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2035.feature diff --git a/changelogs/client_server/newsfragments/2035.feature b/changelogs/client_server/newsfragments/2035.feature new file mode 100644 index 00000000..47029c28 --- /dev/null +++ b/changelogs/client_server/newsfragments/2035.feature @@ -0,0 +1 @@ +Add the option to lazy-load room members for increased client performance. From d14dc1d8e15a12b91cb20592d6e46c6b20ea678a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 21:15:24 -0600 Subject: [PATCH 0359/1250] Clarify that redacted state events affect the room with default values --- specification/client_server_api.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index a254a85d..22cc9425 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1533,11 +1533,12 @@ same way a server does. .. NOTE:: - Redacted events can still affect the state of the room. For example, a - redacted ``join`` event will still result in the user being considered - joined. Similarly, a redacted topic does not necessarily cause the topic - to revert to what is was prior to the event - it causes the topic to be - removed from the room. + Redacted events can still affect the state of the room. When redacted, + state events behave as though their properties were simply not specified + unless their properties are protected by the redaction algorithm. For example, + a redacted ``join`` event will still result in the user being considered joined. + Similarly, a redacted topic does not necessarily cause the topic to revert to + what is was prior to the event - it causes the topic to be removed from the room. Events From 229893589a30f21560cf55fac00d0112fa041413 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 21:18:04 -0600 Subject: [PATCH 0360/1250] Move wording for reason definitions --- event-schemas/schema/m.call.hangup | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/event-schemas/schema/m.call.hangup b/event-schemas/schema/m.call.hangup index 0328e03a..c0478f5a 100644 --- a/event-schemas/schema/m.call.hangup +++ b/event-schemas/schema/m.call.hangup @@ -1,6 +1,6 @@ { "type": "object", - "description": "Sent by either party to signal their termination of the call. This can be sent either once the call has has been established or before to abort the call. The ``reason`` for the hangup is expected to be provided when there was an error in the call negotiation, such as ``ice_failed`` for when ICE negotiation fails or ``invite_timeout`` for when the other party did not answer in time.", + "description": "Sent by either party to signal their termination of the call. This can be sent either once the call has has been established or before to abort the call.", "allOf": [{ "$ref": "core-event-schema/room_event.yaml" }], @@ -18,7 +18,7 @@ }, "reason": { "type": "string", - "description": "Optional error reason for the hangup. This should not be provided when the user naturally ends or rejects the call.", + "description": "Optional error reason for the hangup. This should not be provided when the user naturally ends or rejects the call. When there was an error in the call negotiation, this should be ``ice_failed`` for when ICE negotiation fails or ``invite_timeout`` for when the other party did not answer in time.", "enum": [ "ice_failed", "invite_timeout" From ade346f8cc173a532a0e991b61ed153a3ea93e9c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 21:19:58 -0600 Subject: [PATCH 0361/1250] Add m.server_notice to reserved tags --- specification/modules/tags.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/specification/modules/tags.rst b/specification/modules/tags.rst index a4b0becf..9d0cd554 100644 --- a/specification/modules/tags.rst +++ b/specification/modules/tags.rst @@ -34,9 +34,9 @@ The JSON object associated with each tag gives information about the tag, e.g ho to order the rooms with a given tag. Ordering information is given under the ``order`` key as a number between 0 and -1. The numbers are compared such that 0 is displayed first. Therefore a room -with an ``order`` of ``0.2`` would be displayed before a room with an ``order`` -of ``0.7``. If a room has a tag without an ``order`` key then it should appear +1. The numbers are compared such that 0 is displayed first. Therefore a room +with an ``order`` of ``0.2`` would be displayed before a room with an ``order`` +of ``0.7``. If a room has a tag without an ``order`` key then it should appear after the rooms with that tag that have an ``order`` key. The name of a tag MUST NOT exceed 255 bytes. @@ -60,6 +60,7 @@ The following tags are defined in the ``m.*`` namespace: * ``m.favourite``: The user's favourite rooms. These should be shown with higher precedence than other rooms. * ``m.lowpriority``: These should be shown with lower precedence than others. +* ``m.server_notice``: Used to identify `Server Notice Rooms <#module-server-notices>`_. {{m_tag_event}} From 9acd960cf6afc8ddb011f7db5ca00fbf57cba5a5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 21:22:07 -0600 Subject: [PATCH 0362/1250] Update specification/client_server_api.rst Co-Authored-By: Kitsune Ral --- specification/client_server_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 22cc9425..c18f4d03 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1535,7 +1535,7 @@ same way a server does. Redacted events can still affect the state of the room. When redacted, state events behave as though their properties were simply not specified - unless their properties are protected by the redaction algorithm. For example, + except those protected by the redaction algorithm. For example, a redacted ``join`` event will still result in the user being considered joined. Similarly, a redacted topic does not necessarily cause the topic to revert to what is was prior to the event - it causes the topic to be removed from the room. From 699cafe6701d2206160170c6eaafeb789405507a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 21:27:54 -0600 Subject: [PATCH 0363/1250] v4 is v4, not v3 --- api/server-server/definitions/pdu_v4.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/server-server/definitions/pdu_v4.yaml b/api/server-server/definitions/pdu_v4.yaml index 55b1c26f..a045e657 100644 --- a/api/server-server/definitions/pdu_v4.yaml +++ b/api/server-server/definitions/pdu_v4.yaml @@ -13,7 +13,7 @@ # limitations under the License. type: object title: Persistent Data Unit -description: A persistent data unit (event) for room version 3 and beyond. +description: A persistent data unit (event) for room version 4 and beyond. example: $ref: "../examples/pdu_v4.json" allOf: From 10648aa9e8ce9556d3b881539acca7c9a7962156 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 22:30:37 -0600 Subject: [PATCH 0364/1250] Clarify that FAIL_ERROR is not limited to just homeservers. Fixes https://github.com/matrix-org/matrix-doc/issues/1735 --- changelogs/client_server/newsfragments/2036.clarification | 1 + specification/client_server_api.rst | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/2036.clarification diff --git a/changelogs/client_server/newsfragments/2036.clarification b/changelogs/client_server/newsfragments/2036.clarification new file mode 100644 index 00000000..96058b7b --- /dev/null +++ b/changelogs/client_server/newsfragments/2036.clarification @@ -0,0 +1 @@ +Clarify that ``FAIL_ERROR`` in autodiscovery is not limited to just homeservers. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index a8bbfca0..4158bad8 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -289,7 +289,7 @@ In this section, the following terms are used with specific meanings: ``FAIL_ERROR`` Inform the user that auto-discovery did not return any usable URLs. Do not continue further with the current login process. At this point, valid data - was obtained, but no homeserver is available to serve the client. No further + was obtained, but no server is available to serve the client. No further guess should be attempted and the user should make a conscientious decision what to do next. From d0fd20fdb4b412c9bb596cfc2b06915d46c631a3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 22:40:07 -0600 Subject: [PATCH 0365/1250] Clarify how homeservers are meant to auth themselves to appservices Fixes https://github.com/matrix-org/matrix-doc/issues/1765 Note that the swagger definitions already say that authorization is required. It just wasn't mentioned in the spec. --- .../application_service/newsfragments/2037.clarification | 1 + specification/application_service_api.rst | 8 ++++++++ 2 files changed, 9 insertions(+) create mode 100644 changelogs/application_service/newsfragments/2037.clarification diff --git a/changelogs/application_service/newsfragments/2037.clarification b/changelogs/application_service/newsfragments/2037.clarification new file mode 100644 index 00000000..f425b1c1 --- /dev/null +++ b/changelogs/application_service/newsfragments/2037.clarification @@ -0,0 +1 @@ +Add missing definition for how appservices verify requests came from a homeserver. diff --git a/specification/application_service_api.rst b/specification/application_service_api.rst index 865544dd..81077bcf 100644 --- a/specification/application_service_api.rst +++ b/specification/application_service_api.rst @@ -187,6 +187,14 @@ An example registration file for an IRC-bridging application service is below: Homeserver -> Application Service API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Authorization ++++++++++++++ + +Homeservers MUST include a query parameter named ``access_token`` containing the +``hs_token`` from the application service's registration when making requests to +the application service. Application services MUST verify the provided ``access_token`` +matches their known ``hs_token``, failing the request with a ``M_FORBIDDEN`` error. + Legacy routes +++++++++++++ From d8eb2949066c9c53f7501da9fb86f76fa762e960 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 22:44:24 -0600 Subject: [PATCH 0366/1250] Fix s2s changelog entries --- changelogs/server_server/newsfragments/1904.clarification | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/server_server/newsfragments/1904.clarification b/changelogs/server_server/newsfragments/1904.clarification index 94174ebd..531fdb94 100644 --- a/changelogs/server_server/newsfragments/1904.clarification +++ b/changelogs/server_server/newsfragments/1904.clarification @@ -1 +1 @@ -Fix the `access_token` parameter in the open_id endpoint. +Fix the ``access_token`` parameter in the open_id endpoint. From 88d47fd57e423c3e2e958fc547f7ef4812eb3ca2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 22:51:52 -0600 Subject: [PATCH 0367/1250] Rename changelog entry to point to PR We use the PR for every other entry, so here is no exception. --- .../newsfragments/{1904.clarification => 1906.clarification} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelogs/server_server/newsfragments/{1904.clarification => 1906.clarification} (100%) diff --git a/changelogs/server_server/newsfragments/1904.clarification b/changelogs/server_server/newsfragments/1906.clarification similarity index 100% rename from changelogs/server_server/newsfragments/1904.clarification rename to changelogs/server_server/newsfragments/1906.clarification From 62890d21b25016dc008a5cc2e2f993ee3a0873ab Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 23:08:02 -0600 Subject: [PATCH 0368/1250] Fix example Content-Type for /media/upload request Fixes https://github.com/matrix-org/matrix-doc/issues/1770 --- api/client-server/content-repo.yaml | 11 ++++++----- .../client_server/newsfragments/2041.clarification | 1 + scripts/templating/matrix_templates/units.py | 9 +++++++-- 3 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2041.clarification diff --git a/api/client-server/content-repo.yaml b/api/client-server/content-repo.yaml index 07df18fe..4460bb69 100644 --- a/api/client-server/content-repo.yaml +++ b/api/client-server/content-repo.yaml @@ -41,7 +41,7 @@ paths: name: Content-Type type: string description: The content type of the file being uploaded - x-example: "Content-Type: audio/mpeg" + x-example: "Content-Type: application/pdf" - in: query type: string x-example: "War and Peace.pdf" @@ -51,6 +51,7 @@ paths: name: "" description: The content to be uploaded. required: true + x-example: "" # so the spec shows "" without quotes. schema: type: string example: "" @@ -103,7 +104,7 @@ paths: default: true description: | Indicates to the server that it should not attempt to fetch the media if it is deemed - remote. This is to prevent routing loops where the server contacts itself. Defaults to + remote. This is to prevent routing loops where the server contacts itself. Defaults to true if not provided. responses: 200: @@ -158,7 +159,7 @@ paths: default: true description: | Indicates to the server that it should not attempt to fetch the media if it is deemed - remote. This is to prevent routing loops where the server contacts itself. Defaults to + remote. This is to prevent routing loops where the server contacts itself. Defaults to true if not provided. responses: 200: @@ -228,7 +229,7 @@ paths: default: true description: | Indicates to the server that it should not attempt to fetch the media if it is deemed - remote. This is to prevent routing loops where the server contacts itself. Defaults to + remote. This is to prevent routing loops where the server contacts itself. Defaults to true if not provided. responses: 200: @@ -330,7 +331,7 @@ paths: m.upload.size: type: integer format: int64 - description: |- + description: |- The maximum size an upload can be in bytes. Clients SHOULD use this as a guide when uploading content. If not listed or null, the size limit should be treated as unknown. diff --git a/changelogs/client_server/newsfragments/2041.clarification b/changelogs/client_server/newsfragments/2041.clarification new file mode 100644 index 00000000..39bbddb5 --- /dev/null +++ b/changelogs/client_server/newsfragments/2041.clarification @@ -0,0 +1 @@ +Fix example ``Content-Type`` for ``/media/upload`` request. diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index 466110f8..d4745e4d 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -521,6 +521,7 @@ class MatrixUnits(Units): path_template = path example_query_params = [] example_body = "" + example_mime = "application/json" for param in endpoint_swagger.get("parameters", []): # even body params should have names, otherwise the active docs don't work. param_name = param["name"] @@ -533,6 +534,10 @@ class MatrixUnits(Units): example_body = get_example_for_param(param) continue + if param_loc == "header": + if param["name"] == "Content-Type" and param["x-example"]: + example_mime = param["x-example"] + # description desc = param.get("description", "") if param.get("required"): @@ -610,8 +615,8 @@ class MatrixUnits(Units): example_query_params) if example_body: endpoint["example"][ - "req"] = "%s %s%s HTTP/1.1\nContent-Type: application/json\n\n%s" % ( - method.upper(), path_template, query_string, example_body + "req"] = "%s %s%s HTTP/1.1\nContent-Type: %s\n\n%s" % ( + method.upper(), path_template, query_string, example_mime, example_body ) else: endpoint["example"]["req"] = "%s %s%s HTTP/1.1\n\n" % ( From 572a6056ad64c5f3f654f91a27cf8a42c19d6ee5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 23:15:02 -0600 Subject: [PATCH 0369/1250] Clarify that login flows must be completed in order Fixes https://github.com/matrix-org/matrix-doc/issues/1134 Evidence of this being the case is shown here: https://github.com/matrix-org/synapse/pull/5174 --- changelogs/client_server/newsfragments/2042.clarification | 1 + specification/client_server_api.rst | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2042.clarification diff --git a/changelogs/client_server/newsfragments/2042.clarification b/changelogs/client_server/newsfragments/2042.clarification new file mode 100644 index 00000000..4e17b99f --- /dev/null +++ b/changelogs/client_server/newsfragments/2042.clarification @@ -0,0 +1 @@ +Clarify that login flows are meant to be completed in order. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index a8bbfca0..4b7065b3 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -406,8 +406,9 @@ an additional stage. This exchange continues until the final success. For each endpoint, a server offers one or more 'flows' that the client can use to authenticate itself. Each flow comprises a series of stages, as described -above. The client is free to choose which flow it follows. When all stages in a -flow are complete, authentication is complete and the API call succeeds. +above. The client is free to choose which flow it follows, however the flow's +stages must be completed in order. When all stages in a flow are complete, +authentication is complete and the API call succeeds. User-interactive API in the REST API <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< From 4e58414b26d9d2bc145393091b7e141574c36450 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 23:20:09 -0600 Subject: [PATCH 0370/1250] Clarify that clients should not ack their own messages Fixes https://github.com/matrix-org/matrix-doc/issues/567 --- changelogs/client_server/newsfragments/2043.clarification | 1 + specification/modules/receipts.rst | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2043.clarification diff --git a/changelogs/client_server/newsfragments/2043.clarification b/changelogs/client_server/newsfragments/2043.clarification new file mode 100644 index 00000000..9bb975fa --- /dev/null +++ b/changelogs/client_server/newsfragments/2043.clarification @@ -0,0 +1 @@ +Clarify that clients should not send read receipts for their own messages. diff --git a/specification/modules/receipts.rst b/specification/modules/receipts.rst index faba7b62..ee2b697a 100644 --- a/specification/modules/receipts.rst +++ b/specification/modules/receipts.rst @@ -60,7 +60,8 @@ Clients should send read receipts when there is some certainty that the event in question has been **displayed** to the user. Simply receiving an event does not provide enough certainty that the user has seen the event. The user SHOULD need to *take some action* such as viewing the room that the event was sent to or -dismissing a notification in order for the event to count as "read". +dismissing a notification in order for the event to count as "read". Clients +SHOULD NOT send read receipts for events sent by their own user. A client can update the markers for its user by interacting with the following HTTP APIs. @@ -94,4 +95,3 @@ Security considerations As receipts are sent outside the context of the event graph, there are no integrity checks performed on the contents of ``m.receipt`` events. - From bf86b4b83ca9ee97ef8bc7edcc17a663996bcffd Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 May 2019 23:42:08 -0600 Subject: [PATCH 0371/1250] Fix incorrect PR reference on changelog --- .../client_server/newsfragments/{1903.feature => 1908.feature} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelogs/client_server/newsfragments/{1903.feature => 1908.feature} (100%) diff --git a/changelogs/client_server/newsfragments/1903.feature b/changelogs/client_server/newsfragments/1908.feature similarity index 100% rename from changelogs/client_server/newsfragments/1903.feature rename to changelogs/client_server/newsfragments/1908.feature From 0580f5120693e2535920f5e57e4218e9467b7d18 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 28 May 2019 12:49:50 -0600 Subject: [PATCH 0372/1250] Clarify that failing to follow the flows == 401 --- specification/client_server_api.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 4b7065b3..3ea1411e 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -407,8 +407,9 @@ an additional stage. This exchange continues until the final success. For each endpoint, a server offers one or more 'flows' that the client can use to authenticate itself. Each flow comprises a series of stages, as described above. The client is free to choose which flow it follows, however the flow's -stages must be completed in order. When all stages in a flow are complete, -authentication is complete and the API call succeeds. +stages must be completed in order. Failing to follow the flows in order must +result in an HTTP 401 response, as defined below. When all stages in a flow +are complete, authentication is complete and the API call succeeds. User-interactive API in the REST API <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< From 8151aa331f6b553ffa755f38aaffb5f5b466b07a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 28 May 2019 12:51:36 -0600 Subject: [PATCH 0373/1250] Update specification/client_server_api.rst Co-Authored-By: Hubert Chathi --- specification/client_server_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index c18f4d03..a8246578 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1534,7 +1534,7 @@ same way a server does. .. NOTE:: Redacted events can still affect the state of the room. When redacted, - state events behave as though their properties were simply not specified + state events behave as though their properties were simply not specified, except those protected by the redaction algorithm. For example, a redacted ``join`` event will still result in the user being considered joined. Similarly, a redacted topic does not necessarily cause the topic to revert to From e2da3728a0631f95bae08f7ceb4a18b695841d3b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 28 May 2019 12:53:48 -0600 Subject: [PATCH 0374/1250] Only error if the token doesn't match --- specification/application_service_api.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specification/application_service_api.rst b/specification/application_service_api.rst index 81077bcf..3220df2d 100644 --- a/specification/application_service_api.rst +++ b/specification/application_service_api.rst @@ -193,7 +193,8 @@ Authorization Homeservers MUST include a query parameter named ``access_token`` containing the ``hs_token`` from the application service's registration when making requests to the application service. Application services MUST verify the provided ``access_token`` -matches their known ``hs_token``, failing the request with a ``M_FORBIDDEN`` error. +matches their known ``hs_token``, failing the request with a ``M_FORBIDDEN`` error +if it does not match. Legacy routes +++++++++++++ From 3ade2a9ae78406c2804d57f4dbda09e0655bcb41 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 28 May 2019 13:56:25 -0600 Subject: [PATCH 0375/1250] List the endpoints which support LL --- specification/client_server_api.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index a4b8dd5c..740023fb 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1300,6 +1300,11 @@ as the current membership event for a user. request to ``/sync`` followed by a request to ``/messages`` may result in a future call to ``/sync`` excluding members included by the ``/messages`` call. +The current endpoints which support lazy-loading room members are: + +* |/sync|_ +* |/rooms//messages|_ +* |/rooms/{roomId}/context/{eventId}|_ {{filter_cs_http_api}} From 551806a8ad797895a53f4555a252f1d59048ae43 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 28 May 2019 13:54:22 -0600 Subject: [PATCH 0376/1250] Add a reference to the filtering module to /sync --- api/client-server/sync.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 2c504295..a9f1f714 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -53,6 +53,8 @@ paths: requests. Creating a filter using the filter API is recommended for clients that reuse the same filter multiple times, for example in long poll requests. + + See `Filtering <#filtering>`_ for more information. x-example: "66696p746572" - in: query name: since From c5fdd5cb0bef008945cde2e915245ade190541c5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 28 May 2019 13:55:37 -0600 Subject: [PATCH 0377/1250] Change note style --- api/client-server/event_context.yaml | 2 +- api/client-server/message_pagination.yaml | 2 +- api/client-server/sync.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/client-server/event_context.yaml b/api/client-server/event_context.yaml index c0f391e5..327c8f43 100644 --- a/api/client-server/event_context.yaml +++ b/api/client-server/event_context.yaml @@ -35,7 +35,7 @@ paths: after the specified event. This allows clients to get the context surrounding an event. - *Note*: this endpoint supports lazy-loading. See `Filtering <#filtering>`_ + *Note*: This endpoint supports lazy-loading. See `Filtering <#filtering>`_ for more information. operationId: getEventContext security: diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index 716afb65..8469eec4 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -34,7 +34,7 @@ paths: This API returns a list of message and state events for a room. It uses pagination query parameters to paginate history in the room. - *Note*: this endpoint supports lazy-loading. See `Filtering <#filtering>`_ + *Note*: This endpoint supports lazy-loading. See `Filtering <#filtering>`_ for more information. operationId: getRoomEvents security: diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index a9f1f714..4fe22d50 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -35,7 +35,7 @@ paths: of the state on the server, and then continue to call this API to get incremental deltas to the state, and to receive new messages. - *Note*: this endpoint supports lazy-loading. See `Filtering <#filtering>`_ + *Note*: This endpoint supports lazy-loading. See `Filtering <#filtering>`_ for more information. Lazy-loading members is only supported on a ``StateFilter`` for this endpoint. operationId: sync From 0463084924543ee5b024adb62ac32ee5339855c5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 28 May 2019 14:19:56 -0600 Subject: [PATCH 0378/1250] Spec 3PID unbind API As per [MSC1915](https://github.com/matrix-org/matrix-doc/pull/1915) Implementation proof: * https://github.com/matrix-org/synapse/pull/4982 * https://github.com/matrix-org/sydent/pull/160 The only alteration made which differs from the proposal is clarity on how to handle homeservers not knowing the `id_server`. All other differences are unintentional. --- api/client-server/administrative_contact.yaml | 27 +++++- api/client-server/registration.yaml | 30 ++++++- api/identity/associations.yaml | 83 +++++++++++++++++++ .../client_server/newsfragments/2046.feature | 1 + .../identity_service/newsfragments/2046.new | 1 + .../1915-unbind-identity-server-param.md | 4 +- 6 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2046.feature create mode 100644 changelogs/identity_service/newsfragments/2046.new diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 33ea9786..5cf01805 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -163,6 +163,14 @@ paths: schema: type: object properties: + id_server: + type: string + description: |- + The identity server to unbind from. If not provided, the homeserver + MUST use the ``id_server`` the identifier was added through. If the + homeserver does not know the original ``id_server``, it MUST return + a ``id_server_unbind_result`` of ``no-support``. + example: "example.org" medium: type: string description: The medium of the third party identifier being removed. @@ -180,7 +188,24 @@ paths: user. schema: type: object - properties: {} + properties: + id_server_unbind_result: + type: string + enum: + # XXX: I don't know why, but the order matters here so that "no-support" + # doesn't become "no- support" by the renderer. + - "no-support" + - "success" + description: |- + An indicator as to whether or not the homeserver was able to unbind + the 3PID from the identity server. ``success`` indicates that the + indentity server has unbound the identifier whereas ``no-support`` + indicates that the identity server refuses to support the request + or the homeserver was not able to determine an identity server to + unbind from. + example: "success" + required: + - id_server_unbind_result tags: - User data "/account/3pid/email/requestToken": diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 3195ab41..f003cf1f 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -524,13 +524,39 @@ paths: description: |- Additional authentication information for the user-interactive authentication API. "$ref": "definitions/auth_data.yaml" + id_server: + type: string + description: |- + The identity server to unbind all of the user's 3PIDs from. + If not provided, the homeserver MUST use the ``id_server`` + that was originally use to bind each identifier. If the + homeserver does not know which ``id_server`` that was, + it must return an ``id_server_unbind_result`` of + ``no-support``. + example: "example.org" responses: 200: description: The account has been deactivated. - examples: - application/json: {} schema: type: object + properties: + id_server_unbind_result: + type: string + enum: + - "success" + - "no-support" + description: |- + An indicator as to whether or not the homeserver was able to unbind + the user's 3PIDs from the identity server(s). ``success`` indicates + that all identifiers have been unbound from the identity server while + ``no-support`` indicates that one or more identifiers failed to unbind + due to the identity server refusing the request or the homeserver + being unable to determine an identity server to unbind from. This + must be ``success`` if the homeserver has no identifiers to unbind + for the user. + example: "success" + required: + - id_server_unbind_result 401: description: |- The homeserver requires additional authentication information. diff --git a/api/identity/associations.yaml b/api/identity/associations.yaml index 152a0a9b..f44fe3cc 100644 --- a/api/identity/associations.yaml +++ b/api/identity/associations.yaml @@ -201,3 +201,86 @@ paths: } schema: $ref: "../client-server/definitions/errors/error.yaml" + "/3pid/unbind": + post: + summary: Remove an association between a session and a Matrix user ID. + description: |- + Remove an association between a session and a Matrix user ID. + + Future calls to ``/lookup`` for any of the session's 3pids will not + return the removed association. + + 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`` parameters, + as per ``/3pid/bind``, which proves ownership of the 3PID. + + If this endpoint returns a JSON Matrix error, that error should be passed + through to the client requesting an unbind through a homeserver, if the + homeserver is acting on behalf of a client. + operationId: unbind + parameters: + - in: body + name: body + schema: + type: object + example: { + "sid": "1234", + "client_secret": "monkeys_are_GREAT", + "mxid": "@ears:example.org", + "threepid": { + "medium": "email", + "address": "monkeys_have_ears@example.org" + } + } + properties: + sid: + type: string + description: The Session ID generated by the ``requestToken`` call. + client_secret: + type: string + description: The client secret passed to the ``requestToken`` call. + mxid: + type: string + description: The Matrix user ID to remove from the 3pids. + threepid: + type: object + title: 3PID + description: |- + The 3PID to remove. Must match the 3PID used to generate the session + if using ``sid`` and ``client_secret`` to authenticate this request. + properties: + medium: + type: string + description: |- + A medium from the `3PID Types`_ Appendix, matching the medium + of the identifier to unbind. + address: + type: string + description: The 3PID address to remove. + required: ['medium', 'address'] + required: ["threepid", "mxid"] + responses: + 200: + description: The association was successfully removed. + examples: + application/json: {} + schema: + type: object + 400: + description: |- + If the response body is not a JSON Matrix error, the identity server + does not support unbinds. If a JSON Matrix error is in the response + body, the requesting party should respect the error. + 404: + description: |- + If the response body is not a JSON Matrix error, the identity server + does not support unbinds. If a JSON Matrix error is in the response + body, the requesting party should respect the error. + 501: + description: |- + If the response body is not a JSON Matrix error, the identity server + does not support unbinds. If a JSON Matrix error is in the response + body, the requesting party should respect the error. diff --git a/changelogs/client_server/newsfragments/2046.feature b/changelogs/client_server/newsfragments/2046.feature new file mode 100644 index 00000000..e54df535 --- /dev/null +++ b/changelogs/client_server/newsfragments/2046.feature @@ -0,0 +1 @@ +Add ``id_server`` to ``/deactivate`` and ``/3pid/delete`` endpoints to unbind from a specific identity server. diff --git a/changelogs/identity_service/newsfragments/2046.new b/changelogs/identity_service/newsfragments/2046.new new file mode 100644 index 00000000..7146799b --- /dev/null +++ b/changelogs/identity_service/newsfragments/2046.new @@ -0,0 +1 @@ +Add ``/3pid/unbind`` for removing 3PIDs. diff --git a/proposals/1915-unbind-identity-server-param.md b/proposals/1915-unbind-identity-server-param.md index 6817ece3..5b7a1a50 100644 --- a/proposals/1915-unbind-identity-server-param.md +++ b/proposals/1915-unbind-identity-server-param.md @@ -27,7 +27,9 @@ 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. +server returns an error then that should be returned to the client. If the homeserver +is unable to determine an `id_server` to use, it should return `no-support` for +the `id_server_unbind_result`. Example: From 84f0d9d7e4467460a9caf9128cd739ddd2fb03b6 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 28 May 2019 20:07:45 -0400 Subject: [PATCH 0379/1250] add clarification --- proposals/1717-key_verification.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/1717-key_verification.md b/proposals/1717-key_verification.md index 6c9e2341..429e3a97 100644 --- a/proposals/1717-key_verification.md +++ b/proposals/1717-key_verification.md @@ -139,7 +139,8 @@ Properties: device, an `m.key.verification.cancel` message with `code` set to `m.accepted` is sent to the other devices - `reason` (string): human-readable reason for cancelling. This should only be - used if the recieving client does not understand the code given. + used if the recieving client does not understand the code given in the `code` + property. Verification methods may define their own additional cancellation codes. Cancellation codes defined in the Matrix spec will begin with `m.`; other From 6706d772c91be7c4ab5c8089f4579695e461ffd4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 29 May 2019 00:46:00 -0600 Subject: [PATCH 0380/1250] Fix test vectors with invalid JSON and signature Fixes https://github.com/matrix-org/matrix-doc/issues/2023 The content hashes appear correct, however applying the algorithm defined in the spec never resulted in the signatures previously demonstrated. --- specification/appendices/test_vectors.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/specification/appendices/test_vectors.rst b/specification/appendices/test_vectors.rst index e2b8fb58..7759fa88 100644 --- a/specification/appendices/test_vectors.rst +++ b/specification/appendices/test_vectors.rst @@ -114,7 +114,7 @@ The event signing algorithm should emit the following signed event: "origin_server_ts": 1000000, "signatures": { "domain": { - "ed25519:1": "2Wptgo4CwmLo/Y8B8qinxApKaCkBG2fjTWB7AbP5Uy+aIbygsSdLOFzvdDjww8zUVKCmI02eP9xtyJxc/cLiBA" + "ed25519:1": "JV2dlZUASAefSdywnyCxzykHlyr7xkKGK7IRir1cF8eYsnONrCSb+GRn7aXXstr1UHKvzYjRXPx0001+boD1Ag" } }, "type": "X", @@ -129,7 +129,7 @@ Given the following event containing redactable content: { "content": { - "body": "Here is the message content", + "body": "Here is the message content" }, "event_id": "$0:domain", "origin": "domain", @@ -149,7 +149,7 @@ The event signing algorithm should emit the following signed event: { "content": { - "body": "Here is the message content", + "body": "Here is the message content" }, "event_id": "$0:domain", "hashes": { @@ -162,7 +162,7 @@ The event signing algorithm should emit the following signed event: "sender": "@u:domain", "signatures": { "domain": { - "ed25519:1": "Wm+VzmOUOz08Ds+0NTWb1d4CZrVsJSikkeRxh6aCcUwu6pNC78FunoD7KNWzqFn241eYHYMGCA5McEiVPdhzBA" + "ed25519:1": "4zc79tH2cU6Y+eg4YbbF7KiDOrnwEDjlhTqIKiH4k7L9zD9XCiomD7x9odL9eEwnyy1144QyMBe8O3HK++GHBg" } }, "unsigned": { From ffb70a2fabd46f5197cf123d6ed8bcd5d613566d Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 29 May 2019 15:01:35 -0400 Subject: [PATCH 0381/1250] fix typo Co-Authored-By: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/1719-olm_unwedging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1719-olm_unwedging.md b/proposals/1719-olm_unwedging.md index c181e3f7..5de6463f 100644 --- a/proposals/1719-olm_unwedging.md +++ b/proposals/1719-olm_unwedging.md @@ -19,7 +19,7 @@ from; the client should not create a new session with another device if it has already created one for that given device in the past 1 hour. Clients may wish to ask the sender of the undecryptable messages to re-send the -message. For exampe, if the undecryptable message was a megolm session, then +message. For example, if the undecryptable message was a megolm session, then the client can send an [`m.room_key_request`](https://matrix.org/docs/spec/client_server/r0.4.0.html#m-room-key-request) message to request that the sender re-send the key. From 6929579360113e4e653e884f7e4cb5bfa68fbbd7 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 29 May 2019 15:18:54 -0400 Subject: [PATCH 0382/1250] add some clarifications --- proposals/1719-olm_unwedging.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/proposals/1719-olm_unwedging.md b/proposals/1719-olm_unwedging.md index 5de6463f..dffdc8b1 100644 --- a/proposals/1719-olm_unwedging.md +++ b/proposals/1719-olm_unwedging.md @@ -1,8 +1,13 @@ # Olm unwedging Olm sessions sometimes get out of sync, resulting in undecryptable messages. -This proposal documents a method for devices to create a new session to replace -the broken session. +This can happen for several reasons. For example, if a user restores their +client state from a backup, the client will be using an old ratchet state +([riot-web#3822](https://github.com/vector-im/riot-web/issues/3822)). Or a +client might expire a one-time key that another client is trying to use +([riot-web#3309](https://github.com/vector-im/riot-web/issues/3309)). This +proposal documents a method for devices to create a new session to replace the +broken session. ## Proposal @@ -18,11 +23,11 @@ the number of new sessions it creates per device that it receives a message from; the client should not create a new session with another device if it has already created one for that given device in the past 1 hour. -Clients may wish to ask the sender of the undecryptable messages to re-send the -message. For example, if the undecryptable message was a megolm session, then -the client can send an -[`m.room_key_request`](https://matrix.org/docs/spec/client_server/r0.4.0.html#m-room-key-request) -message to request that the sender re-send the key. +Clients may wish to take steps to mitigate the loss of the undecryptable +messages. For example, megolm sessions that were sent using the old session +would have been lost, so the client can send +[`m.room_key_request`](https://matrix.org/docs/spec/client_server/latest.html#m-room-key-request) +messages to re-request any megolm sessions that it is unable to decrypt. The spec currently says, "If a client has multiple sessions established with another device, it should use the session from which it last received a From 15b8011f63a687bc8961c881c1dcb73fd4318c6b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 29 May 2019 13:37:58 -0600 Subject: [PATCH 0383/1250] Add missing aesthetic parameters to /store-invite Fixes https://github.com/matrix-org/matrix-doc/issues/2048 --- api/identity/store_invite.yaml | 47 ++++++++++++++++--- .../newsfragments/2049.clarification | 1 + 2 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 changelogs/identity_service/newsfragments/2049.clarification diff --git a/api/identity/store_invite.yaml b/api/identity/store_invite.yaml index 69103294..bca78d7e 100644 --- a/api/identity/store_invite.yaml +++ b/api/identity/store_invite.yaml @@ -50,31 +50,66 @@ paths: requests to ``/_matrix/identity/api/v1/pubkey/ephemeral/isvalid``. Currently, invites may only be issued for 3pids of the ``email`` medium. + + Optional fields in the request should be populated to the best of the + server's ability. Identity servers may use these variables when notifying + the ``address`` of the pending invite for display purposes. operationId: storeInvite parameters: - in: body name: body schema: type: object - example: { - "medium": "email", - "address": "foo@bar.baz", - "room_id": "!something:example.tld", - "sender": "@bob:example.com" - } properties: medium: type: string description: The literal string ``email``. + example: "email" address: type: string description: The email address of the invited user. + example: "foo@example.com" room_id: type: string description: The Matrix room ID to which the user is invited + example: "!something:example.org" sender: type: string description: The Matrix user ID of the inviting user + example: "@bob:example.com" + room_alias: + type: string + description: |- + The Matrix room alias for the room to which the user is + invited. This should be retrieved from the ``m.room.canonical_alias`` + state event. + example: "#somewhere:exmaple.org" + room_avatar_url: + type: string + description: |- + The Content URI for the room to which the user is invited. This should + be retrieved from the ``m.room.avatar`` state event. + example: "mxc://example.org/s0meM3dia" + room_join_rules: + type: string + description: |- + The ``join_rule`` for the room to which the user is invited. This should + be retrieved from the ``m.room.join_rules`` state event. + example: "public" + room_name: + type: string + description: |- + The name of the room to which the user is invited. This should be retrieved + from the ``m.room.name`` state event. + example: "Bob's Emporium of Messages" + sender_display_name: + type: string + description: The display name of the user ID initiating the invite. + example: "Bob Smith" + sender_avatar_url: + type: string + description: The Content URI for the avatar of the user ID initiating the invite. + example: "mxc://example.org/an0th3rM3dia" required: ["medium", "address", "room_id", "sender"] responses: 200: diff --git a/changelogs/identity_service/newsfragments/2049.clarification b/changelogs/identity_service/newsfragments/2049.clarification new file mode 100644 index 00000000..403ac8d0 --- /dev/null +++ b/changelogs/identity_service/newsfragments/2049.clarification @@ -0,0 +1 @@ +Add missing aesthetic parameters to ``/store-invite``. From 78d93432f4cf3fde1cb11af37b95fe16b46bbe0c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 29 May 2019 14:00:34 -0600 Subject: [PATCH 0384/1250] Synchronize proposals_intro.rst and CONTRIBUTING.rst --- CONTRIBUTING.rst | 28 +++++++++++++++------------- specification/proposals_intro.rst | 26 +++++++++++++++++--------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 7a6c6be2..0b814fb9 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -26,10 +26,11 @@ For this to be effective, the APIs need to be present and working correctly in a server before they can be documented in the specification. This process can take some time to complete. -For this reason, we have not found the github pull-request model effective for -discussing changes to the specification. Instead, we have adopted the workflow -as described at https://matrix.org/docs/spec/proposals - *please read this for -details on how to contribute spec changes*. +Changes to the protocol (new endpoints, ideas, etc) need to go through the +`proposals process `_. Other changes, +such as fixing bugs, typos, or clarifying existing behaviour do not need a proposal. +If you're not sure, visit us at `#matrix-spec:matrix.org`_ +and ask. Other changes @@ -51,8 +52,7 @@ following: `_ label. (If there is any doubt about whether it is the spec or the implementations - that need fixing, please discuss it with us first in `#matrix-dev:matrix.org - `_.) + that need fixing, please discuss it with us first in `#matrix-spec:matrix.org`_.) * Clarifications to the specification which do not change the behaviour of Matrix servers or clients in a way which might introduce compatibility @@ -60,14 +60,16 @@ following: `clarification `_ label. - For example, recommendations for UI behaviour do not require a proposal - document. On the other hand, changes to event contents would be best - discussed in a proposal document even though no changes would be necessary to - server implementations. + For example, areas where the specification is unclear do not require a proposal + to fix. On the other hand, introducing new behaviour is best represented by a + proposal. -For such changes, please do just open a `pull request`_. +For such changes, please do just open a `pull request`_. If you're not sure if +your change is covered by the above, please visit `#matrix-spec:matrix.org` and +ask. -.. _pull request: https://help.github.com/articles/about-pull-requests +.. _`pull request`: https://help.github.com/articles/about-pull-requests +.. _`#matrix-spec:matrix.org`: https://matrix.to/#/#matrix-spec:matrix.org Adding to the changelog @@ -96,7 +98,7 @@ the ``newsfragments`` directory. The ``type`` can be one of the following: * ``breaking`` - Used when the change is not backwards compatible. -* ``deprecation`` - Used when deprecating something +* ``deprecation`` - Used when deprecating something. All news fragments must have a brief summary explaining the change in the contents of the file. The summary must end in a full stop to be in line with diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index d95128b7..d492700e 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -13,12 +13,18 @@ Proposals for Spec Changes to Matrix If you are interested in submitting a change to the Matrix Specification, please take note of the following guidelines. -All changes to Specification content require a formal proposal process. This -involves writing a proposal, having it reviewed by everyone, having the -proposal being accepted, then actually having your ideas implemented as -committed changes to the `Specification repository +Most changes to the Specification require a formal proposal. Bug fixes, typos, +and clarifications to existing behaviour do not need proposals - see the +`contributing guide `_ +for more information on what does and does not need a proposal. + +The proposal process involves some technical writing, having it reviewed by +everyone, having the proposal being accepted, then actually having your ideas +implemented as committed changes to the `Specification repository `_. +.. TODO: Replace GH team link with https://matrix.org/foundation or something + Meet the `members of the Core Team `_, a group of individuals tasked with ensuring the spec process is as smooth and painless as @@ -33,14 +39,15 @@ Guiding Principles Proposals **must** act to the greater benefit of the entire Matrix ecosystem, rather than benefiting or privileging any single player or subset of players - -and must not contain any patent encumbered intellectual property. Members of the Core Team pledge to act as -a neutral custodian for Matrix on behalf of the whole ecosystem. +and must not contain any patent encumbered intellectual property. Members of +the Core Team pledge to act as a neutral custodian for Matrix on behalf of the +whole ecosystem. For clarity: the Matrix ecosystem is anyone who uses the Matrix protocol. That includes client users, server admins, client developers, bot developers, -bridge and application service developers, users and admins who are indirectly using Matrix via -3rd party networks which happen to be bridged, server developers, room -moderators and admins, companies/projects building products or services on +bridge and application service developers, users and admins who are indirectly +using Matrix via 3rd party networks which happen to be bridged, server developers, +room moderators and admins, companies/projects building products or services on Matrix, spec contributors, translators, and those who created it in the first place. @@ -242,6 +249,7 @@ Spec PR Merged merged A proposal with Postponed proposal-postponed A proposal that is temporarily blocked or a feature that may not be useful currently but perhaps sometime in the future Closed proposal-closed A proposal which has been reviewed and deemed unsuitable for acceptance +Obsolete obsolete A proposal which has been made obsolete by another proposal or decision elsewhere. =============================== ============================= ==================================== From c25afa663ef619a82b4d7f93f96118974a59d4a0 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 29 May 2019 14:56:42 -0600 Subject: [PATCH 0385/1250] Use consistent event examples throughout the Client-Server API Fixes https://github.com/matrix-org/matrix-doc/issues/1968 --- api/client-server/event_context.yaml | 88 ++++-------- api/client-server/message_pagination.yaml | 39 +---- api/client-server/notifications.yaml | 11 +- api/client-server/old_sync.yaml | 136 ++---------------- api/client-server/peeking_events.yaml | 12 +- api/client-server/room_initial_sync.yaml | 89 +----------- api/client-server/rooms.yaml | 136 +++--------------- api/client-server/search.yaml | 13 +- api/client-server/sync.yaml | 44 ++---- .../newsfragments/2050.clarification | 1 + 10 files changed, 94 insertions(+), 475 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2050.clarification diff --git a/api/client-server/event_context.yaml b/api/client-server/event_context.yaml index 91da3cf4..549902a0 100644 --- a/api/client-server/event_context.yaml +++ b/api/client-server/event_context.yaml @@ -101,65 +101,35 @@ paths: - "$ref": "definitions/event-schemas/schema/core-event-schema/state_event.yaml" examples: application/json: { - "end": "t29-57_2_0_2", - "events_after": [ - { - "age": 91911336, - "content": { - "body": "7", - "msgtype": "m.text" - }, - "event_id": "$14460306086CiUaL:localhost:8480", - "origin_server_ts": 1446030608551, - "room_id": "!sCDvXTtzjpiPxaqkkt:localhost:8480", - "type": "m.room.message", - "sender": "@test:localhost:8480" - } - ], - "events_before": [ - { - "age": 91911903, - "content": { - "body": "5", - "msgtype": "m.text" - }, - "event_id": "$14460306074UYTlh:localhost:8480", - "origin_server_ts": 1446030607984, - "room_id": "!sCDvXTtzjpiPxaqkkt:localhost:8480", - "type": "m.room.message", - "sender": "@test:localhost:8480" - } - ], - "start": "t27-54_2_0_2", - "state": [ - { - "age": 3123715284, - "content": { - "creator": "@test:localhost:8480" - }, - "event_id": "$14429988040dgQAE:localhost:8480", - "origin_server_ts": 1442998804603, - "room_id": "!sCDvXTtzjpiPxaqkkt:localhost:8480", - "state_key": "", - "type": "m.room.create", - "sender": "@test:localhost:8480" - }, - { - "age": 2067105053, - "content": { - "avatar_url": "mxc://localhost:8480/tVWZTAIIfqtXMZZtmGCkVjTD#auto", - "displayname": "Bob2", - "membership": "join" - }, - "event_id": "$14440554144URDbf:localhost:8480", - "origin_server_ts": 1444055414834, - "replaces_state": "$14440552472PgiGk:localhost:8480", - "room_id": "!sCDvXTtzjpiPxaqkkt:localhost:8480", - "state_key": "@test:localhost:8480", - "type": "m.room.member", - "sender": "@test:localhost:8480" - } - ] + "end": "t29-57_2_0_2", + "events_after": [ + { + "room_id": "!636q39766251:example.com", + "$ref": "definitions/event-schemas/examples/m.room.message#m.text" } + ], + "event": { + "event_id": "$f3h4d129462ha:example.com", + "room_id": "!636q39766251:example.com", + "$ref": "definitions/event-schemas/examples/m.room.message#m.image" + }, + "events_before": [ + { + "room_id": "!636q39766251:example.com", + "$ref": "definitions/event-schemas/examples/m.room.message#m.file" + } + ], + "start": "t27-54_2_0_2", + "state": [ + { + "room_id": "!636q39766251:example.com", + "$ref": "definitions/event-schemas/examples/m.room.create" + }, + { + "room_id": "!636q39766251:example.com", + "$ref": "definitions/event-schemas/examples/m.room.member" + } + ] + } tags: - Room participation diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index 941e61fb..f29f1f23 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -114,43 +114,16 @@ paths: "end": "t47409-4357353_219380_26003_2265", "chunk": [ { - "origin_server_ts": 1444812213737, - "sender": "@alice:example.com", - "event_id": "$1444812213350496Caaaa:example.com", - "content": { - "body": "hello world", - "msgtype":"m.text" - }, - "room_id":"!Xq3620DUiqCaoxq:example.com", - "type":"m.room.message", - "age": 1042 + "room_id": "!636q39766251:example.com", + "$ref": "definitions/event-schemas/examples/m.room.message#m.text" }, { - "origin_server_ts": 1444812194656 , - "sender": "@bob:example.com", - "event_id": "$1444812213350496Cbbbb:example.com", - "content": { - "body": "the world is big", - "msgtype":"m.text" - }, - "room_id":"!Xq3620DUiqCaoxq:example.com", - "type":"m.room.message", - "age": 20123 + "room_id": "!636q39766251:example.com", + "$ref": "definitions/event-schemas/examples/m.room.name" }, { - "origin_server_ts": 1444812163990, - "sender": "@bob:example.com", - "event_id": "$1444812213350496Ccccc:example.com", - "content": { - "name": "New room name" - }, - "prev_content": { - "name": "Old room name" - }, - "state_key": "", - "room_id":"!Xq3620DUiqCaoxq:example.com", - "type":"m.room.name", - "age": 50789 + "room_id": "!636q39766251:example.com", + "$ref": "definitions/event-schemas/examples/m.room.message#m.video" } ] } diff --git a/api/client-server/notifications.yaml b/api/client-server/notifications.yaml index b450885b..6d9366be 100644 --- a/api/client-server/notifications.yaml +++ b/api/client-server/notifications.yaml @@ -75,16 +75,7 @@ paths: "room_id": "!abcdefg:example.com", "ts": 1475508881945, "event": { - "sender": "@alice:example.com", - "type": "m.room.message", - "age": 124524, - "txn_id": "1234", - "content": { - "body": "I am a fish", - "msgtype": "m.text" - }, - "origin_server_ts": 1417731086797, - "event_id": "$74686972643033:example.com" + "$ref": "definitions/event-schemas/examples/m.room.message#m.text" } } ] diff --git a/api/client-server/old_sync.yaml b/api/client-server/old_sync.yaml index c502c239..c9b7586b 100644 --- a/api/client-server/old_sync.yaml +++ b/api/client-server/old_sync.yaml @@ -64,18 +64,7 @@ paths: "start": "s3456_9_0", "end": "s3457_9_0", "chunk": [ - { - "age": 32, - "content": { - "body": "incoming message", - "msgtype": "m.text" - }, - "event_id": "$14328055551tzaee:localhost", - "origin_server_ts": 1432804485886, - "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", - "type": "m.room.message", - "sender": "@bob:localhost" - } + {"$ref": "definitions/event-schemas/examples/m.room.message#m.text"} ] } schema: @@ -142,16 +131,7 @@ paths: application/json: { "end": "s3456_9_0", "presence": [ - { - "content": { - "avatar_url": "mxc://localhost/GCmhgzMPRjqgpODLsNQzVuHZ#auto", - "displayname": "Bob", - "last_active_ago": 31053, - "presence": "online", - "user_id": "@bob:localhost" - }, - "type": "m.presence" - } + {"$ref": "definitions/event-schemas/examples/m.presence"} ], "account_data": [ { @@ -167,28 +147,12 @@ paths: "messages": { "chunk": [ { - "age": 343513403, - "content": { - "body": "foo", - "msgtype": "m.text" - }, - "event_id": "$14328044851tzTJS:localhost", - "origin_server_ts": 1432804485886, - "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", - "type": "m.room.message", - "sender": "@alice:localhost" + "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", + "$ref": "definitions/event-schemas/examples/m.room.message#m.text" }, { - "age": 343511809, - "content": { - "body": "bar", - "msgtype": "m.text" - }, - "event_id": "$14328044872spjFg:localhost", - "origin_server_ts": 1432804487480, - "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", - "type": "m.room.message", - "sender": "@bob:localhost" + "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", + "$ref": "definitions/event-schemas/examples/m.room.message#m.video" } ], "end": "s3456_9_0", @@ -197,81 +161,20 @@ paths: "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", "state": [ { - "age": 7148266897, - "content": { - "join_rule": "public" - }, - "event_id": "$14259997323TLwtb:localhost", - "origin_server_ts": 1425999732392, - "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", - "state_key": "", - "type": "m.room.join_rules", - "sender": "@alice:localhost" - }, - { - "age": 6547561012, - "content": { - "avatar_url": "mxc://localhost/fzysBrHpPEeTGANCVLXWXNMI#auto", - "membership": "join" - }, - "event_id": "$1426600438280zExKY:localhost", - "membership": "join", - "origin_server_ts": 1426600438277, - "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", - "state_key": "@alice:localhost", - "type": "m.room.member", - "sender": "@alice:localhost" + "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", + "$ref": "definitions/event-schemas/examples/m.room.join_rules" }, { - "age": 7148267200, - "content": { - "creator": "@alice:localhost" - }, - "event_id": "$14259997320KhbwJ:localhost", - "origin_server_ts": 1425999732089, - "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", - "state_key": "", - "type": "m.room.create", - "sender": "@alice:localhost" + "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", + "$ref": "definitions/event-schemas/examples/m.room.member" }, { - "age": 1622568720, - "content": { - "avatar_url": "mxc://localhost/GCmhgzMPRjqgpODLsNQzVuHZ#auto", - "displayname": "Bob", - "membership": "join" - }, - "event_id": "$1431525430134MxlLX:localhost", - "origin_server_ts": 1431525430569, - "replaces_state": "$142652023736BSXcM:localhost", - "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", - "state_key": "@bob:localhost", - "type": "m.room.member", - "sender": "@bob:localhost" + "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", + "$ref": "definitions/event-schemas/examples/m.room.create" }, { - "age": 7148267004, - "content": { - "ban": 50, - "events": { - "m.room.name": 100, - "m.room.power_levels": 100 - }, - "events_default": 0, - "kick": 50, - "redact": 50, - "state_default": 50, - "users": { - "@alice:localhost": 100 - }, - "users_default": 0 - }, - "event_id": "$14259997322mqfaq:localhost", - "origin_server_ts": 1425999732285, - "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", - "state_key": "", - "type": "m.room.power_levels", - "sender": "@alice:localhost" + "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", + "$ref": "definitions/event-schemas/examples/m.room.power_levels" } ], "visibility": "private", @@ -423,16 +326,7 @@ paths: 200: description: The full event. examples: - application/json: { - "content": { - "body": "Hello world!", - "msgtype": "m.text" - }, - "room_id": "!wfgy43Sg4a:matrix.org", - "sender": "@bob:matrix.org", - "event_id": "$asfDuShaf7Gafaw:matrix.org", - "type": "m.room.message" - } + application/json: {"$ref": "definitions/event-schemas/examples/m.room.message#m.text"} schema: allOf: - "$ref": "definitions/event-schemas/schema/core-event-schema/event.yaml" diff --git a/api/client-server/peeking_events.yaml b/api/client-server/peeking_events.yaml index 2f66bae7..e3dc5777 100644 --- a/api/client-server/peeking_events.yaml +++ b/api/client-server/peeking_events.yaml @@ -75,16 +75,8 @@ paths: "end": "s3457_9_0", "chunk": [ { - "age": 32, - "content": { - "body": "incoming message", - "msgtype": "m.text" - }, - "event_id": "$14328055551tzaee:localhost", - "origin_server_ts": 1432804485886, - "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", - "type": "m.room.message", - "sender": "@bob:localhost" + "room_id": "!somewhere:over.the.rainbow", + "$ref": "definitions/event-schemas/examples/m.room.message#m.text" } ] } diff --git a/api/client-server/room_initial_sync.yaml b/api/client-server/room_initial_sync.yaml index c27f0f24..2a354fc0 100644 --- a/api/client-server/room_initial_sync.yaml +++ b/api/client-server/room_initial_sync.yaml @@ -43,28 +43,12 @@ paths: "messages": { "chunk": [ { - "age": 343513403, - "content": { - "body": "foo", - "msgtype": "m.text" - }, - "event_id": "$14328044851tzTJS:example.com", - "origin_server_ts": 1432804485886, "room_id": "!636q39766251:example.com", - "type": "m.room.message", - "sender": "@alice:example.com" + "$ref": "definitions/event-schemas/examples/m.room.message#m.text" }, { - "age": 343511809, - "content": { - "body": "bar", - "msgtype": "m.text" - }, - "event_id": "$14328044872spjFg:example.com", - "origin_server_ts": 1432804487480, "room_id": "!636q39766251:example.com", - "type": "m.room.message", - "sender": "@bob:example.com" + "$ref": "definitions/event-schemas/examples/m.room.message#m.file" } ], "end": "s3456_9_0", @@ -73,81 +57,20 @@ paths: "room_id": "!636q39766251:example.com", "state": [ { - "age": 7148266897, - "content": { - "join_rule": "public" - }, - "event_id": "$14259997323TLwtb:example.com", - "origin_server_ts": 1425999732392, - "room_id": "!636q39766251:example.com", - "state_key": "", - "type": "m.room.join_rules", - "sender": "@alice:example.com" - }, - { - "age": 6547561012, - "content": { - "avatar_url": "mxc://example.com/fzysBrHpPEeTGANCVLXWXNMI#auto", - "membership": "join" - }, - "event_id": "$1426600438280zExKY:example.com", - "membership": "join", - "origin_server_ts": 1426600438277, "room_id": "!636q39766251:example.com", - "state_key": "@alice:example.com", - "type": "m.room.member", - "sender": "@alice:example.com" + "$ref": "definitions/event-schemas/examples/m.room.join_rules" }, { - "age": 7148267200, - "content": { - "creator": "@alice:example.com" - }, - "event_id": "$14259997320KhbwJ:example.com", - "origin_server_ts": 1425999732089, "room_id": "!636q39766251:example.com", - "state_key": "", - "type": "m.room.create", - "sender": "@alice:example.com" + "$ref": "definitions/event-schemas/examples/m.room.member" }, { - "age": 1622568720, - "content": { - "avatar_url": "mxc://example.com/GCmhgzMPRjqgpODLsNQzVuHZ#auto", - "displayname": "Bob", - "membership": "join" - }, - "event_id": "$1431525430134MxlLX:example.com", - "origin_server_ts": 1431525430569, - "replaces_state": "$142652023736BSXcM:example.com", "room_id": "!636q39766251:example.com", - "state_key": "@bob:example.com", - "type": "m.room.member", - "sender": "@bob:example.com" + "$ref": "definitions/event-schemas/examples/m.room.create" }, { - "age": 7148267004, - "content": { - "ban": 50, - "events": { - "m.room.name": 100, - "m.room.power_levels": 100 - }, - "events_default": 0, - "kick": 50, - "redact": 50, - "state_default": 50, - "users": { - "@alice:example.com": 100 - }, - "users_default": 0 - }, - "event_id": "$14259997322mqfaq:example.com", - "origin_server_ts": 1425999732285, "room_id": "!636q39766251:example.com", - "state_key": "", - "type": "m.room.power_levels", - "sender": "@alice:example.com" + "$ref": "definitions/event-schemas/examples/m.room.power_levels" } ], "visibility": "private", diff --git a/api/client-server/rooms.yaml b/api/client-server/rooms.yaml index cc1f2bf7..55456436 100644 --- a/api/client-server/rooms.yaml +++ b/api/client-server/rooms.yaml @@ -42,7 +42,7 @@ paths: name: roomId description: The ID of the room the event is in. required: true - x-example: "!asfDuShaf7Gafaw:matrix.org" + x-example: "!636q39766251:matrix.org" - in: path type: string name: eventId @@ -54,15 +54,9 @@ paths: description: The full event. examples: application/json: { - "content": { - "body": "Hello world!", - "msgtype": "m.text" - }, - "room_id": "!wfgy43Sg4a:matrix.org", - "sender": "@bob:matrix.org", - "event_id": "$asfDuShaf7Gafaw:matrix.org", - "type": "m.room.message" - } + "room_id": "!636q39766251:matrix.org", + "$ref": "definitions/event-schemas/examples/m.room.message#m.text" + } schema: allOf: - "$ref": "definitions/event-schemas/schema/core-event-schema/event.yaml" @@ -178,84 +172,23 @@ paths: description: The current state of the room examples: application/json: [ - { - "age": 7148266897, - "content": { - "join_rule": "public" - }, - "event_id": "$14259997323TLwtb:example.com", - "origin_server_ts": 1425999732392, - "room_id": "!636q39766251:example.com", - "state_key": "", - "type": "m.room.join_rules", - "sender": "@alice:example.com" - }, - { - "age": 6547561012, - "content": { - "avatar_url": "mxc://example.com/fzysBrHpPEeTGANCVLXWXNMI#auto", - "membership": "join" - }, - "event_id": "$1426600438280zExKY:example.com", - "membership": "join", - "origin_server_ts": 1426600438277, - "room_id": "!636q39766251:example.com", - "state_key": "@alice:example.com", - "type": "m.room.member", - "sender": "@alice:example.com" - }, - { - "age": 7148267200, - "content": { - "creator": "@alice:example.com" - }, - "event_id": "$14259997320KhbwJ:example.com", - "origin_server_ts": 1425999732089, - "room_id": "!636q39766251:example.com", - "state_key": "", - "type": "m.room.create", - "sender": "@alice:example.com" - }, - { - "age": 1622568720, - "content": { - "avatar_url": "mxc://example.com/GCmhgzMPRjqgpODLsNQzVuHZ#auto", - "displayname": "Bob", - "membership": "join" - }, - "event_id": "$1431525430134MxlLX:example.com", - "origin_server_ts": 1431525430569, - "replaces_state": "$142652023736BSXcM:example.com", - "room_id": "!636q39766251:example.com", - "state_key": "@bob:example.com", - "type": "m.room.member", - "sender": "@bob:example.com" - }, - { - "age": 7148267004, - "content": { - "ban": 50, - "events": { - "m.room.name": 100, - "m.room.power_levels": 100 - }, - "events_default": 0, - "kick": 50, - "redact": 50, - "state_default": 50, - "users": { - "@alice:example.com": 100 - }, - "users_default": 0 - }, - "event_id": "$14259997322mqfaq:example.com", - "origin_server_ts": 1425999732285, - "room_id": "!636q39766251:example.com", - "state_key": "", - "type": "m.room.power_levels", - "sender": "@alice:example.com" - } - ] + { + "room_id": "!636q39766251:example.com", + "$ref": "definitions/event-schemas/examples/m.room.join_rules" + }, + { + "room_id": "!636q39766251:example.com", + "$ref": "definitions/event-schemas/examples/m.room.member" + }, + { + "room_id": "!636q39766251:example.com", + "$ref": "definitions/event-schemas/examples/m.room.create" + }, + { + "room_id": "!636q39766251:example.com", + "$ref": "definitions/event-schemas/examples/m.room.power_levels" + } + ] schema: type: array title: RoomState @@ -300,33 +233,8 @@ paths: application/json: { "chunk": [ { - "age": 6547561012, - "content": { - "avatar_url": "mxc://example.com/fzysBrHpPEeTGANCVLXWXNMI#auto", - "membership": "join" - }, - "event_id": "$1426600438280zExKY:example.com", - "membership": "join", - "origin_server_ts": 1426600438277, - "room_id": "!636q39766251:example.com", - "state_key": "@alice:example.com", - "type": "m.room.member", - "sender": "@alice:example.com" - }, - { - "age": 1622568720, - "content": { - "avatar_url": "mxc://example.com/GCmhgzMPRjqgpODLsNQzVuHZ#auto", - "displayname": "Bob", - "membership": "join" - }, - "event_id": "$1431525430134MxlLX:example.com", - "origin_server_ts": 1431525430569, - "replaces_state": "$142652023736BSXcM:example.com", "room_id": "!636q39766251:example.com", - "state_key": "@bob:example.com", - "type": "m.room.member", - "sender": "@bob:example.com" + "$ref": "definitions/event-schemas/examples/m.room.member" } ] } diff --git a/api/client-server/search.yaml b/api/client-server/search.yaml index 4a5f4515..9d5d2074 100644 --- a/api/client-server/search.yaml +++ b/api/client-server/search.yaml @@ -280,7 +280,7 @@ paths: Any groups that were requested. The outer ``string`` key is the group key requested (eg: ``room_id`` - or ``sender``). The inner ``string`` key is the grouped value (eg: + or ``sender``). The inner ``string`` key is the grouped value (eg: a room's ID or a user's ID). additionalProperties: type: object @@ -347,16 +347,9 @@ paths: { "rank": 0.00424866, "result": { - "age": 526228296, - "content": { - "body": "Test content martians and men", - "msgtype": "m.text" - }, - "event_id": "$144429830826TWwbB:localhost", - "origin_server_ts": 1444298308034, "room_id": "!qPewotXpIctQySfjSy:localhost", - "type": "m.room.message", - "sender": "@test:localhost" + "event_id": "$144429830826TWwbB:localhost", + "$ref": "definitions/event-schemas/examples/m.room.message#m.text" } } ] diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index f204152a..ad5a6075 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -310,11 +310,7 @@ paths: "next_batch": "s72595_4483_1934", "presence": { "events": [ - { - "sender": "@alice:example.com", - "type": "m.presence", - "content": {"presence": "online"} - } + {"$ref": "definitions/event-schemas/examples/m.presence"} ] }, "account_data": { @@ -333,36 +329,20 @@ paths: "state": { "events": [ { - "sender": "@alice:example.com", - "type": "m.room.member", - "state_key": "@alice:example.com", - "content": {"membership": "join"}, - "origin_server_ts": 1417731086795, - "event_id": "$66697273743031:example.com" + "room_id": "!726s6s6q:example.com", + "$ref": "definitions/event-schemas/examples/m.room.member" } ] }, "timeline": { "events": [ { - "sender": "@bob:example.com", - "type": "m.room.member", - "state_key": "@bob:example.com", - "content": {"membership": "join"}, - "prev_content": {"membership": "invite"}, - "origin_server_ts": 1417731086795, - "event_id": "$7365636s6r6432:example.com" + "room_id": "!726s6s6q:example.com", + "$ref": "definitions/event-schemas/examples/m.room.member" }, { - "sender": "@alice:example.com", - "type": "m.room.message", - "txn_id": "1234", - "content": { - "body": "I am a fish", - "msgtype": "m.text" - }, - "origin_server_ts": 1417731086797, - "event_id": "$74686972643033:example.com" + "room_id": "!726s6s6q:example.com", + "$ref": "definitions/event-schemas/examples/m.room.message#m.text" } ], "limited": true, @@ -370,18 +350,12 @@ paths: }, "ephemeral": { "events": [ - { - "type": "m.typing", - "content": {"user_ids": ["@alice:example.com"]} - } + {"$ref": "definitions/event-schemas/examples/m.typing"} ] }, "account_data": { "events": [ - { - "type": "m.tag", - "content": {"tags": {"work": {"order": 1}}} - }, + {"$ref": "definitions/event-schemas/examples/m.tag"}, { "type": "org.example.custom.room.config", "content": { diff --git a/changelogs/client_server/newsfragments/2050.clarification b/changelogs/client_server/newsfragments/2050.clarification new file mode 100644 index 00000000..384daa11 --- /dev/null +++ b/changelogs/client_server/newsfragments/2050.clarification @@ -0,0 +1 @@ +Use consistent examples of events throughout the specification. From d6d74c4cbef04e194826cf3565b21bf5959a7d31 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 29 May 2019 15:23:45 -0600 Subject: [PATCH 0386/1250] Switch to using $ instead of # for sub-types # is reserved by the swagger validator as a way to include partial content from a JSON object (eg: "#/path" would include {"test": true} from the object {"path":{"test":true}}). Instead of trying to convince the validator that it is wrong, we'll just use a different character. Note that our rendering tools do not care about #-style references to objects. It's still somewhat worth changing the character though. --- api/application-service/transactions.yaml | 2 +- api/client-server/event_context.yaml | 6 +++--- api/client-server/message_pagination.yaml | 4 ++-- api/client-server/notifications.yaml | 2 +- api/client-server/old_sync.yaml | 8 ++++---- api/client-server/peeking_events.yaml | 2 +- api/client-server/room_initial_sync.yaml | 4 ++-- api/client-server/rooms.yaml | 2 +- api/client-server/search.yaml | 2 +- api/client-server/sync.yaml | 2 +- event-schemas/check_examples.py | 4 ++-- ....encrypted#megolm => m.room.encrypted$megolm} | 0 ...m.room.encrypted#olm => m.room.encrypted$olm} | 0 ...oom_state => m.room.member$invite_room_state} | 0 ...y_invite => m.room.member$third_party_invite} | 0 ...om.message#m.audio => m.room.message$m.audio} | 2 +- ...om.message#m.emote => m.room.message$m.emote} | 0 ...room.message#m.file => m.room.message$m.file} | 0 ...om.message#m.image => m.room.message$m.image} | 0 ...sage#m.location => m.room.message$m.location} | 0 ....message#m.notice => m.room.message$m.notice} | 0 ...ver_notice => m.room.message$m.server_notice} | 0 ...room.message#m.text => m.room.message$m.text} | 0 ...om.message#m.video => m.room.message$m.video} | 0 ...request => m.room_key_request$cancel_request} | 0 ...equest#request => m.room_key_request$request} | 0 ...om.message#m.audio => m.room.message$m.audio} | 0 ...om.message#m.emote => m.room.message$m.emote} | 0 ...room.message#m.file => m.room.message$m.file} | 0 ...om.message#m.image => m.room.message$m.image} | 0 ...sage#m.location => m.room.message$m.location} | 0 ....message#m.notice => m.room.message$m.notice} | 0 ...ver_notice => m.room.message$m.server_notice} | 0 ...room.message#m.text => m.room.message$m.text} | 0 ...om.message#m.video => m.room.message$m.video} | 0 scripts/templating/matrix_templates/sections.py | 16 ++++++++-------- scripts/templating/matrix_templates/units.py | 2 +- 37 files changed, 29 insertions(+), 29 deletions(-) rename event-schemas/examples/{m.room.encrypted#megolm => m.room.encrypted$megolm} (100%) rename event-schemas/examples/{m.room.encrypted#olm => m.room.encrypted$olm} (100%) rename event-schemas/examples/{m.room.member#invite_room_state => m.room.member$invite_room_state} (100%) rename event-schemas/examples/{m.room.member#third_party_invite => m.room.member$third_party_invite} (100%) rename event-schemas/examples/{m.room.message#m.audio => m.room.message$m.audio} (99%) rename event-schemas/examples/{m.room.message#m.emote => m.room.message$m.emote} (100%) rename event-schemas/examples/{m.room.message#m.file => m.room.message$m.file} (100%) rename event-schemas/examples/{m.room.message#m.image => m.room.message$m.image} (100%) rename event-schemas/examples/{m.room.message#m.location => m.room.message$m.location} (100%) rename event-schemas/examples/{m.room.message#m.notice => m.room.message$m.notice} (100%) rename event-schemas/examples/{m.room.message#m.server_notice => m.room.message$m.server_notice} (100%) rename event-schemas/examples/{m.room.message#m.text => m.room.message$m.text} (100%) rename event-schemas/examples/{m.room.message#m.video => m.room.message$m.video} (100%) rename event-schemas/examples/{m.room_key_request#cancel_request => m.room_key_request$cancel_request} (100%) rename event-schemas/examples/{m.room_key_request#request => m.room_key_request$request} (100%) rename event-schemas/schema/{m.room.message#m.audio => m.room.message$m.audio} (100%) rename event-schemas/schema/{m.room.message#m.emote => m.room.message$m.emote} (100%) rename event-schemas/schema/{m.room.message#m.file => m.room.message$m.file} (100%) rename event-schemas/schema/{m.room.message#m.image => m.room.message$m.image} (100%) rename event-schemas/schema/{m.room.message#m.location => m.room.message$m.location} (100%) rename event-schemas/schema/{m.room.message#m.notice => m.room.message$m.notice} (100%) rename event-schemas/schema/{m.room.message#m.server_notice => m.room.message$m.server_notice} (100%) rename event-schemas/schema/{m.room.message#m.text => m.room.message$m.text} (100%) rename event-schemas/schema/{m.room.message#m.video => m.room.message$m.video} (100%) diff --git a/api/application-service/transactions.yaml b/api/application-service/transactions.yaml index 98181196..09f15276 100644 --- a/api/application-service/transactions.yaml +++ b/api/application-service/transactions.yaml @@ -56,7 +56,7 @@ paths: example: { "events": [ {"$ref": "../../event-schemas/examples/m.room.member"}, - {"$ref": "../../event-schemas/examples/m.room.message#m.text"} + {"$ref": "../../event-schemas/examples/m.room.message$m.text"} ] } description: Transaction information diff --git a/api/client-server/event_context.yaml b/api/client-server/event_context.yaml index 549902a0..e2018028 100644 --- a/api/client-server/event_context.yaml +++ b/api/client-server/event_context.yaml @@ -105,18 +105,18 @@ paths: "events_after": [ { "room_id": "!636q39766251:example.com", - "$ref": "definitions/event-schemas/examples/m.room.message#m.text" + "$ref": "definitions/event-schemas/examples/m.room.message$m.text" } ], "event": { "event_id": "$f3h4d129462ha:example.com", "room_id": "!636q39766251:example.com", - "$ref": "definitions/event-schemas/examples/m.room.message#m.image" + "$ref": "definitions/event-schemas/examples/m.room.message$m.image" }, "events_before": [ { "room_id": "!636q39766251:example.com", - "$ref": "definitions/event-schemas/examples/m.room.message#m.file" + "$ref": "definitions/event-schemas/examples/m.room.message$m.file" } ], "start": "t27-54_2_0_2", diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index f29f1f23..c9f9d0ae 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -115,7 +115,7 @@ paths: "chunk": [ { "room_id": "!636q39766251:example.com", - "$ref": "definitions/event-schemas/examples/m.room.message#m.text" + "$ref": "definitions/event-schemas/examples/m.room.message$m.text" }, { "room_id": "!636q39766251:example.com", @@ -123,7 +123,7 @@ paths: }, { "room_id": "!636q39766251:example.com", - "$ref": "definitions/event-schemas/examples/m.room.message#m.video" + "$ref": "definitions/event-schemas/examples/m.room.message$m.video" } ] } diff --git a/api/client-server/notifications.yaml b/api/client-server/notifications.yaml index 6d9366be..87341d41 100644 --- a/api/client-server/notifications.yaml +++ b/api/client-server/notifications.yaml @@ -75,7 +75,7 @@ paths: "room_id": "!abcdefg:example.com", "ts": 1475508881945, "event": { - "$ref": "definitions/event-schemas/examples/m.room.message#m.text" + "$ref": "definitions/event-schemas/examples/m.room.message$m.text" } } ] diff --git a/api/client-server/old_sync.yaml b/api/client-server/old_sync.yaml index c9b7586b..a79c3b32 100644 --- a/api/client-server/old_sync.yaml +++ b/api/client-server/old_sync.yaml @@ -64,7 +64,7 @@ paths: "start": "s3456_9_0", "end": "s3457_9_0", "chunk": [ - {"$ref": "definitions/event-schemas/examples/m.room.message#m.text"} + {"$ref": "definitions/event-schemas/examples/m.room.message$m.text"} ] } schema: @@ -148,11 +148,11 @@ paths: "chunk": [ { "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", - "$ref": "definitions/event-schemas/examples/m.room.message#m.text" + "$ref": "definitions/event-schemas/examples/m.room.message$m.text" }, { "room_id": "!TmaZBKYIFrIPVGoUYp:localhost", - "$ref": "definitions/event-schemas/examples/m.room.message#m.video" + "$ref": "definitions/event-schemas/examples/m.room.message$m.video" } ], "end": "s3456_9_0", @@ -326,7 +326,7 @@ paths: 200: description: The full event. examples: - application/json: {"$ref": "definitions/event-schemas/examples/m.room.message#m.text"} + application/json: {"$ref": "definitions/event-schemas/examples/m.room.message$m.text"} schema: allOf: - "$ref": "definitions/event-schemas/schema/core-event-schema/event.yaml" diff --git a/api/client-server/peeking_events.yaml b/api/client-server/peeking_events.yaml index e3dc5777..feac36f4 100644 --- a/api/client-server/peeking_events.yaml +++ b/api/client-server/peeking_events.yaml @@ -76,7 +76,7 @@ paths: "chunk": [ { "room_id": "!somewhere:over.the.rainbow", - "$ref": "definitions/event-schemas/examples/m.room.message#m.text" + "$ref": "definitions/event-schemas/examples/m.room.message$m.text" } ] } diff --git a/api/client-server/room_initial_sync.yaml b/api/client-server/room_initial_sync.yaml index 2a354fc0..72e56ba9 100644 --- a/api/client-server/room_initial_sync.yaml +++ b/api/client-server/room_initial_sync.yaml @@ -44,11 +44,11 @@ paths: "chunk": [ { "room_id": "!636q39766251:example.com", - "$ref": "definitions/event-schemas/examples/m.room.message#m.text" + "$ref": "definitions/event-schemas/examples/m.room.message$m.text" }, { "room_id": "!636q39766251:example.com", - "$ref": "definitions/event-schemas/examples/m.room.message#m.file" + "$ref": "definitions/event-schemas/examples/m.room.message$m.file" } ], "end": "s3456_9_0", diff --git a/api/client-server/rooms.yaml b/api/client-server/rooms.yaml index 55456436..377783c6 100644 --- a/api/client-server/rooms.yaml +++ b/api/client-server/rooms.yaml @@ -55,7 +55,7 @@ paths: examples: application/json: { "room_id": "!636q39766251:matrix.org", - "$ref": "definitions/event-schemas/examples/m.room.message#m.text" + "$ref": "definitions/event-schemas/examples/m.room.message$m.text" } schema: allOf: diff --git a/api/client-server/search.yaml b/api/client-server/search.yaml index 9d5d2074..4fe72d5b 100644 --- a/api/client-server/search.yaml +++ b/api/client-server/search.yaml @@ -349,7 +349,7 @@ paths: "result": { "room_id": "!qPewotXpIctQySfjSy:localhost", "event_id": "$144429830826TWwbB:localhost", - "$ref": "definitions/event-schemas/examples/m.room.message#m.text" + "$ref": "definitions/event-schemas/examples/m.room.message$m.text" } } ] diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index ad5a6075..02fddb84 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -342,7 +342,7 @@ paths: }, { "room_id": "!726s6s6q:example.com", - "$ref": "definitions/event-schemas/examples/m.room.message#m.text" + "$ref": "definitions/event-schemas/examples/m.room.message$m.text" } ], "limited": true, diff --git a/event-schemas/check_examples.py b/event-schemas/check_examples.py index 3e536ec3..2baa3ef0 100755 --- a/event-schemas/check_examples.py +++ b/event-schemas/check_examples.py @@ -112,8 +112,8 @@ def check_example_dir(exampledir, schemadir): continue examplepath = os.path.join(root, filename) schemapath = examplepath.replace(exampledir, schemadir) - if schemapath.find("#") >= 0: - schemapath = schemapath[:schemapath.find("#")] + if schemapath.find("$") >= 0: + schemapath = schemapath[:schemapath.find("$")] try: check_example_file(examplepath, schemapath) except Exception as e: diff --git a/event-schemas/examples/m.room.encrypted#megolm b/event-schemas/examples/m.room.encrypted$megolm similarity index 100% rename from event-schemas/examples/m.room.encrypted#megolm rename to event-schemas/examples/m.room.encrypted$megolm diff --git a/event-schemas/examples/m.room.encrypted#olm b/event-schemas/examples/m.room.encrypted$olm similarity index 100% rename from event-schemas/examples/m.room.encrypted#olm rename to event-schemas/examples/m.room.encrypted$olm diff --git a/event-schemas/examples/m.room.member#invite_room_state b/event-schemas/examples/m.room.member$invite_room_state similarity index 100% rename from event-schemas/examples/m.room.member#invite_room_state rename to event-schemas/examples/m.room.member$invite_room_state diff --git a/event-schemas/examples/m.room.member#third_party_invite b/event-schemas/examples/m.room.member$third_party_invite similarity index 100% rename from event-schemas/examples/m.room.member#third_party_invite rename to event-schemas/examples/m.room.member$third_party_invite diff --git a/event-schemas/examples/m.room.message#m.audio b/event-schemas/examples/m.room.message$m.audio similarity index 99% rename from event-schemas/examples/m.room.message#m.audio rename to event-schemas/examples/m.room.message$m.audio index 2f743d49..58e874e0 100644 --- a/event-schemas/examples/m.room.message#m.audio +++ b/event-schemas/examples/m.room.message$m.audio @@ -11,4 +11,4 @@ }, "msgtype": "m.audio" } -} +} diff --git a/event-schemas/examples/m.room.message#m.emote b/event-schemas/examples/m.room.message$m.emote similarity index 100% rename from event-schemas/examples/m.room.message#m.emote rename to event-schemas/examples/m.room.message$m.emote diff --git a/event-schemas/examples/m.room.message#m.file b/event-schemas/examples/m.room.message$m.file similarity index 100% rename from event-schemas/examples/m.room.message#m.file rename to event-schemas/examples/m.room.message$m.file diff --git a/event-schemas/examples/m.room.message#m.image b/event-schemas/examples/m.room.message$m.image similarity index 100% rename from event-schemas/examples/m.room.message#m.image rename to event-schemas/examples/m.room.message$m.image diff --git a/event-schemas/examples/m.room.message#m.location b/event-schemas/examples/m.room.message$m.location similarity index 100% rename from event-schemas/examples/m.room.message#m.location rename to event-schemas/examples/m.room.message$m.location diff --git a/event-schemas/examples/m.room.message#m.notice b/event-schemas/examples/m.room.message$m.notice similarity index 100% rename from event-schemas/examples/m.room.message#m.notice rename to event-schemas/examples/m.room.message$m.notice diff --git a/event-schemas/examples/m.room.message#m.server_notice b/event-schemas/examples/m.room.message$m.server_notice similarity index 100% rename from event-schemas/examples/m.room.message#m.server_notice rename to event-schemas/examples/m.room.message$m.server_notice diff --git a/event-schemas/examples/m.room.message#m.text b/event-schemas/examples/m.room.message$m.text similarity index 100% rename from event-schemas/examples/m.room.message#m.text rename to event-schemas/examples/m.room.message$m.text diff --git a/event-schemas/examples/m.room.message#m.video b/event-schemas/examples/m.room.message$m.video similarity index 100% rename from event-schemas/examples/m.room.message#m.video rename to event-schemas/examples/m.room.message$m.video diff --git a/event-schemas/examples/m.room_key_request#cancel_request b/event-schemas/examples/m.room_key_request$cancel_request similarity index 100% rename from event-schemas/examples/m.room_key_request#cancel_request rename to event-schemas/examples/m.room_key_request$cancel_request diff --git a/event-schemas/examples/m.room_key_request#request b/event-schemas/examples/m.room_key_request$request similarity index 100% rename from event-schemas/examples/m.room_key_request#request rename to event-schemas/examples/m.room_key_request$request diff --git a/event-schemas/schema/m.room.message#m.audio b/event-schemas/schema/m.room.message$m.audio similarity index 100% rename from event-schemas/schema/m.room.message#m.audio rename to event-schemas/schema/m.room.message$m.audio diff --git a/event-schemas/schema/m.room.message#m.emote b/event-schemas/schema/m.room.message$m.emote similarity index 100% rename from event-schemas/schema/m.room.message#m.emote rename to event-schemas/schema/m.room.message$m.emote diff --git a/event-schemas/schema/m.room.message#m.file b/event-schemas/schema/m.room.message$m.file similarity index 100% rename from event-schemas/schema/m.room.message#m.file rename to event-schemas/schema/m.room.message$m.file diff --git a/event-schemas/schema/m.room.message#m.image b/event-schemas/schema/m.room.message$m.image similarity index 100% rename from event-schemas/schema/m.room.message#m.image rename to event-schemas/schema/m.room.message$m.image diff --git a/event-schemas/schema/m.room.message#m.location b/event-schemas/schema/m.room.message$m.location similarity index 100% rename from event-schemas/schema/m.room.message#m.location rename to event-schemas/schema/m.room.message$m.location diff --git a/event-schemas/schema/m.room.message#m.notice b/event-schemas/schema/m.room.message$m.notice similarity index 100% rename from event-schemas/schema/m.room.message#m.notice rename to event-schemas/schema/m.room.message$m.notice diff --git a/event-schemas/schema/m.room.message#m.server_notice b/event-schemas/schema/m.room.message$m.server_notice similarity index 100% rename from event-schemas/schema/m.room.message#m.server_notice rename to event-schemas/schema/m.room.message$m.server_notice diff --git a/event-schemas/schema/m.room.message#m.text b/event-schemas/schema/m.room.message$m.text similarity index 100% rename from event-schemas/schema/m.room.message#m.text rename to event-schemas/schema/m.room.message$m.text diff --git a/event-schemas/schema/m.room.message#m.video b/event-schemas/schema/m.room.message$m.video similarity index 100% rename from event-schemas/schema/m.room.message#m.video rename to event-schemas/schema/m.room.message$m.video diff --git a/scripts/templating/matrix_templates/sections.py b/scripts/templating/matrix_templates/sections.py index 92afa5ff..c88959ed 100644 --- a/scripts/templating/matrix_templates/sections.py +++ b/scripts/templating/matrix_templates/sections.py @@ -115,7 +115,7 @@ class MatrixSections(Sections): schemas = self.units.get("event_schemas") renders = {} for event_type in schemas: - underscored_event_type = event_type.replace(".", "_").replace("#", "_") + underscored_event_type = event_type.replace(".", "_").replace("$", "_") renders[underscored_event_type + "_event"] = self._render_events( lambda x: x == event_type, sorted ) @@ -125,7 +125,7 @@ class MatrixSections(Sections): def filterFn(eventType): return ( eventType.startswith("m.room") and - not eventType.startswith("m.room.message#m.") + not eventType.startswith("m.room.message$m.") ) return self._render_events(filterFn, sorted) @@ -138,22 +138,22 @@ class MatrixSections(Sections): ]["subtitle"] sections = [] msgtype_order = [ - "m.room.message#m.text", "m.room.message#m.emote", - "m.room.message#m.notice", "m.room.message#m.image", - "m.room.message#m.file" + "m.room.message$m.text", "m.room.message$m.emote", + "m.room.message$m.notice", "m.room.message$m.image", + "m.room.message$m.file" ] excluded_types = [ # We exclude server notices from here because we handle them in a # dedicated module. We do not want to confuse developers this early # in the spec. - "m.room.message#m.server_notice", + "m.room.message$m.server_notice", ] other_msgtypes = [ - k for k in schemas.keys() if k.startswith("m.room.message#") and + k for k in schemas.keys() if k.startswith("m.room.message$") and k not in msgtype_order and k not in excluded_types ] for event_name in (msgtype_order + other_msgtypes): - if not event_name.startswith("m.room.message#m."): + if not event_name.startswith("m.room.message$m."): continue sections.append(template.render( example=examples[event_name][0], diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index d4745e4d..ddb65efe 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -795,7 +795,7 @@ class MatrixUnits(Units): if not filename.startswith("m."): continue - event_name = filename.split("#")[0] + event_name = filename.split("$")[0] filepath = os.path.join(path, filename) logger.info("Reading event example: %s" % filepath) try: From f9472bae411e8db020247eb7394d7bd42fe50d5a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 29 May 2019 16:27:16 -0600 Subject: [PATCH 0387/1250] Change reference for definition of push rule condition kinds Fixes https://github.com/matrix-org/matrix-doc/issues/1970 --- api/client-server/definitions/push_condition.yaml | 12 ++++++++---- .../client_server/newsfragments/2052.clarification | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2052.clarification diff --git a/api/client-server/definitions/push_condition.yaml b/api/client-server/definitions/push_condition.yaml index 796a51f4..8752274e 100644 --- a/api/client-server/definitions/push_condition.yaml +++ b/api/client-server/definitions/push_condition.yaml @@ -16,16 +16,20 @@ title: PushCondition type: object properties: kind: - enum: - - event_match - - contains_display_name - - room_member_count type: string + description: |- + The kind of condition to apply. See `conditions <#conditions>`_ for + more information on the allowed kinds and how they work. key: type: string description: |- Required for ``event_match`` conditions. The dot-separated field of the event to match. + + Required for ``sender_notification_permission`` conditions. The field in + the power level event the user needs a minimum power level for. Fields + must be specified under the ``notifications`` property in the power level + event's ``content``. x-example: content.body pattern: type: string diff --git a/changelogs/client_server/newsfragments/2052.clarification b/changelogs/client_server/newsfragments/2052.clarification new file mode 100644 index 00000000..95bdc928 --- /dev/null +++ b/changelogs/client_server/newsfragments/2052.clarification @@ -0,0 +1 @@ +Clarify which push rule condition kinds exist. From 792bb8faa49c4551067fd824e805ba4f5c195509 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 29 May 2019 16:28:36 -0600 Subject: [PATCH 0388/1250] Renumber changelog to match PR --- .../newsfragments/{2050.clarification => 2051.clarification} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelogs/client_server/newsfragments/{2050.clarification => 2051.clarification} (100%) diff --git a/changelogs/client_server/newsfragments/2050.clarification b/changelogs/client_server/newsfragments/2051.clarification similarity index 100% rename from changelogs/client_server/newsfragments/2050.clarification rename to changelogs/client_server/newsfragments/2051.clarification From 464845feb0695c99f1b81e665e980e0289ec119c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 29 May 2019 16:36:43 -0600 Subject: [PATCH 0389/1250] Make url required for m.file-like messages Fixes https://github.com/matrix-org/matrix-doc/issues/2008 This also removes `filename` from `m.file` because it has never been used in practice. --- changelogs/client_server/newsfragments/2053.clarification | 1 + event-schemas/schema/m.room.message#m.audio | 1 + event-schemas/schema/m.room.message#m.file | 2 +- event-schemas/schema/m.room.message#m.image | 1 + event-schemas/schema/m.room.message#m.video | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/2053.clarification diff --git a/changelogs/client_server/newsfragments/2053.clarification b/changelogs/client_server/newsfragments/2053.clarification new file mode 100644 index 00000000..2a72a88e --- /dev/null +++ b/changelogs/client_server/newsfragments/2053.clarification @@ -0,0 +1 @@ +Clarify the required fields on ``m.file`` (and similar) messages. diff --git a/event-schemas/schema/m.room.message#m.audio b/event-schemas/schema/m.room.message#m.audio index c258b85f..99e28110 100644 --- a/event-schemas/schema/m.room.message#m.audio +++ b/event-schemas/schema/m.room.message#m.audio @@ -38,6 +38,7 @@ properties: required: - msgtype - body + - url type: object type: enum: diff --git a/event-schemas/schema/m.room.message#m.file b/event-schemas/schema/m.room.message#m.file index 2fb4fe50..2389d8a9 100644 --- a/event-schemas/schema/m.room.message#m.file +++ b/event-schemas/schema/m.room.message#m.file @@ -53,7 +53,7 @@ properties: required: - msgtype - body - - filename + - url type: object type: enum: diff --git a/event-schemas/schema/m.room.message#m.image b/event-schemas/schema/m.room.message#m.image index 349f78f4..1e6ebeaa 100644 --- a/event-schemas/schema/m.room.message#m.image +++ b/event-schemas/schema/m.room.message#m.image @@ -28,6 +28,7 @@ properties: required: - msgtype - body + - url type: object type: enum: diff --git a/event-schemas/schema/m.room.message#m.video b/event-schemas/schema/m.room.message#m.video index 8a66fdeb..2da7e0bc 100644 --- a/event-schemas/schema/m.room.message#m.video +++ b/event-schemas/schema/m.room.message#m.video @@ -59,6 +59,7 @@ properties: required: - msgtype - body + - url type: object type: enum: From 0f623113f10cfc50d99305a8d61ce02371636f5c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 29 May 2019 18:35:18 -0600 Subject: [PATCH 0390/1250] Clarify that UIA stages cannot be attempted twice Fixes https://github.com/matrix-org/matrix-doc/issues/1987 Note: Synapse currently does not care, however the spirit of the text in the spec implies that completed == done forever, so we're just reinforcing it here. --- .../client_server/newsfragments/2054.clarification | 1 + specification/client_server_api.rst | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2054.clarification diff --git a/changelogs/client_server/newsfragments/2054.clarification b/changelogs/client_server/newsfragments/2054.clarification new file mode 100644 index 00000000..e43aea2d --- /dev/null +++ b/changelogs/client_server/newsfragments/2054.clarification @@ -0,0 +1 @@ +Clarify that User-Interactive Authentication stages cannot be attempted more than once. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 6c2e364a..318ac08d 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -453,11 +453,10 @@ params presented, that type may be present as a key in this dictionary. For example, the public part of an OAuth client ID could be given here. session - This is a session identifier that the client must pass back to the home - server, if one is provided, in subsequent attempts to authenticate in the same - API call. + This is a session identifier that the client must pass back to the homeserver, + if one is provided, in subsequent attempts to authenticate in the same API call. -The client then chooses a flow and attempts to complete one of the stages. It +The client then chooses a flow and attempts to complete the first stage. It does this by resubmitting the same request with the addition of an ``auth`` key in the object that it submits. This dictionary contains a ``type`` key whose value is the name of the authentication type that the client is attempting to complete. @@ -558,7 +557,9 @@ message in the standard format. For example: } If the client has completed all stages of a flow, the homeserver performs the -API call and returns the result as normal. +API call and returns the result as normal. Completed stages cannot be re-tried; +The client must abandon the current session and start over. Homeservers should +treat retries as authentication errors. Some authentication types may be completed by means other than through the Matrix client, for example, an email confirmation may be completed when the user From 2ed37f5bf464d03a322184221a89f6ebe4c61630 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 29 May 2019 21:00:37 -0600 Subject: [PATCH 0391/1250] Clarify guest accounts and `auth` usage on /register Fixes https://github.com/matrix-org/matrix-doc/issues/1980 Fixes https://github.com/matrix-org/matrix-doc/issues/1984 --- api/client-server/registration.yaml | 34 ++++++++++++++----- .../newsfragments/2055.clarification | 1 + 2 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2055.clarification diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 3195ab41..10b661a3 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -29,7 +29,8 @@ paths: post: summary: Register for an account on this homeserver. description: |- - This API endpoint uses the `User-Interactive Authentication API`_. + This API endpoint uses the `User-Interactive Authentication API`_, except in + the cases where a guest account is being registered. Register for an account on this homeserver. @@ -59,6 +60,11 @@ paths: supplied by the client or generated by the server. The server may invalidate any access token previously associated with that device. See `Relationship between access tokens and devices`_. + + When registering a guest account, all parameters in the request body + with the exception of ``initial_device_display_name`` are ignored by + the server. The server will pick a ``device_id`` for the account + regardless of input. operationId: register parameters: - in: query @@ -72,7 +78,7 @@ paths: enum: - guest - user - description: The kind of account to register. Defaults to `user`. + description: The kind of account to register. Defaults to ``user``. - in: body name: body schema: @@ -80,13 +86,11 @@ paths: properties: auth: description: |- - Additional authentication information for the - user-interactive authentication API. Note that this - information is *not* used to define how the registered user - should be authenticated, but is instead used to - authenticate the ``register`` call itself. It should be - left empty, or omitted, unless an earlier call returned an - response with status code 401. + Additional authentication information for the + user-interactive authentication API. Note that this + information is *not* used to define how the registered user + should be authenticated, but is instead used to + authenticate the ``register`` call itself. "$ref": "definitions/auth_data.yaml" bind_email: type: boolean @@ -194,6 +198,18 @@ paths: The homeserver requires additional authentication information. schema: "$ref": "definitions/auth_response.yaml" + 403: + description: |- + The homeserver does not permit registering the account. This response + can be used to identify that a particular ``kind`` of account is not + allowed, or that registration is generally not supported by the homeserver. + examples: + application/json: { + "errcode": "M_FORBIDDEN", + "error": "Registration is disabled" + } + schema: + "$ref": "definitions/errors/error.yaml" 429: description: This request was rate-limited. schema: diff --git a/changelogs/client_server/newsfragments/2055.clarification b/changelogs/client_server/newsfragments/2055.clarification new file mode 100644 index 00000000..3a57ef7e --- /dev/null +++ b/changelogs/client_server/newsfragments/2055.clarification @@ -0,0 +1 @@ +Clarify which parameters apply in what scenarios on ``/register``. From f3c0c5232fb812d90ceeda1348c1fc2d17558e28 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 29 May 2019 21:44:50 -0600 Subject: [PATCH 0392/1250] Add a table to show how changes in membership should be interpreted Fixes https://github.com/matrix-org/matrix-doc/issues/876 --- .../newsfragments/2056.clarification | 1 + event-schemas/schema/m.room.member | 23 +++++++++++++++++++ scripts/css/tables.css | 4 ++++ 3 files changed, 28 insertions(+) create mode 100644 changelogs/client_server/newsfragments/2056.clarification create mode 100644 scripts/css/tables.css diff --git a/changelogs/client_server/newsfragments/2056.clarification b/changelogs/client_server/newsfragments/2056.clarification new file mode 100644 index 00000000..12521867 --- /dev/null +++ b/changelogs/client_server/newsfragments/2056.clarification @@ -0,0 +1 @@ +Clarify how to interpret changes of ``membership`` over time. diff --git a/event-schemas/schema/m.room.member b/event-schemas/schema/m.room.member index de14644d..20d3cbcc 100644 --- a/event-schemas/schema/m.room.member +++ b/event-schemas/schema/m.room.member @@ -21,6 +21,29 @@ description: |- This event may also include an ``invite_room_state`` key inside the event's ``unsigned`` data. If present, this contains an array of ``StrippedState`` Events. These events provide information on a subset of state events such as the room name. + + The user for which a membership applies is represented by the ``state_key``. Under some conditions, + the ``sender`` and ``state_key`` may not match - this may be interpreted as the ``sender`` affecting + the membership state of the ``state_key`` user. + + The ``membership`` for a given user can change over time. The table below represents the various changes + over time and how clients and servers must interpret those changes. Previous membership can be retrieved + from the ``prev_content`` object on an event. If not present, the user's previous membership must be assumed + as ``leave``. + + .. TODO: Improve how this table is written? We use a csv-table to get around vertical header restrictions. + + .. csv-table:: + :header-rows: 1 + :stub-columns: 1 + + "","to ``invite``","to ``join``","to ``leave``","to ``ban``","to ``knock``" + "from ``invite``","No change.","User joined the room.","If the ``state_key`` is the same as the ``sender``, the user rejected the invite. Otherwise, the ``state_key`` user had their invite revoked.","User was banned.","Not implemented." + "from ``join``","Must never happen.","``displayname`` or ``avatar_url`` changed.","If the ``state_key`` is the same as the ``sender``, the user left. Otherwise, the ``state_key`` user was kicked.","User was kicked and banned.","Not implemented." + "from ``leave``","New invitation sent.","User joined.","Must never happen.","User was banned.","Not implemented." + "from ``ban``","Must never happen.","Must never happen.","User was unbanned.","No change.","Not implemented." + "from ``knock``","Not implemented.","Not implemented.","Not implemented.","Not implemented.","Not implemented." + properties: content: properties: diff --git a/scripts/css/tables.css b/scripts/css/tables.css new file mode 100644 index 00000000..03ee1d85 --- /dev/null +++ b/scripts/css/tables.css @@ -0,0 +1,4 @@ +/* Column with header cells */ +table.docutils tbody th.stub { + background: #eeeeee; +} From 6ae7e49522e34b32fa317756b906a784317ac829 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Thu, 30 May 2019 12:30:43 +0100 Subject: [PATCH 0393/1250] Clarify what the client should receiving on email resending It was a little unclear what the client should do when asked to send a validation email and provides a `send_attempt` value that is not greater than previous attempts. As this is intended to be for when a client mistakenly sends the request twice, it makes logical sense that the implication was to simply resend a success value so the client doesn't error even when an email may have been sent on the first attempt. This behaviour was also mimicked in Synapse/Sydent. --- api/identity/definitions/request_email_validation.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/identity/definitions/request_email_validation.yaml b/api/identity/definitions/request_email_validation.yaml index 1194a18e..d6606f03 100644 --- a/api/identity/definitions/request_email_validation.yaml +++ b/api/identity/definitions/request_email_validation.yaml @@ -39,7 +39,8 @@ properties: avoid repeatedly sending the same email in the case of request retries between the POSTing user and the identity server. The client should increment this value if they desire a new - email (e.g. a reminder) to be sent. + email (e.g. a reminder) to be sent. If they do not, the server + should return a success but not resend the email. example: 1 next_link: type: string From c0c462999374a51b8430b88f7abe58a5a2b4386b Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Thu, 30 May 2019 12:31:26 +0100 Subject: [PATCH 0394/1250] Slight word change --- api/identity/definitions/request_email_validation.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/identity/definitions/request_email_validation.yaml b/api/identity/definitions/request_email_validation.yaml index d6606f03..5d1aac8a 100644 --- a/api/identity/definitions/request_email_validation.yaml +++ b/api/identity/definitions/request_email_validation.yaml @@ -40,7 +40,7 @@ properties: retries between the POSTing user and the identity server. The client should increment this value if they desire a new email (e.g. a reminder) to be sent. If they do not, the server - should return a success but not resend the email. + should response with success but not resend the email. example: 1 next_link: type: string From dda8976d2544a22cb280fce243d23107e2bd4c88 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 30 May 2019 12:33:29 +0100 Subject: [PATCH 0395/1250] Add changelog --- changelogs/client_server/newsfragments/2057.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2057.clarification diff --git a/changelogs/client_server/newsfragments/2057.clarification b/changelogs/client_server/newsfragments/2057.clarification new file mode 100644 index 00000000..de72c201 --- /dev/null +++ b/changelogs/client_server/newsfragments/2057.clarification @@ -0,0 +1 @@ +Clarify what the client should receive upon sending an identical email validation request multiple times. From 54f74cd877eb166ca53d52bd1a16f51a6df68461 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 30 May 2019 16:46:55 -0600 Subject: [PATCH 0396/1250] Add Olm unwedging As per [MSC1719](https://github.com/matrix-org/matrix-doc/pull/1719) No known alterations have been made to the proposal. Implementation proof: https://github.com/matrix-org/matrix-js-sdk/pull/780 --- .../client_server/newsfragments/2059.feature | 1 + event-schemas/examples/m.dummy | 4 ++ event-schemas/schema/m.dummy | 23 +++++++++++ .../modules/end_to_end_encryption.rst | 41 ++++++++++++++++--- 4 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2059.feature create mode 100644 event-schemas/examples/m.dummy create mode 100644 event-schemas/schema/m.dummy diff --git a/changelogs/client_server/newsfragments/2059.feature b/changelogs/client_server/newsfragments/2059.feature new file mode 100644 index 00000000..fde106ce --- /dev/null +++ b/changelogs/client_server/newsfragments/2059.feature @@ -0,0 +1 @@ +Add support for Olm sessions becoming un-stuck. diff --git a/event-schemas/examples/m.dummy b/event-schemas/examples/m.dummy new file mode 100644 index 00000000..0cd39166 --- /dev/null +++ b/event-schemas/examples/m.dummy @@ -0,0 +1,4 @@ +{ + "content": {}, + "type": "m.dummy" +} diff --git a/event-schemas/schema/m.dummy b/event-schemas/schema/m.dummy new file mode 100644 index 00000000..5bebe430 --- /dev/null +++ b/event-schemas/schema/m.dummy @@ -0,0 +1,23 @@ +--- +allOf: + - $ref: core-event-schema/event.yaml + +description: |- + This event type is used to indicate new Olm sessions for end-to-end encryption. + Typically it is encrypted as an ``m.room.encrypted`` event, then sent as a `to-device`_ + event. + + The event does not have any content associated with it. The sending client is expected + to send a key share request shortly after this message, causing the receiving client to + process this ``m.dummy`` event as the most recent event and using the keyshare request + to set up the session. The keyshare request and ``m.dummy`` combination should result + in the original sending client receiving keys over the newly establish session. +properties: + content: + properties: {} + type: object + type: + enum: + - m.dummy + type: string +type: object diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 38a0a06b..a77dbad9 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -1,4 +1,5 @@ .. Copyright 2016 OpenMarket Ltd +.. Copyright 2019 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. @@ -18,7 +19,7 @@ End-to-End Encryption .. _module:e2e: Matrix optionally supports end-to-end encryption, allowing rooms to be created -whose conversation contents is not decryptable or interceptable on any of the +whose conversation contents are not decryptable or interceptable on any of the participating homeservers. Key Distribution @@ -549,6 +550,31 @@ Example: ] } + +Recovering from undecryptable messages +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Occasionally messages may be undecryptable by clients due to a variety of reasons. +When this happens to an Olm-encrypted message, the client should assume that the Olm +session has become corrupted and create a new one to replace it. + +.. Note:: + Megolm-encrypted messages generally do not have the same problem. Usually the key + for an undecryptable Megolm-encrypted message will come later, allowing the client + to decrypt it successfully. Olm does not have a way to recover from the failure, + making this session replacement process required. + +To establish a new session, the client sends a `m.dummy <#m-dummy>`_ to-device event +to the other party to notify them of the new session details. + +Clients should rate-limit the number of sessions it creates per device that it receives +a message from. Clients should not create a new session with another device if it has +already created on for that given device in the past 1 hour. + +Clients should attempt to mitigate loss of the undecryptable messages. For example, +Megolm sessions that were sent using the old session would have been lost. The client +can attempt to retrieve the lost sessions through ``m.room_key_request`` messages. + Messaging Algorithms -------------------- @@ -658,10 +684,13 @@ part of the ed25519 key it claims to have in the Olm payload. This is crucial when the ed25519 key corresponds to a verified device. If a client has multiple sessions established with another device, it should -use the session from which it last received a message. A client may expire old -sessions by defining a maximum number of olm sessions that it will maintain for -each device, and expiring sessions on a Least Recently Used basis. The maximum -number of olm sessions maintained per device should be at least 4. +use the session from which it last received and successfully decrypted a +message. For these purposes, a session that has not received any messages +should use its creation time as the time that it last received a message. +A client may expire old sessions by defining a maximum number of olm sessions +that it will maintain for each device, and expiring sessions on a Least Recently +Used basis. The maximum number of olm sessions maintained per device should +be at least 4. ``m.megolm.v1.aes-sha2`` ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -740,6 +769,8 @@ Events {{m_forwarded_room_key_event}} +{{m_dummy_event}} + Key management API ~~~~~~~~~~~~~~~~~~ From d48265f49be7ba8b4fd4471396dd4deb0796ec25 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 30 May 2019 16:51:24 -0600 Subject: [PATCH 0397/1250] typo --- event-schemas/schema/m.dummy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event-schemas/schema/m.dummy b/event-schemas/schema/m.dummy index 5bebe430..8e4b6f94 100644 --- a/event-schemas/schema/m.dummy +++ b/event-schemas/schema/m.dummy @@ -11,7 +11,7 @@ description: |- to send a key share request shortly after this message, causing the receiving client to process this ``m.dummy`` event as the most recent event and using the keyshare request to set up the session. The keyshare request and ``m.dummy`` combination should result - in the original sending client receiving keys over the newly establish session. + in the original sending client receiving keys over the newly established session. properties: content: properties: {} From 41e07ff7d64ba3bb667532bb0f69c250ba93d149 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 30 May 2019 16:54:19 -0600 Subject: [PATCH 0398/1250] Fix incorrect state of leave->leave As mentioned in PR review, it is possible for moderators in a room to race at kicking someone, resulting in multiple leave events. --- event-schemas/schema/m.room.member | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event-schemas/schema/m.room.member b/event-schemas/schema/m.room.member index 20d3cbcc..8984ac5c 100644 --- a/event-schemas/schema/m.room.member +++ b/event-schemas/schema/m.room.member @@ -40,7 +40,7 @@ description: |- "","to ``invite``","to ``join``","to ``leave``","to ``ban``","to ``knock``" "from ``invite``","No change.","User joined the room.","If the ``state_key`` is the same as the ``sender``, the user rejected the invite. Otherwise, the ``state_key`` user had their invite revoked.","User was banned.","Not implemented." "from ``join``","Must never happen.","``displayname`` or ``avatar_url`` changed.","If the ``state_key`` is the same as the ``sender``, the user left. Otherwise, the ``state_key`` user was kicked.","User was kicked and banned.","Not implemented." - "from ``leave``","New invitation sent.","User joined.","Must never happen.","User was banned.","Not implemented." + "from ``leave``","New invitation sent.","User joined.","No change.","User was banned.","Not implemented." "from ``ban``","Must never happen.","Must never happen.","User was unbanned.","No change.","Not implemented." "from ``knock``","Not implemented.","Not implemented.","Not implemented.","Not implemented.","Not implemented." From da5ce919f2b363e2a660632a8d971dd42f90afb0 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 31 May 2019 12:16:59 -0400 Subject: [PATCH 0399/1250] add sharing secrets, and a bunch of cleanups --- proposals/1946-secure_server-side_storage.md | 104 ++++++++++++++----- 1 file changed, 78 insertions(+), 26 deletions(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index 603fe64e..c44cd57e 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -1,28 +1,39 @@ -# Secure Server-side Storage +# Secure Secret Storage and Sharing Some features may require clients to store encrypted data on the server so that -it can be shared securely between clients. For example, key backups (MSC-1219) +it can be shared securely between clients. Clients may also wish to securely +send such data directly to each other. For example, key backups (MSC-1219) can store the decryption key for the backups on the server, or cross-signing (MSC-1756) can store the signing keys. This proposal presents a standardized way of storing such data. ## Proposal -A user can have multiple keys used for encrypting data. This allows the user -to selectively decrypt data. For example, the user could have one key that can +Secrets are data that clients need to use and thate are sent through or stored +on the server, but should not be visible to server operators. Secrets are +plain strings -- if clients need to use more complicated data, it must be +encoded as a string. + +### Storage + +If secret data is stored on the server, it must be encrypted in order to +prevent homeserver administrators from being able to read it. A user can have +multiple keys used for encrypting data. This allows the user to selectively +decrypt data on clients. For example, the user could have one key that can decrypt everything, and another key that can only decrypt their user-signing key for cross-signing. Each key has an ID, and a discription of the key is -stored in the user's `account_data` using the `type` `m.secure_storage.key.[key +stored in the user's `account_data` using the `type` `m.secret_storage.key.[key ID]`. The contents of the account data for the key will include an `algorithm` property, which indicates the encryption algorithm used, as well as a `name` -property, which is a human-readable name. Other properties depend on the -encryption algorithm, and are described below. +property, which is a human-readable name. The contents will be signed as +signed JSON using the user's master cross-signing key. Other properties depend +on the encryption algorithm, and are described below. Encrypted data can be stored using the `account_data` API. The `type` for the `account_data` is defined by the feature that uses the data. For example, decryption keys for key backups could be stored under the type `m.megolm_backup.v1.recovery_key`, or the self-signing key for cross-signing -could be stored under the type `m.signing_key.self_signing`. +could be stored under the type `m.cross_signing.self_signing`. Data will be stored using using the following format: @@ -50,16 +61,18 @@ is the same as the key for decrypting the other bits. Maybe a special flag in the account data? Or special case backups somehow, say, have clients inspect the backup's `auth_data` to see of the key config is the same? -### Encryption algorithms +#### Encryption algorithms -#### `m.secure_storage.v1.curve25519-aes-sha2` +##### `m.secret_storage.v1.curve25519-aes-sha2` + +The public key is stored in the `pubkey` property of the `m.secret_storage.key.[key +ID]` `account_data`. The data is encrypted and MACed as follows: 1. Generate an ephemeral curve25519 key, and perform an ECDH with the ephemeral - key and the backup's public key to generate a shared secret. The public - half of the ephemeral key, encoded using base64, becomes the `ephemeral` - property. + key and the public key to generate a shared secret. The public half of the + ephemeral key, encoded using base64, becomes the `ephemeral` property. 2. Using the shared secret, generate 80 bytes by performing an HKDF using SHA-256 as the hash, with a salt of 32 bytes of 0, and with the empty string as the info. The first 32 bytes are used as the AES key, the next 32 bytes @@ -74,11 +87,11 @@ The data is encrypted and MACed as follows: (The key HKDF, AES, and HMAC steps are the same as what are used for encryption in olm and megolm.) -FIXME: add an example of `m.secure_storage.key.*`, and of encrypted data. +FIXME: add an example of `m.secret_storage.key.*`, and of encrypted data. -##### Keys +###### Keys -When a user is given a raw key for `m.secure_storage.v1.curve25519-aes-sha2`, +When a user is given a raw key for `m.secret_storage.v1.curve25519-aes-sha2`, it will be encoded as follows (this is the same as what is proposed in MSC1703): * prepend the two bytes 0x8b and 0x01 to the key @@ -92,11 +105,11 @@ it will be encoded as follows (this is the same as what is proposed in MSC1703): When decoding a raw key, the process should be reversed, with the exception that whitespace is insignificant in the user's ASCII input. -##### Passphrase +###### Passphrase A user may wish to use a chosen passphrase rather than a randomly generated key. In this case, information on how to generate the key from a passphrase -will be stored in the `passphrase` property of the `m.secure_storage.key.[key +will be stored in the `passphrase` property of the `m.secret_storage.key.[key ID]` account-data: ```json @@ -110,19 +123,58 @@ ID]` account-data: } ``` -###### `m.pbkdf2` +**`m.pbkdf2`** The key is generated using PBKDF2 using the salt given in the `salt` parameter, and the number of rounds given in the `rounds` parameter. -## Tradeoffs +### Sharing + +Rather than (or in addition to) storing secrets on the server encrypted by a +shared key, devices can send secrets to each other, encrypted using olm. + +To request a secret, a client sends a `m.secret.request` event with `action` +set to `request` to other devices, and `name` set to the name of the secret +that it wishes to retrieve. A device that wishes to share the secret will +reply with a `m.secret.share` event, encrypted using olm. When the original +client obtains the secret, it sends a `m.secret.request` event with `action` +set to `cancel_request` to all devices other than the one that it received the +secret from. + +Clients SHOULD ensure that they only share secrets with other devices that are +allowed to see them. For example, clients SHOULD only share secrets with devices +that are verified and MAY prompt the user to confirm sharing the secret. + +If a feature allows secrets to be stored or shared, then for consistency it +SHOULD use the same name for both the `account_data` `type` and the `name` in +the `m.secret.request`. -Rather than encrypting data on the server using a static key, clients can -exchange data by sending to_device messages encrypted using Olm. This allows -clients to share data securely without requiring the user to enter keys or -passphrases. However, users who have only one device and lose it will still -need a way to, for example, recover their key backup, so we must provide a way -for the data to be stored on the server. +#### Event definitions + +##### `m.secret.request` + +Sent by a client to request a secret from another device. It is sent as an +unencrypted to-device event. + +- `name`: (string) Required if `action` is `request`. The name of the secret + that is being requested. +- `action`: (enum) Required. One of ["request", "cancel_request"]. +- `requesting_device_id`: (string) Required. ID of the device requesting the + secret. +- `request_id`: (string) Required. A random string uniquely identifying the + request for a secret. If the secret is requested multiple times, it should be + reused. It should also reused in order to cancel a request. + +##### `m.secret.share` + +Sent by a client to share a secret with another device, in response to an +`m.secret.request` event. Typically it is encrypted as an `m.room.encrypted` +event, then sent as a to-device event. + +- `request_id`: (string) Required. The ID of the request that this a response to. +- `secret`: (string) Required. The contents of the secret. + +## Tradeoffs Currently, only a public/private key mechanism is defined. It may be useful to also define a secret key mechanism. From 754b19bb929601fa5253470eea5dbfc45361d81b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 31 May 2019 10:21:16 -0600 Subject: [PATCH 0400/1250] typo Co-Authored-By: Hubert Chathi --- specification/modules/end_to_end_encryption.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index a77dbad9..628c1a60 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -569,7 +569,7 @@ to the other party to notify them of the new session details. Clients should rate-limit the number of sessions it creates per device that it receives a message from. Clients should not create a new session with another device if it has -already created on for that given device in the past 1 hour. +already created one for that given device in the past 1 hour. Clients should attempt to mitigate loss of the undecryptable messages. For example, Megolm sessions that were sent using the old session would have been lost. The client From 57e3b152b042183f1bbb424fdaec7518c820dc66 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 31 May 2019 11:37:09 -0600 Subject: [PATCH 0401/1250] Move section to under Olm stuff --- .../modules/end_to_end_encryption.rst | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 628c1a60..e6048c28 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -550,31 +550,6 @@ Example: ] } - -Recovering from undecryptable messages -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Occasionally messages may be undecryptable by clients due to a variety of reasons. -When this happens to an Olm-encrypted message, the client should assume that the Olm -session has become corrupted and create a new one to replace it. - -.. Note:: - Megolm-encrypted messages generally do not have the same problem. Usually the key - for an undecryptable Megolm-encrypted message will come later, allowing the client - to decrypt it successfully. Olm does not have a way to recover from the failure, - making this session replacement process required. - -To establish a new session, the client sends a `m.dummy <#m-dummy>`_ to-device event -to the other party to notify them of the new session details. - -Clients should rate-limit the number of sessions it creates per device that it receives -a message from. Clients should not create a new session with another device if it has -already created one for that given device in the past 1 hour. - -Clients should attempt to mitigate loss of the undecryptable messages. For example, -Megolm sessions that were sent using the old session would have been lost. The client -can attempt to retrieve the lost sessions through ``m.room_key_request`` messages. - Messaging Algorithms -------------------- @@ -692,6 +667,31 @@ that it will maintain for each device, and expiring sessions on a Least Recently Used basis. The maximum number of olm sessions maintained per device should be at least 4. +Recovering from undecryptable messages +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Occasionally messages may be undecryptable by clients due to a variety of reasons. +When this happens to an Olm-encrypted message, the client should assume that the Olm +session has become corrupted and create a new one to replace it. + +.. Note:: + Megolm-encrypted messages generally do not have the same problem. Usually the key + for an undecryptable Megolm-encrypted message will come later, allowing the client + to decrypt it successfully. Olm does not have a way to recover from the failure, + making this session replacement process required. + +To establish a new session, the client sends a `m.dummy <#m-dummy>`_ to-device event +to the other party to notify them of the new session details. + +Clients should rate-limit the number of sessions it creates per device that it receives +a message from. Clients should not create a new session with another device if it has +already created one for that given device in the past 1 hour. + +Clients should attempt to mitigate loss of the undecryptable messages. For example, +Megolm sessions that were sent using the old session would have been lost. The client +can attempt to retrieve the lost sessions through ``m.room_key_request`` messages. + + ``m.megolm.v1.aes-sha2`` ~~~~~~~~~~~~~~~~~~~~~~~~ From fee2ebf682c7c83cb807e3e991bf91fe2dac8b88 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Sun, 2 Jun 2019 16:09:47 -0400 Subject: [PATCH 0402/1250] fix typo Co-Authored-By: Shamil K --- proposals/1946-secure_server-side_storage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index c44cd57e..8487d6d4 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -9,7 +9,7 @@ way of storing such data. ## Proposal -Secrets are data that clients need to use and thate are sent through or stored +Secrets are data that clients need to use and that are sent through or stored on the server, but should not be visible to server operators. Secrets are plain strings -- if clients need to use more complicated data, it must be encoded as a string. From 7a07a6b358cb15cc6ef81fba07037b440ade2879 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 2 Jun 2019 17:41:39 -0600 Subject: [PATCH 0403/1250] Clarify exactly what StrippedState is Fixes https://github.com/matrix-org/matrix-doc/issues/2066 The expectation everywhere is that the `sender` is required. `/initialSync` references StrippedState through a `m.room.member` event reference, and does not need editing. --- api/client-server/sync.yaml | 25 +---------- api/server-server/invites-v1.yaml | 20 +-------- api/server-server/invites-v2.yaml | 20 +-------- .../newsfragments/2067.clarification | 1 + .../newsfragments/2067.clarification | 1 + .../examples/m.room.member$invite_room_state | 19 ++------ event-schemas/examples/stripped_state.json | 18 ++++++++ event-schemas/schema/m.room.member | 19 +------- event-schemas/schema/stripped_state.yaml | 44 +++++++++++++++++++ 9 files changed, 71 insertions(+), 96 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2067.clarification create mode 100644 changelogs/server_server/newsfragments/2067.clarification create mode 100644 event-schemas/examples/stripped_state.json create mode 100644 event-schemas/schema/stripped_state.yaml diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 02fddb84..3db1fa54 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -212,30 +212,7 @@ paths: events: description: The StrippedState events that form the invite state. items: - description: |- - A stripped down state event, with only the ``type``, ``state_key``, - ``sender``, and ``content`` keys. - properties: - content: - description: The ``content`` for the event. - title: EventContent - type: object - state_key: - description: The ``state_key`` for the event. - type: string - type: - description: The ``type`` for the event. - type: string - sender: - description: The ``sender`` for the event. - type: string - required: - - type - - state_key - - content - - sender - title: StrippedState - type: object + $ref: "definitions/event-schemas/schema/stripped_state.yaml" type: array leave: title: Left rooms diff --git a/api/server-server/invites-v1.yaml b/api/server-server/invites-v1.yaml index 2ad0f220..867d7b05 100644 --- a/api/server-server/invites-v1.yaml +++ b/api/server-server/invites-v1.yaml @@ -82,25 +82,7 @@ paths: 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'] + $ref: "../client-server/definitions/event-schemas/schema/stripped_state.yaml" example: [ { "type": "m.room.join_rules", diff --git a/api/server-server/invites-v2.yaml b/api/server-server/invites-v2.yaml index c459a848..6d5b102e 100644 --- a/api/server-server/invites-v2.yaml +++ b/api/server-server/invites-v2.yaml @@ -83,25 +83,7 @@ paths: 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'] + $ref: "../client-server/definitions/event-schemas/schema/stripped_state.yaml" example: [ { "type": "m.room.join_rules", diff --git a/changelogs/client_server/newsfragments/2067.clarification b/changelogs/client_server/newsfragments/2067.clarification new file mode 100644 index 00000000..cc706274 --- /dev/null +++ b/changelogs/client_server/newsfragments/2067.clarification @@ -0,0 +1 @@ +Clarify exactly what invite_room_state consists of. diff --git a/changelogs/server_server/newsfragments/2067.clarification b/changelogs/server_server/newsfragments/2067.clarification new file mode 100644 index 00000000..cc706274 --- /dev/null +++ b/changelogs/server_server/newsfragments/2067.clarification @@ -0,0 +1 @@ +Clarify exactly what invite_room_state consists of. diff --git a/event-schemas/examples/m.room.member$invite_room_state b/event-schemas/examples/m.room.member$invite_room_state index f8f05484..b60abf95 100644 --- a/event-schemas/examples/m.room.member$invite_room_state +++ b/event-schemas/examples/m.room.member$invite_room_state @@ -7,21 +7,8 @@ }, "unsigned": { "age": 1234, - "invite_room_state": [ - { - "type": "m.room.name", - "state_key": "", - "content": { - "name": "Forest of Magic" - } - }, - { - "type": "m.room.join_rules", - "state_key": "", - "content": { - "join_rule": "invite" - } - } - ] + "invite_room_state": { + "$ref": "stripped_state.json" + } } } diff --git a/event-schemas/examples/stripped_state.json b/event-schemas/examples/stripped_state.json new file mode 100644 index 00000000..9d8c1b2b --- /dev/null +++ b/event-schemas/examples/stripped_state.json @@ -0,0 +1,18 @@ +[ + { + "type": "m.room.name", + "sender": "@bob:example.org", + "state_key": "", + "content": { + "name": "Example Room" + } + }, + { + "type": "m.room.join_rules", + "sender": "@bob:example.org", + "state_key": "", + "content": { + "join_rule": "invite" + } + } +] diff --git a/event-schemas/schema/m.room.member b/event-schemas/schema/m.room.member index de14644d..f846196b 100644 --- a/event-schemas/schema/m.room.member +++ b/event-schemas/schema/m.room.member @@ -81,24 +81,7 @@ properties: invite_room_state: description: 'A subset of the state of the room at the time of the invite, if ``membership`` is ``invite``. Note that this state is informational, and SHOULD NOT be trusted; once the client has joined the room, it SHOULD fetch the live state from the server and discard the invite_room_state. Also, clients must not rely on any particular state being present here; they SHOULD behave properly (with possibly a degraded but not a broken experience) in the absence of any particular events here. If they are set on the room, at least the state for ``m.room.avatar``, ``m.room.canonical_alias``, ``m.room.join_rules``, and ``m.room.name`` SHOULD be included.' items: - description: 'A stripped down state event, with only the ``type``, ``state_key`` and ``content`` keys.' - properties: - content: - description: The ``content`` for the event. - title: EventContent - type: object - state_key: - description: The ``state_key`` for the event. - type: string - type: - description: The ``type`` for the event. - type: string - required: - - type - - state_key - - content - title: StrippedState - type: object + $ref: "stripped_state.yaml" type: array required: - membership diff --git a/event-schemas/schema/stripped_state.yaml b/event-schemas/schema/stripped_state.yaml new file mode 100644 index 00000000..ec591bf1 --- /dev/null +++ b/event-schemas/schema/stripped_state.yaml @@ -0,0 +1,44 @@ +# Copyright 2019 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. + +# Note: this, and the example, are in the `event-schemas` directory because +# the CS API uses a symlink. In order for the `m.room.member` event to +# reference this, we'd need to use relative pathing. The symlink makes this +# difficult because the schema would be at two different locations, with +# different relative pathing. + +title: StrippedState +type: object +description: |- + A stripped down state event, with only the ``type``, ``state_key``, + ``sender``, and ``content`` keys. +properties: + content: + description: The ``content`` for the event. + title: EventContent + type: object + state_key: + description: The ``state_key`` for the event. + type: string + type: + description: The ``type`` for the event. + type: string + sender: + description: The ``sender`` for the event. + type: string +required: + - type + - state_key + - content + - sender From b9c4a2561ff8692b8e960e9eb977efb27b86e57b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 2 Jun 2019 17:50:27 -0600 Subject: [PATCH 0404/1250] Fix examples of StrippedState in s2s spec --- api/server-server/invites-v1.yaml | 53 +++---------------------------- api/server-server/invites-v2.yaml | 53 ++++--------------------------- 2 files changed, 11 insertions(+), 95 deletions(-) diff --git a/api/server-server/invites-v1.yaml b/api/server-server/invites-v1.yaml index 867d7b05..2f08dd12 100644 --- a/api/server-server/invites-v1.yaml +++ b/api/server-server/invites-v1.yaml @@ -83,16 +83,8 @@ paths: canonical alias, avatar, and name of the room. items: $ref: "../client-server/definitions/event-schemas/schema/stripped_state.yaml" - example: [ - { - "type": "m.room.join_rules", - "sender": "@someone:matrix.org", - "state_key": "", - "content": { - "join_rule": "public" - } - } - ] + example: + $ref: "../client-server/definitions/event-schemas/examples/stripped_state.json" example: { "$ref": "examples/minimal_pdu.json", "type": "m.room.member", @@ -100,26 +92,6 @@ paths: "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" }, @@ -162,24 +134,9 @@ paths: "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" - } - } - ] + "invite_room_state": { + "$ref": "../../client-server/definitions/event-schemas/examples/stripped_state.json" + } }, "content": { "membership": "invite" diff --git a/api/server-server/invites-v2.yaml b/api/server-server/invites-v2.yaml index 6d5b102e..57ca99ff 100644 --- a/api/server-server/invites-v2.yaml +++ b/api/server-server/invites-v2.yaml @@ -84,16 +84,8 @@ paths: canonical alias, avatar, and name of the room. items: $ref: "../client-server/definitions/event-schemas/schema/stripped_state.yaml" - example: [ - { - "type": "m.room.join_rules", - "sender": "@someone:matrix.org", - "state_key": "", - "content": { - "join_rule": "public" - } - } - ] + example: + $ref: "../client-server/definitions/event-schemas/examples/stripped_state.json" required: ['room_version', 'event'] example: { "room_version": "2", @@ -112,25 +104,7 @@ paths: "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: @@ -156,24 +130,9 @@ paths: "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" - } - } - ] + "invite_room_state": { + "$ref": "../../client-server/definitions/event-schemas/examples/stripped_state.json" + } }, "content": { "membership": "invite" From 237d585e07b376d69e0f7e887b7135bc8250aba6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 2 Jun 2019 17:59:19 -0600 Subject: [PATCH 0405/1250] Shorten references to StrippedState in s2s spec --- api/server-server/invites-v1.yaml | 6 +++--- api/server-server/invites-v2.yaml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/api/server-server/invites-v1.yaml b/api/server-server/invites-v1.yaml index 2f08dd12..83aafb3a 100644 --- a/api/server-server/invites-v1.yaml +++ b/api/server-server/invites-v1.yaml @@ -82,9 +82,9 @@ paths: identify the room. The recommended events to include are the join rules, canonical alias, avatar, and name of the room. items: - $ref: "../client-server/definitions/event-schemas/schema/stripped_state.yaml" + $ref: "../../event-schemas/schema/stripped_state.yaml" example: - $ref: "../client-server/definitions/event-schemas/examples/stripped_state.json" + $ref: "../../event-schemas/examples/stripped_state.json" example: { "$ref": "examples/minimal_pdu.json", "type": "m.room.member", @@ -135,7 +135,7 @@ paths: "sender": "@someone:example.org", "unsigned": { "invite_room_state": { - "$ref": "../../client-server/definitions/event-schemas/examples/stripped_state.json" + "$ref": "../../../event-schemas/examples/stripped_state.json" } }, "content": { diff --git a/api/server-server/invites-v2.yaml b/api/server-server/invites-v2.yaml index 57ca99ff..d2cc63a2 100644 --- a/api/server-server/invites-v2.yaml +++ b/api/server-server/invites-v2.yaml @@ -83,9 +83,9 @@ paths: identify the room. The recommended events to include are the join rules, canonical alias, avatar, and name of the room. items: - $ref: "../client-server/definitions/event-schemas/schema/stripped_state.yaml" + $ref: "../../event-schemas/schema/stripped_state.yaml" example: - $ref: "../client-server/definitions/event-schemas/examples/stripped_state.json" + $ref: "../../event-schemas/examples/stripped_state.json" required: ['room_version', 'event'] example: { "room_version": "2", @@ -131,7 +131,7 @@ paths: "sender": "@someone:example.org", "unsigned": { "invite_room_state": { - "$ref": "../../client-server/definitions/event-schemas/examples/stripped_state.json" + "$ref": "../../../event-schemas/examples/stripped_state.json" } }, "content": { From 0b45f3795bb6c561266f9388f850bae460c204fd Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 2 Jun 2019 18:02:22 -0600 Subject: [PATCH 0406/1250] Rename example to invite_room_state This is a better representation of what it actually is --- api/server-server/invites-v1.yaml | 4 ++-- api/server-server/invites-v2.yaml | 4 ++-- .../examples/{stripped_state.json => invite_room_state.json} | 0 event-schemas/examples/m.room.member$invite_room_state | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) rename event-schemas/examples/{stripped_state.json => invite_room_state.json} (100%) diff --git a/api/server-server/invites-v1.yaml b/api/server-server/invites-v1.yaml index 83aafb3a..8e1c861d 100644 --- a/api/server-server/invites-v1.yaml +++ b/api/server-server/invites-v1.yaml @@ -84,7 +84,7 @@ paths: items: $ref: "../../event-schemas/schema/stripped_state.yaml" example: - $ref: "../../event-schemas/examples/stripped_state.json" + $ref: "../../event-schemas/examples/invite_room_state.json" example: { "$ref": "examples/minimal_pdu.json", "type": "m.room.member", @@ -135,7 +135,7 @@ paths: "sender": "@someone:example.org", "unsigned": { "invite_room_state": { - "$ref": "../../../event-schemas/examples/stripped_state.json" + "$ref": "../../../event-schemas/examples/invite_room_state.json" } }, "content": { diff --git a/api/server-server/invites-v2.yaml b/api/server-server/invites-v2.yaml index d2cc63a2..cae14bb4 100644 --- a/api/server-server/invites-v2.yaml +++ b/api/server-server/invites-v2.yaml @@ -85,7 +85,7 @@ paths: items: $ref: "../../event-schemas/schema/stripped_state.yaml" example: - $ref: "../../event-schemas/examples/stripped_state.json" + $ref: "../../event-schemas/examples/invite_room_state.json" required: ['room_version', 'event'] example: { "room_version": "2", @@ -131,7 +131,7 @@ paths: "sender": "@someone:example.org", "unsigned": { "invite_room_state": { - "$ref": "../../../event-schemas/examples/stripped_state.json" + "$ref": "../../../event-schemas/examples/invite_room_state.json" } }, "content": { diff --git a/event-schemas/examples/stripped_state.json b/event-schemas/examples/invite_room_state.json similarity index 100% rename from event-schemas/examples/stripped_state.json rename to event-schemas/examples/invite_room_state.json diff --git a/event-schemas/examples/m.room.member$invite_room_state b/event-schemas/examples/m.room.member$invite_room_state index b60abf95..2c93eb9b 100644 --- a/event-schemas/examples/m.room.member$invite_room_state +++ b/event-schemas/examples/m.room.member$invite_room_state @@ -8,7 +8,7 @@ "unsigned": { "age": 1234, "invite_room_state": { - "$ref": "stripped_state.json" + "$ref": "invite_room_state.json" } } } From 86019c9adeb05a3998a03b7e12089b151293015a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 2 Jun 2019 18:02:36 -0600 Subject: [PATCH 0407/1250] Skip over partial event definitions in examples --- event-schemas/check_examples.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/event-schemas/check_examples.py b/event-schemas/check_examples.py index 2baa3ef0..31daa478 100755 --- a/event-schemas/check_examples.py +++ b/event-schemas/check_examples.py @@ -106,6 +106,9 @@ def check_example_dir(exampledir, schemadir): if filename.startswith("."): # Skip over any vim .swp files. continue + if filename.endswith(".json"): + # Skip over any explicit examples (partial event definitions) + continue cwd = os.path.basename(os.path.dirname(os.path.join(root, filename))) if cwd == "core": # Skip checking the underlying definitions From 1f86e8e31b11db7514db2d139cb3836f5af0078e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 2 Jun 2019 21:23:59 -0600 Subject: [PATCH 0408/1250] Refactor documentation for content/media repository Fixes https://github.com/matrix-org/matrix-doc/issues/2060 Fixes https://github.com/matrix-org/matrix-doc/issues/772 Fixes https://github.com/matrix-org/matrix-doc/issues/888 --- api/client-server/content-repo.yaml | 156 ++++++++++-------- api/client-server/room_state.yaml | 2 +- .../newsfragments/2068.clarification | 1 + event-schemas/examples/m.room.member | 2 +- .../examples/m.room.member$invite_room_state | 2 +- .../examples/m.room.member$third_party_invite | 2 +- .../msgtype_infos/image_info.yaml | 2 +- event-schemas/schema/m.room.message$m.audio | 2 +- event-schemas/schema/m.room.message$m.file | 2 +- event-schemas/schema/m.room.message$m.image | 2 +- event-schemas/schema/m.room.message$m.video | 4 +- specification/modules/content_repo.rst | 87 +++++++--- 12 files changed, 163 insertions(+), 101 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2068.clarification diff --git a/api/client-server/content-repo.yaml b/api/client-server/content-repo.yaml index 4460bb69..576d29ef 100644 --- a/api/client-server/content-repo.yaml +++ b/api/client-server/content-repo.yaml @@ -1,4 +1,5 @@ # Copyright 2016 OpenMarket Ltd +# Copyright 2019 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. @@ -58,66 +59,41 @@ paths: format: byte responses: 200: - description: The MXC URI for the uploaded content. + description: The `MXC URI`_ for the uploaded content. schema: type: object required: ["content_uri"] properties: content_uri: type: string - description: "The MXC URI to the uploaded content." + description: "The `MXC URI`_ to the uploaded content." examples: application/json: { - "content_uri": "mxc://example.com/AQwafuaFswefuhsfAFAgsw" - } - 429: - description: This request was rate-limited. + "content_uri": "mxc://example.com/AQwafuaFswefuhsfAFAgsw" + } + 403: + description: |- + The user does not have permission to upload the content. Some reasons for this error include: + + - The server does not permit the file type. + - The user has reached a quota for uploaded content. + examples: + application/json: { + "errcode": "M_FORBIDDEN", + "error": "Cannot upload this content" + } schema: - "$ref": "definitions/errors/rate_limited.yaml" - tags: - - Media - "/download/{serverName}/{mediaId}": - get: - summary: "Download content from the content repository." - operationId: getContent - produces: ["*/*"] - parameters: - - in: path - type: string - name: serverName - x-example: matrix.org - required: true - description: | - The server name from the ``mxc://`` URI (the authoritory component) - - in: path - type: string - name: mediaId - x-example: ascERGshawAWawugaAcauga - required: true - description: | - The media ID from the ``mxc://`` URI (the path component) - - in: query - type: boolean - name: allow_remote - x-example: false - required: false - default: true - description: | - Indicates to the server that it should not attempt to fetch the media if it is deemed - remote. This is to prevent routing loops where the server contacts itself. Defaults to - true if not provided. - responses: - 200: - description: "The content that was previously uploaded." - headers: - Content-Type: - description: "The content type of the file that was previously uploaded." - type: "string" - Content-Disposition: - description: "The name of the file that was previously uploaded, if set." - type: "string" + "$ref": "definitions/errors/error.yaml" + 413: + description: |- + The uploaded content is too large for the server. + examples: + application/json: { + "errcode": "M_TOO_LARGE", + "error": "Cannot upload files larger than 100mb" + } schema: - type: file + "$ref": "definitions/errors/error.yaml" 429: description: This request was rate-limited. schema: @@ -126,8 +102,8 @@ paths: - Media "/download/{serverName}/{mediaId}/{fileName}": get: - summary: "Download content from the content repository as a given filename." - operationId: getContentOverrideName + summary: "Download content from the content repository." + operationId: getContent produces: ["*/*"] parameters: - in: path @@ -148,9 +124,7 @@ paths: type: string name: fileName x-example: filename.jpg - required: true - description: | - The filename to give in the Content-Disposition + description: An optional filename to give in the ``Content-Disposition`` header. - in: query type: boolean name: allow_remote @@ -169,10 +143,24 @@ paths: description: "The content type of the file that was previously uploaded." type: "string" Content-Disposition: - description: "The name of file given in the request" + description: |- + The ``fileName`` requested or the name of the file that was previously + uploaded, if set. type: "string" schema: type: file + # This is a workaround for us not being able to say the response is required. + description: "**Required.** The bytes for the uploaded file." + 502: + description: |- + The content is too large for the server to serve. + examples: + application/json: { + "errcode": "M_TOO_LARGE", + "error": "Content is too large to serve" + } + schema: + "$ref": "definitions/errors/error.yaml" 429: description: This request was rate-limited. schema: @@ -181,7 +169,9 @@ paths: - Media "/thumbnail/{serverName}/{mediaId}": get: - summary: "Download a thumbnail of the content from the content repository." + summary: |- + Download a thumbnail of content from the content repository. See the `thumbnailing <#thumbnails>`_ + section for more information. operationId: getContentThumbnail produces: ["image/jpeg", "image/png"] parameters: @@ -189,7 +179,7 @@ paths: type: string name: serverName required: true - x-example: matrix.org + x-example: example.org description: | The server name from the ``mxc://`` URI (the authoritory component) - in: path @@ -205,22 +195,24 @@ paths: name: width required: true description: |- - The *desired* width of the thumbnail. The actual thumbnail may not - match the size specified. + The *desired* width of the thumbnail. The actual thumbnail may be + larger than the size specified. - in: query type: integer x-example: 64 name: height required: true description: |- - The *desired* height of the thumbnail. The actual thumbnail may not - match the size specified. + The *desired* height of the thumbnail. The actual thumbnail may be + larger than the size specified. - in: query type: string enum: ["crop", "scale"] name: method x-example: "scale" - description: The desired resizing method. + description: |- + The desired resizing method. See the `thumbnailing <#thumbnails>`_ + section for more information. - in: query type: boolean name: allow_remote @@ -241,6 +233,40 @@ paths: enum: ["image/jpeg", "image/png"] schema: type: file + # This is a workaround for us not being able to say the response is required. + description: "**Required.** The bytes for the thumbnail." + 400: + description: |- + The request does not make sense to the server, or the server cannot thumbnail + the content. For example, the client requested non-integer dimensions or asked + for negatively-sized images. + examples: + application/json: { + "errcode": "M_UNKNOWN", + "error": "Cannot generate thumbnails for the requested content" + } + schema: + "$ref": "definitions/errors/error.yaml" + 413: + description: |- + The local content is too large for the server to thumbnail. + examples: + application/json: { + "errcode": "M_TOO_LARGE", + "error": "Content is too large to thumbnail" + } + schema: + "$ref": "definitions/errors/error.yaml" + 502: + description: |- + The remote content is too large for the server to thumbnail. + examples: + application/json: { + "errcode": "M_TOO_LARGE", + "error": "Content is too large to thumbnail" + } + schema: + "$ref": "definitions/errors/error.yaml" 429: description: This request was rate-limited. schema: @@ -259,7 +285,7 @@ paths: type: string x-example: "https://matrix.org" name: url - description: "The URL to get a preview of" + description: "The URL to get a preview of." required: true - in: query type: integer @@ -287,7 +313,7 @@ paths: "og:image": type: string description: |- - An MXC URI to the image. Omitted if there is no image. + An `MXC URI`_ to the image. Omitted if there is no image. examples: application/json: { "og:title": "Matrix Blog Post", diff --git a/api/client-server/room_state.yaml b/api/client-server/room_state.yaml index bda66eb8..4b159a3c 100644 --- a/api/client-server/room_state.yaml +++ b/api/client-server/room_state.yaml @@ -70,7 +70,7 @@ paths: type: object example: { "membership": "join", - "avatar_url": "mxc://localhost/SEsfnsuifSDFSSEF#auto", + "avatar_url": "mxc://localhost/SEsfnsuifSDFSSEF", "displayname": "Alice Margatroid" } responses: diff --git a/changelogs/client_server/newsfragments/2068.clarification b/changelogs/client_server/newsfragments/2068.clarification new file mode 100644 index 00000000..77ad7125 --- /dev/null +++ b/changelogs/client_server/newsfragments/2068.clarification @@ -0,0 +1 @@ +Clarify how the content repository works, and what it is used for. diff --git a/event-schemas/examples/m.room.member b/event-schemas/examples/m.room.member index b0aa59dd..18bc457b 100644 --- a/event-schemas/examples/m.room.member +++ b/event-schemas/examples/m.room.member @@ -4,7 +4,7 @@ "type": "m.room.member", "content": { "membership": "join", - "avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF#auto", + "avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF", "displayname": "Alice Margatroid" } } diff --git a/event-schemas/examples/m.room.member$invite_room_state b/event-schemas/examples/m.room.member$invite_room_state index f8f05484..9045dffd 100644 --- a/event-schemas/examples/m.room.member$invite_room_state +++ b/event-schemas/examples/m.room.member$invite_room_state @@ -2,7 +2,7 @@ "$ref": "m.room.member", "content": { "membership": "invite", - "avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF#auto", + "avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF", "displayname": "Alice Margatroid" }, "unsigned": { diff --git a/event-schemas/examples/m.room.member$third_party_invite b/event-schemas/examples/m.room.member$third_party_invite index c688a283..a40d44f9 100644 --- a/event-schemas/examples/m.room.member$third_party_invite +++ b/event-schemas/examples/m.room.member$third_party_invite @@ -2,7 +2,7 @@ "$ref": "m.room.member", "content": { "membership": "invite", - "avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF#auto", + "avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF", "displayname": "Alice Margatroid", "third_party_invite": { "display_name": "alice", diff --git a/event-schemas/schema/core-event-schema/msgtype_infos/image_info.yaml b/event-schemas/schema/core-event-schema/msgtype_infos/image_info.yaml index 8ff27b1e..b6a45007 100644 --- a/event-schemas/schema/core-event-schema/msgtype_infos/image_info.yaml +++ b/event-schemas/schema/core-event-schema/msgtype_infos/image_info.yaml @@ -19,7 +19,7 @@ properties: type: integer thumbnail_url: description: |- - The URL to a thumbnail of the image. Only present if the + The `MXC URI`_ to a thumbnail of the image. Only present if the thumbnail is unencrypted. type: string thumbnail_file: diff --git a/event-schemas/schema/m.room.message$m.audio b/event-schemas/schema/m.room.message$m.audio index 99e28110..40075541 100644 --- a/event-schemas/schema/m.room.message$m.audio +++ b/event-schemas/schema/m.room.message$m.audio @@ -27,7 +27,7 @@ properties: - m.audio type: string url: - description: Required if the file is not encrypted. The URL to the audio clip. + description: Required if the file is not encrypted. The `MXC URI`_ to the audio clip. type: string file: description: |- diff --git a/event-schemas/schema/m.room.message$m.file b/event-schemas/schema/m.room.message$m.file index 2389d8a9..225ca61d 100644 --- a/event-schemas/schema/m.room.message$m.file +++ b/event-schemas/schema/m.room.message$m.file @@ -42,7 +42,7 @@ properties: - m.file type: string url: - description: Required if the file is unencrypted. The URL to the file. + description: Required if the file is unencrypted. The `MXC URI`_ to the file. type: string file: description: |- diff --git a/event-schemas/schema/m.room.message$m.image b/event-schemas/schema/m.room.message$m.image index 1e6ebeaa..8bf9c5fa 100644 --- a/event-schemas/schema/m.room.message$m.image +++ b/event-schemas/schema/m.room.message$m.image @@ -17,7 +17,7 @@ properties: - m.image type: string url: - description: Required if the file is unencrypted. The URL to the image. + description: Required if the file is unencrypted. The `MXC URI`_ to the image. type: string file: description: |- diff --git a/event-schemas/schema/m.room.message$m.video b/event-schemas/schema/m.room.message$m.video index 2da7e0bc..01286ce2 100644 --- a/event-schemas/schema/m.room.message$m.video +++ b/event-schemas/schema/m.room.message$m.video @@ -28,7 +28,7 @@ properties: type: integer thumbnail_url: description: |- - The URL to an image thumbnail of the video clip. Only present if the + The `MXC URI`_ to an image thumbnail of the video clip. Only present if the thumbnail is unencrypted. type: string thumbnail_file: @@ -48,7 +48,7 @@ properties: - m.video type: string url: - description: Required if the file is unencrypted. The URL to the video clip. + description: Required if the file is unencrypted. The `MXC URI`_ to the video clip. type: string file: description: |- diff --git a/specification/modules/content_repo.rst b/specification/modules/content_repo.rst index e7bdb044..823efb3c 100644 --- a/specification/modules/content_repo.rst +++ b/specification/modules/content_repo.rst @@ -1,4 +1,5 @@ .. Copyright 2016 OpenMarket Ltd +.. Copyright 2019 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. @@ -17,27 +18,38 @@ Content repository .. _module:content: -This module allows users to upload content to their homeserver which is -retrievable from other homeservers. Its' purpose is to allow users to share -attachments in a room. Content locations are represented as Matrix Content (MXC) -URIs. They look like:: +The content repository (or "media repository") allows users to upload +files to their homeserver for later user. For example, files which the +user wants to send to a room would be uploaded here, as would an avatar +the user wants to use. - mxc:/// - - : The name of the homeserver where this content originated, e.g. matrix.org - : An opaque ID which identifies the content. - -Uploads are POSTed to a resource on the user's local homeserver which returns a -token which is used to GET the download. Content is downloaded from the -recipient's local homeserver, which must first transfer the content from the -origin homeserver using the same API (unless the origin and destination -homeservers are the same). +Uploads are POSTed to a resource on the user's local homeserver which +returns a MXC URI which can later be used to GET the download. Content +is downloaded from the recipient's local homeserver, which must first +transfer the content from the origin homeserver using the same API +(unless the origin and destination homeservers are the same). When serving content, the server SHOULD provide a ``Content-Security-Policy`` header. The recommended policy is ``sandbox; default-src 'none'; script-src 'none'; plugin-types application/pdf; style-src 'unsafe-inline'; object-src 'self';``. +Content in the repository should be treated as bytes as it may be encrypted. + +Matrix Content (MXC) URIs +------------------------- + +.. _`MXC URI`: + +Content locations are represented as Matrix Content (MXC) URIs. They look +like:: + + mxc:/// + + : The name of the homeserver where this content originated, e.g. matrix.org + : An opaque ID which identifies the content. + + Client behaviour ---------------- @@ -47,6 +59,11 @@ Clients can upload and download content using the following HTTP APIs. Thumbnails ~~~~~~~~~~ +The homeserver SHOULD be able to supply thumbnails for uploaded images and +videos. The exact file types which can be thumbnailed are not currently +specified - see `Issue #1938 `_ +for more information. + The thumbnail methods are "crop" and "scale". "scale" tries to return an image where either the width or the height is smaller than the requested size. The client should then scale and letterbox the image if it needs to @@ -55,18 +72,32 @@ width and height are close to the requested size and the aspect matches the requested size. The client should scale the image if it needs to fit within a given rectangle. +The dimensions given to the thumbnail API are the minimum size the client +would prefer. Servers must never return thumbnails smaller than the client's +requested dimensions, unless the content being thumbnailed is smaller than +the dimensions. When the content is smaller than the requested dimensions, +servers should return the original content rather than thumbnail it. + +Servers SHOULD pre-calculate or have a list of set dimensions for which they +will thumbnail content at. For example, the server may choose that it will +only create thumbnails sized 96x96 or 512x512. When the client requests a +thumbnail, the server will pick the size which is larger than the requested +dimensions. Servers SHOULD pre-calculate the following thumbnails for uploaded +content, and limit thumbnails to the same sizes: + +* 32x32, crop +* 96x96, crop +* 320x240, scale +* 640x480, scale +* 800x600, scale + In summary: * "scale" maintains the original aspect ratio of the image * "crop" provides an image in the aspect ratio of the sizes given in the request + * The server will return an image larger than or equal to the dimensions requested + where possible. -Server behaviour ----------------- - -Homeservers may generate thumbnails for content uploaded to remote -homeservers themselves or may rely on the remote homeserver to thumbnail -the content. Homeservers may return thumbnails of a different size to that -requested. However homeservers should provide exact matches where reasonable. -Homeservers must never upscale images. +Servers MUST NOT upscale thumbnails under any circumstance. Security considerations ----------------------- @@ -88,16 +119,20 @@ UTF-8 encoded traversals, etc). Homeservers have additional content-specific concerns: - Clients may try to upload very large files. Homeservers should not store files - that are too large and should not serve them to clients. + that are too large and should not serve them to clients, returning a HTTP 413 + error with the ``M_TOO_LARGE`` code. - Clients may try to upload very large images. Homeservers should not attempt to - generate thumbnails for images that are too large. + generate thumbnails for images that are too large, returning a HTTP 413 error + with the ``M_TOO_LARGE`` code. - Remote homeservers may host very large files or images. Homeservers should not - proxy or thumbnail large files or images from remote homeservers. + proxy or thumbnail large files or images from remote homeservers, returning a + HTTP 502 error with the ``M_TOO_LARGE`` code. - Clients may try to upload a large number of files. Homeservers should limit the - number and total size of media that can be uploaded by clients. + number and total size of media that can be uploaded by clients, returning a + HTTP 403 error with the ``M_FORBIDDEN`` code. - Clients may try to access a large number of remote files through a homeserver. Homeservers should restrict the number and size of remote files that it caches. From dc6d89caca5ea165bfe472d82f696529e80feaab Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 2 Jun 2019 21:31:06 -0600 Subject: [PATCH 0409/1250] Split download endpoints back apart Apparently you can't have an optional path parameter. --- api/client-server/content-repo.yaml | 68 ++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/api/client-server/content-repo.yaml b/api/client-server/content-repo.yaml index 576d29ef..a9a0c2f6 100644 --- a/api/client-server/content-repo.yaml +++ b/api/client-server/content-repo.yaml @@ -100,11 +100,74 @@ paths: "$ref": "definitions/errors/rate_limited.yaml" tags: - Media - "/download/{serverName}/{mediaId}/{fileName}": + "/download/{serverName}/{mediaId}": get: summary: "Download content from the content repository." operationId: getContent produces: ["*/*"] + parameters: + - in: path + type: string + name: serverName + x-example: matrix.org + required: true + description: | + The server name from the ``mxc://`` URI (the authoritory component) + - in: path + type: string + name: mediaId + x-example: ascERGshawAWawugaAcauga + required: true + description: | + The media ID from the ``mxc://`` URI (the path component) + - in: query + type: boolean + name: allow_remote + x-example: false + required: false + default: true + description: | + Indicates to the server that it should not attempt to fetch the media if it is deemed + remote. This is to prevent routing loops where the server contacts itself. Defaults to + true if not provided. + responses: + 200: + description: "The content that was previously uploaded." + headers: + Content-Type: + description: "The content type of the file that was previously uploaded." + type: "string" + Content-Disposition: + description: |- + The name of the file that was previously uploaded, if set. + type: "string" + schema: + type: file + # This is a workaround for us not being able to say the response is required. + description: "**Required.** The bytes for the uploaded file." + 502: + description: |- + The content is too large for the server to serve. + examples: + application/json: { + "errcode": "M_TOO_LARGE", + "error": "Content is too large to serve" + } + schema: + "$ref": "definitions/errors/error.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" + tags: + - Media + "/download/{serverName}/{mediaId}/{fileName}": + get: + summary: |- + Download content from the content repository. This is the same as + the download endpoint above, except permitting a desired file name. + operationId: getContentOverrideName + produces: ["*/*"] parameters: - in: path type: string @@ -124,7 +187,8 @@ paths: type: string name: fileName x-example: filename.jpg - description: An optional filename to give in the ``Content-Disposition`` header. + required: true + description: A filename to give in the ``Content-Disposition`` header. - in: query type: boolean name: allow_remote From 53aa8fe8ecc7e4d2028894a57395fe3e9340fc2c Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 3 Jun 2019 09:47:09 +0200 Subject: [PATCH 0410/1250] clarify the order events in chunk for /messages --- api/client-server/message_pagination.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index c9f9d0ae..7457530b 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -103,7 +103,7 @@ paths: chunk: type: array description: |- - A list of room events. + A list of room events. The order depends on the ``dir`` parameter. For ``dir=b`` events will be in reverse-chronological order, for ``dir=f`` in chronological order, so that events start at the ``from`` point. items: type: object title: RoomEvent From 0b42a17352356eb879ee21f264dddfdcc78ef647 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Mon, 3 Jun 2019 09:48:38 +0100 Subject: [PATCH 0411/1250] Update api/identity/definitions/request_email_validation.yaml Co-Authored-By: Travis Ralston --- api/identity/definitions/request_email_validation.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/identity/definitions/request_email_validation.yaml b/api/identity/definitions/request_email_validation.yaml index 5d1aac8a..5f15bd41 100644 --- a/api/identity/definitions/request_email_validation.yaml +++ b/api/identity/definitions/request_email_validation.yaml @@ -40,7 +40,7 @@ properties: retries between the POSTing user and the identity server. The client should increment this value if they desire a new email (e.g. a reminder) to be sent. If they do not, the server - should response with success but not resend the email. + should respond with success but not resend the email. example: 1 next_link: type: string From 49b9bfc9f6ed5041807d8d893a29f9753381ad06 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 3 Jun 2019 09:48:53 +0100 Subject: [PATCH 0412/1250] Move changelog to the right place --- .../newsfragments/2057.clarification | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelogs/{client_server => identity_service}/newsfragments/2057.clarification (100%) diff --git a/changelogs/client_server/newsfragments/2057.clarification b/changelogs/identity_service/newsfragments/2057.clarification similarity index 100% rename from changelogs/client_server/newsfragments/2057.clarification rename to changelogs/identity_service/newsfragments/2057.clarification From 39144942da1b235627b652909c0f21c8f57c33ea Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 3 Jun 2019 20:39:41 -0600 Subject: [PATCH 0413/1250] Fix title ordering --- specification/modules/end_to_end_encryption.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index e6048c28..1fd28e93 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -668,7 +668,7 @@ Used basis. The maximum number of olm sessions maintained per device should be at least 4. Recovering from undecryptable messages -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Occasionally messages may be undecryptable by clients due to a variety of reasons. When this happens to an Olm-encrypted message, the client should assume that the Olm From 8b28972a2d38935f3c5c7953ba40dbc5c36ddbcb Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Tue, 4 Jun 2019 09:28:01 +0200 Subject: [PATCH 0414/1250] PR feedback --- api/client-server/message_pagination.yaml | 5 ++++- changelogs/client_server/newsfragments/2069.clarification | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/2069.clarification diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index 7457530b..9a24537c 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -103,7 +103,10 @@ paths: chunk: type: array description: |- - A list of room events. The order depends on the ``dir`` parameter. For ``dir=b`` events will be in reverse-chronological order, for ``dir=f`` in chronological order, so that events start at the ``from`` point. + A list of room events. The order depends on the ``dir`` parameter. + For ``dir=b`` events will be in reverse-chronological order, + for ``dir=f`` in chronological order, so that events start + at the ``from`` point. items: type: object title: RoomEvent diff --git a/changelogs/client_server/newsfragments/2069.clarification b/changelogs/client_server/newsfragments/2069.clarification new file mode 100644 index 00000000..353b545d --- /dev/null +++ b/changelogs/client_server/newsfragments/2069.clarification @@ -0,0 +1 @@ +Clarify the order events in chunk are returned in for /messages From 042455d954699b486b5c732d848697d11fd6a5e4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 4 Jun 2019 10:58:39 -0600 Subject: [PATCH 0415/1250] Update changelog to appease style guidelines --- changelogs/client_server/newsfragments/2069.clarification | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/client_server/newsfragments/2069.clarification b/changelogs/client_server/newsfragments/2069.clarification index 353b545d..127573a6 100644 --- a/changelogs/client_server/newsfragments/2069.clarification +++ b/changelogs/client_server/newsfragments/2069.clarification @@ -1 +1 @@ -Clarify the order events in chunk are returned in for /messages +Clarify the order events in chunk are returned in for ``/messages``. From a3364ff35712be278fc4f5914a89dbb27f41d08a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 4 Jun 2019 12:41:30 -0600 Subject: [PATCH 0416/1250] Spec SAS verification and the common key verification framework Reference implementations: * https://gitlab.matrix.org/matrix-org/olm/commit/94f664e7256215f33639dbbad6aaf87ada082a9f * https://github.com/matrix-org/matrix-react-sdk/pull/2461 * https://github.com/matrix-org/matrix-js-sdk/pull/818 * https://github.com/matrix-org/matrix-react-sdk/pull/2596 * https://github.com/matrix-org/matrix-js-sdk/pull/837 Proposals: * [MSC1717](https://github.com/matrix-org/matrix-doc/pull/1717) * [MSC1267](https://github.com/matrix-org/matrix-doc/issues/1267) No alterations to either proposal have been made intentionally here. --- .../client_server/newsfragments/2072.feature | 1 + data-definitions/sas-emoji.json | 66 ++++ .../examples/m.key.verification.accept | 12 + .../examples/m.key.verification.cancel | 8 + event-schemas/examples/m.key.verification.key | 7 + event-schemas/examples/m.key.verification.mac | 10 + .../examples/m.key.verification.request | 11 + .../examples/m.key.verification.start | 8 + .../m.key.verification.start$m.sas.v1 | 12 + .../schema/m.key.verification.accept | 64 ++++ .../schema/m.key.verification.cancel | 70 ++++ event-schemas/schema/m.key.verification.key | 28 ++ event-schemas/schema/m.key.verification.mac | 38 ++ .../schema/m.key.verification.request | 43 +++ event-schemas/schema/m.key.verification.start | 39 +++ .../schema/m.key.verification.start$m.sas.v1 | 69 ++++ scripts/continuserv/main.go | 2 +- .../templating/matrix_templates/sections.py | 17 + scripts/templating/matrix_templates/units.py | 20 ++ .../modules/end_to_end_encryption.rst | 325 +++++++++++++++++- 20 files changed, 847 insertions(+), 3 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2072.feature create mode 100644 data-definitions/sas-emoji.json create mode 100644 event-schemas/examples/m.key.verification.accept create mode 100644 event-schemas/examples/m.key.verification.cancel create mode 100644 event-schemas/examples/m.key.verification.key create mode 100644 event-schemas/examples/m.key.verification.mac create mode 100644 event-schemas/examples/m.key.verification.request create mode 100644 event-schemas/examples/m.key.verification.start create mode 100644 event-schemas/examples/m.key.verification.start$m.sas.v1 create mode 100644 event-schemas/schema/m.key.verification.accept create mode 100644 event-schemas/schema/m.key.verification.cancel create mode 100644 event-schemas/schema/m.key.verification.key create mode 100644 event-schemas/schema/m.key.verification.mac create mode 100644 event-schemas/schema/m.key.verification.request create mode 100644 event-schemas/schema/m.key.verification.start create mode 100644 event-schemas/schema/m.key.verification.start$m.sas.v1 diff --git a/changelogs/client_server/newsfragments/2072.feature b/changelogs/client_server/newsfragments/2072.feature new file mode 100644 index 00000000..c7d8bd76 --- /dev/null +++ b/changelogs/client_server/newsfragments/2072.feature @@ -0,0 +1 @@ +Add interactive device verification, including a common framework for device verification. diff --git a/data-definitions/sas-emoji.json b/data-definitions/sas-emoji.json new file mode 100644 index 00000000..060fbd49 --- /dev/null +++ b/data-definitions/sas-emoji.json @@ -0,0 +1,66 @@ +[ + {"number": 0, "emoji": "🐶", "description": "Dog", "unicode": "U+1F436"}, + {"number": 1, "emoji": "🐱", "description": "Cat", "unicode": "U+1F431"}, + {"number": 2, "emoji": "🦁", "description": "Lion", "unicode": "U+1F981"}, + {"number": 3, "emoji": "🐎", "description": "Horse", "unicode": "U+1F40E"}, + {"number": 4, "emoji": "🦄", "description": "Unicorn", "unicode": "U+1F984"}, + {"number": 5, "emoji": "🐷", "description": "Pig", "unicode": "U+1F437"}, + {"number": 6, "emoji": "🐘", "description": "Elephant", "unicode": "U+1F418"}, + {"number": 7, "emoji": "🐰", "description": "Rabbit", "unicode": "U+1F430"}, + {"number": 8, "emoji": "🐼", "description": "Panda", "unicode": "U+1F43C"}, + {"number": 9, "emoji": "🐓", "description": "Rooster", "unicode": "U+1F413"}, + {"number": 10, "emoji": "🐧", "description": "Penguin", "unicode": "U+1F427"}, + {"number": 11, "emoji": "🐢", "description": "Turtle", "unicode": "U+1F422"}, + {"number": 12, "emoji": "🐟", "description": "Fish", "unicode": "U+1F41F"}, + {"number": 13, "emoji": "🐙", "description": "Octopus", "unicode": "U+1F419"}, + {"number": 14, "emoji": "🦋", "description": "Butterfly", "unicode": "U+1F98B"}, + {"number": 15, "emoji": "🌷", "description": "Flower", "unicode": "U+1F337"}, + {"number": 16, "emoji": "🌳", "description": "Tree", "unicode": "U+1F333"}, + {"number": 17, "emoji": "🌵", "description": "Cactus", "unicode": "U+1F335"}, + {"number": 18, "emoji": "🍄", "description": "Mushroom", "unicode": "U+1F344"}, + {"number": 19, "emoji": "🌏", "description": "Globe", "unicode": "U+1F30F"}, + {"number": 20, "emoji": "🌙", "description": "Moon", "unicode": "U+1F319"}, + {"number": 21, "emoji": "☁️", "description": "Cloud", "unicode": "U+2601U+FE0F"}, + {"number": 22, "emoji": "🔥", "description": "Fire", "unicode": "U+1F525"}, + {"number": 23, "emoji": "🍌", "description": "Banana", "unicode": "U+1F34C"}, + {"number": 24, "emoji": "🍎", "description": "Apple", "unicode": "U+1F34E"}, + {"number": 25, "emoji": "🍓", "description": "Strawberry", "unicode": "U+1F353"}, + {"number": 26, "emoji": "🌽", "description": "Corn", "unicode": "U+1F33D"}, + {"number": 27, "emoji": "🍕", "description": "Pizza", "unicode": "U+1F355"}, + {"number": 28, "emoji": "🎂", "description": "Cake", "unicode": "U+1F382"}, + {"number": 29, "emoji": "❤️", "description": "Heart", "unicode": "U+2764U+FE0F"}, + {"number": 30, "emoji": "😀", "description": "Smiley", "unicode": "U+1F600"}, + {"number": 31, "emoji": "🤖", "description": "Robot", "unicode": "U+1F916"}, + {"number": 32, "emoji": "🎩", "description": "Hat", "unicode": "U+1F3A9"}, + {"number": 33, "emoji": "👓", "description": "Glasses", "unicode": "U+1F453"}, + {"number": 34, "emoji": "🔧", "description": "Spanner", "unicode": "U+1F527"}, + {"number": 35, "emoji": "🎅", "description": "Santa", "unicode": "U+1F385"}, + {"number": 36, "emoji": "👍", "description": "Thumbs Up", "unicode": "U+1F44D"}, + {"number": 37, "emoji": "☂️", "description": "Umbrella", "unicode": "U+2602U+FE0F"}, + {"number": 38, "emoji": "⌛", "description": "Hourglass", "unicode": "U+231B"}, + {"number": 39, "emoji": "⏰", "description": "Clock", "unicode": "U+23F0"}, + {"number": 40, "emoji": "🎁", "description": "Gift", "unicode": "U+1F381"}, + {"number": 41, "emoji": "💡", "description": "Light Bulb", "unicode": "U+1F4A1"}, + {"number": 42, "emoji": "📕", "description": "Book", "unicode": "U+1F4D5"}, + {"number": 43, "emoji": "✏️", "description": "Pencil", "unicode": "U+270FU+FE0F"}, + {"number": 44, "emoji": "📎", "description": "Paperclip", "unicode": "U+1F4CE"}, + {"number": 45, "emoji": "✂️", "description": "Scissors", "unicode": "U+2702U+FE0F"}, + {"number": 46, "emoji": "🔒", "description": "Lock", "unicode": "U+1F512"}, + {"number": 47, "emoji": "🔑", "description": "Key", "unicode": "U+1F511"}, + {"number": 48, "emoji": "🔨", "description": "Hammer", "unicode": "U+1F528"}, + {"number": 49, "emoji": "☎️", "description": "Telephone", "unicode": "U+260EU+FE0F"}, + {"number": 50, "emoji": "🏁", "description": "Flag", "unicode": "U+1F3C1"}, + {"number": 51, "emoji": "🚂", "description": "Train", "unicode": "U+1F682"}, + {"number": 52, "emoji": "🚲", "description": "Bicycle", "unicode": "U+1F6B2"}, + {"number": 53, "emoji": "✈️", "description": "Aeroplane", "unicode": "U+2708U+FE0F"}, + {"number": 54, "emoji": "🚀", "description": "Rocket", "unicode": "U+1F680"}, + {"number": 55, "emoji": "🏆", "description": "Trophy", "unicode": "U+1F3C6"}, + {"number": 56, "emoji": "⚽", "description": "Ball", "unicode": "U+26BD"}, + {"number": 57, "emoji": "🎸", "description": "Guitar", "unicode": "U+1F3B8"}, + {"number": 58, "emoji": "🎺", "description": "Trumpet", "unicode": "U+1F3BA"}, + {"number": 59, "emoji": "🔔", "description": "Bell", "unicode": "U+1F514"}, + {"number": 60, "emoji": "⚓", "description": "Anchor", "unicode": "U+2693"}, + {"number": 61, "emoji": "🎧", "description": "Headphones", "unicode": "U+1F3A7"}, + {"number": 62, "emoji": "📁", "description": "Folder", "unicode": "U+1F4C1"}, + {"number": 63, "emoji": "📌", "description": "Pin", "unicode": "U+1F4CC"} +] diff --git a/event-schemas/examples/m.key.verification.accept b/event-schemas/examples/m.key.verification.accept new file mode 100644 index 00000000..98e89c06 --- /dev/null +++ b/event-schemas/examples/m.key.verification.accept @@ -0,0 +1,12 @@ +{ + "type": "m.key.verification.accept", + "content": { + "transaction_id": "S0meUniqueAndOpaqueString", + "method": "m.sas.v1", + "key_agreement_protocol": "curve25519", + "hash": "sha256", + "message_authentication_code": "hkdf-hmac-sha256", + "short_authentication_string": ["decimal", "emoji"], + "commitment": "fQpGIW1Snz+pwLZu6sTy2aHy/DYWWTspTJRPyNp0PKkymfIsNffysMl6ObMMFdIJhk6g6pwlIqZ54rxo8SLmAg" + } +} diff --git a/event-schemas/examples/m.key.verification.cancel b/event-schemas/examples/m.key.verification.cancel new file mode 100644 index 00000000..9d78f67c --- /dev/null +++ b/event-schemas/examples/m.key.verification.cancel @@ -0,0 +1,8 @@ +{ + "type": "m.key.verification.cancel", + "content": { + "transaction_id": "S0meUniqueAndOpaqueString", + "code": "m.user", + "reason": "User rejected the key verification request" + } +} diff --git a/event-schemas/examples/m.key.verification.key b/event-schemas/examples/m.key.verification.key new file mode 100644 index 00000000..608a2ebd --- /dev/null +++ b/event-schemas/examples/m.key.verification.key @@ -0,0 +1,7 @@ +{ + "type": "m.key.verification.key", + "content": { + "transaction_id": "S0meUniqueAndOpaqueString", + "key": "fQpGIW1Snz+pwLZu6sTy2aHy/DYWWTspTJRPyNp0PKkymfIsNffysMl6ObMMFdIJhk6g6pwlIqZ54rxo8SLmAg" + } +} diff --git a/event-schemas/examples/m.key.verification.mac b/event-schemas/examples/m.key.verification.mac new file mode 100644 index 00000000..c77c3a8d --- /dev/null +++ b/event-schemas/examples/m.key.verification.mac @@ -0,0 +1,10 @@ +{ + "type": "m.key.verification.mac", + "content": { + "transaction_id": "S0meUniqueAndOpaqueString", + "keys": "2Wptgo4CwmLo/Y8B8qinxApKaCkBG2fjTWB7AbP5Uy+aIbygsSdLOFzvdDjww8zUVKCmI02eP9xtyJxc/cLiBA", + "mac": { + "ed25519:ABCDEF": "fQpGIW1Snz+pwLZu6sTy2aHy/DYWWTspTJRPyNp0PKkymfIsNffysMl6ObMMFdIJhk6g6pwlIqZ54rxo8SLmAg" + } + } +} diff --git a/event-schemas/examples/m.key.verification.request b/event-schemas/examples/m.key.verification.request new file mode 100644 index 00000000..258471d2 --- /dev/null +++ b/event-schemas/examples/m.key.verification.request @@ -0,0 +1,11 @@ +{ + "type": "m.key.verification.request", + "content": { + "from_device": "AliceDevice2", + "transaction_id": "S0meUniqueAndOpaqueString", + "methods": [ + "m.sas.v1" + ], + "timestamp": 1559598944869 + } +} diff --git a/event-schemas/examples/m.key.verification.start b/event-schemas/examples/m.key.verification.start new file mode 100644 index 00000000..52f16150 --- /dev/null +++ b/event-schemas/examples/m.key.verification.start @@ -0,0 +1,8 @@ +{ + "type": "m.key.verification.start", + "content": { + "from_device": "BobDevice1", + "transaction_id": "S0meUniqueAndOpaqueString", + "method": "m.sas.v1" + } +} diff --git a/event-schemas/examples/m.key.verification.start$m.sas.v1 b/event-schemas/examples/m.key.verification.start$m.sas.v1 new file mode 100644 index 00000000..dae1d405 --- /dev/null +++ b/event-schemas/examples/m.key.verification.start$m.sas.v1 @@ -0,0 +1,12 @@ +{ + "type": "m.key.verification.start", + "content": { + "from_device": "BobDevice1", + "transaction_id": "S0meUniqueAndOpaqueString", + "method": "m.sas.v1", + "key_agreement_protocols": ["curve25519"], + "hashes": ["sha256"], + "message_authentication_codes": ["hkdf-hmac-sha256"], + "short_authentication_string": ["decimal", "emoji"] + } +} diff --git a/event-schemas/schema/m.key.verification.accept b/event-schemas/schema/m.key.verification.accept new file mode 100644 index 00000000..e52df39e --- /dev/null +++ b/event-schemas/schema/m.key.verification.accept @@ -0,0 +1,64 @@ +--- +allOf: + - $ref: core-event-schema/event.yaml + +description: |- + Accepts a previously sent ``m.key.verification.start`` messge. Typically sent as a + `to-device`_ event. +properties: + content: + properties: + transaction_id: + type: string + description: |- + An opaque identifier for the verification process. Must be the same as + the one used for the ``m.key.verification.start`` message. + method: + type: string + enum: ["m.sas.v1"] + description: |- + The verification method to use. Must be ``m.sas.v1``. + key_agreement_protocol: + type: string + description: |- + The key agreement protocol the device is choosing to use, out of the + options in the ``m.key.verification.start`` message. + hash: + type: string + description: |- + The hash method the device is choosing to use, out of the options in + the ``m.key.verification.start`` message. + message_authentication_code: + type: string + description: |- + The message authentication code the device is choosing to use, out of + the options in the ``m.key.verification.start`` message. + short_authentication_string: + type: array + description: |- + The SAS methods both devices involved in the verification process + understand. Must be a subset of the options in the ``m.key.verification.start`` + message. + items: + type: string + enum: ["decimal", "emoji"] + commitment: + type: string + description: |- + The hash (encoded as unpadded base64) of the concatenation of the device's + ephemeral public key (encoded as unpadded base64) and the canonical JSON + representation of the ``m.key.verification.start`` message. + required: + - transaction_id + - method + - key_agreement_protocol + - hash + - message_authentication_code + - short_authentication_string + - commitment + type: object + type: + enum: + - m.key.verification.accept + type: string +type: object diff --git a/event-schemas/schema/m.key.verification.cancel b/event-schemas/schema/m.key.verification.cancel new file mode 100644 index 00000000..36ffc9ea --- /dev/null +++ b/event-schemas/schema/m.key.verification.cancel @@ -0,0 +1,70 @@ +--- +allOf: + - $ref: core-event-schema/event.yaml + +description: |- + Cancels a key verification process/request. Typically sent as a `to-device`_ event. +properties: + content: + properties: + transaction_id: + type: string + description: |- + The opaque identifier for the verification process/request. + reason: + type: string + description: |- + A human readable description of the ``code``. The client should only rely on this + string if it does not understand the ``code``. + code: + type: string + # Note: this is not an enum because we go into detail about the different + # error codes. If we made this an enum, we'd be repeating information. + # Also, we can't put a real bulleted list in here because the HTML2RST parser + # cuts the text at weird points, breaking the list completely. + description: |- + The error code for why the process/request was cancelled by the user. Error + codes should use the Java package naming convention if not in the following + list: + + ``m.user``: The user cancelled the verification. + + ``m.timeout``: The verification process timed out. Verification processes + can define their own timeout parameters. + + ``m.unknown_transaction``: The device does not know about the given transaction + ID. + + ``m.unknown_method``: The device does not know how to handle the requested + method. This should be sent for ``m.key.verification.start`` messages and + messages defined by individual verification processes. + + ``m.unexpected_message``: The device received an unexpected message. Typically + raised when one of the parties is handling the verification out of order. + + ``m.key_mismatch``: The key was not verified. + + ``m.user_mismatch``: The expected user did not match the user verified. + + ``m.invalid_message``: The message received was invalid. + + ``m.accepted``: A ``m.key.verification.request`` was accepted by a different + device. The device receiving this error can ignore the verification request. + + Clients should be careful to avoid error loops. For example, if a device sends + an incorrect message and the client returns ``m.invalid_message`` to which it + gets an unexpected response with ``m.unexpected_message``, the client should not + respond again with ``m.unexpected_message`` to avoid the other device potentially + sending another error response. + + .. The above blank line is important for RST. + required: + - transaction_id + - code + - reason + type: object + type: + enum: + - m.key.verification.cancel + type: string +type: object diff --git a/event-schemas/schema/m.key.verification.key b/event-schemas/schema/m.key.verification.key new file mode 100644 index 00000000..6dc4954b --- /dev/null +++ b/event-schemas/schema/m.key.verification.key @@ -0,0 +1,28 @@ +--- +allOf: + - $ref: core-event-schema/event.yaml + +description: |- + Sends the ephemeral public key for a device to the partner device. Typically sent as a + `to-device`_ event. +properties: + content: + properties: + transaction_id: + type: string + description: |- + An opaque identifier for the verification process. Must be the same as + the one used for the ``m.key.verification.start`` message. + key: + type: string + description: |- + The device's ephemeral public key, encoded as unpadded base64. + required: + - transaction_id + - key + type: object + type: + enum: + - m.key.verification.key + type: string +type: object diff --git a/event-schemas/schema/m.key.verification.mac b/event-schemas/schema/m.key.verification.mac new file mode 100644 index 00000000..769ebe15 --- /dev/null +++ b/event-schemas/schema/m.key.verification.mac @@ -0,0 +1,38 @@ +--- +allOf: + - $ref: core-event-schema/event.yaml + +description: |- + Sends the MAC of a device's key to the partner device. Typically sent as a + `to-device`_ event. +properties: + content: + properties: + transaction_id: + type: string + description: |- + An opaque identifier for the verification process. Must be the same as + the one used for the ``m.key.verification.start`` message. + mac: + type: object + description: |- + A map of the key ID to the MAC of the key, using the algorithm in the + verification process. The MAC is encoded as unpadded base64. + additionalProperties: + type: string + description: The key's MAC, encoded as unpadded base64. + keys: + type: string + description: |- + The MAC of the comma-separated, sorted, list of key IDs given in the ``mac`` + property, encoded as unpadded base64. + required: + - transaction_id + - mac + - keys + type: object + type: + enum: + - m.key.verification.mac + type: string +type: object diff --git a/event-schemas/schema/m.key.verification.request b/event-schemas/schema/m.key.verification.request new file mode 100644 index 00000000..c9efa14e --- /dev/null +++ b/event-schemas/schema/m.key.verification.request @@ -0,0 +1,43 @@ +--- +allOf: + - $ref: core-event-schema/event.yaml + +description: |- + Requests a key verification with another user's devices. Typically sent as a + `to-device`_ event. +properties: + content: + properties: + from_device: + type: string + description: |- + The device ID which is initiating the request. + transaction_id: + type: string + description: |- + An opaque identifier for the verification request. Must be unique + with respect to the devices involved. + methods: + type: array + description: |- + The verification methods supported by the sender. + items: + type: string + timestamp: + type: integer + format: int64 + description: |- + The POSIX timestamp in milliseconds for when the request was made. If + the request is in the future by more than 5 minutes or more than 10 + minutes in the past, the message should be ignored by the receiver. + required: + - from_device + - transaction_id + - methods + - timestamp + type: object + type: + enum: + - m.key.verification.request + type: string +type: object diff --git a/event-schemas/schema/m.key.verification.start b/event-schemas/schema/m.key.verification.start new file mode 100644 index 00000000..ad59d6c7 --- /dev/null +++ b/event-schemas/schema/m.key.verification.start @@ -0,0 +1,39 @@ +--- +allOf: + - $ref: core-event-schema/event.yaml + +description: |- + Begins a key verification process. Typically sent as a `to-device`_ event. +properties: + content: + properties: + from_device: + type: string + description: |- + The device ID which is initiating the process. + transaction_id: + type: string + description: |- + An opaque identifier for the verification process. Must be unique + with respect to the devices involved. Must be the same as the + ``transaction_id`` given in the ``m.key.verification.request`` + if this process is originating from a request. + method: + type: string + description: |- + The verification method to use. + next_method: + type: string + description: |- + Optional method to use to verify the other user's key with. Applicable + when the ``method`` chosen only verifies one user's key. + required: + - from_device + - transaction_id + - method + type: object + type: + enum: + - m.key.verification.start + type: string +type: object diff --git a/event-schemas/schema/m.key.verification.start$m.sas.v1 b/event-schemas/schema/m.key.verification.start$m.sas.v1 new file mode 100644 index 00000000..867ca820 --- /dev/null +++ b/event-schemas/schema/m.key.verification.start$m.sas.v1 @@ -0,0 +1,69 @@ +--- +allOf: + - $ref: core-event-schema/event.yaml + +description: |- + Begins a SAS key verification process. Typically sent as a `to-device`_ event. +properties: + content: + properties: + from_device: + type: string + description: |- + The device ID which is initiating the process. + transaction_id: + type: string + description: |- + An opaque identifier for the verification process. Must be unique + with respect to the devices involved. Must be the same as the + ``transaction_id`` given in the ``m.key.verification.request`` + if this process is originating from a request. + method: + type: string + enum: ["m.sas.v1"] + description: |- + The verification method to use. Must be ``m.sas.v1``. + key_agreement_protocols: + type: array + description: |- + The key agreement protocols the sending device understands. Must + include at least ``curve25519``. + items: + type: string + hashes: + type: array + description: |- + The hash methods the sending device understands. Must include at least + ``sha256``. + items: + type: string + message_authentication_codes: + type: array + description: |- + The message authentication codes that the sending device understands. + Must include at least ``hkdf-hmac-sha256``. + items: + type: string + short_authentication_string: + type: array + description: |- + The SAS methods the sending device (and the sending device's user) + understands. Must include at least ``decimal``. Optionally can include + ``emoji``. + items: + type: string + enum: ["decimal", "emoji"] + required: + - from_device + - transaction_id + - method + - key_agreement_protocols + - hashes + - message_authentication_codes + - short_authentication_string + type: object + type: + enum: + - m.key.verification.start + type: string +type: object diff --git a/scripts/continuserv/main.go b/scripts/continuserv/main.go index 2ef6fed9..1bd07e6e 100644 --- a/scripts/continuserv/main.go +++ b/scripts/continuserv/main.go @@ -52,7 +52,7 @@ func main() { walker := makeWalker(dir, w) paths := []string{"api", "changelogs", "event-schemas", "scripts", - "specification"} + "specification", "schemas", "data-definitions"} for _, p := range paths { filepath.Walk(path.Join(dir, p), walker) diff --git a/scripts/templating/matrix_templates/sections.py b/scripts/templating/matrix_templates/sections.py index c88959ed..7000916b 100644 --- a/scripts/templating/matrix_templates/sections.py +++ b/scripts/templating/matrix_templates/sections.py @@ -18,6 +18,7 @@ import inspect import json import os import logging +import re logger = logging.getLogger(__name__) @@ -225,3 +226,19 @@ class MatrixSections(Sections): examples=swagger_def['examples'], title_kind=subtitle_title_char) return rendered + + def render_sas_emoji_table(self): + emoji = self.units.get("sas_emoji") + rendered = ".. csv-table::\n" + rendered += " :header: \"Number\", \"Emoji\", \"Unicode\", \"Description\"\n" + rendered += " :widths: 10, 10, 15, 20\n" + rendered += "\n" + for row in emoji: + rendered += " %d, \"%s\", \"``%s``\", \"%s\"\n" % ( + row['number'], + row['emoji'], + row['unicode'], + row['description'], + ) + rendered += "\n" + return rendered diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index ddb65efe..fe3ba5d2 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -59,6 +59,8 @@ TARGETS = os.path.join(matrix_doc_dir, "specification/targets.yaml") ROOM_EVENT = "core-event-schema/room_event.yaml" STATE_EVENT = "core-event-schema/state_event.yaml" +SAS_EMOJI_JSON = os.path.join(matrix_doc_dir, "data-definitions/sas-emoji.json") + logger = logging.getLogger(__name__) # a yaml Loader which loads mappings into OrderedDicts instead of regular @@ -1088,3 +1090,21 @@ class MatrixUnits(Units): "string": git_version, "revision": git_commit } + + def load_sas_emoji(self): + with open(SAS_EMOJI_JSON, 'r', encoding='utf-8') as sas_json: + emoji = json.load(sas_json) + + # Verify the emoji matches the unicode + for c in emoji: + e = c['emoji'] + logger.info("Checking emoji %s (%s)", e, c['description']) + u = re.sub(r'U\+([0-9a-fA-F]+)', lambda m: chr(int(m.group(1), 16)), c['unicode']) + if e != u: + raise Exception("Emoji %s should be %s not %s" % ( + c['description'], + repr(e), + c['unicode'], + )) + + return emoji diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 1fd28e93..4bd12b71 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -396,8 +396,8 @@ recommended that clients provide mechanisms by which the user can see: Ed25519 signing key for each device, again encoded using unpadded Base64. Alice can then meet Bob in person, or contact him via some other trusted -medium, and ask him to read out the Ed25519 key shown on his device. She -compares this with the value shown for his device on her client. +medium, and use `SAS Verification`_ or ask him to read out the Ed25519 key +shown on his device, comparing it to the one shown on Alice's device. Device verification may reach one of several conclusions. For example: @@ -423,6 +423,327 @@ Device verification may reach one of several conclusions. For example: decrypted by such a device. For the Olm protocol, this is documented at https://matrix.org/git/olm/about/docs/signing.rst. + +Key verification framework +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Verifying keys manually by reading out the Ed25519 key is not very user friendly, +and can lead to errors. In order to help mitigate errors, and to make the process +eaiser for users, some verification methods are supported by the specification. +The methods all use a common framework for negotiating the key verification. + +To use this framework, Alice's client would send ``m.key.verification.request`` +events to Bob's devices. All of the ``to_device`` messages sent to Bob MUST have +the same ``transaction_id`` to indicate they are part of the same request. This +allows Bob to reject the request on one device, and have it apply to all of his +devices. Similarly, it allows Bob to process the verification on one device without +having to involve all of his devices. + +When Bob's device receives a ``m.key.verification.request``, it should prompt Bob +to verify keys with Alice using one of the supported methods in the request. If +Bob's device does not understand any of the methods, it should not cancel the request +as one of his other devices may support the request. Instead, Bob's device should +tell Bob that an unsupported method was used for starting key verification. The +prompt for Bob to accept/reject Alice's request (or the unsupported method prompt) +should be automatically dismissed 10 minutes after the ``timestamp`` field or 2 +minutes after Bob's client receives the message, whichever comes first, if Bob +does not interact with the prompt. The prompt should additionally be hidden if +an appropriate ``m.key.verification.cancel`` message is received. + +If Bob rejects the request, Bob's client must send a ``m.key.verification.cancel`` +message to Alice's device. Upon receipt, Alice's device should tell her that Bob +does not want to verify her device and send ``m.key.verification.cancel`` messages +to all of Bob's devices to notify them that the request was rejected. + +If Bob accepts the request, Bob's device starts the key verification process by +sending a ``m.key.verification.start`` message to Alice's device. Upon receipt +of this message, Alice's device should send a ``m.key.verification.cancel`` message +to all of Bob's other devices to indicate the process has been started. The start +message must use the same ``transaction_id`` from the original key verification +request if it is in response to the request. The start message can be sent indepdently +of any request. + +Individual verification methods may add additional steps, events, and properties to +the verification messages. Event types for methods defined in this specification must +be under the ``m.key.verification`` namespace and any other event types must be namespaced +according to the Java package naming convention. + +Any of Alice's or Bob's devices can cancel the key verification request or process +at any time with a ``m.key.verification.cancel`` message to all applicable devices. + +This framework yields the following handshake, assuming both Alice and Bob each have +2 devices, Bob's first device accepts the key verification request, and Alice's second +device initiates the request. Note how Alice's first device is not involved in the +request or verification process. + +:: + + +---------------+ +---------------+ +-------------+ +-------------+ + | AliceDevice1 | | AliceDevice2 | | BobDevice1 | | BobDevice2 | + +---------------+ +---------------+ +-------------+ +-------------+ + | | | | + | | m.key.verification.request | | + | |---------------------------------->| | + | | | | + | | m.key.verification.request | | + | |-------------------------------------------------->| + | | | | + | | m.key.verification.start | | + | |<----------------------------------| | + | | | | + | | m.key.verification.cancel | | + | |-------------------------------------------------->| + | | | | + + +After the handshake, the verification process begins. + +{{m_key_verification_request_event}} + +{{m_key_verification_start_event}} + +{{m_key_verification_cancel_event}} + + +.. _`SAS Verification`: + +Short Authentication String (SAS) verification +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +SAS verification is a user-friendly key verification process built off the common +framework outlined above. SAS verification is intended to be a highly interactive +process for users, and as such exposes verfiication methods which are easier for +users to use. + +The verification process is heavily inspired by Phil Zimmerman's ZRTP key agreement +handshake. A key part of key agreement in ZRTP is the hash commitment: the party that +begins the Diffie-Hellman key sharing sends a hash of their part of the Diffie-Hellman +exchange, and does not send their part of the Diffie-Hellman exchange until they have +received the other party's part. Thus an attacker essentially only has one attempt to +attack the Diffie-Hellman exchange, and hence we can verify fewer bits while still +achieving a high degree of security: if we verify n bits, then an attacker has a 1 in +2\ :sup:`n` chance of success. For example, if we verify 40 bits, then an attacker has +a 1 in 1,099,511,627,776 chance (or less than 1 in 1012 chance) of success. A failed +attack would result in a mismatched Short Authentication String, alerting users to the +attack. + +The verification process takes place over `to-device`_ messages in two phases: + +1. Key agreement phase (based on `ZRTP key agreement `_). +#. Key verification phase (based on HMAC). + +The process between Alice and Bob verifying each other would be: + +.. |AlicePublicKey| replace:: :math:`K_{A}^{public}` +.. |AlicePrivateKey| replace:: :math:`K_{A}^{private}` +.. |AliceCurve25519| replace:: :math:`K_{A}^{private}K_{A}^{public}` +.. |BobPublicKey| replace:: :math:`K_{B}^{public}` +.. |BobPrivateKey| replace:: :math:`K_{B}^{private}` +.. |BobCurve25519| replace:: :math:`K_{B}^{private}K_{B}^{public}` +.. |AliceBobCurve25519| replace:: :math:`K_{A}^{private}K_{B}^{public}` +.. |BobAliceCurve25519| replace:: :math:`K_{B}^{private}K_{A}^{public}` +.. |AliceBobECDH| replace:: :math:`ECDH(K_{A}^{private},K_{B}^{public})` + +1. Alice and Bob establish a secure connection, likely meeting in-person. "Secure" + here means that either party cannot be impersonated, not explicit secrecy. +#. Alice and Bob communicate which devices they'd like to verify with each other. +#. Alice selects Bob's device from the device list and begins verification. +#. Alice's client ensures it has a copy of Bob's device key. +#. Alice's device sends Bob's device a ``m.key.verification.start`` message. +#. Bob's device receives the message and selects a key agreement protocol, hash + algorithm, message authentication code, and SAS method supported by Alice's + device. +#. Bob's device ensures it has a copy of Alice's device key. +#. Bob's device creates an ephemeral Curve25519 key pair (|BobCurve25519|), and + calculates the hash (using the chosen algorithm) of the public key |BobPublicKey|. +#. Bob's device replies to Alice's device with a ``m.key.verification.accept`` message. +#. Alice's device receives Bob's message and stores the commitment hash for later use. +#. Alice's device creates an ephemeral Curve25519 key pair (|AliceCurve25519|) and + replies to Bob's device with a ``m.key.verification.key``, sending only the public + key |AlicePublicKey|. +#. Bob's device receives Alice's message and replies with its own ``m.key.verification.key`` + message containing its public key |BobPublicKey|. +#. Alice's device receives Bob's message and verifies the commitment hash from earlier + matches the hash of the key Bob's device just sent and the content of Alice's + ``m.key.verification.start`` message. +#. Both Alice and Bob's devices perform an Elliptic-curve Diffie-Hellman (|AliceBobECDH|), + using the result as the shared secret. +#. Both Alice and Bob's devices display a SAS to their users, which is derived + from the shared key using one of the methods in this section. If multiple SAS + methods are available, clients should allow the users to select a method. +#. Alice and Bob compare the strings shown by their devices, and tell their devices if + they match or not. +#. Assuming they match, Alice and Bob's devices calculate the HMAC of their own device + and a comma-separated sorted list of of the key IDs that they wish the other user + to verify. HMAC is defined in RFC 2104, and SHA-256 as the hash function. The key for + the HMAC is different for each item and is calculated by generating 32 bytes (256 bits) + using `the key verification HKDF <#SAS-HKDF>`_. +#. Alice's device sends Bob's device a ``m.key.verification.mac`` message containing the + MAC of Alice's device keys and the MAC of her key IDs to be verified. Bob's device does + the same for Bob's device keys and key IDs concurrently with Alice. +#. When the other device receives the ``m.key.verification.mac`` message, the device + calculates the HMAC of its copies of the other device's keys given in the message, + as well as the HMAC of the comma-seperated, sorted, list of key IDs in the message. + The device compares these with the HMAC values given in the message, and if everything + matches then the device keys are verified. + +The wire protocol looks like the following between Alice and Bob's devices:: + + +-------------+ +-----------+ + | AliceDevice | | BobDevice | + +-------------+ +-----------+ + | | + | m.key.verification.start | + |-------------------------------->| + | | + | m.key.verification.accept | + |<--------------------------------| + | | + | m.key.verification.key | + |-------------------------------->| + | | + | m.key.verification.key | + |<--------------------------------| + | | + | m.key.verification.mac | + |-------------------------------->| + | | + | m.key.verification.mac | + |<--------------------------------| + | | + +Error and exception handling +<<<<<<<<<<<<<<<<<<<<<<<<<<<< + +At any point the interactive verfication can go wrong. The following describes what +to do when an error happens: + +* Alice or Bob can cancel the verification at any time. A ``m.key.verification.cancel`` + message must be sent to signify the cancelation. +* The verification can time out. Clients should time out a verification that does not + complete within 5 minutes. Additionally, clients should expire a ``transaction_id`` + which goes unused for 5 minutes after having last sent/received it. The client should + inform the user that the verification timed out, and send an appropriate ``m.key.verification.cancel`` + message to the other device. +* When the same device attempts to intiate multiple verification attempts, cancel all + attempts with that device. +* When a device receives an unknown ``transaction_id``, it should send an appropriate + ``m.key.verfication.cancel`` message to the other device indicating as such. This + does not apply for inbound ``m.key.verification.start`` or ``m.key.verification.cancel`` + messages. +* If the two devices do not share a common key share, hash, HMAC, or SAS method then + the device should notify the other device with an appropriate ``m.key.verification.cancel`` + message. +* If the user claims the Short Authentication Strings do not match, the device should + send an appropriate ``m.key.verification.cancel`` message to the other device. +* If the device receives a message out of sequence or that it was not expecting, it should + notify the other device with an appropriate ``m.key.verification.cancel`` message. + + +Verification messages specific to SAS +<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + +Building off the common framework, the following events are involved in SAS verification. + +The ``m.key.verification.cancel`` event is unchanged, however the following error codes +are used in addition to those already specified: + +* ``m.unknown_method``: The devices are unable to agree on the key agreement, hash, MAC, + or SAS method. +* ``m.mismatched_commitment``: The hash commitment did not match. +* ``m.mismatched_sas``: The SAS did not match. + + +{{m_key_verification_start_m_sas_v1_event}} + +{{m_key_verification_accept_event}} + +{{m_key_verification_key_event}} + +{{m_key_verification_mac_event}} + + +.. _`SAS-HKDF`: + +HKDF calculation +<<<<<<<<<<<<<<<< + +In all of the SAS methods, HKDF is as defined in RFC 5869 and uses the previously +agreed upon hash function for the hash function. The shared secret is supplied +as the input keying material. No salt is used, and the input parameter is the +concatenation of: + + * The string ``MATRIX_KEY_VERIFICATION_SAS``. + * The Matrix ID of the user who sent the ``m.key.verification.start`` message. + * The Device ID of the device which sent the ``m.key.verification.start`` message. + * The Matrix ID of the user who sent the ``m.key.verification.accept`` message. + * The Device ID of the device which sent the ``m.key.verification.accept`` message. + * The ``transaction_id`` being used. + +HKDF is used over the plain shared secret as it results in a harder attack +as well as more uniform data to work with. + +For verification of each party's device keys, HKDF is as defined in RFC 5869 and +uses SHA-256 as the hash function. The shared secret is supplied as the input keying +material. No salt is used, and in the input parameter is the concatenation of: + + * The string ``MATRIX_KEY_VERIFICATION_MAC``. + * The Matrix ID of the user whose key is being MAC-ed. + * The Device ID of the device sending the MAC. + * The Matrix ID of the other user. + * The Device ID of the device receiving the MAC. + * The ``transaction_id`` being used. + * The Key ID of the key being MAC-ed, or the string ``KEY_IDS`` if the item + being MAC-ed is the list of key IDs. + +SAS method: ``decimal`` +<<<<<<<<<<<<<<<<<<<<<<< + +Generate 5 bytes using `HKDF <#SAS-HKDF>`_ then take sequences of 13 bits to +convert to decimal numbers (resulting in 3 numbers between 0 and 8191 inclusive +each). Add 1000 to each calculated number. + +The bitwise operations to get the numbers given the 5 bytes +:math:`B_{0}, B_{1}, B_{2}, B_{3}, B_{4}` would be: + +* First: :math:`(B_{0} \ll 5 | B_{1} \gg 3) + 1000` +* Second: :math:`(B_{1} \& 0x7 | B_{2} \ll 2 | B_{3} \gg 6) + 1000` +* Third: :math:`((B_{3} \& 0x3F) \ll 7 | B_{4} \gg 1) + 1000` + +The digits are displayed to the user either with an appropriate separator, +such as dashes, or with the numbers on individual lines. + +SAS method: ``emoji`` +<<<<<<<<<<<<<<<<<<<<< + +Generate 6 bytes using `HKDF <#SAS-HKDF>`_ then split the first 42 bits into +7 groups of 6 bits, similar to how one would base64 encode something. Convert +each group of 6 bits to a number and use the following table to get the corresponding +emoji: + +{{sas_emoji_table}} + +.. Note:: + This table is available as JSON at + https://github.com/matrix-org/matrix-doc/blob/master/data-definitions/sas-emoji.json + +.. admonition:: Rationale + + The emoji above were chosen to: + + * Be recognisable without colour. + * Be recognisable at a small size. + * Be recognisable by most cultures. + * Be distinguishable from each other. + * Easily described by a few words. + * Avoid symbols with negative connotations. + * Be likely similar across multiple platforms. + +Clients SHOULD show the emoji with the descriptions from the table, or appropriate +translation of those descriptions. Client authors SHOULD collaborate to create a +common set of translations for all languages. + + .. section name changed, so make sure that old links keep working .. _key-sharing: From 37b1e171fc182d3a055190b02f3cfe7c7ea9cd99 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 4 Jun 2019 23:51:10 +0100 Subject: [PATCH 0417/1250] MSC2076: Enforce key-validity periods when validating event signatures --- proposals/2076-enforce-validity-periods.md | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 proposals/2076-enforce-validity-periods.md diff --git a/proposals/2076-enforce-validity-periods.md b/proposals/2076-enforce-validity-periods.md new file mode 100644 index 00000000..b09aa2f4 --- /dev/null +++ b/proposals/2076-enforce-validity-periods.md @@ -0,0 +1,42 @@ +# MSC2076: Enforce key-validity periods when validating event signatures + +## Background + +The [Federation API +specification](https://matrix.org/docs/spec/server_server/r0.1.1.html#validating-hashes-and-signatures-on-received-events) +specifies that events should be validated via the signature verification +algorithm, but does not specify how the keys for that check should be obtained +and validated. + +In practice, the implementation has been as follows. The receiving server +first requests a copy of the key via the [`GET /_matrix/key/v2/server/` +API](https://matrix.org/docs/spec/server_server/r0.1.1.html#get-matrix-key-v2-server-keyid) +directly from the server which created the signature, or via the [`POST +/_matrix/key/v2/query` API](https://matrix.org/docs/spec/server_server/r0.1.1.html#post-matrix-key-v2-query) +from a trusted key server. Once such a key is obtained, it is then cached +forever. No check is made on the `valid_until_ts` field, and +`minimum_valid_until_ts` is set to zero for calls to `POST +/_matrix/key/v2/query`. + +This is highly unsatisfactory, as it means that, should a key be compromised, +then an attacker can spoof arbitrary events claiming to be from the compromised +server forever, since there is no revocation mechanism. + +## Proposal + +This MSC proposes to enforce the `valid_until_ts` property when validating +event signatures. In particular, the server must ensure that it has a copy of +the key with a `valid_until_ts` at least as large as the `origin_server_ts` of +the event being validated. If it does not have such a copy, it must try to +obtain one via the `GET /_matrix/key/v2/server/` or `POST +/_matrix/key/v2/query` APIs. For the latter, it must set +`minimum_valid_until_ts` to prompt the notary server to attempt to refresh the +key if appropriate. + +Since this changes the rules used to validate events, it will be introduced +with a new room version. This will reduce the risk of divergence between +servers in a room due to some servers accepting events which others reject. + +This MSC also proposes that the current situation - where `valid_until_ts` is +ignored - be formalised for the existing room versions v1-v4, rather than be +left as implementation-specific behaviour. From d2ccd6b268e28437a0a2d70c2fb2d1135fc76757 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 4 Jun 2019 23:53:42 +0100 Subject: [PATCH 0418/1250] MSC2077: room v5 --- proposals/2077-rooms-v5.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 proposals/2077-rooms-v5.md diff --git a/proposals/2077-rooms-v5.md b/proposals/2077-rooms-v5.md new file mode 100644 index 00000000..034c118a --- /dev/null +++ b/proposals/2077-rooms-v5.md @@ -0,0 +1,20 @@ +# MSC2077 - Rooms V6 + +This MSC proposes creating a new room version named v5, which will enforce the +signing key `valid_until_ts` timestamps proposed in +[MSC2076](https://github.com/matrix-org/matrix-doc/issues/2076). + +## Proposal + +The new room version is called "5". The only difference between v5 and v4 is +that v5 rooms enforce the `valid_until_ts` timestamp on signing keys as +proposed in [MSC2076](https://github.com/matrix-org/matrix-doc/issues/2076). + +It is not yet proposed that servers change the default room version used when +creating new rooms, and it is not yet proposed that servers recommend upgrading +existing rooms to v5. + +## Notes + +See also [MSC2002](./2002-rooms-v4.md), which proposed room v4 but also +mentioned that a v5 was anticipated and gave some context for this change. From 3347a480eb0db602d964073129b7e567de84e7e8 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 5 Jun 2019 00:07:05 +0100 Subject: [PATCH 0419/1250] fix typo --- proposals/2077-rooms-v5.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2077-rooms-v5.md b/proposals/2077-rooms-v5.md index 034c118a..0a7eff2b 100644 --- a/proposals/2077-rooms-v5.md +++ b/proposals/2077-rooms-v5.md @@ -1,4 +1,4 @@ -# MSC2077 - Rooms V6 +# MSC2077 - Rooms V5 This MSC proposes creating a new room version named v5, which will enforce the signing key `valid_until_ts` timestamps proposed in From 40b10f254b5c82e11b56f96260e7e9b4f184d52d Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 5 Jun 2019 07:18:25 +0100 Subject: [PATCH 0420/1250] clarifications --- proposals/2077-rooms-v5.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/proposals/2077-rooms-v5.md b/proposals/2077-rooms-v5.md index 0a7eff2b..9f8c1654 100644 --- a/proposals/2077-rooms-v5.md +++ b/proposals/2077-rooms-v5.md @@ -1,18 +1,17 @@ -# MSC2077 - Rooms V5 +# MSC2077 - Room version 5 -This MSC proposes creating a new room version named v5, which will enforce the -signing key `valid_until_ts` timestamps proposed in +This MSC proposes creating room version 5, which will enforce the signing key +`valid_until_ts` timestamps proposed in [MSC2076](https://github.com/matrix-org/matrix-doc/issues/2076). ## Proposal -The new room version is called "5". The only difference between v5 and v4 is +The new room version is called `5`. The only difference between v5 and v4 is that v5 rooms enforce the `valid_until_ts` timestamp on signing keys as proposed in [MSC2076](https://github.com/matrix-org/matrix-doc/issues/2076). -It is not yet proposed that servers change the default room version used when -creating new rooms, and it is not yet proposed that servers recommend upgrading -existing rooms to v5. +It is not yet proposed to change the default room version to v5. Version 5 will +be considered a "stable" version. ## Notes From cf932ad4f817b05ffbaf2464ad3eb1bc6e781d14 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 5 Jun 2019 11:20:28 +0100 Subject: [PATCH 0421/1250] msc2078 - proposal for homeservers sending passwords reset requests --- proposals/2078-homeserver-password-resets.md | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 proposals/2078-homeserver-password-resets.md diff --git a/proposals/2078-homeserver-password-resets.md b/proposals/2078-homeserver-password-resets.md new file mode 100644 index 00000000..f5523cd2 --- /dev/null +++ b/proposals/2078-homeserver-password-resets.md @@ -0,0 +1,21 @@ +# MSC2078 - Sending Password Reset Emails via the Homeserver + +This MSC proposes removing the current requirement of the identity server to send password reset tokens, and allows homeservers to implement the functionality instead. The intention is to put less trust in the identity server which is currently one of the most centralised components of Matrix. As it stands, an attacker in control of a identity server can reset a user's password if that user has registered a third-party identifier (3PID) with that identity server, due to itself also handling the job of confirming the user's control of that identity. + +The MSC aims to simply clarify that homeservers can take on the responisibility of sending password reset tokens themselves. + +## Proposal + +Currently when a client requests a password reset, they make a call to either [/_matrix/client/r0/account/password/email/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-email-requesttoken) or [/_matrix/client/r0/account/password/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-msisdn-requesttoken). This request is supplied all the necessary details as well as a `id_server` field containing the address of a trusted identity server which the user has used in the past to bind their 3PID. Understand that it is recommended for the homeserver to only grant the request if the given identity server is in a trusted list. + +The `id_server` field is currently required as the homeserver must know where to proxy the request to. This MSC proposes not to change the requirements of this field, but instead to clarify that the homeserver is allowed to not proxy the request, but carry it out itself. This would mean the homeserver can both send password reset tokens (via email or sms), as well as accept requests to [/_matrix/identity/api/v1/validate/email/submitToken](https://matrix.org/docs/spec/identity_service/r0.1.0.html#post-matrix-identity-api-v1-validate-email-submittoken) to verify that token. + +Thus, this proposal really only requests that it be clear that a homeserver does not need to proxy requests to `/requestToken`, and instead can ignore the `id_server` field and carry out the request itself. + +## Tradeoffs + +If homeservers choose to not proxy the request, they will need to implement the ability to send emails and/or sms messages. This is left as a detail for the homeserver implementation. + +## Future Considerations + +At some point we should look into removing the `id_server` field altogether and removing any email/sms message sending from the identity server. This would drastically reduce the amount of trust needed in the identity server and its required ability. This is, however, a good first step. From 4e692735f55f18c86033edb00d61f5d1ce17bc38 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 5 Jun 2019 11:25:26 +0100 Subject: [PATCH 0422/1250] Update some wording --- proposals/2078-homeserver-password-resets.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/2078-homeserver-password-resets.md b/proposals/2078-homeserver-password-resets.md index f5523cd2..f1c5928a 100644 --- a/proposals/2078-homeserver-password-resets.md +++ b/proposals/2078-homeserver-password-resets.md @@ -8,9 +8,9 @@ The MSC aims to simply clarify that homeservers can take on the responisibility Currently when a client requests a password reset, they make a call to either [/_matrix/client/r0/account/password/email/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-email-requesttoken) or [/_matrix/client/r0/account/password/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-msisdn-requesttoken). This request is supplied all the necessary details as well as a `id_server` field containing the address of a trusted identity server which the user has used in the past to bind their 3PID. Understand that it is recommended for the homeserver to only grant the request if the given identity server is in a trusted list. -The `id_server` field is currently required as the homeserver must know where to proxy the request to. This MSC proposes not to change the requirements of this field, but instead to clarify that the homeserver is allowed to not proxy the request, but carry it out itself. This would mean the homeserver can both send password reset tokens (via email or sms), as well as accept requests to [/_matrix/identity/api/v1/validate/email/submitToken](https://matrix.org/docs/spec/identity_service/r0.1.0.html#post-matrix-identity-api-v1-validate-email-submittoken) to verify that token. +The `id_server` field is currently required as the homeserver must know where to proxy the request to. This MSC proposes not to change the requirements of this field. Instead, it asks to clarify that the homeserver is allowed to not proxy the request, but carry it out itself. This would mean the homeserver can both send password reset tokens (via email or sms), as well as accept requests to [/_matrix/identity/api/v1/validate/email/submitToken](https://matrix.org/docs/spec/identity_service/r0.1.0.html#post-matrix-identity-api-v1-validate-email-submittoken) to verify that token. -Thus, this proposal really only requests that it be clear that a homeserver does not need to proxy requests to `/requestToken`, and instead can ignore the `id_server` field and carry out the request itself. +Thus, this proposal really only requests that it be clear that a homeserver does not need to proxy requests to `/requestToken`, and instead can ignore the `id_server` field and perform emailing/sms message sending by itself. ## Tradeoffs From c9711acbc5fe231e67c2dbfe15a8c795219a25d5 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 5 Jun 2019 12:52:01 +0100 Subject: [PATCH 0423/1250] Remove attacker bit --- proposals/2078-homeserver-password-resets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2078-homeserver-password-resets.md b/proposals/2078-homeserver-password-resets.md index f1c5928a..8ef560e9 100644 --- a/proposals/2078-homeserver-password-resets.md +++ b/proposals/2078-homeserver-password-resets.md @@ -1,6 +1,6 @@ # MSC2078 - Sending Password Reset Emails via the Homeserver -This MSC proposes removing the current requirement of the identity server to send password reset tokens, and allows homeservers to implement the functionality instead. The intention is to put less trust in the identity server which is currently one of the most centralised components of Matrix. As it stands, an attacker in control of a identity server can reset a user's password if that user has registered a third-party identifier (3PID) with that identity server, due to itself also handling the job of confirming the user's control of that identity. +This MSC proposes removing the current requirement of the identity server to send password reset tokens, and allows homeservers to implement the functionality instead. The intention is to put less trust in the identity server which is currently one of the most centralised components of Matrix. The MSC aims to simply clarify that homeservers can take on the responisibility of sending password reset tokens themselves. From 1956f1a916d5fbb512c834740e9e5cb0a027e6e9 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 5 Jun 2019 12:59:58 +0100 Subject: [PATCH 0424/1250] Revert "Remove attacker bit" This reverts commit c9711acbc5fe231e67c2dbfe15a8c795219a25d5. --- proposals/2078-homeserver-password-resets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2078-homeserver-password-resets.md b/proposals/2078-homeserver-password-resets.md index 8ef560e9..f1c5928a 100644 --- a/proposals/2078-homeserver-password-resets.md +++ b/proposals/2078-homeserver-password-resets.md @@ -1,6 +1,6 @@ # MSC2078 - Sending Password Reset Emails via the Homeserver -This MSC proposes removing the current requirement of the identity server to send password reset tokens, and allows homeservers to implement the functionality instead. The intention is to put less trust in the identity server which is currently one of the most centralised components of Matrix. +This MSC proposes removing the current requirement of the identity server to send password reset tokens, and allows homeservers to implement the functionality instead. The intention is to put less trust in the identity server which is currently one of the most centralised components of Matrix. As it stands, an attacker in control of a identity server can reset a user's password if that user has registered a third-party identifier (3PID) with that identity server, due to itself also handling the job of confirming the user's control of that identity. The MSC aims to simply clarify that homeservers can take on the responisibility of sending password reset tokens themselves. From 085c5667a478fe0f0f64973b3627863d8e656057 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 5 Jun 2019 13:42:23 +0100 Subject: [PATCH 0425/1250] wrap lines --- proposals/2078-homeserver-password-resets.md | 50 ++++++++++++++++---- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/proposals/2078-homeserver-password-resets.md b/proposals/2078-homeserver-password-resets.md index f1c5928a..e64c8651 100644 --- a/proposals/2078-homeserver-password-resets.md +++ b/proposals/2078-homeserver-password-resets.md @@ -1,21 +1,51 @@ # MSC2078 - Sending Password Reset Emails via the Homeserver -This MSC proposes removing the current requirement of the identity server to send password reset tokens, and allows homeservers to implement the functionality instead. The intention is to put less trust in the identity server which is currently one of the most centralised components of Matrix. As it stands, an attacker in control of a identity server can reset a user's password if that user has registered a third-party identifier (3PID) with that identity server, due to itself also handling the job of confirming the user's control of that identity. - -The MSC aims to simply clarify that homeservers can take on the responisibility of sending password reset tokens themselves. +This MSC proposes removing the current requirement of the identity server to +send password reset tokens, and allows homeservers to implement the +functionality instead. The intention is to put less trust in the identity +server which is currently one of the most centralised components of Matrix. As +it stands, an attacker in control of a identity server can reset a user's +password if that user has registered a third-party identifier (3PID) with that +identity server, due to itself also handling the job of confirming the user's +control of that identity. + +The MSC aims to simply clarify that homeservers can take on the responisibility +of sending password reset tokens themselves. ## Proposal -Currently when a client requests a password reset, they make a call to either [/_matrix/client/r0/account/password/email/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-email-requesttoken) or [/_matrix/client/r0/account/password/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-msisdn-requesttoken). This request is supplied all the necessary details as well as a `id_server` field containing the address of a trusted identity server which the user has used in the past to bind their 3PID. Understand that it is recommended for the homeserver to only grant the request if the given identity server is in a trusted list. - -The `id_server` field is currently required as the homeserver must know where to proxy the request to. This MSC proposes not to change the requirements of this field. Instead, it asks to clarify that the homeserver is allowed to not proxy the request, but carry it out itself. This would mean the homeserver can both send password reset tokens (via email or sms), as well as accept requests to [/_matrix/identity/api/v1/validate/email/submitToken](https://matrix.org/docs/spec/identity_service/r0.1.0.html#post-matrix-identity-api-v1-validate-email-submittoken) to verify that token. - -Thus, this proposal really only requests that it be clear that a homeserver does not need to proxy requests to `/requestToken`, and instead can ignore the `id_server` field and perform emailing/sms message sending by itself. +Currently when a client requests a password reset, they make a call to either +[/_matrix/client/r0/account/password/email/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-email-requesttoken) +or +[/_matrix/client/r0/account/password/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-msisdn-requesttoken). +This request is supplied all the necessary details as well as a `id_server` +field containing the address of a trusted identity server which the user has +used in the past to bind their 3PID. Understand that it is recommended for the +homeserver to only grant the request if the given identity server is in a +trusted list. + +The `id_server` field is currently required as the homeserver must know where +to proxy the request to. This MSC proposes not to change the requirements of +this field. Instead, it asks to clarify that the homeserver is allowed to not +proxy the request, but carry it out itself. This would mean the homeserver can +both send password reset tokens (via email or sms), as well as accept requests +to +[/_matrix/identity/api/v1/validate/email/submitToken](https://matrix.org/docs/spec/identity_service/r0.1.0.html#post-matrix-identity-api-v1-validate-email-submittoken) +to verify that token. + +Thus, this proposal really only requests that it be clear that a homeserver +does not need to proxy requests to `/requestToken`, and instead can ignore the +`id_server` field and perform emailing/sms message sending by itself. ## Tradeoffs -If homeservers choose to not proxy the request, they will need to implement the ability to send emails and/or sms messages. This is left as a detail for the homeserver implementation. +If homeservers choose to not proxy the request, they will need to implement the +ability to send emails and/or sms messages. This is left as a detail for the +homeserver implementation. ## Future Considerations -At some point we should look into removing the `id_server` field altogether and removing any email/sms message sending from the identity server. This would drastically reduce the amount of trust needed in the identity server and its required ability. This is, however, a good first step. +At some point we should look into removing the `id_server` field altogether and +removing any email/sms message sending from the identity server. This would +drastically reduce the amount of trust needed in the identity server and its +required ability. This is, however, a good first step. From 8cba7adcdf47ed69ece187f472d3237e532dae32 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 5 Jun 2019 13:52:02 +0100 Subject: [PATCH 0426/1250] Clarify conditions for attack --- proposals/2078-homeserver-password-resets.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/2078-homeserver-password-resets.md b/proposals/2078-homeserver-password-resets.md index e64c8651..0d2207b0 100644 --- a/proposals/2078-homeserver-password-resets.md +++ b/proposals/2078-homeserver-password-resets.md @@ -5,8 +5,9 @@ send password reset tokens, and allows homeservers to implement the functionality instead. The intention is to put less trust in the identity server which is currently one of the most centralised components of Matrix. As it stands, an attacker in control of a identity server can reset a user's -password if that user has registered a third-party identifier (3PID) with that -identity server, due to itself also handling the job of confirming the user's +password if the identity server is considered trusted by that homeserver, and +the user has registered at least one third-party identifier (3PID). This is due +to the identity server currently handling the job of confirming the user's control of that identity. The MSC aims to simply clarify that homeservers can take on the responisibility From 7e18c5d5a8a6cd392561eb260a4ab66eaa759fad Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 5 Jun 2019 14:38:16 +0100 Subject: [PATCH 0427/1250] Add new submit_url response field --- proposals/2078-homeserver-password-resets.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/2078-homeserver-password-resets.md b/proposals/2078-homeserver-password-resets.md index 0d2207b0..b780d188 100644 --- a/proposals/2078-homeserver-password-resets.md +++ b/proposals/2078-homeserver-password-resets.md @@ -21,9 +21,7 @@ or [/_matrix/client/r0/account/password/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-msisdn-requesttoken). This request is supplied all the necessary details as well as a `id_server` field containing the address of a trusted identity server which the user has -used in the past to bind their 3PID. Understand that it is recommended for the -homeserver to only grant the request if the given identity server is in a -trusted list. +used in the past to bind their 3PID. The `id_server` field is currently required as the homeserver must know where to proxy the request to. This MSC proposes not to change the requirements of @@ -34,9 +32,11 @@ to [/_matrix/identity/api/v1/validate/email/submitToken](https://matrix.org/docs/spec/identity_service/r0.1.0.html#post-matrix-identity-api-v1-validate-email-submittoken) to verify that token. -Thus, this proposal really only requests that it be clear that a homeserver -does not need to proxy requests to `/requestToken`, and instead can ignore the -`id_server` field and perform emailing/sms message sending by itself. +An additional complication is that in the case of sms, a full link to reset passwords is not sent, but a short code. The client then asks the user to enter this code, however the client may now not know where to send the code. Should it send it to the identity server or the homeserver? Which sent out the code? + +In order to combat this problem, the field `submit_url` should be added in the response from both the email and msisdn variants of the `/requestToken` Client-Server API, if and only if the homeserver has not sent out the entire link (for instance in the case of a short code through sms). If this field is omitted, the client knows that the link has been sent in its entirety and the verification will be handled out of band. + +If the client receives a response to `/requestToken` with `submit_url`, it should accept the token from user input, then make a request (either POST or GET, depending on whether it desires a machine- or human-readable response) to the content of `submit_url` with the `sid`, `client_secret` and user-entered token. This data should be submitted as query parameters for `GET` request, and a JSON body for a `POST`. ## Tradeoffs From 8259ae292a010b6453f6a7b4f40609370b80dc1d Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 5 Jun 2019 14:39:36 +0100 Subject: [PATCH 0428/1250] Capitalise SMS --- proposals/2078-homeserver-password-resets.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/2078-homeserver-password-resets.md b/proposals/2078-homeserver-password-resets.md index b780d188..1a224fe8 100644 --- a/proposals/2078-homeserver-password-resets.md +++ b/proposals/2078-homeserver-password-resets.md @@ -27,26 +27,26 @@ The `id_server` field is currently required as the homeserver must know where to proxy the request to. This MSC proposes not to change the requirements of this field. Instead, it asks to clarify that the homeserver is allowed to not proxy the request, but carry it out itself. This would mean the homeserver can -both send password reset tokens (via email or sms), as well as accept requests +both send password reset tokens (via email or SMS), as well as accept requests to [/_matrix/identity/api/v1/validate/email/submitToken](https://matrix.org/docs/spec/identity_service/r0.1.0.html#post-matrix-identity-api-v1-validate-email-submittoken) to verify that token. -An additional complication is that in the case of sms, a full link to reset passwords is not sent, but a short code. The client then asks the user to enter this code, however the client may now not know where to send the code. Should it send it to the identity server or the homeserver? Which sent out the code? +An additional complication is that in the case of SMS, a full link to reset passwords is not sent, but a short code. The client then asks the user to enter this code, however the client may now not know where to send the code. Should it send it to the identity server or the homeserver? Which sent out the code? -In order to combat this problem, the field `submit_url` should be added in the response from both the email and msisdn variants of the `/requestToken` Client-Server API, if and only if the homeserver has not sent out the entire link (for instance in the case of a short code through sms). If this field is omitted, the client knows that the link has been sent in its entirety and the verification will be handled out of band. +In order to combat this problem, the field `submit_url` should be added in the response from both the email and msisdn variants of the `/requestToken` Client-Server API, if and only if the homeserver has not sent out the entire link (for instance in the case of a short code through SMS). If this field is omitted, the client knows that the link has been sent in its entirety and the verification will be handled out of band. If the client receives a response to `/requestToken` with `submit_url`, it should accept the token from user input, then make a request (either POST or GET, depending on whether it desires a machine- or human-readable response) to the content of `submit_url` with the `sid`, `client_secret` and user-entered token. This data should be submitted as query parameters for `GET` request, and a JSON body for a `POST`. ## Tradeoffs If homeservers choose to not proxy the request, they will need to implement the -ability to send emails and/or sms messages. This is left as a detail for the +ability to send emails and/or SMS messages. This is left as a detail for the homeserver implementation. ## Future Considerations At some point we should look into removing the `id_server` field altogether and -removing any email/sms message sending from the identity server. This would +removing any email/SMS message sending from the identity server. This would drastically reduce the amount of trust needed in the identity server and its required ability. This is, however, a good first step. From 4174b612794b77a35eee0c9ea4cac8bdee40a62a Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 5 Jun 2019 14:50:40 +0100 Subject: [PATCH 0429/1250] submit_url only if the user has to enter the code somewhere --- proposals/2078-homeserver-password-resets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2078-homeserver-password-resets.md b/proposals/2078-homeserver-password-resets.md index 1a224fe8..47e12224 100644 --- a/proposals/2078-homeserver-password-resets.md +++ b/proposals/2078-homeserver-password-resets.md @@ -34,7 +34,7 @@ to verify that token. An additional complication is that in the case of SMS, a full link to reset passwords is not sent, but a short code. The client then asks the user to enter this code, however the client may now not know where to send the code. Should it send it to the identity server or the homeserver? Which sent out the code? -In order to combat this problem, the field `submit_url` should be added in the response from both the email and msisdn variants of the `/requestToken` Client-Server API, if and only if the homeserver has not sent out the entire link (for instance in the case of a short code through SMS). If this field is omitted, the client knows that the link has been sent in its entirety and the verification will be handled out of band. +In order to combat this problem, the field `submit_url` should be added in the response from both the email and msisdn variants of the `/requestToken` Client-Server API, if and only if the verification message contains a code the user is expected to enter into the client (for instance in the case of a short code through SMS). If this field is omitted, the client knows that the link has been sent in its entirety and the verification will be handled out of band. If the client receives a response to `/requestToken` with `submit_url`, it should accept the token from user input, then make a request (either POST or GET, depending on whether it desires a machine- or human-readable response) to the content of `submit_url` with the `sid`, `client_secret` and user-entered token. This data should be submitted as query parameters for `GET` request, and a JSON body for a `POST`. From 6e0af5e64cda74dad65c602e2425a148c35ddda9 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 5 Jun 2019 15:07:06 +0100 Subject: [PATCH 0430/1250] If no submit_url, just send it to the IS as before --- proposals/2078-homeserver-password-resets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2078-homeserver-password-resets.md b/proposals/2078-homeserver-password-resets.md index 47e12224..1bb5dbc4 100644 --- a/proposals/2078-homeserver-password-resets.md +++ b/proposals/2078-homeserver-password-resets.md @@ -34,7 +34,7 @@ to verify that token. An additional complication is that in the case of SMS, a full link to reset passwords is not sent, but a short code. The client then asks the user to enter this code, however the client may now not know where to send the code. Should it send it to the identity server or the homeserver? Which sent out the code? -In order to combat this problem, the field `submit_url` should be added in the response from both the email and msisdn variants of the `/requestToken` Client-Server API, if and only if the verification message contains a code the user is expected to enter into the client (for instance in the case of a short code through SMS). If this field is omitted, the client knows that the link has been sent in its entirety and the verification will be handled out of band. +In order to combat this problem, the field `submit_url` should be added in the response from both the email and msisdn variants of the `/requestToken` Client-Server API, if and only if the verification message contains a code the user is expected to enter into the client (for instance in the case of a short code through SMS). If this field is omitted, the client should continue the same behaviour from before, which is to send the token to the identity server directly. This is intended for backwards compatibility with older servers. If the client receives a response to `/requestToken` with `submit_url`, it should accept the token from user input, then make a request (either POST or GET, depending on whether it desires a machine- or human-readable response) to the content of `submit_url` with the `sid`, `client_secret` and user-entered token. This data should be submitted as query parameters for `GET` request, and a JSON body for a `POST`. From 6bb48723e8fe7aa88bf1f5f7f42b1f047b057aa0 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 5 Jun 2019 15:43:57 +0100 Subject: [PATCH 0431/1250] The HS can send any URL --- proposals/2078-homeserver-password-resets.md | 28 ++++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/proposals/2078-homeserver-password-resets.md b/proposals/2078-homeserver-password-resets.md index 1bb5dbc4..6f7386d4 100644 --- a/proposals/2078-homeserver-password-resets.md +++ b/proposals/2078-homeserver-password-resets.md @@ -19,24 +19,36 @@ Currently when a client requests a password reset, they make a call to either [/_matrix/client/r0/account/password/email/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-email-requesttoken) or [/_matrix/client/r0/account/password/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-msisdn-requesttoken). -This request is supplied all the necessary details as well as a `id_server` -field containing the address of a trusted identity server which the user has -used in the past to bind their 3PID. +This request is supplied all the necessary details as well as an `id_server` +field containing the address of a identity server trusted by the homeserver. The `id_server` field is currently required as the homeserver must know where to proxy the request to. This MSC proposes not to change the requirements of this field. Instead, it asks to clarify that the homeserver is allowed to not proxy the request, but carry it out itself. This would mean the homeserver can both send password reset tokens (via email or SMS), as well as accept requests -to -[/_matrix/identity/api/v1/validate/email/submitToken](https://matrix.org/docs/spec/identity_service/r0.1.0.html#post-matrix-identity-api-v1-validate-email-submittoken) +an endpoint (with the same parameters as +[/_matrix/identity/api/v1/validate/email/submitToken](https://matrix.org/docs/spec/identity_service/r0.1.0.html#post-matrix-identity-api-v1-validate-email-submittoken)) to verify that token. -An additional complication is that in the case of SMS, a full link to reset passwords is not sent, but a short code. The client then asks the user to enter this code, however the client may now not know where to send the code. Should it send it to the identity server or the homeserver? Which sent out the code? +An additional complication is that in the case of SMS, a full link to reset +passwords is not sent, but a short code. The client then asks the user to enter +this code, however the client may now not know where to send the code. Should +it send it to the identity server or the homeserver? Which sent out the code? -In order to combat this problem, the field `submit_url` should be added in the response from both the email and msisdn variants of the `/requestToken` Client-Server API, if and only if the verification message contains a code the user is expected to enter into the client (for instance in the case of a short code through SMS). If this field is omitted, the client should continue the same behaviour from before, which is to send the token to the identity server directly. This is intended for backwards compatibility with older servers. +In order to combat this problem, the field `submit_url` should be added in the +response from both the email and msisdn variants of the `/requestToken` +Client-Server API, if and only if the verification message contains a code the +user is expected to enter into the client (for instance in the case of a short +code through SMS). If this field is omitted, the client should continue the +same behaviour from before, which is to send the token to the identity server +directly. This is intended for backwards compatibility with older servers. -If the client receives a response to `/requestToken` with `submit_url`, it should accept the token from user input, then make a request (either POST or GET, depending on whether it desires a machine- or human-readable response) to the content of `submit_url` with the `sid`, `client_secret` and user-entered token. This data should be submitted as query parameters for `GET` request, and a JSON body for a `POST`. +If the client receives a response to `/requestToken` with `submit_url`, it +should accept the token from user input, then make a POST request to the +content of `submit_url` with the `sid`, `client_secret` and user-entered token. +This data should be submitted as query parameters for `GET` request, and a JSON +body for a `POST`. ## Tradeoffs From 395acf8e0650a147dbcc7340e48d2d4f21ea20c5 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Wed, 5 Jun 2019 15:58:14 +0100 Subject: [PATCH 0432/1250] Update proposals/2078-homeserver-password-resets.md Co-Authored-By: Hubert Chathi --- proposals/2078-homeserver-password-resets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2078-homeserver-password-resets.md b/proposals/2078-homeserver-password-resets.md index 6f7386d4..e92d679e 100644 --- a/proposals/2078-homeserver-password-resets.md +++ b/proposals/2078-homeserver-password-resets.md @@ -15,7 +15,7 @@ of sending password reset tokens themselves. ## Proposal -Currently when a client requests a password reset, they make a call to either +Currently when a client requests a password reset, it makes a call to either [/_matrix/client/r0/account/password/email/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-email-requesttoken) or [/_matrix/client/r0/account/password/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-msisdn-requesttoken). From e49518099de29e8d092b2fbb675fc941fb1124fc Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 5 Jun 2019 17:37:09 +0100 Subject: [PATCH 0433/1250] Be explicit with request/responses --- proposals/2078-homeserver-password-resets.md | 53 +++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/proposals/2078-homeserver-password-resets.md b/proposals/2078-homeserver-password-resets.md index 6f7386d4..0052c48e 100644 --- a/proposals/2078-homeserver-password-resets.md +++ b/proposals/2078-homeserver-password-resets.md @@ -47,8 +47,57 @@ directly. This is intended for backwards compatibility with older servers. If the client receives a response to `/requestToken` with `submit_url`, it should accept the token from user input, then make a POST request to the content of `submit_url` with the `sid`, `client_secret` and user-entered token. -This data should be submitted as query parameters for `GET` request, and a JSON -body for a `POST`. +`submit_url` can lead to anywhere the homeserver deems necessary for +verification. This data should be submitted as a JSON body. + +An example exchange from the client's perspective is shown below: + +``` +POST https://homeserver.tld/_matrix/client/r0/account/password/email/requestToken + +{ + "client_secret": "monkeys_are_AWESOME", + "email": "alice@homeserver.tld", + "send_attempt": 1, + "id_server": "id.example.com" +} +``` + +If the server responds with a `submit_url` field, it means the client should +collect a token from the user and then submit it to the provided URL. + +``` +{ + "sid": "123abc", + "submit_url": "https://homeserver.tld/path/to/submitToken" +} +``` + +Since a `submit_url` was provided, the client will now collect a token from the +user, say "123456", and then submit that as a POST request to the +`"submit_url"`. + +``` +POST https://homeserver.tld/path/to/submitToken + +{ + "sid": "123abc", + "client_secret": "monkeys_are_AWESOME", + "token": "123456" +} +``` + +The client will then receive an appropriate response: + +``` +{ + "success": true +} +``` + +If the client did not receive a `submit_url` field, they should instead assume +that verification will be completed out of band (e.g. the user clicks a link in +their email and makes the submitToken request with their web browser). ## Tradeoffs From de725c26ccebe93faf556305f4803215f0aab50d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 5 Jun 2019 10:37:22 -0600 Subject: [PATCH 0434/1250] Add more clarity to the media repo --- specification/modules/content_repo.rst | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/specification/modules/content_repo.rst b/specification/modules/content_repo.rst index 823efb3c..1e3d1866 100644 --- a/specification/modules/content_repo.rst +++ b/specification/modules/content_repo.rst @@ -34,8 +34,6 @@ header. The recommended policy is ``sandbox; default-src 'none'; script-src 'none'; plugin-types application/pdf; style-src 'unsafe-inline'; object-src 'self';``. -Content in the repository should be treated as bytes as it may be encrypted. - Matrix Content (MXC) URIs ------------------------- @@ -78,12 +76,7 @@ requested dimensions, unless the content being thumbnailed is smaller than the dimensions. When the content is smaller than the requested dimensions, servers should return the original content rather than thumbnail it. -Servers SHOULD pre-calculate or have a list of set dimensions for which they -will thumbnail content at. For example, the server may choose that it will -only create thumbnails sized 96x96 or 512x512. When the client requests a -thumbnail, the server will pick the size which is larger than the requested -dimensions. Servers SHOULD pre-calculate the following thumbnails for uploaded -content, and limit thumbnails to the same sizes: +Servers SHOULD produce thumbnails with the following dimensions and methods: * 32x32, crop * 96x96, crop @@ -97,7 +90,9 @@ In summary: * The server will return an image larger than or equal to the dimensions requested where possible. -Servers MUST NOT upscale thumbnails under any circumstance. +Servers MUST NOT upscale thumbnails under any circumstance. Servers MUST NOT +return a smaller thumbnail than requested, unless the original content makes +that impossible. Security considerations ----------------------- From fc4965f2748a97312cfe9930aa456ba0caea7302 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 5 Jun 2019 10:40:51 -0600 Subject: [PATCH 0435/1250] Stronger spec words --- api/client-server/registration.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 10b661a3..093bac6b 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -62,8 +62,8 @@ paths: `Relationship between access tokens and devices`_. When registering a guest account, all parameters in the request body - with the exception of ``initial_device_display_name`` are ignored by - the server. The server will pick a ``device_id`` for the account + with the exception of ``initial_device_display_name`` MUST BE ignored + by the server. The server MUST pick a ``device_id`` for the account regardless of input. operationId: register parameters: From d3f21e03605ad1dafb548b0386716103905d6282 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 5 Jun 2019 17:54:18 +0100 Subject: [PATCH 0436/1250] Address review comments --- proposals/2078-homeserver-password-resets.md | 35 ++++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/proposals/2078-homeserver-password-resets.md b/proposals/2078-homeserver-password-resets.md index 0052c48e..64916931 100644 --- a/proposals/2078-homeserver-password-resets.md +++ b/proposals/2078-homeserver-password-resets.md @@ -31,6 +31,17 @@ an endpoint (with the same parameters as [/_matrix/identity/api/v1/validate/email/submitToken](https://matrix.org/docs/spec/identity_service/r0.1.0.html#post-matrix-identity-api-v1-validate-email-submittoken)) to verify that token. +Consideration was taken not to make `id_server` and optional field. Let's +assume for a moment that it was optional. Now, a client could send a request to +`/requestToken` omitting the `id_server` field. The homeserver however has +opted to continue proxying `/requestToken` to the identity server, even though +it knows this is potentially insecure. The homeserver now has no idea which +identity server to proxy the request to, and must return a failure to the +client. The client could then make another request with an `id_server`, but +we've now made two requests that ended up in the same outcome, instead of one, +in hopes of saving a very small amount of bandwidth by omitting the field +originally. + An additional complication is that in the case of SMS, a full link to reset passwords is not sent, but a short code. The client then asks the user to enter this code, however the client may now not know where to send the code. Should @@ -40,15 +51,19 @@ In order to combat this problem, the field `submit_url` should be added in the response from both the email and msisdn variants of the `/requestToken` Client-Server API, if and only if the verification message contains a code the user is expected to enter into the client (for instance in the case of a short -code through SMS). If this field is omitted, the client should continue the -same behaviour from before, which is to send the token to the identity server -directly. This is intended for backwards compatibility with older servers. - -If the client receives a response to `/requestToken` with `submit_url`, it -should accept the token from user input, then make a POST request to the -content of `submit_url` with the `sid`, `client_secret` and user-entered token. +code through SMS). It SHOULD be in the form of +`/_matrix/identity/api/v1/validate/{3pid_type}/submitToken`, similar to the +[same endpoint that exists in the Identity-Server +API](https://matrix.org/docs/spec/identity_service/r0.1.0.html#post-matrix-identity-api-v1-validate-email-submittoken). +If this field is omitted, the client MUST continue the same behaviour from +before, which is to send the token to the identity server directly. This is +intended for backwards compatibility with older servers. + +If the client receives a response to `/requestToken` with `submit_url`, it MUST +accept the token from user input, then make a POST request to the content of +`submit_url` with the `sid`, `client_secret` and user-entered token. `submit_url` can lead to anywhere the homeserver deems necessary for -verification. This data should be submitted as a JSON body. +verification. This data MUST be submitted as a JSON body. An example exchange from the client's perspective is shown below: @@ -69,7 +84,7 @@ collect a token from the user and then submit it to the provided URL. ``` { "sid": "123abc", - "submit_url": "https://homeserver.tld/path/to/submitToken" + "submit_url": "https://homeserver.tld/_matrix/identity/api/v1/validate/msisdn/submitToken" } ``` @@ -78,7 +93,7 @@ user, say "123456", and then submit that as a POST request to the `"submit_url"`. ``` -POST https://homeserver.tld/path/to/submitToken +POST https://homeserver.tld/_matrix/identity/api/v1/validate/msisdn/submitToken { "sid": "123abc", From 3e23dde341b114117a448261d02d45ed495b3e34 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 5 Jun 2019 21:49:02 +0100 Subject: [PATCH 0437/1250] Be clear that any 3PID token request can now be done by the hs --- proposals/2078-homeserver-password-resets.md | 28 ++++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/proposals/2078-homeserver-password-resets.md b/proposals/2078-homeserver-password-resets.md index e9e53151..f8dfc53e 100644 --- a/proposals/2078-homeserver-password-resets.md +++ b/proposals/2078-homeserver-password-resets.md @@ -1,16 +1,22 @@ -# MSC2078 - Sending Password Reset Emails via the Homeserver +# MSC2078 - Sending Third-Party Request Tokens via the Homeserver This MSC proposes removing the current requirement of the identity server to -send password reset tokens, and allows homeservers to implement the -functionality instead. The intention is to put less trust in the identity -server which is currently one of the most centralised components of Matrix. As -it stands, an attacker in control of a identity server can reset a user's -password if the identity server is considered trusted by that homeserver, and -the user has registered at least one third-party identifier (3PID). This is due -to the identity server currently handling the job of confirming the user's -control of that identity. - -The MSC aims to simply clarify that homeservers can take on the responisibility +send third-party request tokens, and allows homeservers to implement the +functionality instead. These request tokens are used to verify the identity of +the request auther as an owner of the third-party identity (3PID). This can be +used for binding a 3PID to an account, or for resetting passwords via email or +SMS. The latter is what this proposal mainly focuses on, but be aware that it +allows for any task that requires requesting a token through a 3PID to be +taken on by the homeserver instead of the identity server. + +The intention is to put less trust in the identity server, which is currently +one of the most centralised components of Matrix. As it stands, an attacker in +control of a identity server can reset a user's password if the identity server +is considered trusted by that homeserver, and the user has registered at least +one 3PID. This is due to the identity server currently handling the job of +confirming the user's control of that identity. + +The MSC aims to simply clarify that homeservers can take on the responsibility of sending password reset tokens themselves. ## Proposal From a6314df44ceb63bd65a9508464e454a3a224d9ff Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 5 Jun 2019 17:03:19 -0600 Subject: [PATCH 0438/1250] Spec v5 rooms: Key validity Proposals: * [MSC2076](https://github.com/matrix-org/matrix-doc/pull/2076) * [MSC2077](https://github.com/matrix-org/matrix-doc/pull/2077) Implementation references: * https://github.com/matrix-org/synapse/commit/00bf99fa628e173ff14c99e5ffd02e8317ee1656 * https://github.com/matrix-org/synapse/pull/5354 * https://github.com/matrix-org/synapse/pull/5321 No known differences from the proposals are included here - alterations are accidental. --- api/server-server/definitions/keys.yaml | 10 +++- .../newsfragments/2080.clarification | 1 + specification/index.rst | 1 + specification/rooms/v5.rst | 54 +++++++++++++++++++ specification/targets.yaml | 4 ++ 5 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 changelogs/server_server/newsfragments/2080.clarification create mode 100644 specification/rooms/v5.rst diff --git a/api/server-server/definitions/keys.yaml b/api/server-server/definitions/keys.yaml index 06619641..c48c320a 100644 --- a/api/server-server/definitions/keys.yaml +++ b/api/server-server/definitions/keys.yaml @@ -94,6 +94,12 @@ properties: type: integer format: int64 description: |- - POSIX timestamp when the list of valid keys should be refreshed. Keys used beyond this - timestamp are no longer valid. + POSIX timestamp when the list of valid keys should be refreshed. This field MUST + be ignored in room versions 1, 2, 3, and 4. Keys used beyond this timestamp MUST + be considered invalid, depending on the `room version specification`_. + + Servers SHOULD use the lesser of this field and 7 days into the future when + determining if a key is valid. This is to avoid a situation where an attacker + publishes a key which is valid for a significant amount of time without a way + for the homeserver owner to revoke it. example: 1052262000000 diff --git a/changelogs/server_server/newsfragments/2080.clarification b/changelogs/server_server/newsfragments/2080.clarification new file mode 100644 index 00000000..c568fa13 --- /dev/null +++ b/changelogs/server_server/newsfragments/2080.clarification @@ -0,0 +1 @@ +Clarify how ``valid_until_ts`` behaves with respect to room version. diff --git a/specification/index.rst b/specification/index.rst index 33dff5a3..2e1ffd27 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -494,6 +494,7 @@ The available room versions are: * `Version 2 `_ - **Stable**. Implements State Resolution Version 2. * `Version 3 `_ - **Stable**. Introduces events whose IDs are the event's hash. * `Version 4 `_ - **Stable**. Builds on v3 by using URL-safe base64 for event IDs. +* `Version 5 `_ - **Stable**. Introduces enforcement of signing key validity periods. Specification Versions ---------------------- diff --git a/specification/rooms/v5.rst b/specification/rooms/v5.rst new file mode 100644 index 00000000..9b9fad7e --- /dev/null +++ b/specification/rooms/v5.rst @@ -0,0 +1,54 @@ +.. Copyright 2019 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. + +Room Version 5 +============== + +This room version builds on `version 4 `_, enforcing signing key validity +periods for events. + +.. contents:: Table of Contents +.. sectnum:: + + +Client considerations +--------------------- + +There are no specific requirements for clients in this room version. Clients should +be aware of event ID changes in `room version 4 `_, however. + + +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 5 uses the same algorithms defined in `room version 4 `_, ensuring +that signing key validity is respected. + +Signing key validity period +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When validating event signatures, servers MUST enforce the ``valid_until_ts`` property +from a key request is at least as large as the ``origin_server_ts`` for the event being +validated. Servers missing a copy of the signing key MUST try to obtain one via the +`GET /_matrix/key/v2/server <../server_server/r0.1.1.html#get-matrix-key-v2-server-keyid>`_ +or `POST /_matrix/key/v2/query <../server_server/r0.1.1.html#post-matrix-key-v2-query>`_ +APIs. When using the ``/query`` endpoint, servers MUST set the ``minimum_valid_until_ts`` +property to prompt the notary server to attempt to refresh the key if appropriate. diff --git a/specification/targets.yaml b/specification/targets.yaml index abcdc240..11d69fc0 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -42,6 +42,10 @@ targets: files: - rooms/v4.rst version_label: v4 + rooms@v5: # this is translated to be rooms/v5.html + files: + - rooms/v5.rst + version_label: v5 appendices: files: - appendices.rst From 7ce1ff21351d61cf9cac88637ac9ac389ee12255 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 5 Jun 2019 20:30:21 -0600 Subject: [PATCH 0439/1250] Clarify which servers are supposed to sign events Fixes https://github.com/matrix-org/matrix-doc/issues/2074 --- .../server_server/newsfragments/2081.clarification | 1 + specification/server_server_api.rst | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 changelogs/server_server/newsfragments/2081.clarification diff --git a/changelogs/server_server/newsfragments/2081.clarification b/changelogs/server_server/newsfragments/2081.clarification new file mode 100644 index 00000000..fd291273 --- /dev/null +++ b/changelogs/server_server/newsfragments/2081.clarification @@ -0,0 +1 @@ +Clarify which servers are supposed to sign events. diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index b765e36a..812f0ffc 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -421,9 +421,8 @@ must ensure that the event: Further details of these checks, and how to handle failures, are described below. -.. TODO: - Flesh this out a bit more, and probably change the doc to group the various - checks in one place, rather than have them spread out. +The `Signing Events <#signing-events>`_ section has more information on which hashes +and signatures are expected on events, and how to calculate them. Definitions @@ -1099,6 +1098,15 @@ originating server, following the algorithm described in `Checking for a signatu Note that this step should succeed whether we have been sent the full event or a redacted copy. +The signatures expected on an event are: + +* The sender's server, unless the invite was created as a result of 3rd party invite. + The sender must already match the 3rd party invite, and the server which actually + sends the event may be a different server. +* For room versions 1 and 2, the server which created the ``event_id``. Other room + versions do not track the ``event_id`` over federation and therefore do not need + a signature from those servers. + If the signature is found to be valid, the expected content hash is calculated as described below. The content hash in the ``hashes`` property of the received event is base64-decoded, and the two are compared for equality. From 80aa5a24dc55433bd95f37cd03dd20fab55c280b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 5 Jun 2019 20:33:09 -0600 Subject: [PATCH 0440/1250] Make v4 the "default" room version As per [MSC2002](https://github.com/matrix-org/matrix-doc/pull/2002). This was missed in https://github.com/matrix-org/matrix-doc/pull/2019 Fixes https://github.com/matrix-org/matrix-doc/issues/2071 --- specification/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/index.rst b/specification/index.rst index 33dff5a3..a6f6f62b 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -485,7 +485,7 @@ some other reason. Versions can switch between stable and unstable periodically for a variety of reasons, including discovered security vulnerabilities and age. Clients should not ask room administrators to upgrade their rooms if the room is -running a stable version. Servers SHOULD use room version 1 as the default room +running a stable version. Servers SHOULD use room version 4 as the default room version when creating new rooms. The available room versions are: From a19eb59f13058afcb6f7b2bb9947a173fb004f5a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 5 Jun 2019 21:10:38 -0600 Subject: [PATCH 0441/1250] Clarify the key object definition for the key management API Fixes https://github.com/matrix-org/matrix-doc/issues/1907 One too far --- api/client-server/keys.yaml | 99 +++++++++++++------ api/server-server/user_keys.yaml | 37 ++++--- .../newsfragments/2083.clarification | 1 + .../newsfragments/2083.clarification | 1 + 4 files changed, 96 insertions(+), 42 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2083.clarification create mode 100644 changelogs/server_server/newsfragments/2083.clarification diff --git a/api/client-server/keys.yaml b/api/client-server/keys.yaml index 718703fd..30056259 100644 --- a/api/client-server/keys.yaml +++ b/api/client-server/keys.yaml @@ -59,22 +59,41 @@ paths: by the key algorithm. May be absent if no new one-time keys are required. - additionalProperties: - type: - - string - - object - example: - "curve25519:AAAAAQ": "/qyvZvwjiTxGdGU0RCguDCLeR+nmsb3FfNG3/Ve4vU8" - signed_curve25519:AAAAHg: - key: "zKbLg+NrIjpnagy+pIY6uPL4ZwEG2v+8F9lmgsnlZzs" - signatures: - "@alice:example.com": - ed25519:JLAFKJWSCS: "FLWxXqGbwrb8SM3Y795eB6OA8bwBcoMZFXBqnTn58AYWZSqiD45tlBVcDa2L7RwdKXebW/VzDlnfVJ+9jok1Bw" - signed_curve25519:AAAAHQ: - key: "j3fR3HemM16M7CWhoI4Sk5ZsdmdfQHsKL1xuSft6MSw" - signatures: - "@alice:example.com": - ed25519:JLAFKJWSCS: "IQeCEPb9HFk217cU9kw9EOiusC6kMIkoIRnbnfOh5Oc63S1ghgyjShBGpu34blQomoalCyXWyhaaT3MrLZYQAA" + additionalProperties: + type: + - string + - type: object + title: KeyObject + properties: + key: + type: string + description: The key, encoded using unpadded base64. + signatures: + type: object + description: |- + Signature for the device. Mapped from user ID to signature object. + additionalProperties: + type: string + required: ['key', 'signatures'] + example: { + "curve25519:AAAAAQ": "/qyvZvwjiTxGdGU0RCguDCLeR+nmsb3FfNG3/Ve4vU8", + "signed_curve25519:AAAAHg": { + "key": "zKbLg+NrIjpnagy+pIY6uPL4ZwEG2v+8F9lmgsnlZzs", + "signatures": { + "@alice:example.com": { + "ed25519:JLAFKJWSCS": "FLWxXqGbwrb8SM3Y795eB6OA8bwBcoMZFXBqnTn58AYWZSqiD45tlBVcDa2L7RwdKXebW/VzDlnfVJ+9jok1Bw" + } + } + }, + "signed_curve25519:AAAAHQ": { + "key": "j3fR3HemM16M7CWhoI4Sk5ZsdmdfQHsKL1xuSft6MSw", + "signatures": { + "@alice:example.com": { + "ed25519:JLAFKJWSCS": "IQeCEPb9HFk217cU9kw9EOiusC6kMIkoIRnbnfOh5Oc63S1ghgyjShBGpu34blQomoalCyXWyhaaT3MrLZYQAA" + } + } + } + } responses: 200: description: @@ -205,12 +224,12 @@ paths: "@alice:example.com": { "ed25519:JLAFKJWSCS": "dSO80A01XiigH3uBiDVx/EjzaoycHcjq9lfQX0uWsqxl2giMIiSPR8a4d291W1ihKJL/a+myXS367WT6NAIcBA" } - }, + }, "unsigned": { "device_display_name": "Alice's mobile phone" } } - + tags: - End-to-end encryption "/keys/claim": @@ -246,8 +265,9 @@ paths: type: string description: algorithm example: "signed_curve25519" - example: + example: { "@alice:example.com": { "JLAFKJWSCS": "signed_curve25519" } + } required: - one_time_keys responses: @@ -263,7 +283,7 @@ paths: If any remote homeservers could not be reached, they are recorded here. The names of the properties are the names of the unreachable servers. - + If the homeserver could be reached, but the user or device was unknown, no failure is recorded. Instead, the corresponding user or device is missing from the ``one_time_keys`` result. @@ -281,14 +301,37 @@ paths: type: - string - object - example: - "@alice:example.com": - JLAFKJWSCS: - signed_curve25519:AAAAHg: - key: "zKbLg+NrIjpnagy+pIY6uPL4ZwEG2v+8F9lmgsnlZzs" - signatures: - "@alice:example.com": - ed25519:JLAFKJWSCS: "FLWxXqGbwrb8SM3Y795eB6OA8bwBcoMZFXBqnTn58AYWZSqiD45tlBVcDa2L7RwdKXebW/VzDlnfVJ+9jok1Bw" + # XXX: We can't define an actual object here, so we have to hope + # that people will look at the swagger source or can figure it out + # from the other endpoints/example. + # - type: object + # title: KeyObject + # properties: + # key: + # type: string + # description: The key, encoded using unpadded base64. + # signatures: + # type: object + # description: |- + # Signature for the device. Mapped from user ID to signature object. + # additionalProperties: + # type: string + # required: ['key', 'signatures'] + example: { + "@alice:example.com": { + "JLAFKJWSCS": { + "signed_curve25519:AAAAHg": { + "key": "zKbLg+NrIjpnagy+pIY6uPL4ZwEG2v+8F9lmgsnlZzs", + "signatures": { + "@alice:example.com": { + "ed25519:JLAFKJWSCS": "FLWxXqGbwrb8SM3Y795eB6OA8bwBcoMZFXBqnTn58AYWZSqiD45tlBVcDa2L7RwdKXebW/VzDlnfVJ+9jok1Bw" + } + } + } + } + } + } + required: ['one_time_keys'] tags: - End-to-end encryption "/keys/changes": diff --git a/api/server-server/user_keys.yaml b/api/server-server/user_keys.yaml index 3c59cf81..613948c3 100644 --- a/api/server-server/user_keys.yaml +++ b/api/server-server/user_keys.yaml @@ -77,25 +77,34 @@ paths: additionalProperties: type: - string - - object - required: ['one_time_keys'] - examples: - application/json: { - "one_time_keys": { - "@alice:example.com": { - "JLAFKJWSCS": { - "signed_curve25518:AAAAHg": { - "key": "zKbLg+NrIjpnagy+pIY6uPL4ZwEG2v+8F9lmgsnlZzs", - "signatures": { - "@alice:example.com": { - "ed25519:JLAFKJWSCS": "FLWxXqGbwrb8SM3Y795eB6OA8bwBcoMZFXBqnTn58AYWZSqiD45tlBVcDa2L7RwdKXebW/VzDlnfVJ+9jok1Bw" + - type: object + title: KeyObject + properties: + key: + type: string + description: The key, encoded using unpadded base64. + signatures: + type: object + description: |- + Signature for the device. Mapped from user ID to signature object. + additionalProperties: + type: string + required: ['key', 'signatures'] + example: { + "@alice:example.com": { + "JLAFKJWSCS": { + "signed_curve25519:AAAAHg": { + "key": "zKbLg+NrIjpnagy+pIY6uPL4ZwEG2v+8F9lmgsnlZzs", + "signatures": { + "@alice:example.com": { + "ed25519:JLAFKJWSCS": "FLWxXqGbwrb8SM3Y795eB6OA8bwBcoMZFXBqnTn58AYWZSqiD45tlBVcDa2L7RwdKXebW/VzDlnfVJ+9jok1Bw" + } } } } } } - } - } + required: ['one_time_keys'] "/user/keys/query": post: summary: Download device identity keys. diff --git a/changelogs/client_server/newsfragments/2083.clarification b/changelogs/client_server/newsfragments/2083.clarification new file mode 100644 index 00000000..8083d85d --- /dev/null +++ b/changelogs/client_server/newsfragments/2083.clarification @@ -0,0 +1 @@ +Clarify the key object definition for the key management API. diff --git a/changelogs/server_server/newsfragments/2083.clarification b/changelogs/server_server/newsfragments/2083.clarification new file mode 100644 index 00000000..8083d85d --- /dev/null +++ b/changelogs/server_server/newsfragments/2083.clarification @@ -0,0 +1 @@ +Clarify the key object definition for the key management API. From e115e3439dd84d195496f740d6951531524450ec Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 5 Jun 2019 22:13:25 -0600 Subject: [PATCH 0442/1250] Touchups on the s2s swagger definitions Duplicate properties, wrong types, etc. --- api/server-server/leaving.yaml | 1 - api/server-server/query.yaml | 6 +++--- api/server-server/user_devices.yaml | 3 +-- api/server-server/version.yaml | 1 + api/server-server/wellknown.yaml | 1 + 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/api/server-server/leaving.yaml b/api/server-server/leaving.yaml index c088cb5d..e0882fe8 100644 --- a/api/server-server/leaving.yaml +++ b/api/server-server/leaving.yaml @@ -57,7 +57,6 @@ paths: `room version specification`_ for precise event formats. **The response body here describes the common event fields in more detail and may be missing other required fields for a PDU.** - schema: schema: type: object properties: diff --git a/api/server-server/query.yaml b/api/server-server/query.yaml index dc14724c..29826b32 100644 --- a/api/server-server/query.yaml +++ b/api/server-server/query.yaml @@ -81,7 +81,7 @@ paths: servers: type: array description: |- - An array of server names that are likely to hold the given room. This + An array of server names that are likely to hold the given room. This list may or may not include the server answering the query. items: type: string @@ -128,7 +128,7 @@ paths: x-example: "@someone:example.org" - in: query name: field - type: enum + type: string enum: ['displayname', 'avatar_url'] description: |- The field to query. If specified, the server will only return the given field @@ -139,7 +139,7 @@ paths: description: |- The profile for the user. If a ``field`` is specified in the request, only the matching field should be included in the response. If no ``field`` was specified, - the response should include the fields of the user's profile that can be made + the response should include the fields of the user's profile that can be made public, such as the display name and avatar. If the user does not have a particular field set on their profile, the server diff --git a/api/server-server/user_devices.yaml b/api/server-server/user_devices.yaml index 4805deb4..362f9baa 100644 --- a/api/server-server/user_devices.yaml +++ b/api/server-server/user_devices.yaml @@ -42,7 +42,6 @@ paths: description: |- The user ID to retrieve devices for. Must be a user local to the receiving homeserver. - required: true x-example: "@alice:example.org" responses: 200: @@ -82,4 +81,4 @@ paths: description: Optional display name for the device. example: "Alice's Mobile Phone" required: ['device_id', 'keys'] - required: ['user_id', 'stream_id', 'devices'] \ No newline at end of file + required: ['user_id', 'stream_id', 'devices'] diff --git a/api/server-server/version.yaml b/api/server-server/version.yaml index 19975529..929f7b91 100644 --- a/api/server-server/version.yaml +++ b/api/server-server/version.yaml @@ -27,6 +27,7 @@ paths: get: summary: Get the implementation name and version of this homeserver. description: Get the implementation name and version of this homeserver. + operationId: getVersion responses: 200: description: diff --git a/api/server-server/wellknown.yaml b/api/server-server/wellknown.yaml index 75676646..bc390bd5 100644 --- a/api/server-server/wellknown.yaml +++ b/api/server-server/wellknown.yaml @@ -29,6 +29,7 @@ paths: 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. + operationId: getWellKnown responses: 200: description: From 500f3d3bf121f30171422566a46dbbeab3d88608 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 5 Jun 2019 22:28:57 -0600 Subject: [PATCH 0443/1250] Clarify that the default s2s transport is JSON over HTTP Fixes https://github.com/matrix-org/matrix-doc/issues/1713 --- .../identity_service/newsfragments/2086.clarification | 1 + specification/client_server_api.rst | 3 ++- specification/server_server_api.rst | 11 +++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 changelogs/identity_service/newsfragments/2086.clarification diff --git a/changelogs/identity_service/newsfragments/2086.clarification b/changelogs/identity_service/newsfragments/2086.clarification new file mode 100644 index 00000000..7016308b --- /dev/null +++ b/changelogs/identity_service/newsfragments/2086.clarification @@ -0,0 +1 @@ +Clarify that the default transport is JSON over HTTP. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index d9342a5b..d5b6491f 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -57,6 +57,8 @@ The following other versions are also available, in reverse chronological order: API Standards ------------- +.. TODO: Move a lot of this to a common area for all specs. + .. TODO Need to specify any HMAC or access_token lifetime/ratcheting tricks We need to specify capability negotiation for extensible transports @@ -82,7 +84,6 @@ names in JSON objects passed over the API also follow this convention. ``/createRoom``. A future version of this specification will address the inconsistency. - Any errors which occur at the Matrix API level MUST return a "standard error response". This is a JSON object which looks like: diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index b765e36a..28876e44 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -83,6 +83,17 @@ The following other versions are also available, in reverse chronological order: - `r0.1.1 `_ - `r0.1.0 `_ + +API standards +------------- + +The mandatory baseline for client-server communication in Matrix is exchanging +JSON objects over HTTP APIs. More efficient optional transports will in future +be supported as optional extensions - e.g. a packed binary encoding over +stream-cipher encrypted TCP socket for low-bandwidth/low-roundtrip mobile usage. +For the default HTTP transport, all API calls use a Content-Type of +``application/json``. In addition, all strings MUST be encoded as UTF-8. + Server discovery ---------------- From 8fd5b15594ebe41f15334078507edc956c3bc8fb Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 5 Jun 2019 22:55:11 -0600 Subject: [PATCH 0444/1250] Reorganize event structure in c2s spec and clarify event capabilities Fixes https://github.com/matrix-org/matrix-doc/issues/1166 Fixes https://github.com/matrix-org/matrix-doc/issues/1527 Fixes https://github.com/matrix-org/matrix-doc/issues/1827 Note: In order to fix the "state events have the following fields: [no words]" bug (1827) we need to resolve references on common event types. When doing this we ultimately end up with more fields than may be required to explain the section, however this commit alters the section descriptions to just say "these fields" instead of "these additional fields". This is also preferable over trying to get the inheritance reversed in the common event types, as the `/sync` endpoint has a high amount of reliance on partial events definitions. --- .../newsfragments/2087.clarification | 1 + .../schema/core-event-schema/room_event.yaml | 3 +- .../schema/core-event-schema/state_event.yaml | 3 +- scripts/templating/matrix_templates/units.py | 1 + specification/client_server_api.rst | 57 +++++++++++++++ specification/events.rst | 73 ------------------- specification/index.rst | 5 ++ specification/targets.yaml | 1 - 8 files changed, 66 insertions(+), 78 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2087.clarification delete mode 100644 specification/events.rst diff --git a/changelogs/client_server/newsfragments/2087.clarification b/changelogs/client_server/newsfragments/2087.clarification new file mode 100644 index 00000000..1974127d --- /dev/null +++ b/changelogs/client_server/newsfragments/2087.clarification @@ -0,0 +1 @@ +Reorganize information about events into a common section. diff --git a/event-schemas/schema/core-event-schema/room_event.yaml b/event-schemas/schema/core-event-schema/room_event.yaml index 007372a5..231d5c65 100644 --- a/event-schemas/schema/core-event-schema/room_event.yaml +++ b/event-schemas/schema/core-event-schema/room_event.yaml @@ -1,7 +1,6 @@ allOf: - $ref: sync_room_event.yaml -description: In addition to the Event fields, Room Events have the following additional - fields. +description: Room Events have the following fields. properties: room_id: description: |- diff --git a/event-schemas/schema/core-event-schema/state_event.yaml b/event-schemas/schema/core-event-schema/state_event.yaml index 37d4426f..816f925f 100644 --- a/event-schemas/schema/core-event-schema/state_event.yaml +++ b/event-schemas/schema/core-event-schema/state_event.yaml @@ -1,7 +1,6 @@ allOf: - $ref: room_event.yaml - $ref: sync_state_event.yaml -description: In addition to the Room Event fields, State Events have the following - additional fields. +description: State Events have the following fields. title: State Event type: object diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index ddb65efe..d44fb9c8 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -748,6 +748,7 @@ class MatrixUnits(Units): with open(filepath, encoding="utf-8") as f: event_schema = yaml.load(f, OrderedLoader) + event_schema = resolve_references(filepath, event_schema) schema_info = process_data_type( event_schema, diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index d9342a5b..80e4a2f4 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1326,6 +1326,63 @@ the event ``type`` key SHOULD follow the Java package naming convention, e.g. ``com.example.myapp.event``. This ensures event types are suitably namespaced for each application and reduces the risk of clashes. +.. Note:: + Events are not limited to the types defined in this specification. New or custom + event types can be created on a whim using the Java package naming convention. + For example, a ``com.example.game.score`` event can be sent by clients and other + clients would receive it through Matrix. + +Note that the structure of these events may be different than those in the +server-server API. + +{{common_event_fields}} + +{{common_room_event_fields}} + +{{common_state_event_fields}} + + +Size limits +~~~~~~~~~~~ + +The complete event MUST NOT be larger than 65535 bytes, when formatted as a +`PDU for the Server-Server protocol <../server_server/%SERVER_RELEASE_LABEL%#pdus>`_, +including any signatures, and encoded as `Canonical JSON`_. + +There are additional restrictions on sizes per key: + +- ``sender`` MUST NOT exceed 255 bytes (including domain). +- ``room_id`` MUST NOT exceed 255 bytes. +- ``state_key`` MUST NOT exceed 255 bytes. +- ``type`` MUST NOT exceed 255 bytes. +- ``event_id`` MUST NOT exceed 255 bytes. + +Some event types have additional size restrictions which are specified in +the description of the event. Additional keys have no limit other than that +implied by the total 65 KB limit on events. + +Room Events +~~~~~~~~~~~ +.. NOTE:: + This section is a work in progress. + +This specification outlines several standard event types, all of which are +prefixed with ``m.`` + +{{m_room_aliases_event}} + +{{m_room_canonical_alias_event}} + +{{m_room_create_event}} + +{{m_room_join_rules_event}} + +{{m_room_member_event}} + +{{m_room_power_levels_event}} + +{{m_room_redaction_event}} + Syncing ~~~~~~~ diff --git a/specification/events.rst b/specification/events.rst deleted file mode 100644 index c5e4a288..00000000 --- a/specification/events.rst +++ /dev/null @@ -1,73 +0,0 @@ -.. Copyright 2016 OpenMarket Ltd -.. -.. Licensed under the Apache License, Version 2.0 (the "License"); -.. you may not use this file except in compliance with the License. -.. You may obtain a copy of the License at -.. -.. http://www.apache.org/licenses/LICENSE-2.0 -.. -.. Unless required by applicable law or agreed to in writing, software -.. distributed under the License is distributed on an "AS IS" BASIS, -.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -.. See the License for the specific language governing permissions and -.. limitations under the License. - -Event Structure -=============== - -All communication in Matrix is expressed in the form of data objects called -Events. These are the fundamental building blocks common to the client-server, -server-server and application-service APIs, and are described below. - -Note that the structure of these events may be different than those in the -server-server API. - -{{common_event_fields}} - -{{common_room_event_fields}} - -{{common_state_event_fields}} - - -Size limits ------------ - -The complete event MUST NOT be larger than 65535 bytes, when formatted as a -`PDU for the Server-Server protocol <../server_server/%SERVER_RELEASE_LABEL%#pdus>`_, -including any signatures, and encoded as `Canonical JSON`_. - -There are additional restrictions on sizes per key: - -- ``sender`` MUST NOT exceed 255 bytes (including domain). -- ``room_id`` MUST NOT exceed 255 bytes. -- ``state_key`` MUST NOT exceed 255 bytes. -- ``type`` MUST NOT exceed 255 bytes. -- ``event_id`` MUST NOT exceed 255 bytes. - -Some event types have additional size restrictions which are specified in -the description of the event. Additional keys have no limit other than that -implied by the total 65 KB limit on events. - -Room Events ------------ -.. NOTE:: - This section is a work in progress. - -This specification outlines several standard event types, all of which are -prefixed with ``m.`` - -{{m_room_aliases_event}} - -{{m_room_canonical_alias_event}} - -{{m_room_create_event}} - -{{m_room_join_rules_event}} - -{{m_room_member_event}} - -{{m_room_power_levels_event}} - -{{m_room_redaction_event}} - -.. _`Canonical JSON`: ../appendices.html#canonical-json diff --git a/specification/index.rst b/specification/index.rst index 33dff5a3..7aa6a672 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -348,6 +348,11 @@ pushed over federation to the participating servers in a room, currently using full mesh topology. Servers may also request backfill of events over federation from the other servers participating in a room. +.. Note:: + Events are not limited to the types defined in this specification. New or custom + event types can be created on a whim using the Java package naming convention. + For example, a ``com.example.game.score`` event can be sent by clients and other + clients would receive it through Matrix. Room Aliases ++++++++++++ diff --git a/specification/targets.yaml b/specification/targets.yaml index abcdc240..ed3dcee3 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -5,7 +5,6 @@ targets: client_server: files: - client_server_api.rst - - { 1: events.rst } - { 1: modules.rst } - { 2: feature_profiles.rst } - { 2: "group:modules" } # reference a group of files From c8a3850598cfa11fbfd1f30005ded4a854eec270 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 5 Jun 2019 23:06:00 -0600 Subject: [PATCH 0445/1250] Merge GET/PUT /state/:event_type endpoints Clarifying that the state key is optional, and how that works. Fixes https://github.com/matrix-org/matrix-doc/issues/1182 --- api/client-server/room_state.yaml | 72 ++----------------- api/client-server/rooms.yaml | 49 ++----------- .../newsfragments/2088.clarification | 1 + 3 files changed, 13 insertions(+), 109 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2088.clarification diff --git a/api/client-server/room_state.yaml b/api/client-server/room_state.yaml index bda66eb8..37da0335 100644 --- a/api/client-server/room_state.yaml +++ b/api/client-server/room_state.yaml @@ -31,6 +31,9 @@ paths: put: summary: Send a state event to the given room. description: | + .. For backwards compatibility with older links... + .. _`put-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-state-eventtype`: + State events can be sent using this endpoint. These events will be overwritten if ````, ```` and ```` all match. @@ -61,7 +64,9 @@ paths: - in: path type: string name: stateKey - description: The state_key for the state to send. Defaults to the empty string. + description: |- + The state_key for the state to send. Defaults to the empty string. When + an empty string, the trailing slash on this endpoint is optional. required: true x-example: "@alice:example.com" - in: body @@ -99,68 +104,3 @@ paths: } tags: - Room participation - "/rooms/{roomId}/state/{eventType}": - put: - summary: Send a state event to the given room. - description: | - State events can be sent using this endpoint. This endpoint is - equivalent to calling `/rooms/{roomId}/state/{eventType}/{stateKey}` - with an empty `stateKey`. Previous state events with matching - `` and ``, and empty ``, will be overwritten. - - Requests to this endpoint **cannot use transaction IDs** - like other ``PUT`` paths because they cannot be differentiated from the - ``state_key``. Furthermore, ``POST`` is unsupported on state paths. - - The body of the request should be the content object of the event; the - fields in this object will vary depending on the type of event. See - `Room Events`_ for the ``m.`` event specification. - operationId: setRoomState - security: - - accessToken: [] - parameters: - - in: path - type: string - name: roomId - description: The room to set the state in - required: true - x-example: "!636q39766251:example.com" - - in: path - type: string - name: eventType - description: The type of event to send. - required: true - x-example: "m.room.name" - - in: body - name: body - schema: - type: object - example: { - "name": "New name for the room" - } - responses: - 200: - description: "An ID for the sent event." - examples: - application/json: { - "event_id": "$YUwRidLecu:example.com" - } - schema: - type: object - properties: - event_id: - type: string - description: |- - A unique identifier for the event. - 403: - description: |- - The sender doesn't have permission to send the event into the room. - schema: - $ref: "definitions/errors/error.yaml" - examples: - application/json: { - "errcode": "M_FORBIDDEN", - "error": "You do not have permission to send the event." - } - tags: - - Room participation diff --git a/api/client-server/rooms.yaml b/api/client-server/rooms.yaml index 377783c6..f29a1860 100644 --- a/api/client-server/rooms.yaml +++ b/api/client-server/rooms.yaml @@ -68,6 +68,9 @@ paths: get: summary: Get the state identified by the type and key. description: |- + .. For backwards compatibility with older links... + .. _`get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-state-eventtype`: + Looks up the contents of a state event in a room. If the user is joined to the room then the state is taken from the current state of the room. If the user has left the room then the state is @@ -91,7 +94,9 @@ paths: - in: path type: string name: stateKey - description: The key of the state to look up. + description: |- + The key of the state to look up. Defaults to an empty string. When + an empty string, the trailing slash on this endpoint is optional. required: true x-example: "" responses: @@ -110,48 +115,6 @@ paths: member of the room. tags: - Room participation - "/rooms/{roomId}/state/{eventType}": - get: - summary: Get the state identified by the type, with the empty state key. - description: |- - Looks up the contents of a state event in a room. If the user is - joined to the room then the state is taken from the current - state of the room. If the user has left the room then the state is - taken from the state of the room when they left. - - This looks up the state event with the empty state key. - operationId: getRoomStateByType - security: - - accessToken: [] - parameters: - - in: path - type: string - name: roomId - description: The room to look up the state in. - required: true - x-example: "!636q39766251:example.com" - - in: path - type: string - name: eventType - description: The type of state to look up. - required: true - x-example: "m.room.name" - responses: - 200: - description: The content of the state event. - examples: - application/json: { - "name": "Example room name"} - schema: - type: object - 404: - description: The room has no state with the given type or key. - 403: - description: > - You aren't a member of the room and weren't previously a - member of the room. - tags: - - Room participation "/rooms/{roomId}/state": get: summary: Get all state events in the current state of a room. diff --git a/changelogs/client_server/newsfragments/2088.clarification b/changelogs/client_server/newsfragments/2088.clarification new file mode 100644 index 00000000..ae22d66a --- /dev/null +++ b/changelogs/client_server/newsfragments/2088.clarification @@ -0,0 +1 @@ +De-duplicate ``/state/`` endpoints, clarifying that the ```` is optional. From bbc740197390091f9d9a83fb0a12c79b1a2e620f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 5 Jun 2019 23:14:33 -0600 Subject: [PATCH 0446/1250] Clarify when and where CORS headers should be returned Fixes https://github.com/matrix-org/matrix-doc/issues/1736 Fixes https://github.com/matrix-org/matrix-doc/issues/2013 --- .../newsfragments/2089.clarification | 1 + specification/client_server_api.rst | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2089.clarification diff --git a/changelogs/client_server/newsfragments/2089.clarification b/changelogs/client_server/newsfragments/2089.clarification new file mode 100644 index 00000000..17405adc --- /dev/null +++ b/changelogs/client_server/newsfragments/2089.clarification @@ -0,0 +1 @@ +Clarify when and where CORS headers should be returned. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index d9342a5b..e38c8ac0 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -242,6 +242,9 @@ recommended. {{versions_cs_http_api}} + +.. _`CORS`: + Web Browser Clients ------------------- @@ -250,9 +253,14 @@ web browser or similar environment. In these cases, the homeserver should respon to pre-flight requests and supply Cross-Origin Resource Sharing (CORS) headers on all requests. -When a client approaches the server with a pre-flight (``OPTIONS``) request, the -server should respond with the CORS headers for that route. The recommended CORS -headers to be returned by servers on all requests are: +Servers MUST expect that clients will approach them with ``OPTIONS`` requests, +allowing clients to discover the CORS headers. All endpoints in this specification s +upport the ``OPTIONS`` method, however the server MUST NOT perform any logic defined +for the endpoints when approached with an ``OPTIONS`` request. + +When a client approaches the server with a request, the server should respond with +the CORS headers for that route. The recommended CORS headers to be returned by +servers on all requests are: .. code:: @@ -296,6 +304,10 @@ In this section, the following terms are used with specific meanings: Well-known URI ~~~~~~~~~~~~~~ +.. Note:: + Servers hosting the ``.well-known`` JSON file SHOULD offer CORS headers, as + per the `CORS`_ section in this specification. + The ``.well-known`` method uses a JSON file at a predetermined location to specify parameter values. The flow for this method is as follows: From 79bbb47d9f200c3d99d3c6d8e2f7456cd66ac94f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 5 Jun 2019 23:18:04 -0600 Subject: [PATCH 0447/1250] Clarify when authorization and rate-limiting are not applicable Fixes https://github.com/matrix-org/matrix-doc/issues/1971 --- .../newsfragments/2090.clarification | 1 + .../matrix_templates/templates/http-api.tmpl | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2090.clarification diff --git a/changelogs/client_server/newsfragments/2090.clarification b/changelogs/client_server/newsfragments/2090.clarification new file mode 100644 index 00000000..23ab50f7 --- /dev/null +++ b/changelogs/client_server/newsfragments/2090.clarification @@ -0,0 +1 @@ +Clarify when authorization and rate-limiting are not applicable. diff --git a/scripts/templating/matrix_templates/templates/http-api.tmpl b/scripts/templating/matrix_templates/templates/http-api.tmpl index 0b9207d9..74836045 100644 --- a/scripts/templating/matrix_templates/templates/http-api.tmpl +++ b/scripts/templating/matrix_templates/templates/http-api.tmpl @@ -10,13 +10,13 @@ {{endpoint.desc}} -{{":Rate-limited: Yes." if endpoint.rate_limited else "" }} -{{":Requires auth: Yes." if endpoint.requires_auth else "" }} +{{":Rate-limited: Yes." if endpoint.rate_limited else ":Rate-limited: No." }} +{{":Requires auth: Yes." if endpoint.requires_auth else ":Requires auth: No." }} .. class:: httpheaders - + Request format: - + {% if (endpoint.req_param_by_loc | length) %} {{ tables.split_paramtable(endpoint.req_param_by_loc) }} {% if (endpoint.req_body_tables) %} @@ -33,7 +33,7 @@ {% if endpoint.res_headers is not none -%} .. class:: httpheaders - + Response headers: {{ tables.paramtable(endpoint.res_headers.rows) }} @@ -42,7 +42,7 @@ {% if endpoint.res_tables|length > 0 -%} .. class:: httpheaders - + Response format: {% for table in endpoint.res_tables -%} @@ -54,7 +54,7 @@ {% endif -%} .. class:: httpheaders - + Example request: .. code:: http @@ -64,7 +64,7 @@ {% if endpoint.responses|length > 0 -%} .. class:: httpheaders - + Response{{"s" if endpoint.responses|length > 1 else "" }}: {% endif -%} @@ -78,7 +78,7 @@ {% if res["example"] -%} .. class:: httpheaders - + Example .. code:: json From 976f32fcab51fde2de0301a7844c9470a9fd7ab4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 5 Jun 2019 23:23:23 -0600 Subject: [PATCH 0448/1250] Clarify that /register must produce valid Matrix User IDs Fixes https://github.com/matrix-org/matrix-doc/issues/1793 --- api/client-server/registration.yaml | 5 ++++- changelogs/client_server/newsfragments/2091.clarification | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/2091.clarification diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 3195ab41..6fa99550 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -59,6 +59,9 @@ paths: supplied by the client or generated by the server. The server may invalidate any access token previously associated with that device. See `Relationship between access tokens and devices`_. + + Any user ID returned by this API must conform to the grammar given in the + `Matrix specification <../appendices.html#user-identifiers>`_. operationId: register parameters: - in: query @@ -142,7 +145,7 @@ paths: The fully-qualified Matrix user ID (MXID) that has been registered. Any user ID returned by this API must conform to the grammar given in the - `Matrix specification `_. + `Matrix specification <../appendices.html#user-identifiers>`_. access_token: type: string description: |- diff --git a/changelogs/client_server/newsfragments/2091.clarification b/changelogs/client_server/newsfragments/2091.clarification new file mode 100644 index 00000000..2c4a276e --- /dev/null +++ b/changelogs/client_server/newsfragments/2091.clarification @@ -0,0 +1 @@ +Clarify that ``/register`` must produce valid Matrix User IDs. From e644227f4b607b3438cb37b21616a68e7f007645 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 6 Jun 2019 14:13:20 -0600 Subject: [PATCH 0449/1250] Clarify that the server shouldn't process retries for UIA --- specification/client_server_api.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 318ac08d..4593311d 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -557,9 +557,10 @@ message in the standard format. For example: } If the client has completed all stages of a flow, the homeserver performs the -API call and returns the result as normal. Completed stages cannot be re-tried; -The client must abandon the current session and start over. Homeservers should -treat retries as authentication errors. +API call and returns the result as normal. Completed stages cannot be retried +by clients, therefore servers must return either a 401 response with the completed +stages, or the result of the API call if all stages were completed when a client +retries a stage. Some authentication types may be completed by means other than through the Matrix client, for example, an email confirmation may be completed when the user From afead2eb1bb578d6ca01af3ed3a8f729b852e795 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 6 Jun 2019 14:18:41 -0600 Subject: [PATCH 0450/1250] Clarify LL in /sync a bit more --- api/client-server/sync.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 4fe22d50..a0d2fd60 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -37,7 +37,13 @@ paths: *Note*: This endpoint supports lazy-loading. See `Filtering <#filtering>`_ for more information. Lazy-loading members is only supported on a ``StateFilter`` - for this endpoint. + for this endpoint. When lazy-loading is enabled, servers MUST include the + syncing user's own membership event when they join a room, or when the + full state of rooms is requested. The user's own membership event is eligible + for being considered redudant by the server. When a sync is ``limited``, + the server MUST return membership events for the timeline, even if the + applicable events are not in the response, regardless as to whether or not + they are redundant. operationId: sync security: - accessToken: [] From 9bf0103ef359202026ffce958c243b898a828f9e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 6 Jun 2019 14:36:30 -0600 Subject: [PATCH 0451/1250] Clarify how many PDUs are in a given transaction object Fixes https://github.com/matrix-org/matrix-doc/issues/2093 --- api/server-server/backfill.yaml | 2 +- .../definitions/single_pdu_transaction.yaml | 32 ++++++++++++++++++ .../unlimited_pdu_transaction.yaml | 33 +++++++++++++++++++ api/server-server/events.yaml | 2 +- .../newsfragments/2095.clarification | 1 + 5 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 api/server-server/definitions/single_pdu_transaction.yaml create mode 100644 api/server-server/definitions/unlimited_pdu_transaction.yaml create mode 100644 changelogs/server_server/newsfragments/2095.clarification diff --git a/api/server-server/backfill.yaml b/api/server-server/backfill.yaml index 0da0e234..2ed6298c 100644 --- a/api/server-server/backfill.yaml +++ b/api/server-server/backfill.yaml @@ -64,7 +64,7 @@ paths: A transaction containing the PDUs that preceded the given event(s), including the given event(s), up to the given limit. schema: - $ref: "definitions/transaction.yaml" + $ref: "definitions/unlimited_pdu_transaction.yaml" "/get_missing_events/{roomId}": post: summary: Retrieves events that the sender is missing diff --git a/api/server-server/definitions/single_pdu_transaction.yaml b/api/server-server/definitions/single_pdu_transaction.yaml new file mode 100644 index 00000000..ff682a44 --- /dev/null +++ b/api/server-server/definitions/single_pdu_transaction.yaml @@ -0,0 +1,32 @@ +# Copyright 2019 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 +allOf: + - $ref: "transaction.yaml" +properties: + pdus: + type: array + description: |- + A single PDU. Note that events have a different format depending on the room + version - check the `room version specification`_ for precise event formats. + items: + type: object + title: PDU + description: |- + The `PDUs <#pdus>`_ contained in the transaction. The event format varies depending + on the room version - check the `room version specification`_ for precise event formats. + properties: [] + example: + $ref: "../examples/minimal_pdu.json" +required: ['origin', 'origin_server_ts', 'pdus'] diff --git a/api/server-server/definitions/unlimited_pdu_transaction.yaml b/api/server-server/definitions/unlimited_pdu_transaction.yaml new file mode 100644 index 00000000..0fc31ee4 --- /dev/null +++ b/api/server-server/definitions/unlimited_pdu_transaction.yaml @@ -0,0 +1,33 @@ +# Copyright 2019 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 +allOf: + - $ref: "transaction.yaml" +properties: + pdus: + type: array + description: |- + List of persistent updates to rooms. Note that events have a different format + depending on the room version - check the `room version specification`_ for + precise event formats. + items: + type: object + title: PDU + description: |- + The `PDUs <#pdus>`_ contained in the transaction. The event format varies depending + on the room version - check the `room version specification`_ for precise event formats. + properties: [] + example: + $ref: "../examples/minimal_pdu.json" +required: ['origin', 'origin_server_ts', 'pdus'] diff --git a/api/server-server/events.yaml b/api/server-server/events.yaml index 1f1a802d..1f8ee537 100644 --- a/api/server-server/events.yaml +++ b/api/server-server/events.yaml @@ -156,4 +156,4 @@ paths: 200: description: A transaction containing a single PDU which is the event requested. schema: - $ref: "definitions/transaction.yaml" + $ref: "definitions/single_pdu_transaction.yaml" diff --git a/changelogs/server_server/newsfragments/2095.clarification b/changelogs/server_server/newsfragments/2095.clarification new file mode 100644 index 00000000..66257e17 --- /dev/null +++ b/changelogs/server_server/newsfragments/2095.clarification @@ -0,0 +1 @@ +Clarify how many PDUs are contained in transaction objects for various endpoints. From f0eb495ceebfced779d54b5fcfab2aabdea35ad2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 6 Jun 2019 15:41:28 -0600 Subject: [PATCH 0452/1250] Clarify how notification counts are calculated in /sync Fixes https://github.com/matrix-org/matrix-doc/issues/2015 --- api/client-server/sync.yaml | 6 ++++-- changelogs/client_server/newsfragments/2097.clarification | 1 + specification/modules/receipts.rst | 4 +++- 3 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2097.clarification diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 02fddb84..4514d417 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -167,11 +167,13 @@ paths: this room. allOf: - $ref: "definitions/event_batch.yaml" - "unread_notifications": + unread_notifications: title: Unread Notification Counts type: object description: |- - Counts of unread notifications for this room + Counts of unread notifications for this room. See the + `Receipts module <#module-receipts>`_ for more information + on how these are calculated. properties: highlight_count: title: Highlighted notification count diff --git a/changelogs/client_server/newsfragments/2097.clarification b/changelogs/client_server/newsfragments/2097.clarification new file mode 100644 index 00000000..68d89bcc --- /dev/null +++ b/changelogs/client_server/newsfragments/2097.clarification @@ -0,0 +1 @@ +Clarify how ``unread_notifications`` is calculated. diff --git a/specification/modules/receipts.rst b/specification/modules/receipts.rst index ee2b697a..1745706e 100644 --- a/specification/modules/receipts.rst +++ b/specification/modules/receipts.rst @@ -26,7 +26,9 @@ to a homeserver. To prevent this from becoming a problem, receipts are implement using "up to" markers. This marker indicates that the acknowledgement applies to all events "up to and including" the event specified. For example, marking an event as "read" would indicate that the user had read all events *up to* the -referenced event. +referenced event. Servers MUST decremement the number of pending notifications +for a user if the events are up to or including the read receipt. This is typically +done by adjusting the ``unread_notifications`` value in a ``/sync`` response. Events ------ From b9c9396c111c08a893dda37225b1073d1d2ce4cd Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 6 Jun 2019 15:59:54 -0600 Subject: [PATCH 0453/1250] Specify some of the common concepts for Matrix in the index See https://github.com/matrix-org/matrix-doc/pull/2061 Fixes https://github.com/matrix-org/matrix-doc/issues/1468 Fixes https://github.com/matrix-org/matrix-doc/issues/1528 The section is not referenced by the specifications yet - they do a fairly good job of explaining it over and over. In future, it would be good to point all the references to the index. --- api/server-server/keys_query.yaml | 8 +++-- api/server-server/keys_server.yaml | 2 ++ .../newsfragments/2097.clarification | 1 + specification/index.rst | 36 +++++++++++++++++++ 4 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 changelogs/server_server/newsfragments/2097.clarification diff --git a/api/server-server/keys_query.yaml b/api/server-server/keys_query.yaml index e616915b..4989f7fa 100644 --- a/api/server-server/keys_query.yaml +++ b/api/server-server/keys_query.yaml @@ -44,8 +44,10 @@ paths: type: string description: |- **Deprecated**. Servers should not use this parameter and instead - opt to return all keys, not just the requested one. The key ID to + opt to return all keys, not just the requested one. The key ID to look up. + + When excluded, the trailing slash on this endpoint is optional. required: false x-example: "ed25519:abc123" - in: query @@ -53,7 +55,7 @@ paths: type: integer format: int64 description: |- - A millisecond POSIX timestamp in milliseconds indicating when the returned + A millisecond POSIX timestamp in milliseconds indicating when the returned certificates will need to be valid until to be useful to the requesting server. If not supplied, the current time as determined by the notary server is used. @@ -114,7 +116,7 @@ paths: format: int64 description: |- A millisecond POSIX timestamp in milliseconds indicating when - the returned certificates will need to be valid until to be + the returned certificates will need to be valid until to be useful to the requesting server. If not supplied, the current time as determined by the notary diff --git a/api/server-server/keys_server.yaml b/api/server-server/keys_server.yaml index 69985ab7..465bb294 100644 --- a/api/server-server/keys_server.yaml +++ b/api/server-server/keys_server.yaml @@ -51,6 +51,8 @@ paths: **Deprecated**. Servers should not use this parameter and instead opt to return all keys, not just the requested one. The key ID to look up. + + When excluded, the trailing slash on this endpoint is optional. required: false x-example: "ed25519:abc123" deprecated: true diff --git a/changelogs/server_server/newsfragments/2097.clarification b/changelogs/server_server/newsfragments/2097.clarification new file mode 100644 index 00000000..10dcecb6 --- /dev/null +++ b/changelogs/server_server/newsfragments/2097.clarification @@ -0,0 +1 @@ +Clarify that the trailing slash is optional on ``/keys/*`` endpoints when no key ID is requested. diff --git a/specification/index.rst b/specification/index.rst index 33dff5a3..375e19c0 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -425,6 +425,42 @@ dedicated API. The API is symmetrical to managing Profile data. Would it really be overengineered to use the same API for both profile & private user data, but with different ACLs? + +Common concepts +--------------- + +Various things are common throughout all of the Matrix APIs. They are +documented here. + +Trailing slashes on API endpoints +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Unless the endpoint is explicltly specified to have a trailing slash, the +slash is optional. For example, an endpoint specified as ``/_matrix/example/`` +would require a trailing slash, however an endpoint specified as ``/_matrix/example`` +has an optional slash (can be excluded when making requests). + +Namespacing +~~~~~~~~~~~ + +Namespacing helps prevent conflicts between multiple applications and the specification +itself. Where namespacing is used, ``m.`` prefixes are used by the specification to +indicate that the field is controlled by the specification. Custom or non-specified +namespaces used in the wild SHOULD use the Java package naming convention to prevent +conflicts. + +As an example, event types are namespaced under ``m.`` in the specification however +any client can send a custom event type, such as ``com.example.game.score`` without +needing to put the event into the ``m.`` namespace. + +Timestamps +~~~~~~~~~~ + +Unless otherwise stated, timestamps are measured as milliseconds since the Unix epoch. +Throughout the specification this may be referred to as POSIX, Unix, or just "time in +milliseconds". + + .. _`room versions`: Room Versions From cd6b012523c5ea11974617036ec1ee189babdb99 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 6 Jun 2019 17:07:49 -0600 Subject: [PATCH 0454/1250] Clarify what a "module" is and update feature profiles for clients Fixes https://github.com/matrix-org/matrix-doc/issues/2009 --- .../newsfragments/2098.clarification | 1 + specification/feature_profiles.rst | 36 ++++++++++++++++++- specification/modules.rst | 8 +++++ specification/modules/_template.rst | 2 +- 4 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2098.clarification diff --git a/changelogs/client_server/newsfragments/2098.clarification b/changelogs/client_server/newsfragments/2098.clarification new file mode 100644 index 00000000..1c8ba3ea --- /dev/null +++ b/changelogs/client_server/newsfragments/2098.clarification @@ -0,0 +1 @@ +Clarify what a "module" is and update feature profiles for clients. diff --git a/specification/feature_profiles.rst b/specification/feature_profiles.rst index c6b8ef4c..bb638380 100644 --- a/specification/feature_profiles.rst +++ b/specification/feature_profiles.rst @@ -1,4 +1,5 @@ .. Copyright 2016 OpenMarket Ltd +.. Copyright 2019 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. @@ -32,33 +33,67 @@ Summary Module / Profile Web Mobile Desktop CLI Embedded ===================================== ========== ========== ========== ========== ========== `Instant Messaging`_ Required Required Required Required Optional + `Direct Messaging`_ Required Required Required Required Optional + `Mentions`_ Required Required Required Optional Optional `Presence`_ Required Required Required Required Optional `Push Notifications`_ Optional Required Optional Optional Optional `Receipts`_ Required Required Required Required Optional + `Fully read markers`_ Optional Optional Optional Optional Optional `Typing Notifications`_ Required Required Required Required Optional `VoIP`_ Required Required Required Optional Optional + `Ignoring Users`_ Required Required Required Optional Optional + `Reporting Content`_ Optional Optional Optional Optional Optional `Content Repository`_ Required Required Required Optional Optional `Managing History Visibility`_ Required Required Required Required Optional `Server Side Search`_ Optional Optional Optional Optional Optional + `Room Upgrades`_ Required Required Required Required Optional `Server Administration`_ Optional Optional Optional Optional Optional `Event Context`_ Optional Optional Optional Optional Optional `Third Party Networks`_ Optional Optional Optional Optional Optional + `Send-to-Device Messaging`_ Optional Optional Optional Optional Optional + `Device Management`_ Optional Optional Optional Optional Optional + `End-to-End Encryption`_ Optional Optional Optional Optional Optional + `Guest Accounts`_ Optional Optional Optional Optional Optional + `Room Previews`_ Optional Optional Optional Optional Optional + `Client Config`_ Optional Optional Optional Optional Optional + `SSO Login`_ Optional Optional Optional Optional Optional + `OpenID`_ Optional Optional Optional Optional Optional + `Stickers`_ Optional Optional Optional Optional Optional + `Server ACLs`_ Optional Optional Optional Optional Optional + `Server Notices`_ Optional Optional Optional Optional Optional ===================================== ========== ========== ========== ========== ========== *Please see each module for more details on what clients need to implement.* .. _Instant Messaging: `module:im`_ +.. _Direct Messaging: `module:dm`_ +.. _Mentions: `module:mentions`_ .. _Presence: `module:presence`_ .. _Push Notifications: `module:push`_ .. _Receipts: `module:receipts`_ +.. _Fully read markers: `module:read-markers`_ .. _Typing Notifications: `module:typing`_ .. _VoIP: `module:voip`_ +.. _Ignoring Users: `module:ignore_users`_ +.. _Reporting Content: `module:report_content`_ .. _Content Repository: `module:content`_ .. _Managing History Visibility: `module:history-visibility`_ .. _Server Side Search: `module:search`_ +.. _Room Upgrades: `module:room-upgrades`_ .. _Server Administration: `module:admin`_ .. _Event Context: `module:event-context`_ .. _Third Party Networks: `module:third-party-networks`_ +.. _Send-to-Device Messaging: `module:to_device`_ +.. _Device Management: `module:device-management`_ +.. _End-to-End Encryption: `module:e2e`_ +.. _Guest Accounts: `module:guest-access`_ +.. _Room Previews: `module:room-previews`_ +.. _Client Config: `module:account_data`_ +.. _SSO Login: `module:sso_login`_ +.. _OpenID: `module:openid`_ +.. _Stickers: `module:stickers`_ +.. _Server ACLs: `module:server-acls`_ +.. Server Notices already has a link elsewhere. Clients ------- @@ -110,4 +145,3 @@ This is a client which is typically running on an embedded device such as a kettle, fridge or car. These clients tend to perform a few operations and run in a resource constrained environment. Like embedded applications, they are not intended to be fully-fledged communication systems. - diff --git a/specification/modules.rst b/specification/modules.rst index 36f79cfd..f2269a5a 100644 --- a/specification/modules.rst +++ b/specification/modules.rst @@ -1,4 +1,5 @@ .. Copyright 2016 OpenMarket Ltd +.. Copyright 2019 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. @@ -15,3 +16,10 @@ Modules ======= +Modules are parts of the Client-Server API which are not universal to all +endpoints and are accessible to all clients. Modules are strictly defined +within this specification and should not be mistaken for XEP or equivalent +extensions from other protocols - in order for an implementation to be +compliant with the Client-Server specification it MUST support all modules +and supporting specification. The exception being clients, which are governed +by `Feature Profiles <#feature-profiles>`_. diff --git a/specification/modules/_template.rst b/specification/modules/_template.rst index aa4f93db..d1fef7f5 100644 --- a/specification/modules/_template.rst +++ b/specification/modules/_template.rst @@ -15,6 +15,7 @@ Module Heading ============== +.. NOTE: Prefer to identify-modules-with-dashes despite historical examples. .. _module:short-name: A short summary of the module. What features does this module provide? An anchor @@ -67,4 +68,3 @@ This includes privacy leaks: for example leaking presence info. How do misbehaving clients or servers impact this module? This section should always be included, if only to say "we've thought about it but there isn't anything to do here". - From 87d8d970745e107f4494256dcbe475fa2c73eda3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 6 Jun 2019 17:19:08 -0600 Subject: [PATCH 0455/1250] Remove incomplete and weird sentence --- specification/modules.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/specification/modules.rst b/specification/modules.rst index f2269a5a..6a2564ce 100644 --- a/specification/modules.rst +++ b/specification/modules.rst @@ -17,9 +17,8 @@ Modules ======= Modules are parts of the Client-Server API which are not universal to all -endpoints and are accessible to all clients. Modules are strictly defined -within this specification and should not be mistaken for XEP or equivalent -extensions from other protocols - in order for an implementation to be -compliant with the Client-Server specification it MUST support all modules -and supporting specification. The exception being clients, which are governed -by `Feature Profiles <#feature-profiles>`_. +endpoints. Modules are strictly defined within this specification and +should not be mistaken for XEP or equivalent extensions from other protocols +- in order for an implementation to be compliant with the Client-Server +specification it MUST support all modules and supporting specification. +The exception being clients, which are governed by `Feature Profiles <#feature-profiles>`_. From 49dbb3ee4fa25ff5a2c5b43115471bb32410982b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 6 Jun 2019 17:26:27 -0600 Subject: [PATCH 0456/1250] Declare Matrix 1.0 in the index Fixes https://github.com/matrix-org/matrix-doc/issues/2044 --- specification/index.rst | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/specification/index.rst b/specification/index.rst index 33dff5a3..67d17a11 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -52,14 +52,11 @@ is useful for browsing the Client-Server API. Introduction to the Matrix APIs ------------------------------- -.. WARNING:: - The Matrix specification is still evolving: the APIs are not yet frozen - and this document is in places a work in progress or stale. We have made every - effort to clearly flag areas which are still being finalised. - We're publishing it at this point because it's complete enough to be more than - useful and provide a canonical reference to how Matrix is evolving. Our end - goal is to mirror WHATWG's `Living Standard - `_. +.. Note:: + The Matrix specification is currently at version 1.0 - a milestone indicating that + anything built on top of Matrix can safely rely on the APIs in the specification + not changing drastically. The specification continues to evolve, however, mirroring + something similar to WHATWG's `Living Standard `_. Matrix is a set of open APIs for open-federated Instant Messaging (IM), Voice over IP (VoIP) and Internet of Things (IoT) communication, designed to create From 06ee60f0046b80d7d85f80e1b23d2c2e1147d0cd Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 6 Jun 2019 17:32:59 -0600 Subject: [PATCH 0457/1250] Clarify what compliant implementations are --- specification/modules.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/specification/modules.rst b/specification/modules.rst index 6a2564ce..1bc88445 100644 --- a/specification/modules.rst +++ b/specification/modules.rst @@ -18,7 +18,10 @@ Modules Modules are parts of the Client-Server API which are not universal to all endpoints. Modules are strictly defined within this specification and -should not be mistaken for XEP or equivalent extensions from other protocols -- in order for an implementation to be compliant with the Client-Server -specification it MUST support all modules and supporting specification. -The exception being clients, which are governed by `Feature Profiles <#feature-profiles>`_. +should not be mistaken for experimental extensions or optional features. +A compliant server implementation MUST support all modules and supporting +specification (unless the implementation only targets clients of certain +profiles, in which case only the required modules for those feature profiles +MUST be implemented). A compliant client implementation MUST support all +the required modules and supporting specification for the `Feature Profile <#feature-profiles>`_ +it targets. From 4f665f06e6cbdca0310c2cc5b533b1cdd1cf50d0 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 6 Jun 2019 17:42:37 -0600 Subject: [PATCH 0458/1250] Clarify what Matrix 1.0 is further And add a table for minimum versions. --- specification/index.rst | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/specification/index.rst b/specification/index.rst index 67d17a11..37c6d682 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -50,13 +50,34 @@ one of the above APIs. The `Matrix Client-Server API Swagger Viewer `_ is useful for browsing the Client-Server API. + +Matrix versions +~~~~~~~~~~~~~~~ + +.. Note:: + As of June 10th 2019, the Matrix specification is considered out of beta - + indicating that all currently released APIs are considered stable and secure + to the best of our knowledge, and the spec should contain the complete + information necessary to develop production-grade implementations of Matrix + without the need for external reference. + +Matrix 1.0 (released June 10th, 2019) consists of the following minimum API +versions: + +======================= ======= +API/Specification Version +======================= ======= +Client-Server API r0.5.0 +Server-Server API r0.1.2 +Application Service API r0.1.1 +Identity Service API r0.1.1 +Push Gateway API r0.1.0 +Room Version v5 +======================= ======= + + Introduction to the Matrix APIs ------------------------------- -.. Note:: - The Matrix specification is currently at version 1.0 - a milestone indicating that - anything built on top of Matrix can safely rely on the APIs in the specification - not changing drastically. The specification continues to evolve, however, mirroring - something similar to WHATWG's `Living Standard `_. Matrix is a set of open APIs for open-federated Instant Messaging (IM), Voice over IP (VoIP) and Internet of Things (IoT) communication, designed to create From ae9abe798ef07de9c48f739b50b01e955725c63b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 6 Jun 2019 23:41:51 -0600 Subject: [PATCH 0459/1250] Revert signature change for redactable event test The previous signature was calculated on the unredacted event, which means the signature produced was wrong. --- specification/appendices/test_vectors.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/appendices/test_vectors.rst b/specification/appendices/test_vectors.rst index 7759fa88..790ed878 100644 --- a/specification/appendices/test_vectors.rst +++ b/specification/appendices/test_vectors.rst @@ -162,7 +162,7 @@ The event signing algorithm should emit the following signed event: "sender": "@u:domain", "signatures": { "domain": { - "ed25519:1": "4zc79tH2cU6Y+eg4YbbF7KiDOrnwEDjlhTqIKiH4k7L9zD9XCiomD7x9odL9eEwnyy1144QyMBe8O3HK++GHBg" + "ed25519:1": "Wm+VzmOUOz08Ds+0NTWb1d4CZrVsJSikkeRxh6aCcUwu6pNC78FunoD7KNWzqFn241eYHYMGCA5McEiVPdhzBA" } }, "unsigned": { From 7f01346bbad3f0cc31bf2d2fcfde4dd7daa0b2f6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 6 Jun 2019 23:50:26 -0600 Subject: [PATCH 0460/1250] Provide a more complete example of a "minimally-sized event" Using all the required fields of a v1 event. --- specification/appendices/test_vectors.rst | 25 +++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/specification/appendices/test_vectors.rst b/specification/appendices/test_vectors.rst index 790ed878..1de458cc 100644 --- a/specification/appendices/test_vectors.rst +++ b/specification/appendices/test_vectors.rst @@ -91,11 +91,22 @@ Given the following minimally-sized event: .. code:: json { + "room_id": "!x:domain", + "sender": "@a:domain", "event_id": "$0:domain", "origin": "domain", "origin_server_ts": 1000000, "signatures": {}, + "hashes": {}, "type": "X", + "content": {}, + "prev_events": [ + ["$1:domain", "ExampleHash"] + ], + "auth_events": [ + ["$2", "ExampleHash2"] + ], + "depth": 3, "unsigned": { "age_ts": 1000000 } @@ -106,15 +117,25 @@ The event signing algorithm should emit the following signed event: .. code:: json { + "auth_events": [ + ["$2", "6tJjLpXtggfke8UxFhAKg82QVkJzvKOVOOSjUDK4ZSI"] + ], + "content": {}, + "depth": 3, "event_id": "$0:domain", "hashes": { - "sha256": "6tJjLpXtggfke8UxFhAKg82QVkJzvKOVOOSjUDK4ZSI" + "sha256": "6AaJICN1NJURTtaomDYfJlCPMIU+0gtkwg7qzd8FiJM" }, "origin": "domain", "origin_server_ts": 1000000, + "prev_events": [ + ["$1:domain", "onLKD1bGljeBWQhWZ1kaP9SorVmRQNdN5aM2JYU2n/g"] + ], + "room_id": "!x:domain", + "sender": "@a:domain", "signatures": { "domain": { - "ed25519:1": "JV2dlZUASAefSdywnyCxzykHlyr7xkKGK7IRir1cF8eYsnONrCSb+GRn7aXXstr1UHKvzYjRXPx0001+boD1Ag" + "ed25519:1": "51U0wpKYsaNLTQRbha2v5EGO2cVA6pCtnAKEXguu3j3efCLlmq/53vEfWhsk3tY6gnLsV0YM4Lx2NGZkzmV2Ag" } }, "type": "X", From d7858354f26aa3bb8a6cc58e0b1db1d280eee21e Mon Sep 17 00:00:00 2001 From: Jamie McClymont Date: Fri, 7 Jun 2019 20:54:47 +1200 Subject: [PATCH 0461/1250] Fix 404s in links from room v1 spec --- specification/rooms/v1.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index 1c7a56c4..e8cbf663 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -293,5 +293,5 @@ 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 +.. _`auth events selection`: ../server_server/r0.1.1.html#auth-events-selection +.. _`Signing Events`: ../server_server/r0.1.1.html#signing-events From 7f65704ebc23c8ebcd8f38b7e5c11172a28e2254 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 7 Jun 2019 12:45:11 +0100 Subject: [PATCH 0462/1250] Update wording and answer review comments --- proposals/2078-homeserver-password-resets.md | 132 +++++++++++-------- 1 file changed, 75 insertions(+), 57 deletions(-) diff --git a/proposals/2078-homeserver-password-resets.md b/proposals/2078-homeserver-password-resets.md index f8dfc53e..5064be20 100644 --- a/proposals/2078-homeserver-password-resets.md +++ b/proposals/2078-homeserver-password-resets.md @@ -3,70 +3,76 @@ This MSC proposes removing the current requirement of the identity server to send third-party request tokens, and allows homeservers to implement the functionality instead. These request tokens are used to verify the identity of -the request auther as an owner of the third-party identity (3PID). This can be -used for binding a 3PID to an account, or for resetting passwords via email or -SMS. The latter is what this proposal mainly focuses on, but be aware that it -allows for any task that requires requesting a token through a 3PID to be -taken on by the homeserver instead of the identity server. +the request author as an owner of the third-party ID (3PID). This can be used +for binding a 3PID to an account, or for resetting passwords via email or SMS. +The latter is what this proposal mainly focuses on, but be aware that it allows +for any task that requires requesting a token for a 3PID to be taken on by the +homeserver instead of the identity server. The intention is to put less trust in the identity server, which is currently one of the most centralised components of Matrix. As it stands, an attacker in control of a identity server can reset a user's password if the identity server is considered trusted by that homeserver, and the user has registered at least -one 3PID. This is due to the identity server currently handling the job of -confirming the user's control of that identity. +one 3PID. This is due to the identity server handling the job of confirming the +user's control of that identity. -The MSC aims to simply clarify that homeservers can take on the responsibility -of sending password reset tokens themselves. +The MSC seeks to clarify that homeservers can take on the responsibility of +sending password reset tokens themselves, and a new response field that will +aid homeservers in doing so. -## Proposal +# Background -Currently when a client requests a password reset, it makes a call to either +Currently when a client requests a 3PID token, it makes a call to one of the +`/requestToken` endpoints on the homeserver. For instance, during password +resets, a token is requested from either [/_matrix/client/r0/account/password/email/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-email-requesttoken) or -[/_matrix/client/r0/account/password/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-msisdn-requesttoken). -This request is supplied all the necessary details as well as an `id_server` -field containing the address of a identity server trusted by the homeserver. - -The `id_server` field is currently required as the homeserver must know where -to proxy the request to. This MSC proposes not to change the requirements of -this field. Instead, it asks to clarify that the homeserver is allowed to not -proxy the request, but carry it out itself. This would mean the homeserver can -both send password reset tokens (via email or SMS), as well as accept requests -an endpoint (with the same parameters as +[/_matrix/client/r0/account/password/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-msisdn-requesttoken), +depending on the medium of the 3PID. These requests are supplied all the +necessary details as well as an `id_server` field containing the domain address +of a identity server trusted by the homeserver. + +In order to facilitate these requests, the homeserver will simply proxy them to +the identity server. The IS will send out a token via email or sms, the user +will click a link or enter the token into their client, and either the client +or the user's browser will make a request **directly to the identity server** +with the token for verification. The IS then informs the homeserver that +verification was successful. At this point you can likely see that there is +potential for abuse here, so instead Homeservers should be given the option to +stop proxying the request to the identity server, and instead just send and +validate the token themselves. + +## Proposal + +The homeserver should be allowed to either proxy `/requestToken` requests or +handle them itself. Specifically, this means that the homeserver can both send +password reset tokens (via email or SMS), as well as accept requests on an +arbitrary endpoint (with the same parameters as [/_matrix/identity/api/v1/validate/email/submitToken](https://matrix.org/docs/spec/identity_service/r0.1.0.html#post-matrix-identity-api-v1-validate-email-submittoken)) to verify that token. -Consideration was taken not to make `id_server` and optional field. Let's -assume for a moment that it was optional. Now, a client could send a request to -`/requestToken` omitting the `id_server` field. The homeserver however has -opted to continue proxying `/requestToken` to the identity server, even though -it knows this is potentially insecure. The homeserver now has no idea which -identity server to proxy the request to, and must return a failure to the -client. The client could then make another request with an `id_server`, but -we've now made two requests that ended up in the same outcome, instead of one, -in hopes of saving a very small amount of bandwidth by omitting the field -originally. - -An additional complication is that in the case of SMS, a full link to reset -passwords is not sent, but a short code. The client then asks the user to enter -this code, however the client may now not know where to send the code. Should -it send it to the identity server or the homeserver? Which sent out the code? - -In order to combat this problem, the field `submit_url` should be added in the -response from both the email and msisdn variants of the `/requestToken` -Client-Server API, if and only if the verification message contains a code the -user is expected to enter into the client (for instance in the case of a short -code through SMS). It SHOULD be in the form of -`/_matrix/identity/api/v1/validate/{3pid_type}/submitToken`, similar to the -[same endpoint that exists in the Identity-Server -API](https://matrix.org/docs/spec/identity_service/r0.1.0.html#post-matrix-identity-api-v1-validate-email-submittoken). -If this field is omitted, the client MUST continue the same behaviour from -before, which is to send the token to the identity server directly. This is -intended for backwards compatibility with older servers. +One additional complication that in the case of SMS, just a code is sent to a +person's phone. This is then given to the client, but the client may not know +where to send the code now, as it doesn't know whether the homeserver or +identity server generated it. + +In order to combat this problem, the field `submit_url` MUST be added in the +response from all of the variants of `/requestToken` in the Client-Server API, +if and only if the verification message contains a code the user is expected to +enter into the client (for instance in the case of a short code through SMS). +This URL is simply where the client should submit this token. The endpoint +should accept the same parameters as +[/_matrix/identity/api/v1/validate/{3pid_type}/submitToken](https://matrix.org/docs/spec/identity_service/r0.1.0.html#post-matrix-identity-api-v1-validate-email-submittoken) +in the Identity Service API. The only recommendation to homeserver developers +for this endpoint's path is to not be exactly the same as that of the identity +server, in order to prevent clashes between setups running both an identity +server and homeserver on the same domain. If `submit_url` is omitted, the +client MUST continue the same behaviour from before, which is to send the token +to the identity server directly. This is intended for backwards compatibility +with older servers. If the client receives a response to `/requestToken` with `submit_url`, it MUST -accept the token from user input, then make a POST request to the content of +accept a token from user input, then make a POST request to the content of `submit_url` with the `sid`, `client_secret` and user-entered token. `submit_url` can lead to anywhere the homeserver deems necessary for verification. This data MUST be submitted as a JSON body. @@ -90,7 +96,7 @@ collect a token from the user and then submit it to the provided URL. ``` { "sid": "123abc", - "submit_url": "https://homeserver.tld/_matrix/identity/api/v1/validate/msisdn/submitToken" + "submit_url": "https://homeserver.tld/_homeserver/password_reset/msisdn/submitToken" } ``` @@ -99,7 +105,7 @@ user, say "123456", and then submit that as a POST request to the `"submit_url"`. ``` -POST https://homeserver.tld/_matrix/identity/api/v1/validate/msisdn/submitToken +POST https://homeserver.tld/_homeserver/password_reset/msisdn/submitToken { "sid": "123abc", @@ -120,15 +126,27 @@ If the client did not receive a `submit_url` field, they should instead assume that verification will be completed out of band (e.g. the user clicks a link in their email and makes the submitToken request with their web browser). -## Tradeoffs +## Dismissed Alternatives -If homeservers choose to not proxy the request, they will need to implement the -ability to send emails and/or SMS messages. This is left as a detail for the -homeserver implementation. - -## Future Considerations +Consideration was taken not to make `id_server` an optional field. Let's +assume for a moment that it was optional. Now, a client could send a request to +`/requestToken` omitting the `id_server` field. The homeserver however has +opted to continue proxying `/requestToken` to the identity server, even though +it knows this is potentially insecure. The homeserver now has no idea which +identity server to proxy the request to, and must return a failure to the +client. The client could then make another request with an `id_server`, but +we've now made two requests that ended up in the same outcome, instead of one, +in hopes of saving a very small amount of bandwidth by omitting the field +originally. At some point we should look into removing the `id_server` field altogether and removing any email/SMS message sending from the identity server. This would drastically reduce the amount of trust needed in the identity server and its required ability. This is, however, a good first step. + +## Tradeoffs + +If homeservers choose to not proxy the request, they will need to implement the +ability to send emails and/or SMS messages. This is left as a detail for the +homeserver implementation. + From 45e271c0f7d1a79b37dce2fe9c73d0b8bb742874 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 7 Jun 2019 13:29:22 +0100 Subject: [PATCH 0463/1250] be super explicit --- proposals/2078-homeserver-password-resets.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/2078-homeserver-password-resets.md b/proposals/2078-homeserver-password-resets.md index 5064be20..8dd7d9c9 100644 --- a/proposals/2078-homeserver-password-resets.md +++ b/proposals/2078-homeserver-password-resets.md @@ -75,7 +75,9 @@ If the client receives a response to `/requestToken` with `submit_url`, it MUST accept a token from user input, then make a POST request to the content of `submit_url` with the `sid`, `client_secret` and user-entered token. `submit_url` can lead to anywhere the homeserver deems necessary for -verification. This data MUST be submitted as a JSON body. +verification. To be clear the content of `id_server` does not matter here, the +client should just submit a POST request to the value of `submit_url`. Additionally +data MUST be submitted as a JSON body. An example exchange from the client's perspective is shown below: From 00fee7463623b38516687d1d4ea5463a5e5e3ec8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 7 Jun 2019 07:40:52 -0600 Subject: [PATCH 0464/1250] Update example --- specification/appendices/test_vectors.rst | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/specification/appendices/test_vectors.rst b/specification/appendices/test_vectors.rst index 1de458cc..05b115db 100644 --- a/specification/appendices/test_vectors.rst +++ b/specification/appendices/test_vectors.rst @@ -93,19 +93,14 @@ Given the following minimally-sized event: { "room_id": "!x:domain", "sender": "@a:domain", - "event_id": "$0:domain", "origin": "domain", "origin_server_ts": 1000000, "signatures": {}, "hashes": {}, "type": "X", "content": {}, - "prev_events": [ - ["$1:domain", "ExampleHash"] - ], - "auth_events": [ - ["$2", "ExampleHash2"] - ], + "prev_events": [], + "auth_events": [], "depth": 3, "unsigned": { "age_ts": 1000000 @@ -117,25 +112,20 @@ The event signing algorithm should emit the following signed event: .. code:: json { - "auth_events": [ - ["$2", "6tJjLpXtggfke8UxFhAKg82QVkJzvKOVOOSjUDK4ZSI"] - ], + "auth_events": [], "content": {}, "depth": 3, - "event_id": "$0:domain", "hashes": { - "sha256": "6AaJICN1NJURTtaomDYfJlCPMIU+0gtkwg7qzd8FiJM" + "sha256": "5jM4wQpv6lnBo7CLIghJuHdW+s2CMBJPUOGOC89ncos" }, "origin": "domain", "origin_server_ts": 1000000, - "prev_events": [ - ["$1:domain", "onLKD1bGljeBWQhWZ1kaP9SorVmRQNdN5aM2JYU2n/g"] - ], + "prev_events": [], "room_id": "!x:domain", "sender": "@a:domain", "signatures": { "domain": { - "ed25519:1": "51U0wpKYsaNLTQRbha2v5EGO2cVA6pCtnAKEXguu3j3efCLlmq/53vEfWhsk3tY6gnLsV0YM4Lx2NGZkzmV2Ag" + "ed25519:1": "KxwGjPSDEtvnFgU00fwFz+l6d2pJM6XBIaMEn81SXPTRl16AqLAYqfIReFGZlHi5KLjAWbOoMszkwsQma+lYAg" } }, "type": "X", From d49c7fb3b02db22a4275bfb0f147b0b4a0477b6d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 7 Jun 2019 08:01:17 -0600 Subject: [PATCH 0465/1250] Apply suggestions from code review Co-Authored-By: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- event-schemas/schema/m.key.verification.accept | 2 +- specification/modules/end_to_end_encryption.rst | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/event-schemas/schema/m.key.verification.accept b/event-schemas/schema/m.key.verification.accept index e52df39e..41c59968 100644 --- a/event-schemas/schema/m.key.verification.accept +++ b/event-schemas/schema/m.key.verification.accept @@ -17,7 +17,7 @@ properties: type: string enum: ["m.sas.v1"] description: |- - The verification method to use. Must be ``m.sas.v1``. + The verification method to use. key_agreement_protocol: type: string description: |- diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 4bd12b71..fb3d2ba5 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -536,15 +536,15 @@ The process between Alice and Bob verifying each other would be: .. |AlicePublicKey| replace:: :math:`K_{A}^{public}` .. |AlicePrivateKey| replace:: :math:`K_{A}^{private}` -.. |AliceCurve25519| replace:: :math:`K_{A}^{private}K_{A}^{public}` +.. |AliceCurve25519| replace:: :math:`K_{A}^{private},K_{A}^{public}` .. |BobPublicKey| replace:: :math:`K_{B}^{public}` .. |BobPrivateKey| replace:: :math:`K_{B}^{private}` -.. |BobCurve25519| replace:: :math:`K_{B}^{private}K_{B}^{public}` +.. |BobCurve25519| replace:: :math:`K_{B}^{private},K_{B}^{public}` .. |AliceBobCurve25519| replace:: :math:`K_{A}^{private}K_{B}^{public}` .. |BobAliceCurve25519| replace:: :math:`K_{B}^{private}K_{A}^{public}` .. |AliceBobECDH| replace:: :math:`ECDH(K_{A}^{private},K_{B}^{public})` -1. Alice and Bob establish a secure connection, likely meeting in-person. "Secure" +1. Alice and Bob establish a secure out-of-band connection, such as meeting in-person or a video call. "Secure" here means that either party cannot be impersonated, not explicit secrecy. #. Alice and Bob communicate which devices they'd like to verify with each other. #. Alice selects Bob's device from the device list and begins verification. @@ -573,9 +573,9 @@ The process between Alice and Bob verifying each other would be: methods are available, clients should allow the users to select a method. #. Alice and Bob compare the strings shown by their devices, and tell their devices if they match or not. -#. Assuming they match, Alice and Bob's devices calculate the HMAC of their own device +#. Assuming they match, Alice and Bob's devices calculate the HMAC of their own device keys and a comma-separated sorted list of of the key IDs that they wish the other user - to verify. HMAC is defined in RFC 2104, and SHA-256 as the hash function. The key for + to verify, using SHA-256 as the hash function. HMAC is defined in [RFC 2104](https://tools.ietf.org/html/rfc2104). The key for the HMAC is different for each item and is calculated by generating 32 bytes (256 bits) using `the key verification HKDF <#SAS-HKDF>`_. #. Alice's device sends Bob's device a ``m.key.verification.mac`` message containing the @@ -619,7 +619,7 @@ At any point the interactive verfication can go wrong. The following describes w to do when an error happens: * Alice or Bob can cancel the verification at any time. A ``m.key.verification.cancel`` - message must be sent to signify the cancelation. + message must be sent to signify the cancellation. * The verification can time out. Clients should time out a verification that does not complete within 5 minutes. Additionally, clients should expire a ``transaction_id`` which goes unused for 5 minutes after having last sent/received it. The client should @@ -668,8 +668,8 @@ are used in addition to those already specified: HKDF calculation <<<<<<<<<<<<<<<< -In all of the SAS methods, HKDF is as defined in RFC 5869 and uses the previously -agreed upon hash function for the hash function. The shared secret is supplied +In all of the SAS methods, HKDF is as defined in [RFC 5869](https://tools.ietf.org/html/rfc5869) and uses the previously +agreed-upon hash function for the hash function. The shared secret is supplied as the input keying material. No salt is used, and the input parameter is the concatenation of: From 3877896a4cb232ce760f1556d7a1fc6de001b95f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 7 Jun 2019 08:10:52 -0600 Subject: [PATCH 0466/1250] Clarify how we now expect verification to be done --- .../modules/end_to_end_encryption.rst | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index fb3d2ba5..fb320dc4 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -384,20 +384,10 @@ man-in-the-middle. This verification process requires an out-of-band channel: there is no way to do it within Matrix without trusting the administrators of the homeservers. -In Matrix, the basic process for device verification is for Alice to verify -that the public Ed25519 signing key she received via ``/keys/query`` for Bob's -device corresponds to the private key in use by Bob's device. For now, it is -recommended that clients provide mechanisms by which the user can see: - -1. The public part of their device's Ed25519 signing key, encoded using - `unpadded Base64`_. - -2. The list of devices in use for each user in a room, along with the public - Ed25519 signing key for each device, again encoded using unpadded Base64. - -Alice can then meet Bob in person, or contact him via some other trusted -medium, and use `SAS Verification`_ or ask him to read out the Ed25519 key -shown on his device, comparing it to the one shown on Alice's device. +In Matrix, verification works by Alice meeting Bob in person, or contact him +via some other trusted medium, and use `SAS Verification`_ to interactively +verify Bob's devices. Alice and Bob may also read aloud their unpadded base64 +encoded Ed25519 public key, as returned by ``/keys/query``. Device verification may reach one of several conclusions. For example: From 5ec1a50b94cca9a92951b7f3139c4ff76ed6c2b2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 7 Jun 2019 08:12:09 -0600 Subject: [PATCH 0467/1250] Linefeeds and other clarifications --- .../modules/end_to_end_encryption.rst | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index fb320dc4..0de1328b 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -530,12 +530,12 @@ The process between Alice and Bob verifying each other would be: .. |BobPublicKey| replace:: :math:`K_{B}^{public}` .. |BobPrivateKey| replace:: :math:`K_{B}^{private}` .. |BobCurve25519| replace:: :math:`K_{B}^{private},K_{B}^{public}` -.. |AliceBobCurve25519| replace:: :math:`K_{A}^{private}K_{B}^{public}` .. |BobAliceCurve25519| replace:: :math:`K_{B}^{private}K_{A}^{public}` .. |AliceBobECDH| replace:: :math:`ECDH(K_{A}^{private},K_{B}^{public})` -1. Alice and Bob establish a secure out-of-band connection, such as meeting in-person or a video call. "Secure" - here means that either party cannot be impersonated, not explicit secrecy. +1. Alice and Bob establish a secure out-of-band connection, such as meeting + in-person or a video call. "Secure" here means that either party cannot be + impersonated, not explicit secrecy. #. Alice and Bob communicate which devices they'd like to verify with each other. #. Alice selects Bob's device from the device list and begins verification. #. Alice's client ensures it has a copy of Bob's device key. @@ -565,9 +565,9 @@ The process between Alice and Bob verifying each other would be: they match or not. #. Assuming they match, Alice and Bob's devices calculate the HMAC of their own device keys and a comma-separated sorted list of of the key IDs that they wish the other user - to verify, using SHA-256 as the hash function. HMAC is defined in [RFC 2104](https://tools.ietf.org/html/rfc2104). The key for - the HMAC is different for each item and is calculated by generating 32 bytes (256 bits) - using `the key verification HKDF <#SAS-HKDF>`_. + to verify, using SHA-256 as the hash function. HMAC is defined in [RFC 2104](https://tools.ietf.org/html/rfc2104). + The key for the HMAC is different for each item and is calculated by generating + 32 bytes (256 bits) using `the key verification HKDF <#SAS-HKDF>`_. #. Alice's device sends Bob's device a ``m.key.verification.mac`` message containing the MAC of Alice's device keys and the MAC of her key IDs to be verified. Bob's device does the same for Bob's device keys and key IDs concurrently with Alice. @@ -611,12 +611,12 @@ to do when an error happens: * Alice or Bob can cancel the verification at any time. A ``m.key.verification.cancel`` message must be sent to signify the cancellation. * The verification can time out. Clients should time out a verification that does not - complete within 5 minutes. Additionally, clients should expire a ``transaction_id`` - which goes unused for 5 minutes after having last sent/received it. The client should - inform the user that the verification timed out, and send an appropriate ``m.key.verification.cancel`` - message to the other device. -* When the same device attempts to intiate multiple verification attempts, cancel all - attempts with that device. + complete within 10 minutes. Additionally, clients should expire a ``transaction_id`` + which goes unused for 10 minutes after having last sent/received it. The client should + inform the user that the verification timed out, and send an appropriate + ``m.key.verification.cancel`` message to the other device. +* When the same device attempts to intiate multiple verification attempts, the receipient + should cancel all attempts with that device. * When a device receives an unknown ``transaction_id``, it should send an appropriate ``m.key.verfication.cancel`` message to the other device indicating as such. This does not apply for inbound ``m.key.verification.start`` or ``m.key.verification.cancel`` @@ -658,10 +658,10 @@ are used in addition to those already specified: HKDF calculation <<<<<<<<<<<<<<<< -In all of the SAS methods, HKDF is as defined in [RFC 5869](https://tools.ietf.org/html/rfc5869) and uses the previously -agreed-upon hash function for the hash function. The shared secret is supplied -as the input keying material. No salt is used, and the input parameter is the -concatenation of: +In all of the SAS methods, HKDF is as defined in [RFC 5869](https://tools.ietf.org/html/rfc5869) +and uses the previously agreed-upon hash function for the hash function. The shared +secret is supplied as the input keying material. No salt is used, and the input +parameter is the concatenation of: * The string ``MATRIX_KEY_VERIFICATION_SAS``. * The Matrix ID of the user who sent the ``m.key.verification.start`` message. @@ -670,8 +670,9 @@ concatenation of: * The Device ID of the device which sent the ``m.key.verification.accept`` message. * The ``transaction_id`` being used. -HKDF is used over the plain shared secret as it results in a harder attack -as well as more uniform data to work with. +.. admonition:: Rationale + HKDF is used over the plain shared secret as it results in a harder attack + as well as more uniform data to work with. For verification of each party's device keys, HKDF is as defined in RFC 5869 and uses SHA-256 as the hash function. The shared secret is supplied as the input keying @@ -697,7 +698,7 @@ The bitwise operations to get the numbers given the 5 bytes :math:`B_{0}, B_{1}, B_{2}, B_{3}, B_{4}` would be: * First: :math:`(B_{0} \ll 5 | B_{1} \gg 3) + 1000` -* Second: :math:`(B_{1} \& 0x7 | B_{2} \ll 2 | B_{3} \gg 6) + 1000` +* Second: :math:`((B_{1} \& 0x7) \ll 10 | B_{2} \ll 2 | B_{3} \gg 6) + 1000` * Third: :math:`((B_{3} \& 0x3F) \ll 7 | B_{4} \gg 1) + 1000` The digits are displayed to the user either with an appropriate separator, From 77c4c4b07cb1cfe30d7a3477944eb2229e62ab2f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 7 Jun 2019 08:27:18 -0600 Subject: [PATCH 0468/1250] Add general clarity --- api/client-server/definitions/room_event_filter.yaml | 2 +- api/client-server/sync.yaml | 9 +++++---- specification/client_server_api.rst | 3 +++ specification/modules/instant_messaging.rst | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/api/client-server/definitions/room_event_filter.yaml b/api/client-server/definitions/room_event_filter.yaml index 0659be8e..7045396d 100644 --- a/api/client-server/definitions/room_event_filter.yaml +++ b/api/client-server/definitions/room_event_filter.yaml @@ -25,7 +25,7 @@ allOf: include_redundant_members: type: boolean description: |- - If ``true``, enables redudant membership events. Does not + If ``true``, enables redundant membership events. Does not apply unless ``lazy_load_members`` is ``true``. See `Lazy-loading room members <#lazy-loading-room-members>`_ for more information. Defaults to ``false``. diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index a0d2fd60..ed9d7420 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -40,10 +40,11 @@ paths: for this endpoint. When lazy-loading is enabled, servers MUST include the syncing user's own membership event when they join a room, or when the full state of rooms is requested. The user's own membership event is eligible - for being considered redudant by the server. When a sync is ``limited``, - the server MUST return membership events for the timeline, even if the - applicable events are not in the response, regardless as to whether or not - they are redundant. + for being considered redundant by the server. When a sync is ``limited``, + the server MUST return membership events for events in the gap (from ``since``), + even if the applicable events are not in the response, regardless as to whether + or not they are redundant. ``include_redundant_members`` is ignored for limited + syncs. operationId: sync security: - accessToken: [] diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 740023fb..5290ec20 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1306,6 +1306,9 @@ The current endpoints which support lazy-loading room members are: * |/rooms//messages|_ * |/rooms/{roomId}/context/{eventId}|_ +API endpoints +~~~~~~~~~~~~~ + {{filter_cs_http_api}} Events diff --git a/specification/modules/instant_messaging.rst b/specification/modules/instant_messaging.rst index dd3e9c6c..c514f481 100644 --- a/specification/modules/instant_messaging.rst +++ b/specification/modules/instant_messaging.rst @@ -293,7 +293,7 @@ choose a name: users (`disambiguating them if required`_) and concatenating them. For example, the client may choose to show "Alice, Bob, and Charlie (@charlie:example.org)" as the room name. The client may optionally - limit the number + limit the number of users it uses to generate a room name. #. If there are fewer heroes than ``m.joined_member_count + m.invited_member_count - 1``, and ``m.joined_member_count + m.invited_member_count`` is greater From a0e82018161f82a723e2d57eb3e14eec42d66610 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 7 Jun 2019 08:27:53 -0600 Subject: [PATCH 0469/1250] Apply suggestions from code review Co-Authored-By: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- api/client-server/event_context.yaml | 2 +- api/client-server/message_pagination.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/client-server/event_context.yaml b/api/client-server/event_context.yaml index 327c8f43..0e7fa531 100644 --- a/api/client-server/event_context.yaml +++ b/api/client-server/event_context.yaml @@ -35,7 +35,7 @@ paths: after the specified event. This allows clients to get the context surrounding an event. - *Note*: This endpoint supports lazy-loading. See `Filtering <#filtering>`_ + *Note*: This endpoint supports lazy-loading of room member events. See `Filtering <#lazy-loading-room-members>`_ for more information. operationId: getEventContext security: diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index 8469eec4..c5d7b8fc 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -34,7 +34,7 @@ paths: This API returns a list of message and state events for a room. It uses pagination query parameters to paginate history in the room. - *Note*: This endpoint supports lazy-loading. See `Filtering <#filtering>`_ + *Note*: This endpoint supports lazy-loading of room member events. See `Filtering <#lazy-loading-room-members>`_ for more information. operationId: getRoomEvents security: From 360ac0b90088a0b9fcb6876fb9bac847fb3f0038 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 7 Jun 2019 08:54:21 -0600 Subject: [PATCH 0470/1250] Update specification/server_server_api.rst Co-Authored-By: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- specification/server_server_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 812f0ffc..7acc71e4 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -1100,7 +1100,7 @@ a redacted copy. The signatures expected on an event are: -* The sender's server, unless the invite was created as a result of 3rd party invite. +* The ``sender``'s server, unless the invite was created as a result of 3rd party invite. The sender must already match the 3rd party invite, and the server which actually sends the event may be a different server. * For room versions 1 and 2, the server which created the ``event_id``. Other room From 31481840525620c8ac657d31956cfa9428f8f2b0 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 7 Jun 2019 10:58:43 +0100 Subject: [PATCH 0471/1250] HS' can send 3PID token. Add a new submit_url field --- api/client-server/administrative_contact.yaml | 116 +++++++++++-- api/client-server/registration.yaml | 162 ++++++++++++++---- 2 files changed, 228 insertions(+), 50 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 33ea9786..d62a4fab 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -132,11 +132,30 @@ paths: } responses: 200: - description: The addition was successful. + description: |- + The addition was successful. + + ``submit_url`` is an optional field containing a URL where the + client must submit a validation token to, with identical parameters + to the Identity Service API's ``/validate/email/submitToken`` + endpoint. The homeserver will send this token to the user, which + should then be prompted to provide it to the client. + + If this field is not present, the client can assume that + verification will happen without the client's involvement. examples: - application/json: {} + application/json: { + "submit_url": "https://example.org/path/to/submitToken" + } schema: type: object + properties: + submit_url: + type: string + description: |- + An optional URL to submit information to to verify a + third-party identifier. + example: "https://example.org/path/to/submitToken" 403: description: The credentials could not be verified with the identity server. examples: @@ -187,12 +206,14 @@ paths: post: summary: Begins the validation process for an email address for association with the user's account. description: |- - Proxies the Identity Service API ``validate/email/requestToken``, but - first checks that the given email address is **not** already associated - with an account on this homeserver. This API should be used to request - validation tokens when adding an email address to an account. This API's - parameters and response are identical to that of the |/register/email/requestToken|_ - endpoint. + The homeserver should check that the given email address is **not** + already associated with an account on this homeserver. This API should + be used to request validation tokens when adding an email address to an + account. This API's parameters and response are identical to that of + the |/register/email/requestToken|_ endpoint. The homeserver has the + choice of validating the email address itself, or proxying the request + to the ``validate/email/requestToken`` Identity Server API on the + server sent in ``id_server``. operationId: requestTokenTo3PIDEmail parameters: - in: body @@ -212,9 +233,38 @@ paths: required: ['id_server'] responses: 200: - description: An email was sent to the given address. + description: |- + An email was sent to the given address. + Note that this may be an email containing the validation token or + it may be informing the user of an error. + + ``submit_url`` is an optional field containing a URL where the + client must submit a validation token to, with identical parameters + to the Identity Service API's ``/validate/email/submitToken`` + endpoint. The homeserver will send this token to the user, which + should then be prompted to provide it to the client. + + If this field is not present, the client can assume that + verification will happen without the client's involvement. schema: - $ref: "../identity/definitions/sid.yaml" + allOf: + - $ref: "../identity/definitions/sid.yaml" + - type: object + properties: + submit_url: + type: string + description: |- + An optional field containing a URL where the client + must submit a validation token to, with identical + parameters to the Identity Service API's + ``/validate/email/submitToken`` endpoint. The homeserver + will send this token to the user, which should then be + prompted to provide it to the client. + + If this field is not present, the client can assume that + verification will happen without the client's + involvement. + example: "https://example.org/path/to/submitToken" 403: description: |- The homeserver does not allow the third party identifier as a @@ -241,12 +291,14 @@ paths: post: summary: Begins the validation process for a phone number for association with the user's account. description: |- - Proxies the Identity Service API ``validate/msisdn/requestToken``, but - first checks that the given phone number is **not** already associated - with an account on this homeserver. This API should be used to request - validation tokens when adding a phone number to an account. This API's - parameters and response are identical to that of the |/register/msisdn/requestToken|_ - endpoint. + The homeserver should check that the given phone number is **not** + already associated with an account on this homeserver. This API should + be used to request validation tokens when adding a phone number to an + account. This API's parameters and response are identical to that of + the |/register/msisdn/requestToken|_ endpoint. The homeserver has the + choice of validating the phone number itself, or proxying the request + to the ``validate/msisdn/requestToken`` Identity Server API on the + server sent in ``id_server``. operationId: requestTokenTo3PIDMSISDN parameters: - in: body @@ -266,9 +318,37 @@ paths: required: ['id_server'] responses: 200: - description: An SMS message was sent to the given phone number. + description: |- + An SMS message was sent to the given phone number. + + ``submit_url`` is an optional field containing a URL where the + client must submit a validation token to, with identical parameters + to the Identity Service API's ``/validate/msisdn/submitToken`` + endpoint. The homeserver will send this token to the user, which + should then be prompted to provide it to the client. + + If this field is not present, the client can assume that + verification will happen without the client's involvement. schema: - $ref: "../identity/definitions/sid.yaml" + allOf: + - $ref: "../identity/definitions/sid.yaml" + - type: object + properties: + submit_url: + type: string + description: |- + An optional field containing a URL where the client + must submit a validation token to, with identical + parameters to the Identity Service API's + ``/validate/email/submitToken`` endpoint. The homeserver + will send this token to the user, which should then be + prompted to provide it to the client. + + If this field is not present, the client can assume that + verification will happen without the client's + involvement. + example: "https://example.org/path/to/submitToken" + 403: description: |- The homeserver does not allow the third party identifier as a diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 3195ab41..00d2e90f 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -204,10 +204,11 @@ paths: post: summary: Begins the validation process for an email to be used during registration. description: |- - Proxies the Identity Service API ``validate/email/requestToken``, but - first checks that the given email address is not already associated - with an account on this homeserver. See the Identity Service API for - further information. + The homeserver should check that the given email address is **not** + already associated with an account on this homeserver. The homeserver + has the choice of validating the email address itself, or proxying the + request to the ``validate/email/requestToken`` Identity Server API on + the server sent in ``id_server``. operationId: requestTokenToRegisterEmail parameters: - in: body @@ -231,8 +232,34 @@ paths: An email has been sent to the specified address. Note that this may be an email containing the validation token or it may be informing the user of an error. + + ``submit_url`` is an optional field containing a URL where the + client must submit a validation token to, with identical parameters + to the Identity Service API's ``/validate/email/submitToken`` + endpoint. The homeserver will send this token to the user, which + should then be prompted to provide it to the client. + + If this field is not present, the client can assume that + verification will happen without the client's involvement. schema: - $ref: "../identity/definitions/sid.yaml" + allOf: + - $ref: "../identity/definitions/sid.yaml" + - type: object + properties: + submit_url: + type: string + description: |- + An optional field containing a URL where the client + must submit a validation token to, with identical + parameters to the Identity Service API's + ``/validate/email/submitToken`` endpoint. The homeserver + will send this token to the user, which should then be + prompted to provide it to the client. + + If this field is not present, the client can assume that + verification will happen without the client's + involvement. + example: "https://example.org/path/to/submitToken" 403: description: The homeserver does not permit the address to be bound. schema: @@ -264,10 +291,11 @@ paths: post: summary: Requests a validation token be sent to the given phone number for the purpose of registering an account description: |- - Proxies the Identity Service API ``validate/msisdn/requestToken``, but - first checks that the given phone number is not already associated - with an account on this homeserver. See the Identity Service API for - further information. + The homeserver should check that the given phone number is **not** + already associated with an account on this homeserver. The homeserver + has the choice of validating the phone number itself, or proxying the + request to the ``validate/msisdn/requestToken`` Identity Server API on + the server sent in ``id_server``. operationId: requestTokenToRegisterMSISDN parameters: - in: body @@ -291,8 +319,34 @@ paths: An SMS message has been sent to the specified phone number. Note that this may be an SMS message containing the validation token or it may be informing the user of an error. + + ``submit_url`` is an optional field containing a URL where the + client must submit a validation token to, with identical parameters + to the Identity Service API's ``/validate/msisdn/submitToken`` + endpoint. The homeserver will send this token to the user, which + should then be prompted to provide it to the client. + + If this field is not present, the client can assume that + verification will happen without the client's involvement. schema: - $ref: "../identity/definitions/sid.yaml" + allOf: + - $ref: "../identity/definitions/sid.yaml" + - type: object + properties: + submit_url: + type: string + description: |- + An optional field containing a URL where the client + must submit a validation token to, with identical + parameters to the Identity Service API's + ``/validate/email/submitToken`` endpoint. The homeserver + will send this token to the user, which should then be + prompted to provide it to the client. + + If this field is not present, the client can assume that + verification will happen without the client's + involvement. + example: "https://example.org/path/to/submitToken" 403: description: The homeserver does not permit the address to be bound. schema: @@ -377,16 +431,21 @@ paths: post: summary: Requests a validation token be sent to the given email address for the purpose of resetting a user's password description: |- - Proxies the Identity Service API ``validate/email/requestToken``, but - first checks that the given email address **is** associated with an account - on this homeserver. This API should be used to request - validation tokens when authenticating for the - `account/password` endpoint. This API's parameters and response are - identical to that of the HS API |/register/email/requestToken|_ except that - `M_THREEPID_NOT_FOUND` may be returned if no account matching the - given email address could be found. The server may instead send an - email to the given address prompting the user to create an account. - `M_THREEPID_IN_USE` may not be returned. + The homeserver should check that the given email address **is + associated** with an account on this homeserver. This API should be + used to request validation tokens when authenticating for the + ``account/password`` endpoint. + + This API's parameters and response are identical to that of the HS API + |/register/email/requestToken|_ except that ``M_THREEPID_NOT_FOUND`` + may be returned if no account matching the given email address could be + found. The server may instead send an email to the given address + prompting the user to create an account. ``M_THREEPID_IN_USE`` may not + be returned. + + The homeserver has the choice of validating the email address itself, + or proxying the request to the ``validate/email/requestToken`` Identity + server api on the server sent in ``id_server``. .. |/register/email/requestToken| replace:: ``/register/email/requestToken`` @@ -412,7 +471,24 @@ paths: 200: description: An email was sent to the given address. schema: - $ref: "../identity/definitions/sid.yaml" + allOf: + - $ref: "../identity/definitions/sid.yaml" + - type: object + properties: + submit_url: + type: string + description: |- + An optional field containing a URL where the client must + submit a validation token to, with identical parameters + to the Identity Service API's + ``/validate/email/submitToken`` endpoint. The homeserver + will send this token to the user, which should then be + prompted to provide it to the client. + + If this field is not present, the client can assume that + verification will happen without the client's + involvement. + example: "https://example.org/path/to/submitToken" 403: description: |- The homeserver does not allow the third party identifier as a @@ -439,16 +515,21 @@ paths: post: summary: Requests a validation token be sent to the given phone number for the purpose of resetting a user's password. description: |- - Proxies the Identity Service API ``validate/msisdn/requestToken``, but - first checks that the given phone number **is** associated with an account - on this homeserver. This API should be used to request - validation tokens when authenticating for the - `account/password` endpoint. This API's parameters and response are - identical to that of the HS API |/register/msisdn/requestToken|_ except that - `M_THREEPID_NOT_FOUND` may be returned if no account matching the - given phone number could be found. The server may instead send an - SMS message to the given address prompting the user to create an account. - `M_THREEPID_IN_USE` may not be returned. + The homeserver should check that the given phone number **is + associated** with an account on this homeserver. This API should be + used to request validation tokens when authenticating for the + ``account/password`` endpoint. + + This API's parameters and response are identical to that of the HS API + |/register/msisdn/requestToken|_ except that ``M_THREEPID_NOT_FOUND`` may + be returned if no account matching the given phone number could be + found. The server may instead send the SMS to the given phone number + prompting the user to create an account. ``M_THREEPID_IN_USE`` may not + be returned. + + The homeserver has the choice of validating the phone number itself, or + proxying the request to the ``validate/msisdn/requestToken`` Identity + server api on the server sent in ``id_server``. .. |/register/msisdn/requestToken| replace:: ``/register/msisdn/requestToken`` @@ -474,7 +555,24 @@ paths: 200: description: An SMS message was sent to the given phone number. schema: - $ref: "../identity/definitions/sid.yaml" + allOf: + - $ref: "../identity/definitions/sid.yaml" + - type: object + properties: + submit_url: + type: string + description: |- + An optional field containing a URL where the client must + submit a validation token to, with identical parameters + to the Identity Service API's + ``/validate/msisdn/submitToken`` endpoint. The homeserver + will send this token to the user, which should then be + prompted to provide it to the client. + + If this field is not present, the client can assume that + verification will happen without the client's + involvement. + example: "https://example.org/path/to/submitToken" 403: description: |- The homeserver does not allow the third party identifier as a From e4339fd68755344527cce85895ac131ee8618e6e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 7 Jun 2019 09:01:14 -0600 Subject: [PATCH 0472/1250] More clarity --- specification/client_server_api.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 5290ec20..c62740d4 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1276,12 +1276,12 @@ effort to reduce the number of resources used, clients can enable "lazy-loading" for room members. By doing this, servers will only ever send membership events which are relevant to the client. -In terms of filters, this means enabling ``lazy_load_members`` on a ``StateFilter`` -or ``RoomEventFilter``. When enabled, lazy-loading aware endpoints (see below) -will only include membership events for the ``sender`` of events being included -in the response. For example, if a client makes a ``/sync`` request with lazy-loading -enabled, the server will only return membership events for the ``sender`` of events -in the timeline, not all members of a room. +In terms of filters, this means enabling ``lazy_load_members`` on a ``RoomEventFilter`` +(or a ``StateFilter`` in the case of ``/sync`` only). When enabled, lazy-loading +aware endpoints (see below) will only include membership events for the ``sender`` +of events being included in the response. For example, if a client makes a ``/sync`` +request with lazy-loading enabled, the server will only return membership events +for the ``sender`` of events in the timeline, not all members of a room. Repeated calls to lazy-loading aware endpoints will result in redundant membership events being excluded by default. Clients often track which membership events they From 46747e897ecc0b7c4c06e6488a02b5c208c87d3d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 7 Jun 2019 10:32:06 -0600 Subject: [PATCH 0473/1250] ing --- specification/modules/end_to_end_encryption.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 0de1328b..62881967 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -384,7 +384,7 @@ man-in-the-middle. This verification process requires an out-of-band channel: there is no way to do it within Matrix without trusting the administrators of the homeservers. -In Matrix, verification works by Alice meeting Bob in person, or contact him +In Matrix, verification works by Alice meeting Bob in person, or contacting him via some other trusted medium, and use `SAS Verification`_ to interactively verify Bob's devices. Alice and Bob may also read aloud their unpadded base64 encoded Ed25519 public key, as returned by ``/keys/query``. From a38af2009f72fc91f3aa4a90a323a050ba8dde06 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 7 Jun 2019 10:37:57 -0600 Subject: [PATCH 0474/1250] Apply suggestions from code review Co-Authored-By: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- api/client-server/message_pagination.yaml | 6 +++--- api/client-server/sync.yaml | 4 ++-- specification/client_server_api.rst | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index c5d7b8fc..3e01437a 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -115,14 +115,14 @@ paths: type: array description: |- A list of state events relevant to showing the ``chunk``. For example, if - lazy-loading members is enabled in the filter then this will contain any - applicable membership events. Servers should be careful to not exclude + ``lazy_load_members`` is enabled in the filter then this will contain any + the membership events for the the senders of events in the ``chunk``. Servers should be careful to not exclude membership events which are older than ones already sent to the client. Likewise, clients should be cautious and avoid using older membership events as the current membership event when paginating backwards. Unless ``include_redundant_members`` is ``true``, the server should remove - redundant members which would have already been sent to clients in prior calls + membership events which would have already been sent to clients in prior calls to lazy-loading aware endpoints with the same filter. items: type: object diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index ed9d7420..45829f68 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -41,8 +41,8 @@ paths: syncing user's own membership event when they join a room, or when the full state of rooms is requested. The user's own membership event is eligible for being considered redundant by the server. When a sync is ``limited``, - the server MUST return membership events for events in the gap (from ``since``), - even if the applicable events are not in the response, regardless as to whether + the server MUST return membership events for events in the gap (between ``since`` and the start of the returned timeline), + regardless as to whether or not they are redundant. ``include_redundant_members`` is ignored for limited syncs. operationId: sync diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index c62740d4..42f34849 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1286,7 +1286,7 @@ for the ``sender`` of events in the timeline, not all members of a room. Repeated calls to lazy-loading aware endpoints will result in redundant membership events being excluded by default. Clients often track which membership events they already have, therefore making the extra information not as useful to the client. -Clients can always request redundant members by setting ``include_redundant_members`` +Clients can always request redundant membership events by setting ``include_redundant_members`` to true in the filter. Servers should be cautious about which events they consider redundant. Membership @@ -1296,9 +1296,9 @@ as the current membership event for a user. .. Note:: Repeated calls using the same filter to *any* lazy-loading aware endpoint may - result in redundant members being excluded from future calls. For example, a + result in redundant membership events being excluded from future calls. For example, a request to ``/sync`` followed by a request to ``/messages`` may result in a - future call to ``/sync`` excluding members included by the ``/messages`` call. + future call to ``/sync`` excluding membership events returned by the ``/messages`` call. The current endpoints which support lazy-loading room members are: From 8a6ef187db803e8150670b6b3b16a496eccfd9db Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 7 Jun 2019 17:52:17 +0100 Subject: [PATCH 0475/1250] more object! --- api/client-server/administrative_contact.yaml | 2 ++ api/client-server/registration.yaml | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 71ea3e6a..c2985f66 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -272,6 +272,7 @@ paths: If this field is not present, the client can assume that verification will happen without the client's involvement. schema: + type: object allOf: - $ref: "../identity/definitions/sid.yaml" - type: object @@ -355,6 +356,7 @@ paths: If this field is not present, the client can assume that verification will happen without the client's involvement. schema: + type: object allOf: - $ref: "../identity/definitions/sid.yaml" - type: object diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index c8afed83..769614c1 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -248,6 +248,7 @@ paths: If this field is not present, the client can assume that verification will happen without the client's involvement. schema: + type: object allOf: - $ref: "../identity/definitions/sid.yaml" - type: object @@ -335,6 +336,7 @@ paths: If this field is not present, the client can assume that verification will happen without the client's involvement. schema: + type: object allOf: - $ref: "../identity/definitions/sid.yaml" - type: object @@ -477,6 +479,7 @@ paths: 200: description: An email was sent to the given address. schema: + type: object allOf: - $ref: "../identity/definitions/sid.yaml" - type: object @@ -561,6 +564,7 @@ paths: 200: description: An SMS message was sent to the given phone number. schema: + type: object allOf: - $ref: "../identity/definitions/sid.yaml" - type: object From a8edb066aa52bdadff63c2fa9d9b5ad50a8f5b99 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 7 Jun 2019 18:00:12 +0100 Subject: [PATCH 0476/1250] Clear up some wording --- api/client-server/registration.yaml | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 769614c1..d97766e2 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -213,8 +213,10 @@ paths: The homeserver should check that the given email address is **not** already associated with an account on this homeserver. The homeserver has the choice of validating the email address itself, or proxying the - request to the ``validate/email/requestToken`` Identity Server API on - the server sent in ``id_server``. + request to the ``validate/email/requestToken`` Identity Server API. The + request should be proxied to the domain that is sent by the client in + the ``id_server``. It is imperative that the homeserver keep a list of + trusted Identity Servers and only proxies to those it trusts. operationId: requestTokenToRegisterEmail parameters: - in: body @@ -301,8 +303,10 @@ paths: The homeserver should check that the given phone number is **not** already associated with an account on this homeserver. The homeserver has the choice of validating the phone number itself, or proxying the - request to the ``validate/msisdn/requestToken`` Identity Server API on - the server sent in ``id_server``. + request to the ``validate/msisdn/requestToken`` Identity Server API. The + request should be proxied to the domain that is sent by the client in + the ``id_server``. It is imperative that the homeserver keep a list of + trusted Identity Servers and only proxies to those it trusts. operationId: requestTokenToRegisterMSISDN parameters: - in: body @@ -453,7 +457,11 @@ paths: The homeserver has the choice of validating the email address itself, or proxying the request to the ``validate/email/requestToken`` Identity - server api on the server sent in ``id_server``. + Server API. The request should be proxied to the domain that is sent by + the client in the ``id_server``. It is imperative that the homeserver + keep a list of trusted Identity Servers and only proxies to those it + trusts. + .. |/register/email/requestToken| replace:: ``/register/email/requestToken`` @@ -536,9 +544,12 @@ paths: prompting the user to create an account. ``M_THREEPID_IN_USE`` may not be returned. - The homeserver has the choice of validating the phone number itself, or - proxying the request to the ``validate/msisdn/requestToken`` Identity - server api on the server sent in ``id_server``. + The homeserver has the choice of validating the phone number itself, + or proxying the request to the ``validate/msisdn/requestToken`` Identity + Server API. The request should be proxied to the domain that is sent by + the client in the ``id_server``. It is imperative that the homeserver + keep a list of trusted Identity Servers and only proxies to those it + trusts. .. |/register/msisdn/requestToken| replace:: ``/register/msisdn/requestToken`` From be568ba9ab8c8f4342220331eb66fe70ae09e5c7 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 7 Jun 2019 19:10:26 +0100 Subject: [PATCH 0477/1250] link to the legalified version of MSC1779 --- proposals/1779-open-governance.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index 0a1cfca4..bfe86eb8 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -12,6 +12,9 @@ for more context. This obsoletes [MSC1318](https://github.com/matrix-org/matrix-doc/issues/1318). +**This MSC is now formalised in the official Rules of the Matrix.org Foundation, +maintained at https://docs.google.com/document/d/1MhqsuIUxPc7Vf_y8D250mKZlLeQS6E39DPY6Azpc2NY** + ## Introduction Historically the core team of Matrix has been paid to work on it by the same From 1776ba28d3d98d3a63c7b7becc032621aab9632b Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Sat, 8 Jun 2019 18:52:38 +0100 Subject: [PATCH 0478/1250] Address review comments --- api/client-server/administrative_contact.yaml | 70 +++++--------- api/client-server/registration.yaml | 94 ++++++++----------- 2 files changed, 63 insertions(+), 101 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index c2985f66..bc6f98c7 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -134,15 +134,6 @@ paths: 200: description: |- The addition was successful. - - ``submit_url`` is an optional field containing a URL where the - client must submit a validation token to, with identical parameters - to the Identity Service API's ``/validate/email/submitToken`` - endpoint. The homeserver will send this token to the user, which - should then be prompted to provide it to the client. - - If this field is not present, the client can assume that - verification will happen without the client's involvement. examples: application/json: { "submit_url": "https://example.org/path/to/submitToken" @@ -153,8 +144,15 @@ paths: submit_url: type: string description: |- - An optional URL to submit information to to verify a - third-party identifier. + An optional field containing a URL where the client must + submit the validation token to, with identical parameters + to the Identity Service API's + ``/validate/email/submitToken`` endpoint. The homeserver + must send this token to the user (if applicable), which + should then be prompted to provide it to the client. + + If this field is not present, the client can assume that + verification will happen without the client's involvement. example: "https://example.org/path/to/submitToken" 403: description: The credentials could not be verified with the identity server. @@ -231,14 +229,14 @@ paths: post: summary: Begins the validation process for an email address for association with the user's account. description: |- - The homeserver should check that the given email address is **not** + The homeserver must check that the given email address is **not** already associated with an account on this homeserver. This API should be used to request validation tokens when adding an email address to an account. This API's parameters and response are identical to that of the |/register/email/requestToken|_ endpoint. The homeserver has the choice of validating the email address itself, or proxying the request - to the ``validate/email/requestToken`` Identity Server API on the - server sent in ``id_server``. + to the ``validate/email/requestToken`` Identity Service API as + identified by ``id_server``. operationId: requestTokenTo3PIDEmail parameters: - in: body @@ -262,15 +260,6 @@ paths: An email was sent to the given address. Note that this may be an email containing the validation token or it may be informing the user of an error. - - ``submit_url`` is an optional field containing a URL where the - client must submit a validation token to, with identical parameters - to the Identity Service API's ``/validate/email/submitToken`` - endpoint. The homeserver will send this token to the user, which - should then be prompted to provide it to the client. - - If this field is not present, the client can assume that - verification will happen without the client's involvement. schema: type: object allOf: @@ -280,11 +269,11 @@ paths: submit_url: type: string description: |- - An optional field containing a URL where the client - must submit a validation token to, with identical - parameters to the Identity Service API's + An optional field containing a URL where the client must + submit the validation token to, with identical parameters + to the Identity Service API's ``/validate/email/submitToken`` endpoint. The homeserver - will send this token to the user, which should then be + must send this token to the user, which should then be prompted to provide it to the client. If this field is not present, the client can assume that @@ -317,14 +306,14 @@ paths: post: summary: Begins the validation process for a phone number for association with the user's account. description: |- - The homeserver should check that the given phone number is **not** + The homeserver must check that the given phone number is **not** already associated with an account on this homeserver. This API should be used to request validation tokens when adding a phone number to an account. This API's parameters and response are identical to that of the |/register/msisdn/requestToken|_ endpoint. The homeserver has the choice of validating the phone number itself, or proxying the request - to the ``validate/msisdn/requestToken`` Identity Server API on the - server sent in ``id_server``. + to the ``validate/msisdn/requestToken`` Identity Service API as + identified by ``id_server``. operationId: requestTokenTo3PIDMSISDN parameters: - in: body @@ -345,16 +334,7 @@ paths: responses: 200: description: |- - An SMS message was sent to the given phone number. - - ``submit_url`` is an optional field containing a URL where the - client must submit a validation token to, with identical parameters - to the Identity Service API's ``/validate/msisdn/submitToken`` - endpoint. The homeserver will send this token to the user, which - should then be prompted to provide it to the client. - - If this field is not present, the client can assume that - verification will happen without the client's involvement. + A SMS message was sent to the given phone number. schema: type: object allOf: @@ -364,12 +344,12 @@ paths: submit_url: type: string description: |- - An optional field containing a URL where the client - must submit a validation token to, with identical - parameters to the Identity Service API's + An optional field containing a URL where the client must + submit the validation token to, with identical parameters + to the Identity Service API's ``/validate/email/submitToken`` endpoint. The homeserver - will send this token to the user, which should then be - prompted to provide it to the client. + must send this token to the user (if applicable), which + should then be prompted to provide it to the client. If this field is not present, the client can assume that verification will happen without the client's diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index d97766e2..c8615d29 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -210,10 +210,10 @@ paths: post: summary: Begins the validation process for an email to be used during registration. description: |- - The homeserver should check that the given email address is **not** + The homeserver must check that the given email address is **not** already associated with an account on this homeserver. The homeserver has the choice of validating the email address itself, or proxying the - request to the ``validate/email/requestToken`` Identity Server API. The + request to the ``validate/email/requestToken`` Identity Service API. The request should be proxied to the domain that is sent by the client in the ``id_server``. It is imperative that the homeserver keep a list of trusted Identity Servers and only proxies to those it trusts. @@ -240,15 +240,6 @@ paths: An email has been sent to the specified address. Note that this may be an email containing the validation token or it may be informing the user of an error. - - ``submit_url`` is an optional field containing a URL where the - client must submit a validation token to, with identical parameters - to the Identity Service API's ``/validate/email/submitToken`` - endpoint. The homeserver will send this token to the user, which - should then be prompted to provide it to the client. - - If this field is not present, the client can assume that - verification will happen without the client's involvement. schema: type: object allOf: @@ -258,12 +249,12 @@ paths: submit_url: type: string description: |- - An optional field containing a URL where the client - must submit a validation token to, with identical - parameters to the Identity Service API's + An optional field containing a URL where the client must + submit the validation token to, with identical parameters + to the Identity Service API's ``/validate/email/submitToken`` endpoint. The homeserver - will send this token to the user, which should then be - prompted to provide it to the client. + must send this token to the user (if applicable), which + should then be prompted to provide it to the client. If this field is not present, the client can assume that verification will happen without the client's @@ -300,10 +291,10 @@ paths: post: summary: Requests a validation token be sent to the given phone number for the purpose of registering an account description: |- - The homeserver should check that the given phone number is **not** + The homeserver must check that the given phone number is **not** already associated with an account on this homeserver. The homeserver has the choice of validating the phone number itself, or proxying the - request to the ``validate/msisdn/requestToken`` Identity Server API. The + request to the ``validate/msisdn/requestToken`` Identity Service API. The request should be proxied to the domain that is sent by the client in the ``id_server``. It is imperative that the homeserver keep a list of trusted Identity Servers and only proxies to those it trusts. @@ -327,18 +318,9 @@ paths: responses: 200: description: |- - An SMS message has been sent to the specified phone number. - Note that this may be an SMS message containing the validation token or it may be informing - the user of an error. - - ``submit_url`` is an optional field containing a URL where the - client must submit a validation token to, with identical parameters - to the Identity Service API's ``/validate/msisdn/submitToken`` - endpoint. The homeserver will send this token to the user, which - should then be prompted to provide it to the client. - - If this field is not present, the client can assume that - verification will happen without the client's involvement. + A SMS message has been sent to the specified phone number. Note + that this may be an SMS message containing the validation token or + it may be informing the user of an error. schema: type: object allOf: @@ -348,12 +330,12 @@ paths: submit_url: type: string description: |- - An optional field containing a URL where the client - must submit a validation token to, with identical - parameters to the Identity Service API's + An optional field containing a URL where the client must + submit the validation token to, with identical parameters + to the Identity Service API's ``/validate/email/submitToken`` endpoint. The homeserver - will send this token to the user, which should then be - prompted to provide it to the client. + must send this token to the user (if applicable), which + should then be prompted to provide it to the client. If this field is not present, the client can assume that verification will happen without the client's @@ -443,17 +425,17 @@ paths: post: summary: Requests a validation token be sent to the given email address for the purpose of resetting a user's password description: |- - The homeserver should check that the given email address **is + The homeserver must check that the given email address **is associated** with an account on this homeserver. This API should be used to request validation tokens when authenticating for the ``account/password`` endpoint. - This API's parameters and response are identical to that of the HS API - |/register/email/requestToken|_ except that ``M_THREEPID_NOT_FOUND`` - may be returned if no account matching the given email address could be - found. The server may instead send an email to the given address - prompting the user to create an account. ``M_THREEPID_IN_USE`` may not - be returned. + This API's parameters and response are identical to that of the + |/register/email/requestToken|_ endpoint, except that + ``M_THREEPID_NOT_FOUND`` may be returned if no account matching the + given email address could be found. The server may instead send an + email to the given address prompting the user to create an account. + ``M_THREEPID_IN_USE`` may not be returned. The homeserver has the choice of validating the email address itself, or proxying the request to the ``validate/email/requestToken`` Identity @@ -496,11 +478,11 @@ paths: type: string description: |- An optional field containing a URL where the client must - submit a validation token to, with identical parameters + submit the validation token to, with identical parameters to the Identity Service API's ``/validate/email/submitToken`` endpoint. The homeserver - will send this token to the user, which should then be - prompted to provide it to the client. + must send this token to the user (if applicable), which + should then be prompted to provide it to the client. If this field is not present, the client can assume that verification will happen without the client's @@ -532,17 +514,17 @@ paths: post: summary: Requests a validation token be sent to the given phone number for the purpose of resetting a user's password. description: |- - The homeserver should check that the given phone number **is + The homeserver must check that the given phone number **is associated** with an account on this homeserver. This API should be used to request validation tokens when authenticating for the ``account/password`` endpoint. - This API's parameters and response are identical to that of the HS API - |/register/msisdn/requestToken|_ except that ``M_THREEPID_NOT_FOUND`` may - be returned if no account matching the given phone number could be - found. The server may instead send the SMS to the given phone number - prompting the user to create an account. ``M_THREEPID_IN_USE`` may not - be returned. + This API's parameters and response are identical to that of the + |/register/msisdn/requestToken|_ endpoint, except that + ``M_THREEPID_NOT_FOUND`` may be returned if no account matching the + given phone number could be found. The server may instead send the SMS + to the given phone number prompting the user to create an account. + ``M_THREEPID_IN_USE`` may not be returned. The homeserver has the choice of validating the phone number itself, or proxying the request to the ``validate/msisdn/requestToken`` Identity @@ -573,7 +555,7 @@ paths: required: ['id_server'] responses: 200: - description: An SMS message was sent to the given phone number. + description: A SMS message was sent to the given phone number. schema: type: object allOf: @@ -584,11 +566,11 @@ paths: type: string description: |- An optional field containing a URL where the client must - submit a validation token to, with identical parameters + submit the validation token to, with identical parameters to the Identity Service API's ``/validate/msisdn/submitToken`` endpoint. The homeserver - will send this token to the user, which should then be - prompted to provide it to the client. + must send this token to the user (if applicable), which + should then be prompted to provide it to the client. If this field is not present, the client can assume that verification will happen without the client's From 0ded48427652857f92e323d5d85580adf0b6c7bd Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Sun, 9 Jun 2019 16:10:44 +0100 Subject: [PATCH 0479/1250] Address review comments --- api/client-server/administrative_contact.yaml | 4 ++-- api/client-server/registration.yaml | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index bc6f98c7..99451294 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -235,7 +235,7 @@ paths: account. This API's parameters and response are identical to that of the |/register/email/requestToken|_ endpoint. The homeserver has the choice of validating the email address itself, or proxying the request - to the ``validate/email/requestToken`` Identity Service API as + to the ``/validate/email/requestToken`` Identity Service API as identified by ``id_server``. operationId: requestTokenTo3PIDEmail parameters: @@ -312,7 +312,7 @@ paths: account. This API's parameters and response are identical to that of the |/register/msisdn/requestToken|_ endpoint. The homeserver has the choice of validating the phone number itself, or proxying the request - to the ``validate/msisdn/requestToken`` Identity Service API as + to the ``/validate/msisdn/requestToken`` Identity Service API as identified by ``id_server``. operationId: requestTokenTo3PIDMSISDN parameters: diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index c8615d29..21626815 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -213,7 +213,7 @@ paths: The homeserver must check that the given email address is **not** already associated with an account on this homeserver. The homeserver has the choice of validating the email address itself, or proxying the - request to the ``validate/email/requestToken`` Identity Service API. The + request to the ``/validate/email/requestToken`` Identity Service API. The request should be proxied to the domain that is sent by the client in the ``id_server``. It is imperative that the homeserver keep a list of trusted Identity Servers and only proxies to those it trusts. @@ -294,7 +294,7 @@ paths: The homeserver must check that the given phone number is **not** already associated with an account on this homeserver. The homeserver has the choice of validating the phone number itself, or proxying the - request to the ``validate/msisdn/requestToken`` Identity Service API. The + request to the ``/validate/msisdn/requestToken`` Identity Service API. The request should be proxied to the domain that is sent by the client in the ``id_server``. It is imperative that the homeserver keep a list of trusted Identity Servers and only proxies to those it trusts. @@ -428,7 +428,7 @@ paths: The homeserver must check that the given email address **is associated** with an account on this homeserver. This API should be used to request validation tokens when authenticating for the - ``account/password`` endpoint. + ``/account/password`` endpoint. This API's parameters and response are identical to that of the |/register/email/requestToken|_ endpoint, except that @@ -438,7 +438,7 @@ paths: ``M_THREEPID_IN_USE`` may not be returned. The homeserver has the choice of validating the email address itself, - or proxying the request to the ``validate/email/requestToken`` Identity + or proxying the request to the ``/validate/email/requestToken`` Identity Server API. The request should be proxied to the domain that is sent by the client in the ``id_server``. It is imperative that the homeserver keep a list of trusted Identity Servers and only proxies to those it @@ -517,7 +517,7 @@ paths: The homeserver must check that the given phone number **is associated** with an account on this homeserver. This API should be used to request validation tokens when authenticating for the - ``account/password`` endpoint. + ``/account/password`` endpoint. This API's parameters and response are identical to that of the |/register/msisdn/requestToken|_ endpoint, except that @@ -527,7 +527,7 @@ paths: ``M_THREEPID_IN_USE`` may not be returned. The homeserver has the choice of validating the phone number itself, - or proxying the request to the ``validate/msisdn/requestToken`` Identity + or proxying the request to the ``/validate/msisdn/requestToken`` Identity Server API. The request should be proxied to the domain that is sent by the client in the ``id_server``. It is imperative that the homeserver keep a list of trusted Identity Servers and only proxies to those it From fba61941af471e885fb2310ddb443660e92f0929 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Sun, 9 Jun 2019 20:02:57 +0100 Subject: [PATCH 0480/1250] Move submit_url responses to ref --- api/client-server/administrative_contact.yaml | 41 +--------- api/client-server/registration.yaml | 80 +------------------ api/identity/definitions/sid.yaml | 14 ++++ 3 files changed, 20 insertions(+), 115 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 99451294..d26e5a96 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -261,25 +261,7 @@ paths: Note that this may be an email containing the validation token or it may be informing the user of an error. schema: - type: object - allOf: - - $ref: "../identity/definitions/sid.yaml" - - type: object - properties: - submit_url: - type: string - description: |- - An optional field containing a URL where the client must - submit the validation token to, with identical parameters - to the Identity Service API's - ``/validate/email/submitToken`` endpoint. The homeserver - must send this token to the user, which should then be - prompted to provide it to the client. - - If this field is not present, the client can assume that - verification will happen without the client's - involvement. - example: "https://example.org/path/to/submitToken" + - $ref: "../identity/definitions/sid.yaml" 403: description: |- The homeserver does not allow the third party identifier as a @@ -336,26 +318,7 @@ paths: description: |- A SMS message was sent to the given phone number. schema: - type: object - allOf: - - $ref: "../identity/definitions/sid.yaml" - - type: object - properties: - submit_url: - type: string - description: |- - An optional field containing a URL where the client must - submit the validation token to, with identical parameters - to the Identity Service API's - ``/validate/email/submitToken`` endpoint. The homeserver - must send this token to the user (if applicable), which - should then be prompted to provide it to the client. - - If this field is not present, the client can assume that - verification will happen without the client's - involvement. - example: "https://example.org/path/to/submitToken" - + - $ref: "../identity/definitions/sid.yaml" 403: description: |- The homeserver does not allow the third party identifier as a diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 21626815..a2a0d47f 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -241,25 +241,7 @@ paths: Note that this may be an email containing the validation token or it may be informing the user of an error. schema: - type: object - allOf: - - $ref: "../identity/definitions/sid.yaml" - - type: object - properties: - submit_url: - type: string - description: |- - An optional field containing a URL where the client must - submit the validation token to, with identical parameters - to the Identity Service API's - ``/validate/email/submitToken`` endpoint. The homeserver - must send this token to the user (if applicable), which - should then be prompted to provide it to the client. - - If this field is not present, the client can assume that - verification will happen without the client's - involvement. - example: "https://example.org/path/to/submitToken" + - $ref: "../identity/definitions/sid.yaml" 403: description: The homeserver does not permit the address to be bound. schema: @@ -322,25 +304,7 @@ paths: that this may be an SMS message containing the validation token or it may be informing the user of an error. schema: - type: object - allOf: - - $ref: "../identity/definitions/sid.yaml" - - type: object - properties: - submit_url: - type: string - description: |- - An optional field containing a URL where the client must - submit the validation token to, with identical parameters - to the Identity Service API's - ``/validate/email/submitToken`` endpoint. The homeserver - must send this token to the user (if applicable), which - should then be prompted to provide it to the client. - - If this field is not present, the client can assume that - verification will happen without the client's - involvement. - example: "https://example.org/path/to/submitToken" + - $ref: "../identity/definitions/sid.yaml" 403: description: The homeserver does not permit the address to be bound. schema: @@ -469,25 +433,7 @@ paths: 200: description: An email was sent to the given address. schema: - type: object - allOf: - - $ref: "../identity/definitions/sid.yaml" - - type: object - properties: - submit_url: - type: string - description: |- - An optional field containing a URL where the client must - submit the validation token to, with identical parameters - to the Identity Service API's - ``/validate/email/submitToken`` endpoint. The homeserver - must send this token to the user (if applicable), which - should then be prompted to provide it to the client. - - If this field is not present, the client can assume that - verification will happen without the client's - involvement. - example: "https://example.org/path/to/submitToken" + - $ref: "../identity/definitions/sid.yaml" 403: description: |- The homeserver does not allow the third party identifier as a @@ -557,25 +503,7 @@ paths: 200: description: A SMS message was sent to the given phone number. schema: - type: object - allOf: - - $ref: "../identity/definitions/sid.yaml" - - type: object - properties: - submit_url: - type: string - description: |- - An optional field containing a URL where the client must - submit the validation token to, with identical parameters - to the Identity Service API's - ``/validate/msisdn/submitToken`` endpoint. The homeserver - must send this token to the user (if applicable), which - should then be prompted to provide it to the client. - - If this field is not present, the client can assume that - verification will happen without the client's - involvement. - example: "https://example.org/path/to/submitToken" + - $ref: "../identity/definitions/sid.yaml" 403: description: |- The homeserver does not allow the third party identifier as a diff --git a/api/identity/definitions/sid.yaml b/api/identity/definitions/sid.yaml index c1f1ae64..c09ed395 100644 --- a/api/identity/definitions/sid.yaml +++ b/api/identity/definitions/sid.yaml @@ -21,4 +21,18 @@ properties: ``[0-9a-zA-Z.=_-]``. Their length must not exceed 255 characters and they must not be empty. example: "123abc" + submit_url: + type: string + description: |- + An optional field containing a URL where the client must + submit the validation token to, with identical parameters + to the Identity Service API's + ``/validate/email/submitToken`` endpoint. The homeserver + must send this token to the user (if applicable), which + should then be prompted to provide it to the client. + + If this field is not present, the client can assume that + verification will happen without the client's + involvement. + example: "https://example.org/path/to/submitToken" required: ['sid'] From 525bedf8e14327556153d19933efcd488fa61017 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Sun, 9 Jun 2019 20:10:44 +0100 Subject: [PATCH 0481/1250] Fix refs --- api/client-server/administrative_contact.yaml | 6 ++++-- api/client-server/registration.yaml | 12 ++++++++---- api/identity/definitions/sid.yaml | 14 -------------- 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index d26e5a96..c19872e8 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -261,7 +261,8 @@ paths: Note that this may be an email containing the validation token or it may be informing the user of an error. schema: - - $ref: "../identity/definitions/sid.yaml" + type: object + $ref: "definitions/sid.yaml" 403: description: |- The homeserver does not allow the third party identifier as a @@ -318,7 +319,8 @@ paths: description: |- A SMS message was sent to the given phone number. schema: - - $ref: "../identity/definitions/sid.yaml" + type: object + $ref: "definitions/sid.yaml" 403: description: |- The homeserver does not allow the third party identifier as a diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index a2a0d47f..4ea8b252 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -241,7 +241,8 @@ paths: Note that this may be an email containing the validation token or it may be informing the user of an error. schema: - - $ref: "../identity/definitions/sid.yaml" + type: object + $ref: "definitions/sid.yaml" 403: description: The homeserver does not permit the address to be bound. schema: @@ -304,7 +305,8 @@ paths: that this may be an SMS message containing the validation token or it may be informing the user of an error. schema: - - $ref: "../identity/definitions/sid.yaml" + type: object + $ref: "definitions/sid.yaml" 403: description: The homeserver does not permit the address to be bound. schema: @@ -433,7 +435,8 @@ paths: 200: description: An email was sent to the given address. schema: - - $ref: "../identity/definitions/sid.yaml" + type: object + $ref: "definitions/sid.yaml" 403: description: |- The homeserver does not allow the third party identifier as a @@ -503,7 +506,8 @@ paths: 200: description: A SMS message was sent to the given phone number. schema: - - $ref: "../identity/definitions/sid.yaml" + type: object + $ref: "definitions/sid.yaml" 403: description: |- The homeserver does not allow the third party identifier as a diff --git a/api/identity/definitions/sid.yaml b/api/identity/definitions/sid.yaml index c09ed395..c1f1ae64 100644 --- a/api/identity/definitions/sid.yaml +++ b/api/identity/definitions/sid.yaml @@ -21,18 +21,4 @@ properties: ``[0-9a-zA-Z.=_-]``. Their length must not exceed 255 characters and they must not be empty. example: "123abc" - submit_url: - type: string - description: |- - An optional field containing a URL where the client must - submit the validation token to, with identical parameters - to the Identity Service API's - ``/validate/email/submitToken`` endpoint. The homeserver - must send this token to the user (if applicable), which - should then be prompted to provide it to the client. - - If this field is not present, the client can assume that - verification will happen without the client's - involvement. - example: "https://example.org/path/to/submitToken" required: ['sid'] From 2551ff6ce0b4100a3436344c2043241998635fa0 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Sun, 9 Jun 2019 20:12:23 +0100 Subject: [PATCH 0482/1250] Actually check in code --- api/client-server/definitions/sid.yaml | 38 ++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 api/client-server/definitions/sid.yaml diff --git a/api/client-server/definitions/sid.yaml b/api/client-server/definitions/sid.yaml new file mode 100644 index 00000000..50b45ca9 --- /dev/null +++ b/api/client-server/definitions/sid.yaml @@ -0,0 +1,38 @@ +# Copyright 2019 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 +properties: + sid: + type: string + description: |- + The session ID. Session IDs are opaque strings generated by the identity + server. They must consist entirely of the characters + ``[0-9a-zA-Z.=_-]``. Their length must not exceed 255 characters and they + must not be empty. + example: "123abc" + submit_url: + type: string + description: |- + An optional field containing a URL where the client must + submit the validation token to, with identical parameters + to the Identity Service API's + ``/validate/email/submitToken`` endpoint. The homeserver + must send this token to the user (if applicable), which + should then be prompted to provide it to the client. + + If this field is not present, the client can assume that + verification will happen without the client's + involvement. + example: "https://example.org/path/to/submitToken" +required: ['sid'] From 046a83448862d000048b644386cfacd5df6190e3 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Sun, 9 Jun 2019 22:04:58 +0100 Subject: [PATCH 0483/1250] Slight code cleanup --- api/client-server/administrative_contact.yaml | 14 +++++--------- api/client-server/registration.yaml | 12 ++++-------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index c19872e8..f0a86762 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -132,8 +132,7 @@ paths: } responses: 200: - description: |- - The addition was successful. + description: The addition was successful. examples: application/json: { "submit_url": "https://example.org/path/to/submitToken" @@ -257,11 +256,10 @@ paths: responses: 200: description: |- - An email was sent to the given address. - Note that this may be an email containing the validation token or - it may be informing the user of an error. + An email was sent to the given address. Note that this may be an + email containing the validation token or it may be informing the + user of an error. schema: - type: object $ref: "definitions/sid.yaml" 403: description: |- @@ -316,10 +314,8 @@ paths: required: ['id_server'] responses: 200: - description: |- - A SMS message was sent to the given phone number. + description: A SMS message was sent to the given phone number. schema: - type: object $ref: "definitions/sid.yaml" 403: description: |- diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 4ea8b252..c892b08d 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -237,11 +237,10 @@ paths: responses: 200: description: |- - An email has been sent to the specified address. - Note that this may be an email containing the validation token or it may be informing - the user of an error. + An email has been sent to the specified address. Note that this + may be an email containing the validation token or it may be + informing the user of an error. schema: - type: object $ref: "definitions/sid.yaml" 403: description: The homeserver does not permit the address to be bound. @@ -301,11 +300,10 @@ paths: responses: 200: description: |- - A SMS message has been sent to the specified phone number. Note + A SMS message has been sent to the specified phone number. Note that this may be an SMS message containing the validation token or it may be informing the user of an error. schema: - type: object $ref: "definitions/sid.yaml" 403: description: The homeserver does not permit the address to be bound. @@ -435,7 +433,6 @@ paths: 200: description: An email was sent to the given address. schema: - type: object $ref: "definitions/sid.yaml" 403: description: |- @@ -506,7 +503,6 @@ paths: 200: description: A SMS message was sent to the given phone number. schema: - type: object $ref: "definitions/sid.yaml" 403: description: |- From fe23de7d7f43f6d7ed30f0a9a320b940071e89f9 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 10 Jun 2019 05:20:15 +0100 Subject: [PATCH 0484/1250] A SMS -> An SMS --- api/client-server/administrative_contact.yaml | 2 +- api/client-server/registration.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index f0a86762..4c1ea2e7 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -314,7 +314,7 @@ paths: required: ['id_server'] responses: 200: - description: A SMS message was sent to the given phone number. + description: An SMS message was sent to the given phone number. schema: $ref: "definitions/sid.yaml" 403: diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index c892b08d..00334434 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -300,7 +300,7 @@ paths: responses: 200: description: |- - A SMS message has been sent to the specified phone number. Note + An SMS message has been sent to the specified phone number. Note that this may be an SMS message containing the validation token or it may be informing the user of an error. schema: @@ -501,7 +501,7 @@ paths: required: ['id_server'] responses: 200: - description: A SMS message was sent to the given phone number. + description: An SMS message was sent to the given phone number. schema: $ref: "definitions/sid.yaml" 403: From 29340c6eb815dc2fedeec9f18468c58e385cda78 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 9 Jun 2019 22:50:23 -0600 Subject: [PATCH 0485/1250] Clarify that the common identifier format can be broken We already reference in the Event IDs section that the format depends on the room version, so we just need to link there. Fixes https://github.com/matrix-org/matrix-doc/issues/2103 --- specification/appendices/identifier_grammar.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/specification/appendices/identifier_grammar.rst b/specification/appendices/identifier_grammar.rst index ea805955..b5b0537a 100644 --- a/specification/appendices/identifier_grammar.rst +++ b/specification/appendices/identifier_grammar.rst @@ -88,8 +88,8 @@ Common Identifier Format ~~~~~~~~~~~~~~~~~~~~~~~~ The Matrix protocol uses a common format to assign unique identifiers to a -number of entities, including users, events and rooms. Each identifier takes -the form:: +number of entities, including users, events and rooms. Each identifier typically +takes the form:: &localpart:domain @@ -106,7 +106,9 @@ The sigil characters are as follows: * ``#``: Room alias The precise grammar defining the allowable format of an identifier depends on -the type of identifier. +the type of identifier. For example, event IDs can be represented without a +``domain`` component under some conditions - see the `Event IDs <#room-ids-and-event-ids>`_ +section below for more information. User Identifiers ++++++++++++++++ From ab0c1bc054247f732e66dd2b424d8c3a12a5e492 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 10 Jun 2019 08:41:35 +0100 Subject: [PATCH 0486/1250] Add changelog, update imperative check, rename sid.yaml --- api/client-server/administrative_contact.yaml | 14 +++++---- .../{sid.yaml => request_token_response.yaml} | 0 api/client-server/registration.yaml | 30 +++++++++---------- .../client_server/newsfragments/2101.breaking | 1 + 4 files changed, 25 insertions(+), 20 deletions(-) rename api/client-server/definitions/{sid.yaml => request_token_response.yaml} (100%) create mode 100644 changelogs/client_server/newsfragments/2101.breaking diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 4c1ea2e7..4438b643 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -135,7 +135,7 @@ paths: description: The addition was successful. examples: application/json: { - "submit_url": "https://example.org/path/to/submitToken" + "submit_url": "https://example.org/path/to/submitToken" } schema: type: object @@ -235,7 +235,9 @@ paths: the |/register/email/requestToken|_ endpoint. The homeserver has the choice of validating the email address itself, or proxying the request to the ``/validate/email/requestToken`` Identity Service API as - identified by ``id_server``. + identified by ``id_server``. It is imperative that the + homeserver keep a list of trusted Identity Servers and only proxies to + those that it trusts. operationId: requestTokenTo3PIDEmail parameters: - in: body @@ -260,7 +262,7 @@ paths: email containing the validation token or it may be informing the user of an error. schema: - $ref: "definitions/sid.yaml" + $ref: "definitions/request_token_response.yaml" 403: description: |- The homeserver does not allow the third party identifier as a @@ -294,7 +296,9 @@ paths: the |/register/msisdn/requestToken|_ endpoint. The homeserver has the choice of validating the phone number itself, or proxying the request to the ``/validate/msisdn/requestToken`` Identity Service API as - identified by ``id_server``. + identified by ``id_server``. It is imperative that the + homeserver keep a list of trusted Identity Servers and only proxies to + those that it trusts. operationId: requestTokenTo3PIDMSISDN parameters: - in: body @@ -316,7 +320,7 @@ paths: 200: description: An SMS message was sent to the given phone number. schema: - $ref: "definitions/sid.yaml" + $ref: "definitions/request_token_response.yaml" 403: description: |- The homeserver does not allow the third party identifier as a diff --git a/api/client-server/definitions/sid.yaml b/api/client-server/definitions/request_token_response.yaml similarity index 100% rename from api/client-server/definitions/sid.yaml rename to api/client-server/definitions/request_token_response.yaml diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 00334434..5ec657e0 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -241,7 +241,7 @@ paths: may be an email containing the validation token or it may be informing the user of an error. schema: - $ref: "definitions/sid.yaml" + $ref: "definitions/request_token_response.yaml" 403: description: The homeserver does not permit the address to be bound. schema: @@ -304,7 +304,7 @@ paths: that this may be an SMS message containing the validation token or it may be informing the user of an error. schema: - $ref: "definitions/sid.yaml" + $ref: "definitions/request_token_response.yaml" 403: description: The homeserver does not permit the address to be bound. schema: @@ -402,11 +402,11 @@ paths: ``M_THREEPID_IN_USE`` may not be returned. The homeserver has the choice of validating the email address itself, - or proxying the request to the ``/validate/email/requestToken`` Identity - Server API. The request should be proxied to the domain that is sent by - the client in the ``id_server``. It is imperative that the homeserver - keep a list of trusted Identity Servers and only proxies to those it - trusts. + or proxying the request to the ``/validate/email/requestToken`` + Identity Service API. The request should be proxied to the domain that + is sent by the client in the ``id_server``. It is imperative that the + homeserver keep a list of trusted Identity Servers and only proxies to + those that it trusts. .. |/register/email/requestToken| replace:: ``/register/email/requestToken`` @@ -433,7 +433,7 @@ paths: 200: description: An email was sent to the given address. schema: - $ref: "definitions/sid.yaml" + $ref: "definitions/request_token_response.yaml" 403: description: |- The homeserver does not allow the third party identifier as a @@ -472,12 +472,12 @@ paths: to the given phone number prompting the user to create an account. ``M_THREEPID_IN_USE`` may not be returned. - The homeserver has the choice of validating the phone number itself, - or proxying the request to the ``/validate/msisdn/requestToken`` Identity - Server API. The request should be proxied to the domain that is sent by - the client in the ``id_server``. It is imperative that the homeserver - keep a list of trusted Identity Servers and only proxies to those it - trusts. + The homeserver has the choice of validating the phone number itself, or + proxying the request to the ``/validate/msisdn/requestToken`` Identity + Service API. The request should be proxied to the domain that is sent + by the client in the ``id_server``. It is imperative that the + homeserver keep a list of trusted Identity Servers and only proxies to + those that it trusts. .. |/register/msisdn/requestToken| replace:: ``/register/msisdn/requestToken`` @@ -503,7 +503,7 @@ paths: 200: description: An SMS message was sent to the given phone number. schema: - $ref: "definitions/sid.yaml" + $ref: "definitions/request_token_response.yaml" 403: description: |- The homeserver does not allow the third party identifier as a diff --git a/changelogs/client_server/newsfragments/2101.breaking b/changelogs/client_server/newsfragments/2101.breaking new file mode 100644 index 00000000..84c645ab --- /dev/null +++ b/changelogs/client_server/newsfragments/2101.breaking @@ -0,0 +1 @@ +Add a new ``submit_url`` field to the response of various `.../requestToken` endpoints. From 0f82056ca2a46bd35483ee83c18c75035d85056f Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 10 Jun 2019 08:43:34 +0100 Subject: [PATCH 0487/1250] Highlight breaking change --- changelogs/client_server/newsfragments/2101.breaking | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/client_server/newsfragments/2101.breaking b/changelogs/client_server/newsfragments/2101.breaking index 84c645ab..bcbdcd55 100644 --- a/changelogs/client_server/newsfragments/2101.breaking +++ b/changelogs/client_server/newsfragments/2101.breaking @@ -1 +1 @@ -Add a new ``submit_url`` field to the response of various `.../requestToken` endpoints. +Breaking change: Add a new ``submit_url`` field to the response of various `.../requestToken` endpoints. Clients should request a token from the user to submit 3PID validation when they received this field. Older clients will not know about this field and thus may display a deceptive message thinking that validation will be handled out of bounds. From d1fde0837af4ecfde83532f0c027bde4f4c5ea10 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 10 Jun 2019 09:06:13 +0100 Subject: [PATCH 0488/1250] Consolidate id_server into ref. id_server/next_link are ignored --- api/client-server/administrative_contact.yaml | 24 ++----------------- .../definitions/request_email_validation.yaml | 14 ++++++++--- .../request_msisdn_validation.yaml | 14 ++++++++--- 3 files changed, 24 insertions(+), 28 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 4438b643..6ee4a152 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -244,17 +244,7 @@ paths: name: body required: true schema: - allOf: - - $ref: "../identity/definitions/request_email_validation.yaml" - - type: object - properties: - id_server: - type: string - description: |- - The hostname of the identity server to communicate with. May - optionally include a port. - example: "id.example.com" - required: ['id_server'] + $ref: "../identity/definitions/request_email_validation.yaml" responses: 200: description: |- @@ -305,17 +295,7 @@ paths: name: body required: true schema: - allOf: - - $ref: "../identity/definitions/request_msisdn_validation.yaml" - - type: object - properties: - id_server: - type: string - description: |- - The hostname of the identity server to communicate with. May - optionally include a port. - example: "id.example.com" - required: ['id_server'] + $ref: "../identity/definitions/request_msisdn_validation.yaml" responses: 200: description: An SMS message was sent to the given phone number. diff --git a/api/identity/definitions/request_email_validation.yaml b/api/identity/definitions/request_email_validation.yaml index 5f15bd41..b99fe121 100644 --- a/api/identity/definitions/request_email_validation.yaml +++ b/api/identity/definitions/request_email_validation.yaml @@ -45,7 +45,15 @@ properties: next_link: type: string description: |- - Optional. When the validation is completed, the identity - server will redirect the user to this URL. + Optional. When the validation is completed, the identity server will + redirect the user to this URL. This option is ignored when submitting + 3PID validation information through a POST request. example: "https://example.org/congratulations.html" -required: ["client_secret", "email", "send_attempt"] + id_server: + type: string + description: |- + The hostname of the identity server to communicate with. May optionally + include a port. This parameter is ignored when the homeserver handles + 3PID verification. + example: "id.example.com" +required: ["client_secret", "email", "send_attempt", "id_server"] diff --git a/api/identity/definitions/request_msisdn_validation.yaml b/api/identity/definitions/request_msisdn_validation.yaml index 1a8c0cf8..08dd0482 100644 --- a/api/identity/definitions/request_msisdn_validation.yaml +++ b/api/identity/definitions/request_msisdn_validation.yaml @@ -51,7 +51,15 @@ properties: next_link: type: string description: |- - Optional. When the validation is completed, the identity - server will redirect the user to this URL. + Optional. When the validation is completed, the identity server will + redirect the user to this URL. This option is ignored when submitting + 3PID validation information through a POST request. example: "https://example.org/congratulations.html" -required: ["client_secret", "country", "phone_number", "send_attempt"] + id_server: + type: string + description: |- + The hostname of the identity server to communicate with. May optionally + include a port. This parameter is ignored when the homeserver handles + 3PID verification. + example: "id.example.com" +required: ["client_secret", "country", "phone_number", "send_attempt", "id_server"] From 7116f9334e8925e2c710c529dd1d0ab8c44209de Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 10 Jun 2019 09:09:26 +0100 Subject: [PATCH 0489/1250] More consolidation --- api/client-server/registration.yaml | 48 +++-------------------------- 1 file changed, 4 insertions(+), 44 deletions(-) diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 5ec657e0..edc52c6a 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -223,17 +223,7 @@ paths: name: body required: true schema: - allOf: - - $ref: "../identity/definitions/request_email_validation.yaml" - - type: object - properties: - id_server: - type: string - description: |- - The hostname of the identity server to communicate with. May - optionally include a port. - example: "id.example.com" - required: ['id_server'] + $ref: "../identity/definitions/request_email_validation.yaml" responses: 200: description: |- @@ -286,17 +276,7 @@ paths: name: body required: true schema: - allOf: - - $ref: "../identity/definitions/request_msisdn_validation.yaml" - - type: object - properties: - id_server: - type: string - description: |- - The hostname of the identity server to communicate with. May - optionally include a port. - example: "id.example.com" - required: ['id_server'] + $ref: "../identity/definitions/request_msisdn_validation.yaml" responses: 200: description: |- @@ -418,17 +398,7 @@ paths: name: body required: true schema: - allOf: - - $ref: "../identity/definitions/request_email_validation.yaml" - - type: object - properties: - id_server: - type: string - description: |- - The hostname of the identity server to communicate with. May - optionally include a port. - example: "id.example.com" - required: ['id_server'] + $ref: "../identity/definitions/request_email_validation.yaml" responses: 200: description: An email was sent to the given address. @@ -488,17 +458,7 @@ paths: name: body required: true schema: - allOf: - - $ref: "../identity/definitions/request_msisdn_validation.yaml" - - type: object - properties: - id_server: - type: string - description: |- - The hostname of the identity server to communicate with. May - optionally include a port. - example: "id.example.com" - required: ['id_server'] + $ref: "../identity/definitions/request_msisdn_validation.yaml" responses: 200: description: An SMS message was sent to the given phone number. From 2068cba598b3e3630950f95d0d730a1a2e081a56 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 10 Jun 2019 09:14:25 +0100 Subject: [PATCH 0490/1250] Clients should submit a POST request --- api/client-server/administrative_contact.yaml | 8 ++++---- .../definitions/request_token_response.yaml | 16 +++++++--------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 6ee4a152..a3a391bc 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -145,10 +145,10 @@ paths: description: |- An optional field containing a URL where the client must submit the validation token to, with identical parameters - to the Identity Service API's - ``/validate/email/submitToken`` endpoint. The homeserver - must send this token to the user (if applicable), which - should then be prompted to provide it to the client. + to the Identity Service API's ``POST + /validate/email/submitToken`` endpoint. The homeserver must + send this token to the user (if applicable), which should + then be prompted to provide it to the client. If this field is not present, the client can assume that verification will happen without the client's involvement. diff --git a/api/client-server/definitions/request_token_response.yaml b/api/client-server/definitions/request_token_response.yaml index 50b45ca9..48f818e5 100644 --- a/api/client-server/definitions/request_token_response.yaml +++ b/api/client-server/definitions/request_token_response.yaml @@ -24,15 +24,13 @@ properties: submit_url: type: string description: |- - An optional field containing a URL where the client must - submit the validation token to, with identical parameters - to the Identity Service API's - ``/validate/email/submitToken`` endpoint. The homeserver - must send this token to the user (if applicable), which - should then be prompted to provide it to the client. + An optional field containing a URL where the client must submit the + validation token to, with identical parameters to the Identity Service + API's ``POST /validate/email/submitToken`` endpoint. The homeserver must + send this token to the user (if applicable), which should then be + prompted to provide it to the client. - If this field is not present, the client can assume that - verification will happen without the client's - involvement. + If this field is not present, the client can assume that verification + will happen without the client's involvement. example: "https://example.org/path/to/submitToken" required: ['sid'] From 0506d09cf7735ac01ffe30e1783cd0429a761c28 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 10 Jun 2019 19:38:44 +0100 Subject: [PATCH 0491/1250] incorporate LL review from matthew --- .../definitions/room_event_filter.yaml | 3 +- api/client-server/message_pagination.yaml | 14 ++-- api/client-server/sync.yaml | 19 +++--- specification/client_server_api.rst | 67 ++++++++++++------- specification/modules/instant_messaging.rst | 2 +- 5 files changed, 63 insertions(+), 42 deletions(-) diff --git a/api/client-server/definitions/room_event_filter.yaml b/api/client-server/definitions/room_event_filter.yaml index 7045396d..880cb173 100644 --- a/api/client-server/definitions/room_event_filter.yaml +++ b/api/client-server/definitions/room_event_filter.yaml @@ -25,7 +25,8 @@ allOf: include_redundant_members: type: boolean description: |- - If ``true``, enables redundant membership events. Does not + If ``true``, sends all membership events for all events, even if they have already + been sent to the client. Does not apply unless ``lazy_load_members`` is ``true``. See `Lazy-loading room members <#lazy-loading-room-members>`_ for more information. Defaults to ``false``. diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index 3e01437a..35555375 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -115,15 +115,13 @@ paths: type: array description: |- A list of state events relevant to showing the ``chunk``. For example, if - ``lazy_load_members`` is enabled in the filter then this will contain any - the membership events for the the senders of events in the ``chunk``. Servers should be careful to not exclude - membership events which are older than ones already sent to the client. - Likewise, clients should be cautious and avoid using older membership - events as the current membership event when paginating backwards. + ``lazy_load_members`` is enabled in the filter then this may contain + the membership events for the senders of events in the ``chunk``. - Unless ``include_redundant_members`` is ``true``, the server should remove - membership events which would have already been sent to clients in prior calls - to lazy-loading aware endpoints with the same filter. + Unless ``include_redundant_members`` is ``true``, the server + may remove membership events which would have already been + sent to the client in prior calls to this endpoint, assuming + the membership of those members has not changed. items: type: object title: RoomStateEvent diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 45829f68..00ed562d 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -39,12 +39,15 @@ paths: for more information. Lazy-loading members is only supported on a ``StateFilter`` for this endpoint. When lazy-loading is enabled, servers MUST include the syncing user's own membership event when they join a room, or when the - full state of rooms is requested. The user's own membership event is eligible + full state of rooms is requested, to aid discovering the user's avatar & + displayname. + + Like other members, the user's own membership event is eligible for being considered redundant by the server. When a sync is ``limited``, - the server MUST return membership events for events in the gap (between ``since`` and the start of the returned timeline), - regardless as to whether - or not they are redundant. ``include_redundant_members`` is ignored for limited - syncs. + the server MUST return membership events for events in the gap + (between ``since`` and the start of the returned timeline), regardless + as to whether or not they are redundant. This ensures that joins/leaves + and profile changes which occur during the gap are not lost. operationId: sync security: - accessToken: [] @@ -149,9 +152,9 @@ paths: type: array description: |- The users which can be used to generate a room name - if the room does not have one. Required if the room - does not have a ``m.room.name`` or ``m.room.canonical_alias`` - state event with non-empty content. + if the room does not have one. Required if the room's + ``m.room.name`` or ``m.room.canonical_alias`` state events + are unset or empty. This should be the first 5 members of the room, ordered by stream ordering, which are joined or invited. The diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 42f34849..a292eaeb 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1273,32 +1273,51 @@ Lazy-loading room members Membership events often take significant resources for clients to track. In an effort to reduce the number of resources used, clients can enable "lazy-loading" -for room members. By doing this, servers will only ever send membership events +for room members. By doing this, servers will attempt to only send membership events which are relevant to the client. -In terms of filters, this means enabling ``lazy_load_members`` on a ``RoomEventFilter`` -(or a ``StateFilter`` in the case of ``/sync`` only). When enabled, lazy-loading -aware endpoints (see below) will only include membership events for the ``sender`` -of events being included in the response. For example, if a client makes a ``/sync`` -request with lazy-loading enabled, the server will only return membership events -for the ``sender`` of events in the timeline, not all members of a room. - -Repeated calls to lazy-loading aware endpoints will result in redundant membership -events being excluded by default. Clients often track which membership events they -already have, therefore making the extra information not as useful to the client. -Clients can always request redundant membership events by setting ``include_redundant_members`` -to true in the filter. - -Servers should be cautious about which events they consider redundant. Membership -events can change over time, and should be included as relevant to maintain the -historical record. Likewise, clients should be cautious about treating an older event -as the current membership event for a user. - -.. Note:: - Repeated calls using the same filter to *any* lazy-loading aware endpoint may - result in redundant membership events being excluded from future calls. For example, a - request to ``/sync`` followed by a request to ``/messages`` may result in a - future call to ``/sync`` excluding membership events returned by the ``/messages`` call. +It is important to understand that lazy-loading is not intended to be a +perfect optimisation, and that it may not be practical for the server to +calculate precisely which membership events are relevant to the client. As a +result, it is valid for the server to send redundant membership events to the +client to ease implementation, although such redundancy should be minimised +where possible to conserve bandwidth. + +In terms of filters, lazy-loading is enabled by enabling ``lazy_load_members`` +on a ``RoomEventFilter`` (or a ``StateFilter`` in the case of ``/sync`` only). +When enabled, lazy-loading aware endpoints (see below) will only include +membership events for the ``sender`` of events being included in the response. +For example, if a client makes a ``/sync`` request with lazy-loading enabled, +the server will only return membership events for the ``sender`` of events in +the timeline, not all members of a room. + +When processing a sequence of events (e.g. by looping on ``/sync`` or +paginating ``/messages``), it is common for blocks of events in the sequence +to share a similar set of senders. Rather than responses in the sequence +sending duplicate membership events for these senders to the client, the +server MAY assume that clients will remember membership events they have +already been sent, and choose to skip sending membership events for members +whose membership has not changed. These are called 'redundant membership +events'. Clients may request that redundant membership events are always +included in responses by setting ``include_redundant_members`` to true in the +filter. + +The expected pattern for using lazy-loading is currently: + +* Client performs an initial /sync with lazy-loading enabled, and receives + only the membership events which relate to the senders of the events it + receives. +* Clients which support display-name tab-completion or other operations which + require rapid access to all members in a room should call /members for the + currently selected room, with an ``?at`` parameter set to the /sync + response's from token. The member list for the room is then maintained by + the state in subsequent incremental /sync responses. +* Clients which do not support tab-completion may instead pull in profiles for + arbitrary users (e.g. read receipts, typing notifications) on demand by + querying the room state or ``/profile``. + +.. TODO-spec + This implies that GET /state should also take an ``?at`` param The current endpoints which support lazy-loading room members are: diff --git a/specification/modules/instant_messaging.rst b/specification/modules/instant_messaging.rst index c514f481..679eabdc 100644 --- a/specification/modules/instant_messaging.rst +++ b/specification/modules/instant_messaging.rst @@ -287,7 +287,7 @@ choose a name: on the members of the room. Clients should consider `m.room.member`_ events for users other than the logged-in user, as defined below. - i. If the ``m.heroes`` for the room are greater or equal to + i. If the number of ``m.heroes`` for the room are greater or equal to ``m.joined_member_count + m.invited_member_count - 1``, then use the membership events for the heroes to calculate display names for the users (`disambiguating them if required`_) and concatenating them. For From cf19f525767a9db9a982a966e47f11a983f4eab3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2019 13:21:24 -0600 Subject: [PATCH 0492/1250] Enforce 7 day validity requirement everywhere also misc formatting fixes --- api/server-server/definitions/keys.yaml | 2 +- specification/rooms/v5.rst | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/api/server-server/definitions/keys.yaml b/api/server-server/definitions/keys.yaml index c48c320a..8bc6c563 100644 --- a/api/server-server/definitions/keys.yaml +++ b/api/server-server/definitions/keys.yaml @@ -98,7 +98,7 @@ properties: be ignored in room versions 1, 2, 3, and 4. Keys used beyond this timestamp MUST be considered invalid, depending on the `room version specification`_. - Servers SHOULD use the lesser of this field and 7 days into the future when + Servers MUST use the lesser of this field and 7 days into the future when determining if a key is valid. This is to avoid a situation where an attacker publishes a key which is valid for a significant amount of time without a way for the homeserver owner to revoke it. diff --git a/specification/rooms/v5.rst b/specification/rooms/v5.rst index 9b9fad7e..97ebf2fe 100644 --- a/specification/rooms/v5.rst +++ b/specification/rooms/v5.rst @@ -15,8 +15,8 @@ Room Version 5 ============== -This room version builds on `version 4 `_, enforcing signing key validity -periods for events. +This room version builds on `version 4 `_ while enforcing signing +key validity periods for events. .. contents:: Table of Contents .. sectnum:: @@ -52,3 +52,8 @@ validated. Servers missing a copy of the signing key MUST try to obtain one via or `POST /_matrix/key/v2/query <../server_server/r0.1.1.html#post-matrix-key-v2-query>`_ APIs. When using the ``/query`` endpoint, servers MUST set the ``minimum_valid_until_ts`` property to prompt the notary server to attempt to refresh the key if appropriate. + +Servers MUST use the lesser of ``valid_until_ts`` and 7 days into the future when +determining if a key is valid. This is to avoid a situation where an attacker +publishes a key which is valid for a significant amount of time without a way for +the homeserver owner to revoke it. From 1886a2346a27579cd378b4f112181d880626b460 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2019 13:38:43 -0600 Subject: [PATCH 0493/1250] Move explanation of notifications to notifications module --- api/client-server/sync.yaml | 4 ++-- specification/modules/push.rst | 11 +++++++++++ specification/modules/receipts.rst | 5 ++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 4514d417..89292673 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -172,8 +172,8 @@ paths: type: object description: |- Counts of unread notifications for this room. See the - `Receipts module <#module-receipts>`_ for more information - on how these are calculated. + `Receiving notifications section <#receiving-notifications>`_ + for more information on how these are calculated. properties: highlight_count: title: Highlighted notification count diff --git a/specification/modules/push.rst b/specification/modules/push.rst index 1bac0c2e..33ca7fd7 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -1,4 +1,5 @@ .. Copyright 2016 OpenMarket Ltd +.. Copyright 2019 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. @@ -116,6 +117,16 @@ have received. {{notifications_cs_http_api}} +Receiving notifications +~~~~~~~~~~~~~~~~~~~~~~~ + +Servers MUST include the number of unread notifications in a client's ``/sync`` +stream, and MUST update it as it changes. Notifications are determined by the +push rules which apply to an event. + +When the user updates their read receipt (either by using the API or by sending an +event), notifications prior to and including that event MUST be marked as read. + Push Rules ~~~~~~~~~~ A push rule is a single rule that states under what *conditions* an event should diff --git a/specification/modules/receipts.rst b/specification/modules/receipts.rst index 1745706e..4630091f 100644 --- a/specification/modules/receipts.rst +++ b/specification/modules/receipts.rst @@ -26,9 +26,8 @@ to a homeserver. To prevent this from becoming a problem, receipts are implement using "up to" markers. This marker indicates that the acknowledgement applies to all events "up to and including" the event specified. For example, marking an event as "read" would indicate that the user had read all events *up to* the -referenced event. Servers MUST decremement the number of pending notifications -for a user if the events are up to or including the read receipt. This is typically -done by adjusting the ``unread_notifications`` value in a ``/sync`` response. +referenced event. See the `Receiving notifications <#receiving-notifications>`_ +section for more information on how read receipts affect notification counts. Events ------ From 49831fb74fbde025c6d1c95a57ae5d15d0919fd5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2019 13:48:55 -0600 Subject: [PATCH 0494/1250] Clarifications about namespaces --- specification/index.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/specification/index.rst b/specification/index.rst index 375e19c0..547375e3 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -446,12 +446,13 @@ Namespacing Namespacing helps prevent conflicts between multiple applications and the specification itself. Where namespacing is used, ``m.`` prefixes are used by the specification to indicate that the field is controlled by the specification. Custom or non-specified -namespaces used in the wild SHOULD use the Java package naming convention to prevent +namespaces used in the wild MUST use the Java package naming convention to prevent conflicts. -As an example, event types are namespaced under ``m.`` in the specification however -any client can send a custom event type, such as ``com.example.game.score`` without -needing to put the event into the ``m.`` namespace. +As an example, event types defined in the specification are namespaced under the +special ``m.`` prefix, however any client can send a custom event type, such as +``com.example.game.score`` (assuming the client has rights to the ``com.example`` +namespace) without needing to put the event into the ``m.`` namespace. Timestamps ~~~~~~~~~~ From 19c827e581476a18875ea471263453d11a6d5cc3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2019 13:49:05 -0600 Subject: [PATCH 0495/1250] Remove trailing slashes section --- specification/index.rst | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/specification/index.rst b/specification/index.rst index 547375e3..5acec2ea 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -432,13 +432,7 @@ Common concepts Various things are common throughout all of the Matrix APIs. They are documented here. -Trailing slashes on API endpoints -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Unless the endpoint is explicltly specified to have a trailing slash, the -slash is optional. For example, an endpoint specified as ``/_matrix/example/`` -would require a trailing slash, however an endpoint specified as ``/_matrix/example`` -has an optional slash (can be excluded when making requests). +.. TODO: Some words about trailing slashes. See https://github.com/matrix-org/matrix-doc/issues/2107 Namespacing ~~~~~~~~~~~ From 51698a5dd55232d39746269bfd164647ec56548f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2019 14:04:14 -0600 Subject: [PATCH 0496/1250] Clarify that people must own the namespace to use it --- specification/client_server_api.rst | 3 ++- specification/index.rst | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 80e4a2f4..b67beca1 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1330,7 +1330,8 @@ namespaced for each application and reduces the risk of clashes. Events are not limited to the types defined in this specification. New or custom event types can be created on a whim using the Java package naming convention. For example, a ``com.example.game.score`` event can be sent by clients and other - clients would receive it through Matrix. + clients would receive it through Matrix, assuming the client has access to the + ``com.example`` namespace. Note that the structure of these events may be different than those in the server-server API. diff --git a/specification/index.rst b/specification/index.rst index 7aa6a672..bf12a271 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -352,7 +352,8 @@ from the other servers participating in a room. Events are not limited to the types defined in this specification. New or custom event types can be created on a whim using the Java package naming convention. For example, a ``com.example.game.score`` event can be sent by clients and other - clients would receive it through Matrix. + clients would receive it through Matrix, assuming the client has access to the + ``com.example`` namespace. Room Aliases ++++++++++++ From 37e2d81d580083f8d7ed2f1a99e368231aab299c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2019 14:04:27 -0600 Subject: [PATCH 0497/1250] Hardcode the state event fields table into the spec See comment for why. --- specification/client_server_api.rst | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index b67beca1..ad58fd1a 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1340,7 +1340,28 @@ server-server API. {{common_room_event_fields}} -{{common_state_event_fields}} +.. This is normally where we'd put the common_state_event_fields variable for the +.. magic table of what makes up a state event, however the table is verbose in our +.. custom rendering of swagger. To combat this, we just hardcode this particular +.. table. + +State Event Fields +++++++++++++++++++ + +In addition to the fields of a Room Event, State Events have the following fields. + ++-----------+--------+-------------------------------------------------------------+ +| Key | Type | Description | ++===========+========+=============================================================+ +| state_key | string | **Required.** A unique key which defines the overwriting | +| | | semantics for this piece of room state. This value is often | +| | | a zero-length string. The presence of this key makes this | +| | | event a State Event. State keys starting with an ``@`` are | +| | | reserved for referencing user IDs, such as room members. | +| | | With the exception of a few events, state events set with | +| | | a given user's ID as the state key MUST only be set by that | +| | | user. | ++-----------+--------+-------------------------------------------------------------+ Size limits From ad2eefdde9b065800b5bc33e7697e14c8de82d90 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2019 14:23:04 -0600 Subject: [PATCH 0498/1250] Shuffle and clarify identifier grammar Specifically, make it clearer that event IDs are the weird exception in this section. --- .../appendices/identifier_grammar.rst | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/specification/appendices/identifier_grammar.rst b/specification/appendices/identifier_grammar.rst index b5b0537a..c2c734ab 100644 --- a/specification/appendices/identifier_grammar.rst +++ b/specification/appendices/identifier_grammar.rst @@ -88,14 +88,13 @@ Common Identifier Format ~~~~~~~~~~~~~~~~~~~~~~~~ The Matrix protocol uses a common format to assign unique identifiers to a -number of entities, including users, events and rooms. Each identifier typically -takes the form:: +number of entities, including users, events and rooms. Each identifier takes +the form:: - &localpart:domain + &string -where ``&`` represents a 'sigil' character; ``domain`` is the `server name`_ of -the homeserver which allocated the identifier, and ``localpart`` is an -identifier allocated by that homeserver. +where ``&`` represents a 'sigil' character; ``string`` is the string which makes +up the identifier. The sigil characters are as follows: @@ -105,9 +104,16 @@ The sigil characters are as follows: * ``+``: Group ID * ``#``: Room alias +User IDs, group IDs, room IDs, room aliases, and sometimes event IDs take the form:: + + &localpart:domain + +where ``domain`` is the `server name`_ of the homeserver which allocated the +identifier, and ``localpart`` is an identifier allocated by that homeserver. + The precise grammar defining the allowable format of an identifier depends on -the type of identifier. For example, event IDs can be represented without a -``domain`` component under some conditions - see the `Event IDs <#room-ids-and-event-ids>`_ +the type of identifier. For example, event IDs can sometimes be represented with +a ``domain`` component under some conditions - see the `Event IDs <#room-ids-and-event-ids>`_ section below for more information. User Identifiers From 572d29348c293012a03326c9ee0bfac74b76bf98 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Tue, 11 Jun 2019 00:18:37 +0100 Subject: [PATCH 0499/1250] Update changelogs/client_server/newsfragments/2101.breaking Co-Authored-By: Travis Ralston --- changelogs/client_server/newsfragments/2101.breaking | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/client_server/newsfragments/2101.breaking b/changelogs/client_server/newsfragments/2101.breaking index bcbdcd55..68971171 100644 --- a/changelogs/client_server/newsfragments/2101.breaking +++ b/changelogs/client_server/newsfragments/2101.breaking @@ -1 +1 @@ -Breaking change: Add a new ``submit_url`` field to the response of various `.../requestToken` endpoints. Clients should request a token from the user to submit 3PID validation when they received this field. Older clients will not know about this field and thus may display a deceptive message thinking that validation will be handled out of bounds. +Add a new ``submit_url`` field to the responses of ``/requestToken`` which older clients will not be able to handle correctly. From 1a22508e150071a275c08e3a13ace15211924f74 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 10 Jun 2019 19:18:58 -0400 Subject: [PATCH 0500/1250] identity server -> the server --- api/client-server/definitions/request_token_response.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/api/client-server/definitions/request_token_response.yaml b/api/client-server/definitions/request_token_response.yaml index 48f818e5..8776d143 100644 --- a/api/client-server/definitions/request_token_response.yaml +++ b/api/client-server/definitions/request_token_response.yaml @@ -16,10 +16,9 @@ properties: sid: type: string description: |- - The session ID. Session IDs are opaque strings generated by the identity - server. They must consist entirely of the characters - ``[0-9a-zA-Z.=_-]``. Their length must not exceed 255 characters and they - must not be empty. + The session ID. Session IDs are opaque strings generated by a server. + They must consist entirely of the characters ``[0-9a-zA-Z.=_-]``. Their + length must not exceed 255 characters and they must not be empty. example: "123abc" submit_url: type: string From 5f24f63338f94a08c51754877a708fb596154e09 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 10 Jun 2019 19:21:14 -0400 Subject: [PATCH 0501/1250] Better wording --- api/client-server/definitions/request_token_response.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/client-server/definitions/request_token_response.yaml b/api/client-server/definitions/request_token_response.yaml index 8776d143..98fefe07 100644 --- a/api/client-server/definitions/request_token_response.yaml +++ b/api/client-server/definitions/request_token_response.yaml @@ -16,9 +16,9 @@ properties: sid: type: string description: |- - The session ID. Session IDs are opaque strings generated by a server. - They must consist entirely of the characters ``[0-9a-zA-Z.=_-]``. Their - length must not exceed 255 characters and they must not be empty. + The session ID. Session IDs are opaque strings that must consist entirely + of the characters ``[0-9a-zA-Z.=_-]``. Their length must not exceed 255 + characters and they must not be empty. example: "123abc" submit_url: type: string From 04930c6ddfb0a5fadbde2a8255a2a8d59c430c98 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2019 08:29:50 -0600 Subject: [PATCH 0502/1250] Don't enforce MXC URIs, but also don't confuse people --- .../core-event-schema/msgtype_infos/image_info.yaml | 4 ++-- event-schemas/schema/m.room.message$m.audio | 4 +++- event-schemas/schema/m.room.message$m.file | 4 +++- event-schemas/schema/m.room.message$m.image | 4 +++- event-schemas/schema/m.room.message$m.video | 8 +++++--- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/event-schemas/schema/core-event-schema/msgtype_infos/image_info.yaml b/event-schemas/schema/core-event-schema/msgtype_infos/image_info.yaml index b6a45007..ff40efcb 100644 --- a/event-schemas/schema/core-event-schema/msgtype_infos/image_info.yaml +++ b/event-schemas/schema/core-event-schema/msgtype_infos/image_info.yaml @@ -19,8 +19,8 @@ properties: type: integer thumbnail_url: description: |- - The `MXC URI`_ to a thumbnail of the image. Only present if the - thumbnail is unencrypted. + The URL (typically `MXC URI`_) to a thumbnail of the image. + Only present if the thumbnail is unencrypted. type: string thumbnail_file: description: |- diff --git a/event-schemas/schema/m.room.message$m.audio b/event-schemas/schema/m.room.message$m.audio index 40075541..88b459ec 100644 --- a/event-schemas/schema/m.room.message$m.audio +++ b/event-schemas/schema/m.room.message$m.audio @@ -27,7 +27,9 @@ properties: - m.audio type: string url: - description: Required if the file is not encrypted. The `MXC URI`_ to the audio clip. + description: |- + Required if the file is not encrypted. The URL (typically `MXC URI`_) + to the audio clip. type: string file: description: |- diff --git a/event-schemas/schema/m.room.message$m.file b/event-schemas/schema/m.room.message$m.file index 225ca61d..9f4fdf07 100644 --- a/event-schemas/schema/m.room.message$m.file +++ b/event-schemas/schema/m.room.message$m.file @@ -42,7 +42,9 @@ properties: - m.file type: string url: - description: Required if the file is unencrypted. The `MXC URI`_ to the file. + description: |- + Required if the file is unencrypted. The URL (typically `MXC URI`_) + to the file. type: string file: description: |- diff --git a/event-schemas/schema/m.room.message$m.image b/event-schemas/schema/m.room.message$m.image index 8bf9c5fa..a466562a 100644 --- a/event-schemas/schema/m.room.message$m.image +++ b/event-schemas/schema/m.room.message$m.image @@ -17,7 +17,9 @@ properties: - m.image type: string url: - description: Required if the file is unencrypted. The `MXC URI`_ to the image. + description: |- + Required if the file is unencrypted. The URL (typically `MXC URI`_) + to the image. type: string file: description: |- diff --git a/event-schemas/schema/m.room.message$m.video b/event-schemas/schema/m.room.message$m.video index 01286ce2..b23c2392 100644 --- a/event-schemas/schema/m.room.message$m.video +++ b/event-schemas/schema/m.room.message$m.video @@ -28,8 +28,8 @@ properties: type: integer thumbnail_url: description: |- - The `MXC URI`_ to an image thumbnail of the video clip. Only present if the - thumbnail is unencrypted. + The URL (typically `MXC URI`_) to an image thumbnail of + the video clip. Only present if the thumbnail is unencrypted. type: string thumbnail_file: description: |- @@ -48,7 +48,9 @@ properties: - m.video type: string url: - description: Required if the file is unencrypted. The `MXC URI`_ to the video clip. + description: |- + Required if the file is unencrypted. The URL (typically `MXC URI`_) + to the video clip. type: string file: description: |- From ca8b539b2fe51e01c6042519aa04aa78b7e55d72 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2019 08:47:25 -0600 Subject: [PATCH 0503/1250] humans prefer to be treated as people --- api/client-server/administrative_contact.yaml | 2 +- api/client-server/definitions/request_token_response.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index a3a391bc..af7cdcd6 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -147,7 +147,7 @@ paths: submit the validation token to, with identical parameters to the Identity Service API's ``POST /validate/email/submitToken`` endpoint. The homeserver must - send this token to the user (if applicable), which should + send this token to the user (if applicable), who should then be prompted to provide it to the client. If this field is not present, the client can assume that diff --git a/api/client-server/definitions/request_token_response.yaml b/api/client-server/definitions/request_token_response.yaml index 98fefe07..bca57227 100644 --- a/api/client-server/definitions/request_token_response.yaml +++ b/api/client-server/definitions/request_token_response.yaml @@ -26,7 +26,7 @@ properties: An optional field containing a URL where the client must submit the validation token to, with identical parameters to the Identity Service API's ``POST /validate/email/submitToken`` endpoint. The homeserver must - send this token to the user (if applicable), which should then be + send this token to the user (if applicable), who should then be prompted to provide it to the client. If this field is not present, the client can assume that verification From b32f0e768f3a478e01913c997f97b5522b2baad5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2019 08:47:40 -0600 Subject: [PATCH 0504/1250] clarify that UIA can now be done by the HS --- specification/client_server_api.rst | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 2e979cf7..fd63339e 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -762,17 +762,17 @@ the auth code. Homeservers can choose any path for the ``redirect URI``. Once the OAuth flow has completed, the client retries the request with the session only, as above. -Email-based (identity server) -<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +Email-based (identity / homeserver) +<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< :Type: ``m.login.email.identity`` :Description: Authentication is supported by authorising an email address with an identity - server. + server, or homeserver if supported. Prior to submitting this, the client should authenticate with an identity -server. After authenticating, the session information should be submitted to -the homeserver. +server (or homeserver). After authenticating, the session information should +be submitted to the homeserver. To use this authentication type, clients should submit an auth dict as follows: @@ -790,17 +790,17 @@ To use this authentication type, clients should submit an auth dict as follows: "session": "" } -Phone number/MSISDN-based (identity server) -<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +Phone number/MSISDN-based (identity / homeserver) +<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< :Type: ``m.login.msisdn`` :Description: Authentication is supported by authorising a phone number with an identity - server. + server, or homeserver if supported. Prior to submitting this, the client should authenticate with an identity -server. After authenticating, the session information should be submitted to -the homeserver. +server (or homeserver). After authenticating, the session information should +be submitted to the homeserver. To use this authentication type, clients should submit an auth dict as follows: From f7aa2adfb4bd01ffb10cc76d45ef18c44469ffe5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2019 09:16:44 -0600 Subject: [PATCH 0505/1250] Fix indentation --- api/client-server/keys.yaml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/api/client-server/keys.yaml b/api/client-server/keys.yaml index 30056259..0cf074b0 100644 --- a/api/client-server/keys.yaml +++ b/api/client-server/keys.yaml @@ -59,22 +59,22 @@ paths: by the key algorithm. May be absent if no new one-time keys are required. - additionalProperties: - type: - - string - - type: object - title: KeyObject - properties: - key: + additionalProperties: + type: + - string + - type: object + title: KeyObject + properties: + key: + type: string + description: The key, encoded using unpadded base64. + signatures: + type: object + description: |- + Signature for the device. Mapped from user ID to signature object. + additionalProperties: type: string - description: The key, encoded using unpadded base64. - signatures: - type: object - description: |- - Signature for the device. Mapped from user ID to signature object. - additionalProperties: - type: string - required: ['key', 'signatures'] + required: ['key', 'signatures'] example: { "curve25519:AAAAAQ": "/qyvZvwjiTxGdGU0RCguDCLeR+nmsb3FfNG3/Ve4vU8", "signed_curve25519:AAAAHg": { From 85f34f942f4c1980658d147d5002f44fb76885fd Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2019 09:18:29 -0600 Subject: [PATCH 0506/1250] Fix invalid doc error Another annoying case of Swagger fighting us --- api/client-server/keys.yaml | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/api/client-server/keys.yaml b/api/client-server/keys.yaml index 0cf074b0..0ea52e4a 100644 --- a/api/client-server/keys.yaml +++ b/api/client-server/keys.yaml @@ -62,19 +62,23 @@ paths: additionalProperties: type: - string - - type: object - title: KeyObject - properties: - key: - type: string - description: The key, encoded using unpadded base64. - signatures: - type: object - description: |- - Signature for the device. Mapped from user ID to signature object. - additionalProperties: - type: string - required: ['key', 'signatures'] + - object + # XXX: We can't define an actual object here, so we have to hope + # that people will look at the swagger source or can figure it out + # from the other endpoints/example. + # - type: object + # title: KeyObject + # properties: + # key: + # type: string + # description: The key, encoded using unpadded base64. + # signatures: + # type: object + # description: |- + # Signature for the device. Mapped from user ID to signature object. + # additionalProperties: + # type: string + # required: ['key', 'signatures'] example: { "curve25519:AAAAAQ": "/qyvZvwjiTxGdGU0RCguDCLeR+nmsb3FfNG3/Ve4vU8", "signed_curve25519:AAAAHg": { From 56745c76aa24c3d358574540b0f011aff6f0b15f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2019 09:22:02 -0600 Subject: [PATCH 0507/1250] Clarify that submit_url being not present only matters for r0.5 --- api/client-server/administrative_contact.yaml | 4 +++- api/client-server/definitions/request_token_response.yaml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index af7cdcd6..c196c109 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -151,7 +151,9 @@ paths: then be prompted to provide it to the client. If this field is not present, the client can assume that - verification will happen without the client's involvement. + verification will happen without the client's involvement + provided the homeserver advertises this specification version + in the ``/versions`` response (ie: r0.5.0). example: "https://example.org/path/to/submitToken" 403: description: The credentials could not be verified with the identity server. diff --git a/api/client-server/definitions/request_token_response.yaml b/api/client-server/definitions/request_token_response.yaml index bca57227..e47db8a0 100644 --- a/api/client-server/definitions/request_token_response.yaml +++ b/api/client-server/definitions/request_token_response.yaml @@ -30,6 +30,8 @@ properties: prompted to provide it to the client. If this field is not present, the client can assume that verification - will happen without the client's involvement. + will happen without the client's involvement provided the homeserver + advertises this specification version in the ``/versions`` response + (ie: r0.5.0). example: "https://example.org/path/to/submitToken" required: ['sid'] From 8b7887dfc21615386c0b80e14550d0faf2e5505b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2019 09:47:02 -0600 Subject: [PATCH 0508/1250] Link to key algorithms section --- api/client-server/keys.yaml | 5 ++++- api/server-server/user_keys.yaml | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/api/client-server/keys.yaml b/api/client-server/keys.yaml index 0ea52e4a..cce0edca 100644 --- a/api/client-server/keys.yaml +++ b/api/client-server/keys.yaml @@ -56,7 +56,7 @@ paths: One-time public keys for "pre-key" messages. The names of the properties should be in the format ``:``. The format of the key is determined - by the key algorithm. + by the `key algorithm <#key-algorithms>`_. May be absent if no new one-time keys are required. additionalProperties: @@ -299,6 +299,9 @@ paths: description: |- One-time keys for the queried devices. A map from user ID, to a map from devices to a map from ``:`` to the key object. + + See the `key algorithms <#key-algorithms>`_ section for information + on the Key Object format. additionalProperties: type: object additionalProperties: diff --git a/api/server-server/user_keys.yaml b/api/server-server/user_keys.yaml index 613948c3..ea59de2d 100644 --- a/api/server-server/user_keys.yaml +++ b/api/server-server/user_keys.yaml @@ -72,6 +72,9 @@ paths: description: |- One-time keys for the queried devices. A map from user ID, to a map from devices to a map from ``:`` to the key object. + + See the Client-Server Key Algorithms section for more information on + the Key Object format. additionalProperties: type: object additionalProperties: From c9345ba6a32618ded7fbfd992469164f4f239496 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2019 09:53:36 -0600 Subject: [PATCH 0509/1250] Never forget the past --- specification/client_server_api.rst | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index ad58fd1a..948ddc22 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1350,18 +1350,21 @@ State Event Fields In addition to the fields of a Room Event, State Events have the following fields. -+-----------+--------+-------------------------------------------------------------+ -| Key | Type | Description | -+===========+========+=============================================================+ -| state_key | string | **Required.** A unique key which defines the overwriting | -| | | semantics for this piece of room state. This value is often | -| | | a zero-length string. The presence of this key makes this | -| | | event a State Event. State keys starting with an ``@`` are | -| | | reserved for referencing user IDs, such as room members. | -| | | With the exception of a few events, state events set with | -| | | a given user's ID as the state key MUST only be set by that | -| | | user. | -+-----------+--------+-------------------------------------------------------------+ ++--------------+--------------+-------------------------------------------------------------+ +| Key | Type | Description | ++==============+==============+=============================================================+ +| state_key | string | **Required.** A unique key which defines the overwriting | +| | | semantics for this piece of room state. This value is often | +| | | a zero-length string. The presence of this key makes this | +| | | event a State Event. State keys starting with an ``@`` are | +| | | reserved for referencing user IDs, such as room members. | +| | | With the exception of a few events, state events set with | +| | | a given user's ID as the state key MUST only be set by that | +| | | user. | ++--------------+--------------+-------------------------------------------------------------+ +| prev_content | EventContent | Optional. The previous ``content`` for this event. If there | +| | | is no previous content, this key will be missing. | ++--------------+--------------+-------------------------------------------------------------+ Size limits From 4f915f27604c8ce9d3e347d991060a7561dbc4f9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2019 10:15:51 -0600 Subject: [PATCH 0510/1250] Appservice r0.1.1 --- changelogs/application_service.rst | 10 ++++++++++ .../newsfragments/1650.clarification | 1 - .../newsfragments/2037.clarification | 1 - specification/application_service_api.rst | 1 + 4 files changed, 11 insertions(+), 2 deletions(-) delete mode 100644 changelogs/application_service/newsfragments/1650.clarification delete mode 100644 changelogs/application_service/newsfragments/2037.clarification diff --git a/changelogs/application_service.rst b/changelogs/application_service.rst index 9d098837..bbc461b2 100644 --- a/changelogs/application_service.rst +++ b/changelogs/application_service.rst @@ -1,3 +1,13 @@ +r0.1.1 +====== + +Spec Clarifications +------------------- + +- Change examples to use example.org instead of a real domain. (`#1650 `_) +- Add missing definition for how appservices verify requests came from a homeserver. (`#2037 `_) + + r0.1.0 ====== diff --git a/changelogs/application_service/newsfragments/1650.clarification b/changelogs/application_service/newsfragments/1650.clarification deleted file mode 100644 index 617b7ab6..00000000 --- a/changelogs/application_service/newsfragments/1650.clarification +++ /dev/null @@ -1 +0,0 @@ -Change examples to use example.org instead of a real domain. diff --git a/changelogs/application_service/newsfragments/2037.clarification b/changelogs/application_service/newsfragments/2037.clarification deleted file mode 100644 index f425b1c1..00000000 --- a/changelogs/application_service/newsfragments/2037.clarification +++ /dev/null @@ -1 +0,0 @@ -Add missing definition for how appservices verify requests came from a homeserver. diff --git a/specification/application_service_api.rst b/specification/application_service_api.rst index 3220df2d..ee7e9de7 100644 --- a/specification/application_service_api.rst +++ b/specification/application_service_api.rst @@ -52,6 +52,7 @@ Other versions of this specification The following other versions are also available, in reverse chronological order: - `HEAD `_: Includes all changes since the latest versioned release. +- `r0.1.1 `_ - `r0.1.0 `_ From 34ad81e81b60775db732edacbd5af59d95579d24 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2019 10:30:56 -0600 Subject: [PATCH 0511/1250] Identity r0.2.0 --- changelogs/identity_service.rst | 19 +++++++++++++++++++ .../newsfragments/1853.clarification | 1 - .../newsfragments/1967.clarification | 1 - .../identity_service/newsfragments/2046.new | 1 - .../newsfragments/2049.clarification | 1 - .../newsfragments/2057.clarification | 1 - .../newsfragments/2086.clarification | 1 - specification/identity_service_api.rst | 1 + specification/modules/third_party_invites.rst | 2 +- 9 files changed, 21 insertions(+), 7 deletions(-) delete mode 100644 changelogs/identity_service/newsfragments/1853.clarification delete mode 100644 changelogs/identity_service/newsfragments/1967.clarification delete mode 100644 changelogs/identity_service/newsfragments/2046.new delete mode 100644 changelogs/identity_service/newsfragments/2049.clarification delete mode 100644 changelogs/identity_service/newsfragments/2057.clarification delete mode 100644 changelogs/identity_service/newsfragments/2086.clarification diff --git a/changelogs/identity_service.rst b/changelogs/identity_service.rst index 0405d515..d60812b8 100644 --- a/changelogs/identity_service.rst +++ b/changelogs/identity_service.rst @@ -1,3 +1,22 @@ +r0.2.0 +====== + +New Endpoints +------------- + +- Add ``/3pid/unbind`` for removing 3PIDs. (`#2046 `_) + + +Spec Clarifications +------------------- + +- Fix various spelling mistakes throughout the specification. (`#1853 `_) +- Fix route for ``/3pid/bind``. (`#1967 `_) +- Add missing aesthetic parameters to ``/store-invite``. (`#2049 `_) +- Clarify what the client should receive upon sending an identical email validation request multiple times. (`#2057 `_) +- Clarify that the default transport is JSON over HTTP. (`#2086 `_) + + r0.1.0 ====== diff --git a/changelogs/identity_service/newsfragments/1853.clarification b/changelogs/identity_service/newsfragments/1853.clarification deleted file mode 100644 index b0f05203..00000000 --- a/changelogs/identity_service/newsfragments/1853.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling mistakes throughout the specification. diff --git a/changelogs/identity_service/newsfragments/1967.clarification b/changelogs/identity_service/newsfragments/1967.clarification deleted file mode 100644 index b080caeb..00000000 --- a/changelogs/identity_service/newsfragments/1967.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix route for ``/3pid/bind``. diff --git a/changelogs/identity_service/newsfragments/2046.new b/changelogs/identity_service/newsfragments/2046.new deleted file mode 100644 index 7146799b..00000000 --- a/changelogs/identity_service/newsfragments/2046.new +++ /dev/null @@ -1 +0,0 @@ -Add ``/3pid/unbind`` for removing 3PIDs. diff --git a/changelogs/identity_service/newsfragments/2049.clarification b/changelogs/identity_service/newsfragments/2049.clarification deleted file mode 100644 index 403ac8d0..00000000 --- a/changelogs/identity_service/newsfragments/2049.clarification +++ /dev/null @@ -1 +0,0 @@ -Add missing aesthetic parameters to ``/store-invite``. diff --git a/changelogs/identity_service/newsfragments/2057.clarification b/changelogs/identity_service/newsfragments/2057.clarification deleted file mode 100644 index de72c201..00000000 --- a/changelogs/identity_service/newsfragments/2057.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify what the client should receive upon sending an identical email validation request multiple times. diff --git a/changelogs/identity_service/newsfragments/2086.clarification b/changelogs/identity_service/newsfragments/2086.clarification deleted file mode 100644 index 7016308b..00000000 --- a/changelogs/identity_service/newsfragments/2086.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that the default transport is JSON over HTTP. diff --git a/specification/identity_service_api.rst b/specification/identity_service_api.rst index 88c7a8ab..952a239d 100644 --- a/specification/identity_service_api.rst +++ b/specification/identity_service_api.rst @@ -51,6 +51,7 @@ Other versions of this specification The following other versions are also available, in reverse chronological order: - `HEAD `_: Includes all changes since the latest versioned release. +- `r0.2.0 `_ - `r0.1.0 `_ General principles diff --git a/specification/modules/third_party_invites.rst b/specification/modules/third_party_invites.rst index b8ab9657..282b06f4 100644 --- a/specification/modules/third_party_invites.rst +++ b/specification/modules/third_party_invites.rst @@ -255,4 +255,4 @@ these is left to the implementer's discretion. -.. _`identity server /isvalid`: ../identity_service/unstable.html#get-matrix-identity-api-v1-pubkey-isvalid +.. _`identity server /isvalid`: ../identity_service/%IDENTITY_RELEASE_LABEL%.html#get-matrix-identity-api-v1-pubkey-isvalid From 8e6ccf0a0e79eca83e4e968f7b7c9b837df3d4a7 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2019 10:38:12 -0600 Subject: [PATCH 0512/1250] Federation r0.1.2 --- changelogs/server_server.rst | 17 +++++++++++++++++ .../newsfragments/1650.clarification | 1 - .../newsfragments/1906.clarification | 1 - .../newsfragments/1991.clarification | 1 - .../newsfragments/2067.clarification | 1 - .../newsfragments/2080.clarification | 1 - .../newsfragments/2081.clarification | 1 - .../newsfragments/2083.clarification | 1 - .../newsfragments/2095.clarification | 1 - .../newsfragments/2097.clarification | 1 - specification/identity_service_api.rst | 2 +- specification/modules/send_to_device.rst | 2 +- specification/rooms/v1.rst | 4 ++-- specification/rooms/v2.rst | 2 +- specification/rooms/v3.rst | 4 ++-- specification/rooms/v4.rst | 4 ++-- specification/rooms/v5.rst | 4 ++-- specification/server_server_api.rst | 1 + 18 files changed, 29 insertions(+), 20 deletions(-) delete mode 100644 changelogs/server_server/newsfragments/1650.clarification delete mode 100644 changelogs/server_server/newsfragments/1906.clarification delete mode 100644 changelogs/server_server/newsfragments/1991.clarification delete mode 100644 changelogs/server_server/newsfragments/2067.clarification delete mode 100644 changelogs/server_server/newsfragments/2080.clarification delete mode 100644 changelogs/server_server/newsfragments/2081.clarification delete mode 100644 changelogs/server_server/newsfragments/2083.clarification delete mode 100644 changelogs/server_server/newsfragments/2095.clarification delete mode 100644 changelogs/server_server/newsfragments/2097.clarification diff --git a/changelogs/server_server.rst b/changelogs/server_server.rst index a21da177..11f99a5f 100644 --- a/changelogs/server_server.rst +++ b/changelogs/server_server.rst @@ -1,3 +1,20 @@ +r0.1.2 +====== + +Spec Clarifications +------------------- + +- Change examples to use example.org instead of a real domain. (`#1650 `_) +- Fix the ``access_token`` parameter in the open_id endpoint. (`#1906 `_) +- Fix various spelling mistakes throughout the specification. (`#1991 `_) +- Clarify exactly what invite_room_state consists of. (`#2067 `_) +- Clarify how ``valid_until_ts`` behaves with respect to room version. (`#2080 `_) +- Clarify which servers are supposed to sign events. (`#2081 `_) +- Clarify the key object definition for the key management API. (`#2083 `_) +- Clarify how many PDUs are contained in transaction objects for various endpoints. (`#2095 `_) +- Clarify that the trailing slash is optional on ``/keys/*`` endpoints when no key ID is requested. (`#2097 `_) + + r0.1.1 ====== diff --git a/changelogs/server_server/newsfragments/1650.clarification b/changelogs/server_server/newsfragments/1650.clarification deleted file mode 100644 index 617b7ab6..00000000 --- a/changelogs/server_server/newsfragments/1650.clarification +++ /dev/null @@ -1 +0,0 @@ -Change examples to use example.org instead of a real domain. diff --git a/changelogs/server_server/newsfragments/1906.clarification b/changelogs/server_server/newsfragments/1906.clarification deleted file mode 100644 index 531fdb94..00000000 --- a/changelogs/server_server/newsfragments/1906.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix the ``access_token`` parameter in the open_id endpoint. diff --git a/changelogs/server_server/newsfragments/1991.clarification b/changelogs/server_server/newsfragments/1991.clarification deleted file mode 100644 index b0f05203..00000000 --- a/changelogs/server_server/newsfragments/1991.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling mistakes throughout the specification. diff --git a/changelogs/server_server/newsfragments/2067.clarification b/changelogs/server_server/newsfragments/2067.clarification deleted file mode 100644 index cc706274..00000000 --- a/changelogs/server_server/newsfragments/2067.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify exactly what invite_room_state consists of. diff --git a/changelogs/server_server/newsfragments/2080.clarification b/changelogs/server_server/newsfragments/2080.clarification deleted file mode 100644 index c568fa13..00000000 --- a/changelogs/server_server/newsfragments/2080.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify how ``valid_until_ts`` behaves with respect to room version. diff --git a/changelogs/server_server/newsfragments/2081.clarification b/changelogs/server_server/newsfragments/2081.clarification deleted file mode 100644 index fd291273..00000000 --- a/changelogs/server_server/newsfragments/2081.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify which servers are supposed to sign events. diff --git a/changelogs/server_server/newsfragments/2083.clarification b/changelogs/server_server/newsfragments/2083.clarification deleted file mode 100644 index 8083d85d..00000000 --- a/changelogs/server_server/newsfragments/2083.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify the key object definition for the key management API. diff --git a/changelogs/server_server/newsfragments/2095.clarification b/changelogs/server_server/newsfragments/2095.clarification deleted file mode 100644 index 66257e17..00000000 --- a/changelogs/server_server/newsfragments/2095.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify how many PDUs are contained in transaction objects for various endpoints. diff --git a/changelogs/server_server/newsfragments/2097.clarification b/changelogs/server_server/newsfragments/2097.clarification deleted file mode 100644 index 10dcecb6..00000000 --- a/changelogs/server_server/newsfragments/2097.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that the trailing slash is optional on ``/keys/*`` endpoints when no key ID is requested. diff --git a/specification/identity_service_api.rst b/specification/identity_service_api.rst index 88c7a8ab..b0b186a4 100644 --- a/specification/identity_service_api.rst +++ b/specification/identity_service_api.rst @@ -279,4 +279,4 @@ this isn't possible. .. _`Unpadded Base64`: ../appendices.html#unpadded-base64 .. _`3PID Types`: ../appendices.html#pid-types .. _`Signing JSON`: ../appendices.html#signing-json -.. _`/3pid/onbind`: ../server_server/r0.1.1.html#put-matrix-federation-v1-3pid-onbind +.. _`/3pid/onbind`: ../server_server/%SERVER_RELEASE_LABEL%.html#put-matrix-federation-v1-3pid-onbind diff --git a/specification/modules/send_to_device.rst b/specification/modules/send_to_device.rst index cca0338a..7ab622bc 100644 --- a/specification/modules/send_to_device.rst +++ b/specification/modules/send_to_device.rst @@ -63,7 +63,7 @@ If the client sends messages to users on remote domains, those messages should be sent on to the remote servers via `federation`_. -.. _`federation`: ../server_server/latest.html#send-to-device-messaging +.. _`federation`: ../server_server/%SERVER_RELEASE_LABEL%.html#send-to-device-messaging .. TODO-spec: diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index e8cbf663..b5ef217a 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -293,5 +293,5 @@ 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 +.. _`auth events selection`: ../server_server/%SERVER_RELEASE_LABEL%.html#auth-events-selection +.. _`Signing Events`: ../server_server/%SERVER_RELEASE_LABEL%.html#signing-events diff --git a/specification/rooms/v2.rst b/specification/rooms/v2.rst index 247f6909..4e8365bf 100644 --- a/specification/rooms/v2.rst +++ b/specification/rooms/v2.rst @@ -161,7 +161,7 @@ The *resolution* of a set of states is obtained as follows: resolved state. -.. _`authorization rules`: ../server_server/r0.1.1.html#authorization-rules +.. _`authorization rules`: ../server_server/%SERVER_RELEASE_LABEL%.html#authorization-rules Rejected events +++++++++++++++ diff --git a/specification/rooms/v3.rst b/specification/rooms/v3.rst index 733c6984..8ef52acc 100644 --- a/specification/rooms/v3.rst +++ b/specification/rooms/v3.rst @@ -120,5 +120,5 @@ The remaining rules are the same as `room version 1 `_ -or `POST /_matrix/key/v2/query <../server_server/r0.1.1.html#post-matrix-key-v2-query>`_ +`GET /_matrix/key/v2/server <../server_server/%SERVER_RELEASE_LABEL%.html#get-matrix-key-v2-server-keyid>`_ +or `POST /_matrix/key/v2/query <../server_server/%SERVER_RELEASE_LABEL%.html#post-matrix-key-v2-query>`_ APIs. When using the ``/query`` endpoint, servers MUST set the ``minimum_valid_until_ts`` property to prompt the notary server to attempt to refresh the key if appropriate. diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index d608965b..03c624ab 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -80,6 +80,7 @@ Other versions of this specification The following other versions are also available, in reverse chronological order: - `HEAD `_: Includes all changes since the latest versioned release. +- `r0.1.2 `_ - `r0.1.1 `_ - `r0.1.0 `_ From 1ca60bf5d7658316aa0e917770f06ee4771af364 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2019 10:40:48 -0600 Subject: [PATCH 0513/1250] Client-Server r0.5.0 --- changelogs/client_server.rst | 82 +++++++++++++++++++ .../newsfragments/1650.clarification | 1 - .../newsfragments/1656.clarification | 1 - .../client_server/newsfragments/1701.feature | 1 - .../newsfragments/1744.clarification | 1 - .../client_server/newsfragments/1786.feature | 1 - .../client_server/newsfragments/1789.feature | 1 - .../client_server/newsfragments/1790.feature | 1 - .../client_server/newsfragments/1791.feature | 1 - .../newsfragments/1817.deprecation | 1 - .../client_server/newsfragments/1829.feature | 1 - .../newsfragments/1838.clarification | 1 - .../newsfragments/1853.clarification | 1 - .../newsfragments/1860.clarification | 1 - .../client_server/newsfragments/1873.new | 1 - .../client_server/newsfragments/1874.feature | 1 - .../client_server/newsfragments/1875.feature | 1 - .../client_server/newsfragments/1879.feature | 1 - .../newsfragments/1889.clarification | 1 - .../newsfragments/1891.clarification | 1 - .../client_server/newsfragments/1908.feature | 1 - .../newsfragments/1933.clarification | 1 - .../newsfragments/1969.clarification | 1 - .../newsfragments/1975.clarification | 1 - .../newsfragments/1988.clarification | 1 - .../newsfragments/1989.clarification | 1 - .../newsfragments/1991.clarification | 1 - .../newsfragments/1992.clarification | 1 - .../newsfragments/1999.clarification | 1 - .../newsfragments/2016.clarification | 1 - .../client_server/newsfragments/2020.feature | 1 - .../newsfragments/2025.clarification | 1 - .../client_server/newsfragments/2026.feature | 1 - .../newsfragments/2027.clarification | 1 - .../newsfragments/2028.clarification | 1 - .../newsfragments/2029.clarification | 1 - .../client_server/newsfragments/2030.feature | 1 - .../newsfragments/2031.clarification | 1 - .../newsfragments/2032.clarification | 1 - .../client_server/newsfragments/2035.feature | 1 - .../newsfragments/2036.clarification | 1 - .../newsfragments/2041.clarification | 1 - .../newsfragments/2042.clarification | 1 - .../newsfragments/2043.clarification | 1 - .../client_server/newsfragments/2046.feature | 1 - .../newsfragments/2051.clarification | 1 - .../newsfragments/2052.clarification | 1 - .../newsfragments/2053.clarification | 1 - .../newsfragments/2054.clarification | 1 - .../newsfragments/2055.clarification | 1 - .../newsfragments/2056.clarification | 1 - .../client_server/newsfragments/2059.feature | 1 - .../newsfragments/2067.clarification | 1 - .../newsfragments/2068.clarification | 1 - .../newsfragments/2069.clarification | 1 - .../client_server/newsfragments/2072.feature | 1 - .../newsfragments/2083.clarification | 1 - .../newsfragments/2087.clarification | 1 - .../newsfragments/2088.clarification | 1 - .../newsfragments/2089.clarification | 1 - .../newsfragments/2090.clarification | 1 - .../newsfragments/2091.clarification | 1 - .../newsfragments/2097.clarification | 1 - .../newsfragments/2098.clarification | 1 - .../client_server/newsfragments/2101.breaking | 1 - specification/client_server_api.rst | 1 + 66 files changed, 83 insertions(+), 64 deletions(-) delete mode 100644 changelogs/client_server/newsfragments/1650.clarification delete mode 100644 changelogs/client_server/newsfragments/1656.clarification delete mode 100644 changelogs/client_server/newsfragments/1701.feature delete mode 100644 changelogs/client_server/newsfragments/1744.clarification delete mode 100644 changelogs/client_server/newsfragments/1786.feature delete mode 100644 changelogs/client_server/newsfragments/1789.feature delete mode 100644 changelogs/client_server/newsfragments/1790.feature delete mode 100644 changelogs/client_server/newsfragments/1791.feature delete mode 100644 changelogs/client_server/newsfragments/1817.deprecation delete mode 100644 changelogs/client_server/newsfragments/1829.feature delete mode 100644 changelogs/client_server/newsfragments/1838.clarification delete mode 100644 changelogs/client_server/newsfragments/1853.clarification delete mode 100644 changelogs/client_server/newsfragments/1860.clarification delete mode 100644 changelogs/client_server/newsfragments/1873.new delete mode 100644 changelogs/client_server/newsfragments/1874.feature delete mode 100644 changelogs/client_server/newsfragments/1875.feature delete mode 100644 changelogs/client_server/newsfragments/1879.feature delete mode 100644 changelogs/client_server/newsfragments/1889.clarification delete mode 100644 changelogs/client_server/newsfragments/1891.clarification delete mode 100644 changelogs/client_server/newsfragments/1908.feature delete mode 100644 changelogs/client_server/newsfragments/1933.clarification delete mode 100644 changelogs/client_server/newsfragments/1969.clarification delete mode 100644 changelogs/client_server/newsfragments/1975.clarification delete mode 100644 changelogs/client_server/newsfragments/1988.clarification delete mode 100644 changelogs/client_server/newsfragments/1989.clarification delete mode 100644 changelogs/client_server/newsfragments/1991.clarification delete mode 100644 changelogs/client_server/newsfragments/1992.clarification delete mode 100644 changelogs/client_server/newsfragments/1999.clarification delete mode 100644 changelogs/client_server/newsfragments/2016.clarification delete mode 100644 changelogs/client_server/newsfragments/2020.feature delete mode 100644 changelogs/client_server/newsfragments/2025.clarification delete mode 100644 changelogs/client_server/newsfragments/2026.feature delete mode 100644 changelogs/client_server/newsfragments/2027.clarification delete mode 100644 changelogs/client_server/newsfragments/2028.clarification delete mode 100644 changelogs/client_server/newsfragments/2029.clarification delete mode 100644 changelogs/client_server/newsfragments/2030.feature delete mode 100644 changelogs/client_server/newsfragments/2031.clarification delete mode 100644 changelogs/client_server/newsfragments/2032.clarification delete mode 100644 changelogs/client_server/newsfragments/2035.feature delete mode 100644 changelogs/client_server/newsfragments/2036.clarification delete mode 100644 changelogs/client_server/newsfragments/2041.clarification delete mode 100644 changelogs/client_server/newsfragments/2042.clarification delete mode 100644 changelogs/client_server/newsfragments/2043.clarification delete mode 100644 changelogs/client_server/newsfragments/2046.feature delete mode 100644 changelogs/client_server/newsfragments/2051.clarification delete mode 100644 changelogs/client_server/newsfragments/2052.clarification delete mode 100644 changelogs/client_server/newsfragments/2053.clarification delete mode 100644 changelogs/client_server/newsfragments/2054.clarification delete mode 100644 changelogs/client_server/newsfragments/2055.clarification delete mode 100644 changelogs/client_server/newsfragments/2056.clarification delete mode 100644 changelogs/client_server/newsfragments/2059.feature delete mode 100644 changelogs/client_server/newsfragments/2067.clarification delete mode 100644 changelogs/client_server/newsfragments/2068.clarification delete mode 100644 changelogs/client_server/newsfragments/2069.clarification delete mode 100644 changelogs/client_server/newsfragments/2072.feature delete mode 100644 changelogs/client_server/newsfragments/2083.clarification delete mode 100644 changelogs/client_server/newsfragments/2087.clarification delete mode 100644 changelogs/client_server/newsfragments/2088.clarification delete mode 100644 changelogs/client_server/newsfragments/2089.clarification delete mode 100644 changelogs/client_server/newsfragments/2090.clarification delete mode 100644 changelogs/client_server/newsfragments/2091.clarification delete mode 100644 changelogs/client_server/newsfragments/2097.clarification delete mode 100644 changelogs/client_server/newsfragments/2098.clarification delete mode 100644 changelogs/client_server/newsfragments/2101.breaking diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index eb92c29d..c56a1073 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -1,3 +1,85 @@ +r0.5.0 +====== + +Breaking Changes +---------------- + +- Add a new ``submit_url`` field to the responses of ``/requestToken`` which older clients will not be able to handle correctly. (`#2101 `_) + + +Deprecations +------------ + +- Remove references to presence lists. (`#1817 `_) + + +New Endpoints +------------- + +- ``GET /account_data`` routes. (`#1873 `_) + + +Backwards Compatible Changes +---------------------------- + +- Add megolm session export format. (`#1701 `_) +- Add support for advertising experimental features to clients. (`#1786 `_) +- Add a generic SSO login API. (`#1789 `_) +- Add a mechanism for servers to redirect clients to an alternative homeserver after logging in. (`#1790 `_) +- Add room version upgrades. (`#1791 `_, `#1875 `_) +- Support optional features by having clients query for capabilities. (`#1829 `_, `#1879 `_) +- Add ``M_RESOURCE_LIMIT_EXCEEDED`` as an error code for when homeservers exceed limits imposed on them. (`#1874 `_) +- Emit ``M_UNSUPPORTED_ROOM_VERSION`` error codes where applicable on ``/createRoom`` and ``/invite`` APIs. (`#1908 `_) +- Add a ``.m.rule.tombstone`` default push rule for room ugprade notifications. (`#2020 `_) +- Add support for sending server notices to clients. (`#2026 `_) +- Add MSISDN (phone number) support to User-Interactive Authentication. (`#2030 `_) +- Add the option to lazy-load room members for increased client performance. (`#2035 `_) +- Add ``id_server`` to ``/deactivate`` and ``/3pid/delete`` endpoints to unbind from a specific identity server. (`#2046 `_) +- Add support for Olm sessions becoming un-stuck. (`#2059 `_) +- Add interactive device verification, including a common framework for device verification. (`#2072 `_) + + +Spec Clarifications +------------------- + +- Change examples to use example.org instead of a real domain. (`#1650 `_) +- Clarify that ``state_default`` in ``m.room.power_levels`` always defaults to 50. (`#1656 `_) +- Add missing ``status_msg`` to ``m.presence`` schema. (`#1744 `_) +- Fix various spelling mistakes throughout the specification. (`#1838 `_, `#1853 `_, `#1860 `_, `#1933 `_, `#1969 `_, `#1988 `_, `#1989 `_, `#1991 `_, `#1992 `_) +- Add the missing ``m.push_rules`` event schema. (`#1889 `_) +- Clarify how modern day local echo is meant to be solved by clients. (`#1891 `_) +- Clarify that ``width`` and ``height`` are required parameters on ``/_matrix/media/r0/thumbnail/{serverName}/{mediaId}``. (`#1975 `_) +- Clarify how ``m.login.dummy`` can be used to disambiguate login flows. (`#1999 `_) +- Remove ``prev_content`` from the redaction algorithm's essential keys list. (`#2016 `_) +- Fix the ``third_party_signed`` definitions for the join APIs. (`#2025 `_) +- Clarify why User Interactive Auth is used on password changes and how access tokens are handled. (`#2027 `_) +- Clarify that devices are deleted upon logout. (`#2028 `_) +- Add ``M_NOT_FOUND`` error definition for deleting room aliases. (`#2029 `_) +- Add missing ``reason`` to ``m.call.hangup``. (`#2031 `_) +- Clarify how redactions affect room state. (`#2032 `_) +- Clarify that ``FAIL_ERROR`` in autodiscovery is not limited to just homeservers. (`#2036 `_) +- Fix example ``Content-Type`` for ``/media/upload`` request. (`#2041 `_) +- Clarify that login flows are meant to be completed in order. (`#2042 `_) +- Clarify that clients should not send read receipts for their own messages. (`#2043 `_) +- Use consistent examples of events throughout the specification. (`#2051 `_) +- Clarify which push rule condition kinds exist. (`#2052 `_) +- Clarify the required fields on ``m.file`` (and similar) messages. (`#2053 `_) +- Clarify that User-Interactive Authentication stages cannot be attempted more than once. (`#2054 `_) +- Clarify which parameters apply in what scenarios on ``/register``. (`#2055 `_) +- Clarify how to interpret changes of ``membership`` over time. (`#2056 `_) +- Clarify exactly what invite_room_state consists of. (`#2067 `_) +- Clarify how the content repository works, and what it is used for. (`#2068 `_) +- Clarify the order events in chunk are returned in for ``/messages``. (`#2069 `_) +- Clarify the key object definition for the key management API. (`#2083 `_) +- Reorganize information about events into a common section. (`#2087 `_) +- De-duplicate ``/state/`` endpoints, clarifying that the ```` is optional. (`#2088 `_) +- Clarify when and where CORS headers should be returned. (`#2089 `_) +- Clarify when authorization and rate-limiting are not applicable. (`#2090 `_) +- Clarify that ``/register`` must produce valid Matrix User IDs. (`#2091 `_) +- Clarify how ``unread_notifications`` is calculated. (`#2097 `_) +- Clarify what a "module" is and update feature profiles for clients. (`#2098 `_) + + r0.4.0 ====== diff --git a/changelogs/client_server/newsfragments/1650.clarification b/changelogs/client_server/newsfragments/1650.clarification deleted file mode 100644 index 617b7ab6..00000000 --- a/changelogs/client_server/newsfragments/1650.clarification +++ /dev/null @@ -1 +0,0 @@ -Change examples to use example.org instead of a real domain. diff --git a/changelogs/client_server/newsfragments/1656.clarification b/changelogs/client_server/newsfragments/1656.clarification deleted file mode 100644 index 0c8f4ad0..00000000 --- a/changelogs/client_server/newsfragments/1656.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that ``state_default`` in ``m.room.power_levels`` always defaults to 50. diff --git a/changelogs/client_server/newsfragments/1701.feature b/changelogs/client_server/newsfragments/1701.feature deleted file mode 100644 index cf6084ae..00000000 --- a/changelogs/client_server/newsfragments/1701.feature +++ /dev/null @@ -1 +0,0 @@ -Add megolm session export format. diff --git a/changelogs/client_server/newsfragments/1744.clarification b/changelogs/client_server/newsfragments/1744.clarification deleted file mode 100644 index dfe838f1..00000000 --- a/changelogs/client_server/newsfragments/1744.clarification +++ /dev/null @@ -1 +0,0 @@ -Add missing ``status_msg`` to ``m.presence`` schema. diff --git a/changelogs/client_server/newsfragments/1786.feature b/changelogs/client_server/newsfragments/1786.feature deleted file mode 100644 index 6f21778c..00000000 --- a/changelogs/client_server/newsfragments/1786.feature +++ /dev/null @@ -1 +0,0 @@ -Add support for advertising experimental features to clients. diff --git a/changelogs/client_server/newsfragments/1789.feature b/changelogs/client_server/newsfragments/1789.feature deleted file mode 100644 index 97c1e5ca..00000000 --- a/changelogs/client_server/newsfragments/1789.feature +++ /dev/null @@ -1 +0,0 @@ -Add a generic SSO login API. diff --git a/changelogs/client_server/newsfragments/1790.feature b/changelogs/client_server/newsfragments/1790.feature deleted file mode 100644 index 26dccd05..00000000 --- a/changelogs/client_server/newsfragments/1790.feature +++ /dev/null @@ -1 +0,0 @@ -Add a mechanism for servers to redirect clients to an alternative homeserver after logging in. diff --git a/changelogs/client_server/newsfragments/1791.feature b/changelogs/client_server/newsfragments/1791.feature deleted file mode 100644 index 0a854c8f..00000000 --- a/changelogs/client_server/newsfragments/1791.feature +++ /dev/null @@ -1 +0,0 @@ -Add room version upgrades. diff --git a/changelogs/client_server/newsfragments/1817.deprecation b/changelogs/client_server/newsfragments/1817.deprecation deleted file mode 100644 index 2c52d198..00000000 --- a/changelogs/client_server/newsfragments/1817.deprecation +++ /dev/null @@ -1 +0,0 @@ -Remove references to presence lists. diff --git a/changelogs/client_server/newsfragments/1829.feature b/changelogs/client_server/newsfragments/1829.feature deleted file mode 100644 index 107291f3..00000000 --- a/changelogs/client_server/newsfragments/1829.feature +++ /dev/null @@ -1 +0,0 @@ -Support optional features by having clients query for capabilities. diff --git a/changelogs/client_server/newsfragments/1838.clarification b/changelogs/client_server/newsfragments/1838.clarification deleted file mode 100644 index b0f05203..00000000 --- a/changelogs/client_server/newsfragments/1838.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling mistakes throughout the specification. diff --git a/changelogs/client_server/newsfragments/1853.clarification b/changelogs/client_server/newsfragments/1853.clarification deleted file mode 100644 index b0f05203..00000000 --- a/changelogs/client_server/newsfragments/1853.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling mistakes throughout the specification. diff --git a/changelogs/client_server/newsfragments/1860.clarification b/changelogs/client_server/newsfragments/1860.clarification deleted file mode 100644 index b0f05203..00000000 --- a/changelogs/client_server/newsfragments/1860.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling mistakes throughout the specification. diff --git a/changelogs/client_server/newsfragments/1873.new b/changelogs/client_server/newsfragments/1873.new deleted file mode 100644 index 724a4308..00000000 --- a/changelogs/client_server/newsfragments/1873.new +++ /dev/null @@ -1 +0,0 @@ -``GET /account_data`` routes. diff --git a/changelogs/client_server/newsfragments/1874.feature b/changelogs/client_server/newsfragments/1874.feature deleted file mode 100644 index bdab5464..00000000 --- a/changelogs/client_server/newsfragments/1874.feature +++ /dev/null @@ -1 +0,0 @@ -Add ``M_RESOURCE_LIMIT_EXCEEDED`` as an error code for when homeservers exceed limits imposed on them. diff --git a/changelogs/client_server/newsfragments/1875.feature b/changelogs/client_server/newsfragments/1875.feature deleted file mode 100644 index 0a854c8f..00000000 --- a/changelogs/client_server/newsfragments/1875.feature +++ /dev/null @@ -1 +0,0 @@ -Add room version upgrades. diff --git a/changelogs/client_server/newsfragments/1879.feature b/changelogs/client_server/newsfragments/1879.feature deleted file mode 100644 index 107291f3..00000000 --- a/changelogs/client_server/newsfragments/1879.feature +++ /dev/null @@ -1 +0,0 @@ -Support optional features by having clients query for capabilities. diff --git a/changelogs/client_server/newsfragments/1889.clarification b/changelogs/client_server/newsfragments/1889.clarification deleted file mode 100644 index 2737a7ee..00000000 --- a/changelogs/client_server/newsfragments/1889.clarification +++ /dev/null @@ -1 +0,0 @@ -Add the missing ``m.push_rules`` event schema. diff --git a/changelogs/client_server/newsfragments/1891.clarification b/changelogs/client_server/newsfragments/1891.clarification deleted file mode 100644 index ef4edfb4..00000000 --- a/changelogs/client_server/newsfragments/1891.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify how modern day local echo is meant to be solved by clients. diff --git a/changelogs/client_server/newsfragments/1908.feature b/changelogs/client_server/newsfragments/1908.feature deleted file mode 100644 index 1c64d826..00000000 --- a/changelogs/client_server/newsfragments/1908.feature +++ /dev/null @@ -1 +0,0 @@ -Emit ``M_UNSUPPORTED_ROOM_VERSION`` error codes where applicable on ``/createRoom`` and ``/invite`` APIs. diff --git a/changelogs/client_server/newsfragments/1933.clarification b/changelogs/client_server/newsfragments/1933.clarification deleted file mode 100644 index b0f05203..00000000 --- a/changelogs/client_server/newsfragments/1933.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling mistakes throughout the specification. diff --git a/changelogs/client_server/newsfragments/1969.clarification b/changelogs/client_server/newsfragments/1969.clarification deleted file mode 100644 index b0f05203..00000000 --- a/changelogs/client_server/newsfragments/1969.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling mistakes throughout the specification. diff --git a/changelogs/client_server/newsfragments/1975.clarification b/changelogs/client_server/newsfragments/1975.clarification deleted file mode 100644 index ac118bfd..00000000 --- a/changelogs/client_server/newsfragments/1975.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that ``width`` and ``height`` are required parameters on ``/_matrix/media/r0/thumbnail/{serverName}/{mediaId}``. diff --git a/changelogs/client_server/newsfragments/1988.clarification b/changelogs/client_server/newsfragments/1988.clarification deleted file mode 100644 index b0f05203..00000000 --- a/changelogs/client_server/newsfragments/1988.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling mistakes throughout the specification. diff --git a/changelogs/client_server/newsfragments/1989.clarification b/changelogs/client_server/newsfragments/1989.clarification deleted file mode 100644 index b0f05203..00000000 --- a/changelogs/client_server/newsfragments/1989.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling mistakes throughout the specification. diff --git a/changelogs/client_server/newsfragments/1991.clarification b/changelogs/client_server/newsfragments/1991.clarification deleted file mode 100644 index b0f05203..00000000 --- a/changelogs/client_server/newsfragments/1991.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling mistakes throughout the specification. diff --git a/changelogs/client_server/newsfragments/1992.clarification b/changelogs/client_server/newsfragments/1992.clarification deleted file mode 100644 index b0f05203..00000000 --- a/changelogs/client_server/newsfragments/1992.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling mistakes throughout the specification. diff --git a/changelogs/client_server/newsfragments/1999.clarification b/changelogs/client_server/newsfragments/1999.clarification deleted file mode 100644 index 748c55f2..00000000 --- a/changelogs/client_server/newsfragments/1999.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify how ``m.login.dummy`` can be used to disambiguate login flows. diff --git a/changelogs/client_server/newsfragments/2016.clarification b/changelogs/client_server/newsfragments/2016.clarification deleted file mode 100644 index 77ea0d4c..00000000 --- a/changelogs/client_server/newsfragments/2016.clarification +++ /dev/null @@ -1 +0,0 @@ -Remove ``prev_content`` from the redaction algorithm's essential keys list. diff --git a/changelogs/client_server/newsfragments/2020.feature b/changelogs/client_server/newsfragments/2020.feature deleted file mode 100644 index 0d7c7eb8..00000000 --- a/changelogs/client_server/newsfragments/2020.feature +++ /dev/null @@ -1 +0,0 @@ -Add a ``.m.rule.tombstone`` default push rule for room ugprade notifications. diff --git a/changelogs/client_server/newsfragments/2025.clarification b/changelogs/client_server/newsfragments/2025.clarification deleted file mode 100644 index 9e99b23d..00000000 --- a/changelogs/client_server/newsfragments/2025.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix the ``third_party_signed`` definitions for the join APIs. diff --git a/changelogs/client_server/newsfragments/2026.feature b/changelogs/client_server/newsfragments/2026.feature deleted file mode 100644 index f82b9aea..00000000 --- a/changelogs/client_server/newsfragments/2026.feature +++ /dev/null @@ -1 +0,0 @@ -Add support for sending server notices to clients. diff --git a/changelogs/client_server/newsfragments/2027.clarification b/changelogs/client_server/newsfragments/2027.clarification deleted file mode 100644 index db74ea56..00000000 --- a/changelogs/client_server/newsfragments/2027.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify why User Interactive Auth is used on password changes and how access tokens are handled. diff --git a/changelogs/client_server/newsfragments/2028.clarification b/changelogs/client_server/newsfragments/2028.clarification deleted file mode 100644 index 75e21e74..00000000 --- a/changelogs/client_server/newsfragments/2028.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that devices are deleted upon logout. diff --git a/changelogs/client_server/newsfragments/2029.clarification b/changelogs/client_server/newsfragments/2029.clarification deleted file mode 100644 index 95b65481..00000000 --- a/changelogs/client_server/newsfragments/2029.clarification +++ /dev/null @@ -1 +0,0 @@ -Add ``M_NOT_FOUND`` error definition for deleting room aliases. diff --git a/changelogs/client_server/newsfragments/2030.feature b/changelogs/client_server/newsfragments/2030.feature deleted file mode 100644 index b5975a73..00000000 --- a/changelogs/client_server/newsfragments/2030.feature +++ /dev/null @@ -1 +0,0 @@ -Add MSISDN (phone number) support to User-Interactive Authentication. diff --git a/changelogs/client_server/newsfragments/2031.clarification b/changelogs/client_server/newsfragments/2031.clarification deleted file mode 100644 index 9bed3bcc..00000000 --- a/changelogs/client_server/newsfragments/2031.clarification +++ /dev/null @@ -1 +0,0 @@ -Add missing ``reason`` to ``m.call.hangup``. diff --git a/changelogs/client_server/newsfragments/2032.clarification b/changelogs/client_server/newsfragments/2032.clarification deleted file mode 100644 index e497b8be..00000000 --- a/changelogs/client_server/newsfragments/2032.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify how redactions affect room state. diff --git a/changelogs/client_server/newsfragments/2035.feature b/changelogs/client_server/newsfragments/2035.feature deleted file mode 100644 index 47029c28..00000000 --- a/changelogs/client_server/newsfragments/2035.feature +++ /dev/null @@ -1 +0,0 @@ -Add the option to lazy-load room members for increased client performance. diff --git a/changelogs/client_server/newsfragments/2036.clarification b/changelogs/client_server/newsfragments/2036.clarification deleted file mode 100644 index 96058b7b..00000000 --- a/changelogs/client_server/newsfragments/2036.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that ``FAIL_ERROR`` in autodiscovery is not limited to just homeservers. diff --git a/changelogs/client_server/newsfragments/2041.clarification b/changelogs/client_server/newsfragments/2041.clarification deleted file mode 100644 index 39bbddb5..00000000 --- a/changelogs/client_server/newsfragments/2041.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix example ``Content-Type`` for ``/media/upload`` request. diff --git a/changelogs/client_server/newsfragments/2042.clarification b/changelogs/client_server/newsfragments/2042.clarification deleted file mode 100644 index 4e17b99f..00000000 --- a/changelogs/client_server/newsfragments/2042.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that login flows are meant to be completed in order. diff --git a/changelogs/client_server/newsfragments/2043.clarification b/changelogs/client_server/newsfragments/2043.clarification deleted file mode 100644 index 9bb975fa..00000000 --- a/changelogs/client_server/newsfragments/2043.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that clients should not send read receipts for their own messages. diff --git a/changelogs/client_server/newsfragments/2046.feature b/changelogs/client_server/newsfragments/2046.feature deleted file mode 100644 index e54df535..00000000 --- a/changelogs/client_server/newsfragments/2046.feature +++ /dev/null @@ -1 +0,0 @@ -Add ``id_server`` to ``/deactivate`` and ``/3pid/delete`` endpoints to unbind from a specific identity server. diff --git a/changelogs/client_server/newsfragments/2051.clarification b/changelogs/client_server/newsfragments/2051.clarification deleted file mode 100644 index 384daa11..00000000 --- a/changelogs/client_server/newsfragments/2051.clarification +++ /dev/null @@ -1 +0,0 @@ -Use consistent examples of events throughout the specification. diff --git a/changelogs/client_server/newsfragments/2052.clarification b/changelogs/client_server/newsfragments/2052.clarification deleted file mode 100644 index 95bdc928..00000000 --- a/changelogs/client_server/newsfragments/2052.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify which push rule condition kinds exist. diff --git a/changelogs/client_server/newsfragments/2053.clarification b/changelogs/client_server/newsfragments/2053.clarification deleted file mode 100644 index 2a72a88e..00000000 --- a/changelogs/client_server/newsfragments/2053.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify the required fields on ``m.file`` (and similar) messages. diff --git a/changelogs/client_server/newsfragments/2054.clarification b/changelogs/client_server/newsfragments/2054.clarification deleted file mode 100644 index e43aea2d..00000000 --- a/changelogs/client_server/newsfragments/2054.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that User-Interactive Authentication stages cannot be attempted more than once. diff --git a/changelogs/client_server/newsfragments/2055.clarification b/changelogs/client_server/newsfragments/2055.clarification deleted file mode 100644 index 3a57ef7e..00000000 --- a/changelogs/client_server/newsfragments/2055.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify which parameters apply in what scenarios on ``/register``. diff --git a/changelogs/client_server/newsfragments/2056.clarification b/changelogs/client_server/newsfragments/2056.clarification deleted file mode 100644 index 12521867..00000000 --- a/changelogs/client_server/newsfragments/2056.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify how to interpret changes of ``membership`` over time. diff --git a/changelogs/client_server/newsfragments/2059.feature b/changelogs/client_server/newsfragments/2059.feature deleted file mode 100644 index fde106ce..00000000 --- a/changelogs/client_server/newsfragments/2059.feature +++ /dev/null @@ -1 +0,0 @@ -Add support for Olm sessions becoming un-stuck. diff --git a/changelogs/client_server/newsfragments/2067.clarification b/changelogs/client_server/newsfragments/2067.clarification deleted file mode 100644 index cc706274..00000000 --- a/changelogs/client_server/newsfragments/2067.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify exactly what invite_room_state consists of. diff --git a/changelogs/client_server/newsfragments/2068.clarification b/changelogs/client_server/newsfragments/2068.clarification deleted file mode 100644 index 77ad7125..00000000 --- a/changelogs/client_server/newsfragments/2068.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify how the content repository works, and what it is used for. diff --git a/changelogs/client_server/newsfragments/2069.clarification b/changelogs/client_server/newsfragments/2069.clarification deleted file mode 100644 index 127573a6..00000000 --- a/changelogs/client_server/newsfragments/2069.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify the order events in chunk are returned in for ``/messages``. diff --git a/changelogs/client_server/newsfragments/2072.feature b/changelogs/client_server/newsfragments/2072.feature deleted file mode 100644 index c7d8bd76..00000000 --- a/changelogs/client_server/newsfragments/2072.feature +++ /dev/null @@ -1 +0,0 @@ -Add interactive device verification, including a common framework for device verification. diff --git a/changelogs/client_server/newsfragments/2083.clarification b/changelogs/client_server/newsfragments/2083.clarification deleted file mode 100644 index 8083d85d..00000000 --- a/changelogs/client_server/newsfragments/2083.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify the key object definition for the key management API. diff --git a/changelogs/client_server/newsfragments/2087.clarification b/changelogs/client_server/newsfragments/2087.clarification deleted file mode 100644 index 1974127d..00000000 --- a/changelogs/client_server/newsfragments/2087.clarification +++ /dev/null @@ -1 +0,0 @@ -Reorganize information about events into a common section. diff --git a/changelogs/client_server/newsfragments/2088.clarification b/changelogs/client_server/newsfragments/2088.clarification deleted file mode 100644 index ae22d66a..00000000 --- a/changelogs/client_server/newsfragments/2088.clarification +++ /dev/null @@ -1 +0,0 @@ -De-duplicate ``/state/`` endpoints, clarifying that the ```` is optional. diff --git a/changelogs/client_server/newsfragments/2089.clarification b/changelogs/client_server/newsfragments/2089.clarification deleted file mode 100644 index 17405adc..00000000 --- a/changelogs/client_server/newsfragments/2089.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify when and where CORS headers should be returned. diff --git a/changelogs/client_server/newsfragments/2090.clarification b/changelogs/client_server/newsfragments/2090.clarification deleted file mode 100644 index 23ab50f7..00000000 --- a/changelogs/client_server/newsfragments/2090.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify when authorization and rate-limiting are not applicable. diff --git a/changelogs/client_server/newsfragments/2091.clarification b/changelogs/client_server/newsfragments/2091.clarification deleted file mode 100644 index 2c4a276e..00000000 --- a/changelogs/client_server/newsfragments/2091.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that ``/register`` must produce valid Matrix User IDs. diff --git a/changelogs/client_server/newsfragments/2097.clarification b/changelogs/client_server/newsfragments/2097.clarification deleted file mode 100644 index 68d89bcc..00000000 --- a/changelogs/client_server/newsfragments/2097.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify how ``unread_notifications`` is calculated. diff --git a/changelogs/client_server/newsfragments/2098.clarification b/changelogs/client_server/newsfragments/2098.clarification deleted file mode 100644 index 1c8ba3ea..00000000 --- a/changelogs/client_server/newsfragments/2098.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify what a "module" is and update feature profiles for clients. diff --git a/changelogs/client_server/newsfragments/2101.breaking b/changelogs/client_server/newsfragments/2101.breaking deleted file mode 100644 index 68971171..00000000 --- a/changelogs/client_server/newsfragments/2101.breaking +++ /dev/null @@ -1 +0,0 @@ -Add a new ``submit_url`` field to the responses of ``/requestToken`` which older clients will not be able to handle correctly. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index bc2d66d7..dd6e3246 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -45,6 +45,7 @@ Other versions of this specification The following other versions are also available, in reverse chronological order: - `HEAD `_: Includes all changes since the latest versioned release. +- `r0.5.0 `_ - `r0.4.0 `_ - `r0.3.0 `_ - `r0.2.0 `_ From 8f1f8b4fe5bf5b21ca943678c54d30b1ffbf3025 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2019 11:28:35 -0600 Subject: [PATCH 0514/1250] Fix references to filtering We can't have two different backlinks for the same text, so use LL as the label --- api/client-server/event_context.yaml | 4 ++-- api/client-server/message_pagination.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/client-server/event_context.yaml b/api/client-server/event_context.yaml index 802f5f27..3bea351c 100644 --- a/api/client-server/event_context.yaml +++ b/api/client-server/event_context.yaml @@ -35,8 +35,8 @@ paths: after the specified event. This allows clients to get the context surrounding an event. - *Note*: This endpoint supports lazy-loading of room member events. See `Filtering <#lazy-loading-room-members>`_ - for more information. + *Note*: This endpoint supports lazy-loading of room member events. See + `Lazy-loading room members <#lazy-loading-room-members>`_ for more information. operationId: getEventContext security: - accessToken: [] diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index dc33b717..22828219 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -34,8 +34,8 @@ paths: This API returns a list of message and state events for a room. It uses pagination query parameters to paginate history in the room. - *Note*: This endpoint supports lazy-loading of room member events. See `Filtering <#lazy-loading-room-members>`_ - for more information. + *Note*: This endpoint supports lazy-loading of room member events. See + `Lazy-loading room members <#lazy-loading-room-members>`_ for more information. operationId: getRoomEvents security: - accessToken: [] From ba5479e46f1cd0aecdec54d200233a8d4f771882 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2019 11:30:04 -0600 Subject: [PATCH 0515/1250] Reference Canonical JSON --- specification/client_server_api.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index dd6e3246..9b16abc3 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1491,6 +1491,8 @@ Some event types have additional size restrictions which are specified in the description of the event. Additional keys have no limit other than that implied by the total 65 KB limit on events. +.. _`Canonical JSON`: ../appendices.html#canonical-json + Room Events ~~~~~~~~~~~ .. NOTE:: From 19a3d574b7e9b961b9df5ceeaa5e13e7f34a077a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2019 11:31:24 -0600 Subject: [PATCH 0516/1250] Fix HKDF rationale --- specification/modules/end_to_end_encryption.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 62881967..36336c74 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -671,6 +671,7 @@ parameter is the concatenation of: * The ``transaction_id`` being used. .. admonition:: Rationale + HKDF is used over the plain shared secret as it results in a harder attack as well as more uniform data to work with. From 26349417ba01d5a28fc35faa9f66038a294c316a Mon Sep 17 00:00:00 2001 From: Sorunome Date: Tue, 11 Jun 2019 21:13:16 +0200 Subject: [PATCH 0517/1250] update spoiler render idea --- proposals/2010-spoilers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2010-spoilers.md b/proposals/2010-spoilers.md index 366f4a3e..40feed29 100644 --- a/proposals/2010-spoilers.md +++ b/proposals/2010-spoilers.md @@ -20,7 +20,7 @@ It adds a new attribute, `data-mx-spoiler`, to the `` tag. If the attribut contents of the span tag should be rendered as a spoiler. Optionally, you can specify a reason for the spoiler by setting the attribute string. It could be rendered, for example, similar to this: -![Spoiler rendering idea](https://user-images.githubusercontent.com/2433620/58178745-082c1480-7ca7-11e9-901b-13b147cfd157.png) +![Spoiler rendering idea](https://user-images.githubusercontent.com/2433620/59299700-95063480-8c8d-11e9-9348-3e2c8bc94bdc.gif) The plain-text fallback could be rendered as `(Spoiler: )` and `(Spoiler for : )` respectively. From e60d2defbd608476a4ae15816bf51e813c0e6713 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 12 Jun 2019 13:47:09 -0600 Subject: [PATCH 0518/1250] Fix changelog generation Only include the target version, not all versions. Additionally, make sure the appservice spec isn't hardcoded as "unstable". --- scripts/templating/matrix_templates/units.py | 4 ++++ specification/application_service_api.rst | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index eeda9e63..157fa5a1 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -962,6 +962,9 @@ class MatrixUnits(Units): if re.match("^[=]{3,}$", line.strip()): # the last line was a header - use that as our new title_part title_part = prev_line.strip() + # take off the last line from the changelog_body_lines because it's the title + if len(changelog_body_lines) > 0: + changelog_body_lines = changelog_body_lines[:len(changelog_body_lines) - 1] continue if re.match("^[-]{3,}$", line.strip()): # the last line is a subheading - drop this line because it's the underline @@ -975,6 +978,7 @@ class MatrixUnits(Units): # that it renders correctly in the section. We also add newlines so that there's # intentionally blank lines that make rst2html happy. changelog_body_lines.append(" " + line + '\n') + prev_line = line if len(changelog_body_lines) > 0: changelogs[api_name] = "".join(changelog_body_lines) diff --git a/specification/application_service_api.rst b/specification/application_service_api.rst index ee7e9de7..11a07839 100644 --- a/specification/application_service_api.rst +++ b/specification/application_service_api.rst @@ -36,7 +36,7 @@ Changelog --------- -.. topic:: Version: unstable +.. topic:: Version: %APPSERVICE_RELEASE_LABEL% {{application_service_changelog}} This version of the specification is generated from From 18eca900220031bc92de970ce68662d5c3e9a89a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 12 Jun 2019 13:48:50 -0600 Subject: [PATCH 0519/1250] Exclude DEL from historical user IDs The range is inclusive, so don't include 7F --- specification/appendices/identifier_grammar.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/appendices/identifier_grammar.rst b/specification/appendices/identifier_grammar.rst index c2c734ab..4cce1f90 100644 --- a/specification/appendices/identifier_grammar.rst +++ b/specification/appendices/identifier_grammar.rst @@ -190,7 +190,7 @@ history includes events with a ``sender`` which does not conform. In order to handle these rooms successfully, clients and servers MUST accept user IDs with localparts from the expanded character set:: - extended_user_id_char = %x21-39 / %x3B-7F ; all ascii printing chars except : + extended_user_id_char = %x21-39 / %x3B-7E ; all ascii printing chars except : Mapping from other character sets <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< From b8f1f3792744878b26f17b413c3c7936428a7f05 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 12 Jun 2019 15:29:25 -0600 Subject: [PATCH 0520/1250] Remove incorrect id_server param from IS spec Fixes https://github.com/matrix-org/matrix-doc/issues/2118 --- api/client-server/administrative_contact.yaml | 4 +-- .../definitions/request_email_validation.yaml | 26 +++++++++++++++++++ .../request_msisdn_validation.yaml | 26 +++++++++++++++++++ api/client-server/registration.yaml | 14 +++++----- .../definitions/request_email_validation.yaml | 9 +------ .../request_msisdn_validation.yaml | 9 +------ .../newsfragments/2124.clarification | 1 + 7 files changed, 64 insertions(+), 25 deletions(-) create mode 100644 api/client-server/definitions/request_email_validation.yaml create mode 100644 api/client-server/definitions/request_msisdn_validation.yaml create mode 100644 changelogs/identity_service/newsfragments/2124.clarification diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index c196c109..0e93e4cd 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -246,7 +246,7 @@ paths: name: body required: true schema: - $ref: "../identity/definitions/request_email_validation.yaml" + $ref: "./definitions/request_email_validation.yaml" responses: 200: description: |- @@ -297,7 +297,7 @@ paths: name: body required: true schema: - $ref: "../identity/definitions/request_msisdn_validation.yaml" + $ref: "./definitions/request_msisdn_validation.yaml" responses: 200: description: An SMS message was sent to the given phone number. diff --git a/api/client-server/definitions/request_email_validation.yaml b/api/client-server/definitions/request_email_validation.yaml new file mode 100644 index 00000000..15bc5b3a --- /dev/null +++ b/api/client-server/definitions/request_email_validation.yaml @@ -0,0 +1,26 @@ +# Copyright 2019 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 +allOf: +- $ref: "../../identity/definitions/request_email_validation.yaml" +- type: object + properties: + id_server: + type: string + description: |- + The hostname of the identity server to communicate with. May optionally + include a port. This parameter is ignored when the homeserver handles + 3PID verification. + example: "id.example.com" + required: ["id_server"] diff --git a/api/client-server/definitions/request_msisdn_validation.yaml b/api/client-server/definitions/request_msisdn_validation.yaml new file mode 100644 index 00000000..370a10cc --- /dev/null +++ b/api/client-server/definitions/request_msisdn_validation.yaml @@ -0,0 +1,26 @@ +# Copyright 2019 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 +allOf: +- $ref: "../../identity/definitions/request_msisdn_validation.yaml" +- type: object + properties: + id_server: + type: string + description: |- + The hostname of the identity server to communicate with. May optionally + include a port. This parameter is ignored when the homeserver handles + 3PID verification. + example: "id.example.com" + required: ["id_server"] diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index d04e1a33..71177d0c 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -242,7 +242,7 @@ paths: name: body required: true schema: - $ref: "../identity/definitions/request_email_validation.yaml" + $ref: "./definitions/request_email_validation.yaml" responses: 200: description: |- @@ -295,7 +295,7 @@ paths: name: body required: true schema: - $ref: "../identity/definitions/request_msisdn_validation.yaml" + $ref: "./definitions/request_msisdn_validation.yaml" responses: 200: description: |- @@ -392,14 +392,14 @@ paths: associated** with an account on this homeserver. This API should be used to request validation tokens when authenticating for the ``/account/password`` endpoint. - + This API's parameters and response are identical to that of the |/register/email/requestToken|_ endpoint, except that ``M_THREEPID_NOT_FOUND`` may be returned if no account matching the given email address could be found. The server may instead send an email to the given address prompting the user to create an account. ``M_THREEPID_IN_USE`` may not be returned. - + The homeserver has the choice of validating the email address itself, or proxying the request to the ``/validate/email/requestToken`` Identity Service API. The request should be proxied to the domain that @@ -417,7 +417,7 @@ paths: name: body required: true schema: - $ref: "../identity/definitions/request_email_validation.yaml" + $ref: "./definitions/request_email_validation.yaml" responses: 200: description: An email was sent to the given address. @@ -453,14 +453,14 @@ paths: associated** with an account on this homeserver. This API should be used to request validation tokens when authenticating for the ``/account/password`` endpoint. - + This API's parameters and response are identical to that of the |/register/msisdn/requestToken|_ endpoint, except that ``M_THREEPID_NOT_FOUND`` may be returned if no account matching the given phone number could be found. The server may instead send the SMS to the given phone number prompting the user to create an account. ``M_THREEPID_IN_USE`` may not be returned. - + The homeserver has the choice of validating the phone number itself, or proxying the request to the ``/validate/msisdn/requestToken`` Identity Service API. The request should be proxied to the domain that is sent diff --git a/api/identity/definitions/request_email_validation.yaml b/api/identity/definitions/request_email_validation.yaml index b99fe121..1a7502c7 100644 --- a/api/identity/definitions/request_email_validation.yaml +++ b/api/identity/definitions/request_email_validation.yaml @@ -49,11 +49,4 @@ properties: redirect the user to this URL. This option is ignored when submitting 3PID validation information through a POST request. example: "https://example.org/congratulations.html" - id_server: - type: string - description: |- - The hostname of the identity server to communicate with. May optionally - include a port. This parameter is ignored when the homeserver handles - 3PID verification. - example: "id.example.com" -required: ["client_secret", "email", "send_attempt", "id_server"] +required: ["client_secret", "email", "send_attempt"] diff --git a/api/identity/definitions/request_msisdn_validation.yaml b/api/identity/definitions/request_msisdn_validation.yaml index 08dd0482..018bd733 100644 --- a/api/identity/definitions/request_msisdn_validation.yaml +++ b/api/identity/definitions/request_msisdn_validation.yaml @@ -55,11 +55,4 @@ properties: redirect the user to this URL. This option is ignored when submitting 3PID validation information through a POST request. example: "https://example.org/congratulations.html" - id_server: - type: string - description: |- - The hostname of the identity server to communicate with. May optionally - include a port. This parameter is ignored when the homeserver handles - 3PID verification. - example: "id.example.com" -required: ["client_secret", "country", "phone_number", "send_attempt", "id_server"] +required: ["client_secret", "country", "phone_number", "send_attempt"] diff --git a/changelogs/identity_service/newsfragments/2124.clarification b/changelogs/identity_service/newsfragments/2124.clarification new file mode 100644 index 00000000..384af82f --- /dev/null +++ b/changelogs/identity_service/newsfragments/2124.clarification @@ -0,0 +1 @@ +Remove incorrect ``id_server`` parameter from ``/requestToken`` endpoints. From 67ea3b9ce8321499a81961cdc1faddbf2cbacb2a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 12 Jun 2019 15:41:10 -0600 Subject: [PATCH 0521/1250] Add 403 error to IS unbind Fixes https://github.com/matrix-org/matrix-doc/issues/2117 --- api/identity/associations.yaml | 13 +++++++++++++ .../newsfragments/2126.clarification | 1 + 2 files changed, 14 insertions(+) create mode 100644 changelogs/identity_service/newsfragments/2126.clarification diff --git a/api/identity/associations.yaml b/api/identity/associations.yaml index f44fe3cc..8ff4a9ed 100644 --- a/api/identity/associations.yaml +++ b/api/identity/associations.yaml @@ -279,6 +279,19 @@ paths: If the response body is not a JSON Matrix error, the identity server does not support unbinds. If a JSON Matrix error is in the response body, the requesting party should respect the error. + 403: + description: |- + The credentials supplied to authenticate the request were invalid. + This may also be returned if the identity server does not support + the chosen authentication method (such as blocking homeservers from + unbinding identifiers). + examples: + application/json: { + "errcode": "M_FORBIDDEN", + "error": "Invalid homeserver signature" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" 501: description: |- If the response body is not a JSON Matrix error, the identity server diff --git a/changelogs/identity_service/newsfragments/2126.clarification b/changelogs/identity_service/newsfragments/2126.clarification new file mode 100644 index 00000000..1475b4b4 --- /dev/null +++ b/changelogs/identity_service/newsfragments/2126.clarification @@ -0,0 +1 @@ +Clarify that identity servers can return 403 for unbind requests. From e670fb1f5a67daefdf4d4351ff33dd21bb945981 Mon Sep 17 00:00:00 2001 From: Jimmy Cuadra Date: Wed, 12 Jun 2019 14:32:33 -0700 Subject: [PATCH 0522/1250] Add missing format fields to m.room.message$m.notice schema. Signed-off-by: Jimmy Cuadra --- .../client_server/newsfragments/2125.clarification | 1 + event-schemas/schema/m.room.message$m.notice | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 changelogs/client_server/newsfragments/2125.clarification diff --git a/changelogs/client_server/newsfragments/2125.clarification b/changelogs/client_server/newsfragments/2125.clarification new file mode 100644 index 00000000..c71cdfff --- /dev/null +++ b/changelogs/client_server/newsfragments/2125.clarification @@ -0,0 +1 @@ +Add missing format fields to ``m.room.message$m.notice`` schema. diff --git a/event-schemas/schema/m.room.message$m.notice b/event-schemas/schema/m.room.message$m.notice index ef97e28a..19c4f985 100644 --- a/event-schemas/schema/m.room.message$m.notice +++ b/event-schemas/schema/m.room.message$m.notice @@ -12,6 +12,16 @@ properties: enum: - m.notice type: string + format: + description: |- + The format used in the ``formatted_body``. Currently only + ``org.matrix.custom.html`` is supported. + type: string + formatted_body: + description: |- + The formatted version of the ``body``. This is required if ``format`` + is specified. + type: string required: - msgtype - body From decb75555c103cd4c00066fe49ea9dc4757aabcc Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 12 Jun 2019 18:09:15 -0600 Subject: [PATCH 0523/1250] =?UTF-8?q?We're=20stable=20now=20=F0=9F=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CONTRIBUTING.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 0b814fb9..fc5b146f 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -75,10 +75,8 @@ ask. Adding to the changelog ~~~~~~~~~~~~~~~~~~~~~~~ -Currently only changes to the client-server API need to end up in a changelog. The -other APIs are not yet stable and therefore do not have a changelog. Adding to the -changelog can only be done after you've opened your pull request, so be sure to do -that first. +All API specifications require a changelog entry. Adding to the changelog can only +be done after you've opened your pull request, so be sure to do that first. The changelog is managed by Towncrier (https://github.com/hawkowl/towncrier) in the form of "news fragments". The news fragments for the client-server API are stored From 2dd0da7d50ed8209ba277c5b10bacf7f1ebdecd2 Mon Sep 17 00:00:00 2001 From: Jimmy Cuadra Date: Fri, 14 Jun 2019 13:46:20 -0700 Subject: [PATCH 0524/1250] Fix typo in key verification framework section. Signed-off-by: Jimmy Cuadra --- changelogs/client_server/newsfragments/2131.clarification | 1 + specification/modules/end_to_end_encryption.rst | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/2131.clarification diff --git a/changelogs/client_server/newsfragments/2131.clarification b/changelogs/client_server/newsfragments/2131.clarification new file mode 100644 index 00000000..3c41fb60 --- /dev/null +++ b/changelogs/client_server/newsfragments/2131.clarification @@ -0,0 +1 @@ +Fix typo in key verification framework section. diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 36336c74..f94fec2d 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -419,7 +419,7 @@ Key verification framework Verifying keys manually by reading out the Ed25519 key is not very user friendly, and can lead to errors. In order to help mitigate errors, and to make the process -eaiser for users, some verification methods are supported by the specification. +easier for users, some verification methods are supported by the specification. The methods all use a common framework for negotiating the key verification. To use this framework, Alice's client would send ``m.key.verification.request`` From b885714d94aa694fe267e3d36318b12d48499934 Mon Sep 17 00:00:00 2001 From: Jimmy Cuadra Date: Thu, 13 Jun 2019 17:21:11 -0700 Subject: [PATCH 0525/1250] Remove the "required" designation from the `url` field of certain m.room.message msgtypes. Now that content referenced by the *m.audio*, *m.file*, *m.image*, and *m.video* message types can be encrypted, the `url` field is required *only* if the content is unencrypted. The "required" designation in the event schemas (which prefixes the field description with "Required" in bold in the generated HTML) is used to indicate fields which must always be present, and this is no longer the case. Signed-off-by: Jimmy Cuadra --- changelogs/client_server/newsfragments/2129.clarification | 1 + event-schemas/schema/m.room.message$m.audio | 3 +-- event-schemas/schema/m.room.message$m.file | 1 - event-schemas/schema/m.room.message$m.image | 1 - event-schemas/schema/m.room.message$m.video | 1 - 5 files changed, 2 insertions(+), 5 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2129.clarification diff --git a/changelogs/client_server/newsfragments/2129.clarification b/changelogs/client_server/newsfragments/2129.clarification new file mode 100644 index 00000000..82ed4fce --- /dev/null +++ b/changelogs/client_server/newsfragments/2129.clarification @@ -0,0 +1 @@ +Remove "required" designation from the ``url`` field of certain ``m`.room.message` msgtypes. diff --git a/event-schemas/schema/m.room.message$m.audio b/event-schemas/schema/m.room.message$m.audio index 88b459ec..fb049fc9 100644 --- a/event-schemas/schema/m.room.message$m.audio +++ b/event-schemas/schema/m.room.message$m.audio @@ -28,7 +28,7 @@ properties: type: string url: description: |- - Required if the file is not encrypted. The URL (typically `MXC URI`_) + Required if the file is unencrypted. The URL (typically `MXC URI`_) to the audio clip. type: string file: @@ -40,7 +40,6 @@ properties: required: - msgtype - body - - url type: object type: enum: diff --git a/event-schemas/schema/m.room.message$m.file b/event-schemas/schema/m.room.message$m.file index 9f4fdf07..54a999ec 100644 --- a/event-schemas/schema/m.room.message$m.file +++ b/event-schemas/schema/m.room.message$m.file @@ -55,7 +55,6 @@ properties: required: - msgtype - body - - url type: object type: enum: diff --git a/event-schemas/schema/m.room.message$m.image b/event-schemas/schema/m.room.message$m.image index a466562a..8944ce96 100644 --- a/event-schemas/schema/m.room.message$m.image +++ b/event-schemas/schema/m.room.message$m.image @@ -30,7 +30,6 @@ properties: required: - msgtype - body - - url type: object type: enum: diff --git a/event-schemas/schema/m.room.message$m.video b/event-schemas/schema/m.room.message$m.video index b23c2392..1a3c3e40 100644 --- a/event-schemas/schema/m.room.message$m.video +++ b/event-schemas/schema/m.room.message$m.video @@ -61,7 +61,6 @@ properties: required: - msgtype - body - - url type: object type: enum: From bc71dacaf4f65e2a27705a658fc4b303ecba16c9 Mon Sep 17 00:00:00 2001 From: Jimmy Cuadra Date: Fri, 14 Jun 2019 16:05:25 -0700 Subject: [PATCH 0526/1250] Clarify the distinction between *m.key.verification.start* and its *m.sas.v1* variant. Currently the *m.key.verification.start* event appears twice with the exact same title, in the "Key verification framework" section and the "Short Authentication (SAS) verification" section. It's not immediately clear that the first occurrence describes the format of the event in general terms and that the second occurrence describes the fields when the *m.sas.v1* verification method is being used. This is a similar relationship to the *m.room.message* event and its various *msgtype* variants. This commit does three things: * It tweaks the generation of the documentation to change the title of the second occurrence of *m.key.verification.start* to distinguish it from the first. * It updates the language in the description of the two versions of the event to better describe the relationship between the two. * It adds the optional `next_method` field to the schema of the *m.sas.v1* variant, as specified in the general form of *m.key.verification.start*. Signed-off-by: Jimmy Cuadra --- .../client_server/newsfragments/2132.clarification | 1 + event-schemas/schema/m.key.verification.start | 2 +- event-schemas/schema/m.key.verification.start$m.sas.v1 | 8 ++++++-- scripts/templating/matrix_templates/units.py | 9 +++++++++ 4 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2132.clarification diff --git a/changelogs/client_server/newsfragments/2132.clarification b/changelogs/client_server/newsfragments/2132.clarification new file mode 100644 index 00000000..53063400 --- /dev/null +++ b/changelogs/client_server/newsfragments/2132.clarification @@ -0,0 +1 @@ +Clarify the distinction between *m.key.verification.start* and its *m.sas.v1* variant. diff --git a/event-schemas/schema/m.key.verification.start b/event-schemas/schema/m.key.verification.start index ad59d6c7..99b4998e 100644 --- a/event-schemas/schema/m.key.verification.start +++ b/event-schemas/schema/m.key.verification.start @@ -3,7 +3,7 @@ allOf: - $ref: core-event-schema/event.yaml description: |- - Begins a key verification process. Typically sent as a `to-device`_ event. + Begins a key verification process. Typically sent as a `to-device`_ event. The ``method`` field determines the type of verification. The fields in the event will differ depending on the ``method``. This definition includes fields that are in common among all variants. properties: content: properties: diff --git a/event-schemas/schema/m.key.verification.start$m.sas.v1 b/event-schemas/schema/m.key.verification.start$m.sas.v1 index 867ca820..a42f20e7 100644 --- a/event-schemas/schema/m.key.verification.start$m.sas.v1 +++ b/event-schemas/schema/m.key.verification.start$m.sas.v1 @@ -3,7 +3,7 @@ allOf: - $ref: core-event-schema/event.yaml description: |- - Begins a SAS key verification process. Typically sent as a `to-device`_ event. + Begins an SAS key verification process using the ``m.sas.v1`` method. Typically sent as a `to-device`_ event. properties: content: properties: @@ -22,7 +22,11 @@ properties: type: string enum: ["m.sas.v1"] description: |- - The verification method to use. Must be ``m.sas.v1``. + The verification method to use. + next_method: + type: string + description: |- + Optional method to use to verify the other user's key with. key_agreement_protocols: type: array description: |- diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index 157fa5a1..8538de2d 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -902,6 +902,15 @@ class MatrixUnits(Units): "`m.room.message msgtypes`_." ) + # method types for m.key.verification.start + if schema["type"] == "m.key.verification.start": + methods = Units.prop( + json_schema, "properties/content/properties/method/enum" + ) + if methods: + schema["type_with_msgtype"] = schema["type"] + " (" + methods[0] + ")" + + # Assign state key info if it has some if schema["typeof"] == "State Event": skey_desc = Units.prop( From 5384b61d95c82dcde6e924ce40f037f7f659d70f Mon Sep 17 00:00:00 2001 From: Jimmy Cuadra Date: Fri, 14 Jun 2019 17:35:39 -0700 Subject: [PATCH 0527/1250] Fix style issues brought up during code review. Signed-off-by: Jimmy Cuadra --- changelogs/client_server/newsfragments/2132.clarification | 2 +- event-schemas/schema/m.key.verification.start | 4 +++- scripts/templating/matrix_templates/units.py | 1 - 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/changelogs/client_server/newsfragments/2132.clarification b/changelogs/client_server/newsfragments/2132.clarification index 53063400..1c458340 100644 --- a/changelogs/client_server/newsfragments/2132.clarification +++ b/changelogs/client_server/newsfragments/2132.clarification @@ -1 +1 @@ -Clarify the distinction between *m.key.verification.start* and its *m.sas.v1* variant. +Clarify the distinction between ``m`.key.verification.start` and its `m`.`sas.v1` variant. diff --git a/event-schemas/schema/m.key.verification.start b/event-schemas/schema/m.key.verification.start index 99b4998e..28926f4f 100644 --- a/event-schemas/schema/m.key.verification.start +++ b/event-schemas/schema/m.key.verification.start @@ -3,7 +3,9 @@ allOf: - $ref: core-event-schema/event.yaml description: |- - Begins a key verification process. Typically sent as a `to-device`_ event. The ``method`` field determines the type of verification. The fields in the event will differ depending on the ``method``. This definition includes fields that are in common among all variants. + Begins a key verification process. Typically sent as a `to-device`_ event. The ``method`` + field determines the type of verification. The fields in the event will differ depending + on the ``method``. This definition includes fields that are in common among all variants. properties: content: properties: diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index 8538de2d..04e6f8a9 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -910,7 +910,6 @@ class MatrixUnits(Units): if methods: schema["type_with_msgtype"] = schema["type"] + " (" + methods[0] + ")" - # Assign state key info if it has some if schema["typeof"] == "State Event": skey_desc = Units.prop( From 33ca891e71e6673ff6bdd3706d34c9c45d16da03 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 14 Jun 2019 22:22:43 -0600 Subject: [PATCH 0528/1250] Fix link to Olm signing specification See https://github.com/matrix-org/matrix.org/issues/478 --- changelogs/client_server/newsfragments/2133.clarification | 1 + specification/modules/end_to_end_encryption.rst | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/2133.clarification diff --git a/changelogs/client_server/newsfragments/2133.clarification b/changelogs/client_server/newsfragments/2133.clarification new file mode 100644 index 00000000..3a003179 --- /dev/null +++ b/changelogs/client_server/newsfragments/2133.clarification @@ -0,0 +1 @@ +Fix link to Olm signing specification. diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index f94fec2d..27ba4998 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -411,7 +411,7 @@ Device verification may reach one of several conclusions. For example: protocol to verify that a given message was sent from a device holding that Ed25519 private key, or to encrypt a message so that it may only be decrypted by such a device. For the Olm protocol, this is documented at - https://matrix.org/git/olm/about/docs/signing.rst. + https://matrix.org/docs/spec/olm_signing.html. Key verification framework From 6f460ad70aa6c642b582bc9a3b140ffbcab41271 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 14 Jun 2019 22:26:29 -0600 Subject: [PATCH 0529/1250] minus spec according to the apache .htaccess we use --- specification/modules/end_to_end_encryption.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 27ba4998..329c0170 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -411,7 +411,7 @@ Device verification may reach one of several conclusions. For example: protocol to verify that a given message was sent from a device holding that Ed25519 private key, or to encrypt a message so that it may only be decrypted by such a device. For the Olm protocol, this is documented at - https://matrix.org/docs/spec/olm_signing.html. + https://matrix.org/docs/olm_signing.html. Key verification framework From 3eff76b00aabfc34cc267dafe857cedc7bf564f6 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Sat, 15 Jun 2019 12:36:57 +0100 Subject: [PATCH 0530/1250] MSC 2134 --- proposals/2134-identity-hash-lookup.md | 56 ++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 proposals/2134-identity-hash-lookup.md diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md new file mode 100644 index 00000000..af732cfe --- /dev/null +++ b/proposals/2134-identity-hash-lookup.md @@ -0,0 +1,56 @@ +# MSC 2134: Identity Hash Lookups + +[Issue #2130](https://github.com/matrix-org/matrix-doc/issues/2130) has been recently created in response to a security issue brought up by an independant party. To summarise the issue, lookups (of matrix userids) are performed using non-hashed 3pids which means that the 3pid is identifiable to anyone who can see the payload (e.g. willh AT matrix.org can be identified by a human). + +The problem with this, is that a malicious identity service could then store the plaintext 3pid and make an assumption that the requesting entity knows the holder of the 3pid, even if the identity service does not know of the 3pid beforehand. + +If the 3pid is hashed, the identity service could not determine the owner of the 3pid unless the identity service has already been made aware of the 3pid by the owner themselves (using the /bind mechanism). + +Note that this proposal does not stop a identity service from mapping hashed 3pids to many users, in an attempt to form a social graph. However the identity of the 3pid will remain a mystery until /bind is used. + +It should be clear that there is a need to hide any address from the identity service that has not been explicitly bound to it, and this proposal aims to solve that for the lookup API. + + +## Proposal + +This proposal suggests making changes to the Identity Service API's lookup endpoints. Due to the nature of this proposal, the new endpoints should be +on a `v2` path: + +- `/_matrix/identity/api/v2/lookup` +- `/_matrix/identity/api/v2/bulk_lookup` + +The parameters will remain the same, but `address` should no longer be in a plain-text format. Medium will now take a SHA-256 format hash value, and the resulting digest should be encoded in base64 format. For example: + +```python +address = "willh@matrix.org" +digest = hashlib.sha256(address.encode()).digest() +result_address = base64.encodebytes(digest).decode() +print(result_address) +CpvOgBf0hFzdqZD4ASvWW0DAefErRRX5y8IegMBO98w= +``` + +SHA-256 has been chosen as it is [currently used elsewhere](https://matrix.org/docs/spec/server_server/r0.1.2#adding-hashes-and-signatures-to-outgoing-events) in the Matrix protocol, and the only requirement for the hashing algorithm is that it cannot be used to guess the real value of the address + +No parameter changes will be made to /bind, but identity services should keep a hashed value for each address it knows about in order to process lookups quicker and it is the recommendation that this is done at the time of bind. + +`v1` versions of these endpoints may be disabled at the discretion of the implementation, and should return a `M_FORBIDDEN` `errcode` if so. + + +## Tradeoffs + +* This approach means that the client now needs to calculate a hash by itself, but the belief is that most librarys provide a mechanism for doing so. +* There is a small cost incurred by doing hashes before requests, but this is outweighed by the privacy implications of sending plaintext addresses. + + +## Potential issues + +This proposal does not force a identity service to stop handling plaintext requests, because a large amount of the matrix ecosystem relies upon this behavior. However, a conscious effort should be made by all users to use the privacy respecting endpoints outlined above. Identity services may disallow use of the v1 endpoint. + + +## Security considerations + +None + +## Conclusion + +This proposal outlines a quick and effective method to stop bulk collection of users contact lists and their social graphs without any disasterous side effects. All functionality which depends on the lookup service should continue to function unhindered by the use of hashes. \ No newline at end of file From a8c26d208b8ceae31b2d9d55f5a2c75c3a6ba4d4 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Sat, 15 Jun 2019 12:43:20 +0100 Subject: [PATCH 0531/1250] Wrap --- proposals/2134-identity-hash-lookup.md | 56 ++++++++++++++++++-------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index af732cfe..1bc48e9a 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -1,25 +1,38 @@ -# MSC 2134: Identity Hash Lookups +# MSC2134: Identity Hash Lookups -[Issue #2130](https://github.com/matrix-org/matrix-doc/issues/2130) has been recently created in response to a security issue brought up by an independant party. To summarise the issue, lookups (of matrix userids) are performed using non-hashed 3pids which means that the 3pid is identifiable to anyone who can see the payload (e.g. willh AT matrix.org can be identified by a human). +[Issue #2130](https://github.com/matrix-org/matrix-doc/issues/2130) has been recently +created in response to a security issue brought up by an independant party. To summarise +the issue, lookups (of matrix userids) are performed using non-hashed 3pids which means +that the 3pid is identifiable to anyone who can see the payload (e.g. willh AT matrix.org +can be identified by a human). -The problem with this, is that a malicious identity service could then store the plaintext 3pid and make an assumption that the requesting entity knows the holder of the 3pid, even if the identity service does not know of the 3pid beforehand. +The problem with this, is that a malicious identity service could then store the plaintext +3pid and make an assumption that the requesting entity knows the holder of the 3pid, even +if the identity service does not know of the 3pid beforehand. -If the 3pid is hashed, the identity service could not determine the owner of the 3pid unless the identity service has already been made aware of the 3pid by the owner themselves (using the /bind mechanism). +If the 3pid is hashed, the identity service could not determinethe owner of the 3pid +unless the identity service has already been made aware of the 3pid by the owner +themselves (using the /bind mechanism). -Note that this proposal does not stop a identity service from mapping hashed 3pids to many users, in an attempt to form a social graph. However the identity of the 3pid will remain a mystery until /bind is used. +Note that this proposal does not stop a identity service from mapping hashed 3pids to many +users, in an attempt to form a social graph. However the identity of the 3pid will remain +a mystery until /bind is used. -It should be clear that there is a need to hide any address from the identity service that has not been explicitly bound to it, and this proposal aims to solve that for the lookup API. +It should be clear that there is a need to hide any address from the identity service that +has not been explicitly bound to it, and this proposal aims to solve that for the lookup API. ## Proposal -This proposal suggests making changes to the Identity Service API's lookup endpoints. Due to the nature of this proposal, the new endpoints should be -on a `v2` path: +This proposal suggests making changes to the Identity Service API's lookup endpoints. Due +to the nature of this proposal, the new endpoints should be on a `v2` path: - `/_matrix/identity/api/v2/lookup` - `/_matrix/identity/api/v2/bulk_lookup` -The parameters will remain the same, but `address` should no longer be in a plain-text format. Medium will now take a SHA-256 format hash value, and the resulting digest should be encoded in base64 format. For example: +The parameters will remain the same, but `address` should no longer be in a plain-text +format. Medium will now take a SHA-256 format hash value, and the resulting digest should +be encoded in base64 format. For example: ```python address = "willh@matrix.org" @@ -29,22 +42,31 @@ print(result_address) CpvOgBf0hFzdqZD4ASvWW0DAefErRRX5y8IegMBO98w= ``` -SHA-256 has been chosen as it is [currently used elsewhere](https://matrix.org/docs/spec/server_server/r0.1.2#adding-hashes-and-signatures-to-outgoing-events) in the Matrix protocol, and the only requirement for the hashing algorithm is that it cannot be used to guess the real value of the address +SHA-256 has been chosen as it is [currently used elsewhere](https://matrix.org/docs/spec/server_server/r0.1.2#adding-hashes-and-signatures-to-outgoing-events) in the Matrix protocol, and the only +requirement for the hashing algorithm is that it cannot be used to guess the real value of the address -No parameter changes will be made to /bind, but identity services should keep a hashed value for each address it knows about in order to process lookups quicker and it is the recommendation that this is done at the time of bind. +No parameter changes will be made to /bind, but identity services should keep a hashed value +for each address it knows about in order to process lookups quicker and it is the recommendation +that this is done at the time of bind. -`v1` versions of these endpoints may be disabled at the discretion of the implementation, and should return a `M_FORBIDDEN` `errcode` if so. +`v1` versions of these endpoints may be disabled at the discretion of the implementation, and +should return a `M_FORBIDDEN` `errcode` if so. ## Tradeoffs -* This approach means that the client now needs to calculate a hash by itself, but the belief is that most librarys provide a mechanism for doing so. -* There is a small cost incurred by doing hashes before requests, but this is outweighed by the privacy implications of sending plaintext addresses. +* This approach means that the client now needs to calculate a hash by itself, but the belief + is that most librarys provide a mechanism for doing so. +* There is a small cost incurred by doing hashes before requests, but this is outweighed by + the privacy implications of sending plaintext addresses. ## Potential issues -This proposal does not force a identity service to stop handling plaintext requests, because a large amount of the matrix ecosystem relies upon this behavior. However, a conscious effort should be made by all users to use the privacy respecting endpoints outlined above. Identity services may disallow use of the v1 endpoint. +This proposal does not force a identity service to stop handling plaintext requests, because +a large amount of the matrix ecosystem relies upon this behavior. However, a conscious effort +should be made by all users to use the privacy respecting endpoints outlined above. Identity +services may disallow use of the v1 endpoint. ## Security considerations @@ -53,4 +75,6 @@ None ## Conclusion -This proposal outlines a quick and effective method to stop bulk collection of users contact lists and their social graphs without any disasterous side effects. All functionality which depends on the lookup service should continue to function unhindered by the use of hashes. \ No newline at end of file +This proposal outlines a quick and effective method to stop bulk collection of users contact +lists and their social graphs without any disasterous side effects. All functionality which +depends on the lookup service should continue to function unhindered by the use of hashes. \ No newline at end of file From 8b92df74abfd6c045bf348a05b67281328cdcb6a Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Sat, 15 Jun 2019 13:25:42 +0100 Subject: [PATCH 0532/1250] s/medium/address --- proposals/2134-identity-hash-lookup.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 1bc48e9a..29144ec6 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -31,7 +31,7 @@ to the nature of this proposal, the new endpoints should be on a `v2` path: - `/_matrix/identity/api/v2/bulk_lookup` The parameters will remain the same, but `address` should no longer be in a plain-text -format. Medium will now take a SHA-256 format hash value, and the resulting digest should +format. `address` will now take a SHA-256 format hash value, and the resulting digest should be encoded in base64 format. For example: ```python @@ -42,6 +42,8 @@ print(result_address) CpvOgBf0hFzdqZD4ASvWW0DAefErRRX5y8IegMBO98w= ``` +### Example request + SHA-256 has been chosen as it is [currently used elsewhere](https://matrix.org/docs/spec/server_server/r0.1.2#adding-hashes-and-signatures-to-outgoing-events) in the Matrix protocol, and the only requirement for the hashing algorithm is that it cannot be used to guess the real value of the address From 12431f1a4e4f5ef0a7d61c1bcf3f1989d227c7f5 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Sat, 15 Jun 2019 13:29:59 +0100 Subject: [PATCH 0533/1250] Base64 potential issue --- proposals/2134-identity-hash-lookup.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 29144ec6..54e8bcbf 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -2,15 +2,15 @@ [Issue #2130](https://github.com/matrix-org/matrix-doc/issues/2130) has been recently created in response to a security issue brought up by an independant party. To summarise -the issue, lookups (of matrix userids) are performed using non-hashed 3pids which means -that the 3pid is identifiable to anyone who can see the payload (e.g. willh AT matrix.org -can be identified by a human). +the issue, lookups (of matrix user ids) are performed using non-hashed 3pids which means +that the 3pid is identifiable to anyone who can see the payload (e.g. willh@matrix.org +can be identified). The problem with this, is that a malicious identity service could then store the plaintext 3pid and make an assumption that the requesting entity knows the holder of the 3pid, even if the identity service does not know of the 3pid beforehand. -If the 3pid is hashed, the identity service could not determinethe owner of the 3pid +If the 3pid is hashed, the identity service could not determine the owner of the 3pid unless the identity service has already been made aware of the 3pid by the owner themselves (using the /bind mechanism). @@ -21,7 +21,6 @@ a mystery until /bind is used. It should be clear that there is a need to hide any address from the identity service that has not been explicitly bound to it, and this proposal aims to solve that for the lookup API. - ## Proposal This proposal suggests making changes to the Identity Service API's lookup endpoints. Due @@ -58,7 +57,7 @@ should return a `M_FORBIDDEN` `errcode` if so. ## Tradeoffs * This approach means that the client now needs to calculate a hash by itself, but the belief - is that most librarys provide a mechanism for doing so. + is that most languages provide a mechanism for doing so. * There is a small cost incurred by doing hashes before requests, but this is outweighed by the privacy implications of sending plaintext addresses. @@ -70,6 +69,10 @@ a large amount of the matrix ecosystem relies upon this behavior. However, a con should be made by all users to use the privacy respecting endpoints outlined above. Identity services may disallow use of the v1 endpoint. +Base64 has been chosen to encode the value due to it's ubiquitous support in many languages, +however it does mean that special characters in the address will have to be encoded when used +as a parameter value. + ## Security considerations From 8affb23e5ef62e01ba5c43d3d91f633748580994 Mon Sep 17 00:00:00 2001 From: Jimmy Cuadra Date: Sat, 15 Jun 2019 13:44:58 -0700 Subject: [PATCH 0534/1250] Address feedback from code review. * Switch "an SAS" back to "a SAS" * Remove the `next_method` field from m.key.verification.start$m.sas.v1 but add additional clarification to its description on m.key.verification.start that it is never present for methods that verify keys both ways. --- event-schemas/schema/m.key.verification.start | 3 ++- event-schemas/schema/m.key.verification.start$m.sas.v1 | 6 +----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/event-schemas/schema/m.key.verification.start b/event-schemas/schema/m.key.verification.start index 28926f4f..faa7a96a 100644 --- a/event-schemas/schema/m.key.verification.start +++ b/event-schemas/schema/m.key.verification.start @@ -28,7 +28,8 @@ properties: type: string description: |- Optional method to use to verify the other user's key with. Applicable - when the ``method`` chosen only verifies one user's key. + when the ``method`` chosen only verifies one user's key. This field will + never be present if the ``method`` verifies keys both ways. required: - from_device - transaction_id diff --git a/event-schemas/schema/m.key.verification.start$m.sas.v1 b/event-schemas/schema/m.key.verification.start$m.sas.v1 index a42f20e7..daf6fa39 100644 --- a/event-schemas/schema/m.key.verification.start$m.sas.v1 +++ b/event-schemas/schema/m.key.verification.start$m.sas.v1 @@ -3,7 +3,7 @@ allOf: - $ref: core-event-schema/event.yaml description: |- - Begins an SAS key verification process using the ``m.sas.v1`` method. Typically sent as a `to-device`_ event. + Begins a SAS key verification process using the ``m.sas.v1`` method. Typically sent as a `to-device`_ event. properties: content: properties: @@ -23,10 +23,6 @@ properties: enum: ["m.sas.v1"] description: |- The verification method to use. - next_method: - type: string - description: |- - Optional method to use to verify the other user's key with. key_agreement_protocols: type: array description: |- From 802b90d1132407efb1b1ae6adc6511901f9ace46 Mon Sep 17 00:00:00 2001 From: Anatoly Sablin Date: Sun, 16 Jun 2019 22:24:06 +0300 Subject: [PATCH 0535/1250] Typo. --- event-schemas/schema/m.key.verification.accept | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event-schemas/schema/m.key.verification.accept b/event-schemas/schema/m.key.verification.accept index 41c59968..ad54488e 100644 --- a/event-schemas/schema/m.key.verification.accept +++ b/event-schemas/schema/m.key.verification.accept @@ -3,7 +3,7 @@ allOf: - $ref: core-event-schema/event.yaml description: |- - Accepts a previously sent ``m.key.verification.start`` messge. Typically sent as a + Accepts a previously sent ``m.key.verification.start`` message. Typically sent as a `to-device`_ event. properties: content: From c63b5aff697c71c80b34b73ddf3ba327dae7c3b9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 17 Jun 2019 00:10:59 -0600 Subject: [PATCH 0536/1250] Create 2136.clarification --- changelogs/client_server/newsfragments/2136.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2136.clarification diff --git a/changelogs/client_server/newsfragments/2136.clarification b/changelogs/client_server/newsfragments/2136.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/client_server/newsfragments/2136.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. From f8dbf2b360b8b2f220b9c43c450b2845db10a1e1 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Mon, 17 Jun 2019 13:17:57 +0100 Subject: [PATCH 0537/1250] Update proposals/2134-identity-hash-lookup.md Co-Authored-By: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- proposals/2134-identity-hash-lookup.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 54e8bcbf..ad00c6fc 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -80,6 +80,6 @@ None ## Conclusion -This proposal outlines a quick and effective method to stop bulk collection of users contact +This proposal outlines a quick and effective method to stop bulk collection of user's contact lists and their social graphs without any disasterous side effects. All functionality which -depends on the lookup service should continue to function unhindered by the use of hashes. \ No newline at end of file +depends on the lookup service should continue to function unhindered by the use of hashes. From d09af5b191472fd7078aeff1b5c13558ab4a1212 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 17 Jun 2019 11:18:24 -0600 Subject: [PATCH 0538/1250] Identity r0.2.1 --- changelogs/identity_service.rst | 10 ++++++++++ .../identity_service/newsfragments/2124.clarification | 1 - .../identity_service/newsfragments/2126.clarification | 1 - 3 files changed, 10 insertions(+), 2 deletions(-) delete mode 100644 changelogs/identity_service/newsfragments/2124.clarification delete mode 100644 changelogs/identity_service/newsfragments/2126.clarification diff --git a/changelogs/identity_service.rst b/changelogs/identity_service.rst index d60812b8..cb06709d 100644 --- a/changelogs/identity_service.rst +++ b/changelogs/identity_service.rst @@ -1,3 +1,13 @@ +r0.2.1 +====== + +Spec Clarifications +------------------- + +- Remove incorrect ``id_server`` parameter from ``/requestToken`` endpoints. (`#2124 `_) +- Clarify that identity servers can return 403 for unbind requests. (`#2126 `_) + + r0.2.0 ====== diff --git a/changelogs/identity_service/newsfragments/2124.clarification b/changelogs/identity_service/newsfragments/2124.clarification deleted file mode 100644 index 384af82f..00000000 --- a/changelogs/identity_service/newsfragments/2124.clarification +++ /dev/null @@ -1 +0,0 @@ -Remove incorrect ``id_server`` parameter from ``/requestToken`` endpoints. diff --git a/changelogs/identity_service/newsfragments/2126.clarification b/changelogs/identity_service/newsfragments/2126.clarification deleted file mode 100644 index 1475b4b4..00000000 --- a/changelogs/identity_service/newsfragments/2126.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that identity servers can return 403 for unbind requests. From d2b47a585d5fbdba44b8d461f30a8e72a1e50e25 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 18 Jun 2019 16:37:02 +0100 Subject: [PATCH 0539/1250] Allow for changing the hashing algo and add at-rest details --- proposals/2134-identity-hash-lookup.md | 99 ++++++++++++++------------ 1 file changed, 55 insertions(+), 44 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index ad00c6fc..9b448d68 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -1,57 +1,59 @@ # MSC2134: Identity Hash Lookups -[Issue #2130](https://github.com/matrix-org/matrix-doc/issues/2130) has been recently -created in response to a security issue brought up by an independant party. To summarise -the issue, lookups (of matrix user ids) are performed using non-hashed 3pids which means -that the 3pid is identifiable to anyone who can see the payload (e.g. willh@matrix.org -can be identified). +[Issue #2130](https://github.com/matrix-org/matrix-doc/issues/2130) has been +recently created in response to a security issue brought up by an independent +party. To summarise the issue, lookups (of matrix user ids) are performed using +non-hashed 3pids (third-party IDs) which means that the identity server can +identify and record every 3pid that the user wants to check, whether that +address is already known by the identity server or not. -The problem with this, is that a malicious identity service could then store the plaintext -3pid and make an assumption that the requesting entity knows the holder of the 3pid, even -if the identity service does not know of the 3pid beforehand. +If the 3pid is hashed, the identity service could not determine the address +unless it has already seen that address in plain-text during a previous call of +the /bind mechanism. -If the 3pid is hashed, the identity service could not determine the owner of the 3pid -unless the identity service has already been made aware of the 3pid by the owner -themselves (using the /bind mechanism). +Note that in terms of privacy, this proposal does not stop an identity service +from mapping hashed 3pids to users, resulting in a social graph. However, the +identity of the 3pid will at least remain a mystery until /bind is used. -Note that this proposal does not stop a identity service from mapping hashed 3pids to many -users, in an attempt to form a social graph. However the identity of the 3pid will remain -a mystery until /bind is used. - -It should be clear that there is a need to hide any address from the identity service that -has not been explicitly bound to it, and this proposal aims to solve that for the lookup API. +This proposal thus calls for the Identity Service’s /lookup API to use hashed +3pids instead of their plain-text counterparts. ## Proposal -This proposal suggests making changes to the Identity Service API's lookup endpoints. Due -to the nature of this proposal, the new endpoints should be on a `v2` path: +This proposal suggests making changes to the Identity Service API's lookup +endpoints. Due to the nature of this proposal, the new endpoints should be on a +`v2` path: - `/_matrix/identity/api/v2/lookup` - `/_matrix/identity/api/v2/bulk_lookup` -The parameters will remain the same, but `address` should no longer be in a plain-text -format. `address` will now take a SHA-256 format hash value, and the resulting digest should -be encoded in base64 format. For example: +The parameters will remain the same, but `address` should no longer be in a +plain-text format. `address` will now take a hash value, and the resulting +digest should be encoded in unpadded base64. For example: ```python -address = "willh@matrix.org" +address = "user@example.org" digest = hashlib.sha256(address.encode()).digest() -result_address = base64.encodebytes(digest).decode() +result_address = unpaddedbase64.encode_base64(digest) print(result_address) -CpvOgBf0hFzdqZD4ASvWW0DAefErRRX5y8IegMBO98w= +CpvOgBf0hFzdqZD4ASvWW0DAefErRRX5y8IegMBO98w ``` ### Example request -SHA-256 has been chosen as it is [currently used elsewhere](https://matrix.org/docs/spec/server_server/r0.1.2#adding-hashes-and-signatures-to-outgoing-events) in the Matrix protocol, and the only -requirement for the hashing algorithm is that it cannot be used to guess the real value of the address +SHA-256 has been chosen as it is [currently used +elsewhere](https://matrix.org/docs/spec/server_server/r0.1.2#adding-hashes-and-signatures-to-outgoing-events) +in the Matrix protocol. As time goes on, this algorithm may be changed provided +a spec bump is performed. Then, clients making a request to `/lookup` must use +the hashing algorithm defined in whichever version of the CS spec they and the +IS have agreed to speaking. -No parameter changes will be made to /bind, but identity services should keep a hashed value -for each address it knows about in order to process lookups quicker and it is the recommendation -that this is done at the time of bind. +No parameter changes will be made to /bind, but identity services should keep a +hashed value for each address it knows about in order to process lookups +quicker. It is the recommendation that this is done during the act of binding. -`v1` versions of these endpoints may be disabled at the discretion of the implementation, and -should return a `M_FORBIDDEN` `errcode` if so. +`v1` versions of these endpoints may be disabled at the discretion of the +implementation, and should return a `M_FORBIDDEN` `errcode` if so. ## Tradeoffs @@ -59,20 +61,27 @@ should return a `M_FORBIDDEN` `errcode` if so. * This approach means that the client now needs to calculate a hash by itself, but the belief is that most languages provide a mechanism for doing so. * There is a small cost incurred by doing hashes before requests, but this is outweighed by - the privacy implications of sending plaintext addresses. - + the privacy implications of sending plain-text addresses. ## Potential issues -This proposal does not force a identity service to stop handling plaintext requests, because -a large amount of the matrix ecosystem relies upon this behavior. However, a conscious effort -should be made by all users to use the privacy respecting endpoints outlined above. Identity -services may disallow use of the v1 endpoint. +This proposal does not force an identity service to stop handling plain-text +requests, because a large amount of the matrix ecosystem relies upon this +behavior. However, a conscious effort should be made by all users to use the +privacy respecting endpoints outlined above. Identity services may disallow use +of the v1 endpoint. -Base64 has been chosen to encode the value due to it's ubiquitous support in many languages, -however it does mean that special characters in the address will have to be encoded when used -as a parameter value. +Unpadded base64 has been chosen to encode the value due to its ubiquitous +support in many languages, however it does mean that special characters in the +address will have to be encoded when used as a parameter value. +## Other considered solutions + +Ideally identity servers would never receive plain-text addresses, however it +is necessary for the identity server to send an email/sms message during a +bind, as it cannot trust a homeserver to do so as the homeserver may be lying. +Additionally, only storing 3pid hashes at rest instead of the plain-text +versions is impractical if the hashing algorithm ever needs to be changed. ## Security considerations @@ -80,6 +89,8 @@ None ## Conclusion -This proposal outlines a quick and effective method to stop bulk collection of user's contact -lists and their social graphs without any disasterous side effects. All functionality which -depends on the lookup service should continue to function unhindered by the use of hashes. +This proposal outlines an effective method to stop bulk collection of user's +contact lists and their social graphs without any disastrous side effects. All +functionality which depends on the lookup service should continue to function +unhindered by the use of hashes. + From 063b9f60e0441f252df7cdf00fc5b5ee1774b99a Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 18 Jun 2019 16:50:47 +0100 Subject: [PATCH 0540/1250] Require a salt to defend against rainbow tables --- proposals/2134-identity-hash-lookup.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 9b448d68..bc25b92e 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -43,10 +43,12 @@ CpvOgBf0hFzdqZD4ASvWW0DAefErRRX5y8IegMBO98w SHA-256 has been chosen as it is [currently used elsewhere](https://matrix.org/docs/spec/server_server/r0.1.2#adding-hashes-and-signatures-to-outgoing-events) -in the Matrix protocol. As time goes on, this algorithm may be changed provided -a spec bump is performed. Then, clients making a request to `/lookup` must use -the hashing algorithm defined in whichever version of the CS spec they and the -IS have agreed to speaking. +in the Matrix protocol. Additionally a hardcoded salt (“matrix” or something) +must be prepended to the data before hashing in order to serve as a weak +defense against existing rainbow tables. As time goes on, this algorithm may be +changed provided a spec bump is performed. Then, clients making a request to +`/lookup` must use the hashing algorithm defined in whichever version of the CS +spec they and the IS have agreed to speaking. No parameter changes will be made to /bind, but identity services should keep a hashed value for each address it knows about in order to process lookups From bc9b6c3659e861779367de35234666523b319d2a Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 18 Jun 2019 17:03:49 +0100 Subject: [PATCH 0541/1250] Add salt to example and signal link --- proposals/2134-identity-hash-lookup.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index bc25b92e..a34ee767 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -33,7 +33,8 @@ digest should be encoded in unpadded base64. For example: ```python address = "user@example.org" -digest = hashlib.sha256(address.encode()).digest() +salt = "matrix" +digest = hashlib.sha256((salt + address).encode()).digest() result_address = unpaddedbase64.encode_base64(digest) print(result_address) CpvOgBf0hFzdqZD4ASvWW0DAefErRRX5y8IegMBO98w @@ -85,6 +86,8 @@ bind, as it cannot trust a homeserver to do so as the homeserver may be lying. Additionally, only storing 3pid hashes at rest instead of the plain-text versions is impractical if the hashing algorithm ever needs to be changed. +Bloom filters are an alternative method of providing private contact discovery, however does not scale well due to clients needing to download a large filter that needs updating every time a new bind is made. Further considered solutions are explored in https://signal.org/blog/contact-discovery/ Signal's eventual solution of using SGX is considered impractical for a Matrix-style setup. + ## Security considerations None From 5049e552e7da9ff65ddbaa7610072baa5dfa0827 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 18 Jun 2019 17:05:46 +0100 Subject: [PATCH 0542/1250] Drop /api from the new endpoint --- proposals/2134-identity-hash-lookup.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index a34ee767..45f7d5f0 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -22,10 +22,11 @@ This proposal thus calls for the Identity Service’s /lookup API to use hashed This proposal suggests making changes to the Identity Service API's lookup endpoints. Due to the nature of this proposal, the new endpoints should be on a -`v2` path: +`v2` path (we also drop the `/api` in order to preserve consistency across +other endpoints): -- `/_matrix/identity/api/v2/lookup` -- `/_matrix/identity/api/v2/bulk_lookup` +- `/_matrix/identity/v2/lookup` +- `/_matrix/identity/v2/bulk_lookup` The parameters will remain the same, but `address` should no longer be in a plain-text format. `address` will now take a hash value, and the resulting From 6bb4a9e9110e58bd9a383b3957b909db7ca54222 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 18 Jun 2019 17:09:06 +0100 Subject: [PATCH 0543/1250] Add per-is salt consideration --- proposals/2134-identity-hash-lookup.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 45f7d5f0..f7c36e74 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -89,6 +89,10 @@ versions is impractical if the hashing algorithm ever needs to be changed. Bloom filters are an alternative method of providing private contact discovery, however does not scale well due to clients needing to download a large filter that needs updating every time a new bind is made. Further considered solutions are explored in https://signal.org/blog/contact-discovery/ Signal's eventual solution of using SGX is considered impractical for a Matrix-style setup. +We could let an identity server specify its own salt for the hashes, however it +would require an extra network call before uploading 3pid hashes in order for +the client to ask the server which salt it requires. + ## Security considerations None From f41ed02c9e8f1c12a307567a38a15e71295e3495 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 18 Jun 2019 17:22:28 +0100 Subject: [PATCH 0544/1250] remove sec concerns --- proposals/2134-identity-hash-lookup.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index f7c36e74..8451f72c 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -93,10 +93,6 @@ We could let an identity server specify its own salt for the hashes, however it would require an extra network call before uploading 3pid hashes in order for the client to ask the server which salt it requires. -## Security considerations - -None - ## Conclusion This proposal outlines an effective method to stop bulk collection of user's From 82463833300121a2ddc5b2676e5e8fd64f4263d3 Mon Sep 17 00:00:00 2001 From: Jimmy Cuadra Date: Tue, 18 Jun 2019 16:37:37 -0700 Subject: [PATCH 0545/1250] Fix typos in changelog entry. --- changelogs/client_server/newsfragments/2132.clarification | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/client_server/newsfragments/2132.clarification b/changelogs/client_server/newsfragments/2132.clarification index 1c458340..b8a4cc8a 100644 --- a/changelogs/client_server/newsfragments/2132.clarification +++ b/changelogs/client_server/newsfragments/2132.clarification @@ -1 +1 @@ -Clarify the distinction between ``m`.key.verification.start` and its `m`.`sas.v1` variant. +Clarify the distinction between ``m.key.verification.start`` and its ``m.sas.v1`` variant. From 3ee27d38180a6142237b86499830c2d4b4c610a5 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 19 Jun 2019 15:14:30 +0100 Subject: [PATCH 0546/1250] salt->pepper. 1 pepper/is. add multi-hash idea --- proposals/2134-identity-hash-lookup.md | 98 ++++++++++++++++++++------ 1 file changed, 78 insertions(+), 20 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 8451f72c..cd5e3868 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -28,31 +28,81 @@ other endpoints): - `/_matrix/identity/v2/lookup` - `/_matrix/identity/v2/bulk_lookup` -The parameters will remain the same, but `address` should no longer be in a -plain-text format. `address` will now take a hash value, and the resulting -digest should be encoded in unpadded base64. For example: +`address` should no longer be in a plain-text format, but will now take a hash +value, and the resulting digest should be encoded in unpadded base64. For +example: ```python address = "user@example.org" -salt = "matrix" -digest = hashlib.sha256((salt + address).encode()).digest() +pepper = "matrix" +digest = hashlib.sha256((pepper + address).encode()).digest() result_address = unpaddedbase64.encode_base64(digest) print(result_address) CpvOgBf0hFzdqZD4ASvWW0DAefErRRX5y8IegMBO98w ``` -### Example request - SHA-256 has been chosen as it is [currently used elsewhere](https://matrix.org/docs/spec/server_server/r0.1.2#adding-hashes-and-signatures-to-outgoing-events) -in the Matrix protocol. Additionally a hardcoded salt (“matrix” or something) -must be prepended to the data before hashing in order to serve as a weak -defense against existing rainbow tables. As time goes on, this algorithm may be -changed provided a spec bump is performed. Then, clients making a request to -`/lookup` must use the hashing algorithm defined in whichever version of the CS -spec they and the IS have agreed to speaking. - -No parameter changes will be made to /bind, but identity services should keep a +in the Matrix protocol. Additionally a +[pepper](https://en.wikipedia.org/wiki/Pepper_(cryptography)) must be prepended +to the data before hashing in order to serve as a weak defense against existing +rainbow tables. This pepper will be specified by the identity server in order +to prevent a single rainbow table being generated for all identity servers. As +time goes on, this algorithm may be changed provided a spec bump is performed. +Then, clients making a request to `/lookup` must use the hashing algorithm +defined in whichever version of the CS spec they and the IS have agreed to +speaking. + +Identity servers can specify their own peppers, which can be handy if a rainbow table is released for their current one. Identity servers could also set a timer for rotating this value to further impede rainbow table publishing. As such, it must be possible for clients to be able to query what pepper an identity server requires before sending it hashes. Thus a new endpoint must be added: + +``` +GET /_matrix/identity/v2/lookup_pepper +``` + +This endpoint takes no parameters, and simply returns the current pepper as a JSON object: + +``` +{ + "pepper": "matrixrocks" +} +``` + +In addition, the pepper the client used must be appended as a parameter to the +new `/lookup` and `/bulk_lookup` endpoints, ensuring that the client is using +the right one. If it does not match what the server has on file (which may be +the case is it rotated right after the client's request for it), then client +will know to query the pepper again instead of just getting a response saying +no contacts are registered on that identity server. + +Thus, a call to `/bulk_lookup` would look like the following: + +``` +{ + "threepids": [ + [ + "email", + "user@example.org" + ], + [ + "msisdn", + "123456789" + ], + [ + "email", + "user2@example.org" + ] + ], + "pepper": "matrixrocks" +} +``` + +If the pepper does not match the server's, the client should receive a `400 +M_INVALID_PARAM` with the error `Provided pepper value does not match +'$server_pepper'`. Clients should ensure they don't enter an infinite loop if +they receive this error more than once even after changing to the correct +pepper. + +No parameter changes will be made to /bind, but identity servers should keep a hashed value for each address it knows about in order to process lookups quicker. It is the recommendation that this is done during the act of binding. @@ -87,11 +137,19 @@ bind, as it cannot trust a homeserver to do so as the homeserver may be lying. Additionally, only storing 3pid hashes at rest instead of the plain-text versions is impractical if the hashing algorithm ever needs to be changed. -Bloom filters are an alternative method of providing private contact discovery, however does not scale well due to clients needing to download a large filter that needs updating every time a new bind is made. Further considered solutions are explored in https://signal.org/blog/contact-discovery/ Signal's eventual solution of using SGX is considered impractical for a Matrix-style setup. - -We could let an identity server specify its own salt for the hashes, however it -would require an extra network call before uploading 3pid hashes in order for -the client to ask the server which salt it requires. +Bloom filters are an alternative method of providing private contact discovery, +however does not scale well due to clients needing to download a large filter +that needs updating every time a new bind is made. Further considered solutions +are explored in https://signal.org/blog/contact-discovery/ Signal's eventual +solution of using SGX is considered impractical for a Matrix-style setup. + +Bit out of scope for this MSC, but there was an argument for not keeping all +IDs as hashed on disk in the identity server, that being if a hashing algorithm +was broken, we couldn't update the hashing algorithm without having the +plaintext 3PIDs. Well @toml helpfully said that we could just take the old +hashes and rehash them in the more secure hashing algorithm, thus transforming +the algo from ex. SHA256 to SHA256+SomeBetterAlg. This may spur an MSC in the +future that supports this, unless it is just an implementation detail. ## Conclusion From f28476f0f3887535fe8c21603933c8831db9d203 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 19 Jun 2019 16:29:24 +0100 Subject: [PATCH 0547/1250] line wrap and fix wording --- proposals/2134-identity-hash-lookup.md | 28 ++++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index cd5e3868..8ccfcfce 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -53,7 +53,12 @@ Then, clients making a request to `/lookup` must use the hashing algorithm defined in whichever version of the CS spec they and the IS have agreed to speaking. -Identity servers can specify their own peppers, which can be handy if a rainbow table is released for their current one. Identity servers could also set a timer for rotating this value to further impede rainbow table publishing. As such, it must be possible for clients to be able to query what pepper an identity server requires before sending it hashes. Thus a new endpoint must be added: +Identity servers can specify their own peppers, which can be handy if a rainbow +table is released for their current one. Identity servers could also set a +timer for rotating this value to further impede rainbow table publishing. As +such, it must be possible for clients to be able to query what pepper an +identity server requires before sending it hashes. Thus a new endpoint must be +added: ``` GET /_matrix/identity/v2/lookup_pepper @@ -81,15 +86,15 @@ Thus, a call to `/bulk_lookup` would look like the following: "threepids": [ [ "email", - "user@example.org" + "vNjEQuRCOmBp/KTuIpZ7RUJgPAbVAyqa0Uzh770tQaw" ], [ "msisdn", - "123456789" + "0VnvYk7YZpe08fP/CGqs3f39QtRjqAA2lPd14eLZXiw" ], [ "email", - "user2@example.org" + "BJaLI0RrLFDMbsk0eEp5BMsYDYzvOzDneQP/9NTemYA" ] ], "pepper": "matrixrocks" @@ -143,13 +148,14 @@ that needs updating every time a new bind is made. Further considered solutions are explored in https://signal.org/blog/contact-discovery/ Signal's eventual solution of using SGX is considered impractical for a Matrix-style setup. -Bit out of scope for this MSC, but there was an argument for not keeping all -IDs as hashed on disk in the identity server, that being if a hashing algorithm -was broken, we couldn't update the hashing algorithm without having the -plaintext 3PIDs. Well @toml helpfully said that we could just take the old -hashes and rehash them in the more secure hashing algorithm, thus transforming -the algo from ex. SHA256 to SHA256+SomeBetterAlg. This may spur an MSC in the -future that supports this, unless it is just an implementation detail. +While a bit out of scope for this MSC, there has been debate over preventing +3pids as being kept as plain-text on disk. The argument against this was that +if the hashing algorithm (in this case SHA-256) was broken, we couldn't update +the hashing algorithm without having the plaintext 3PIDs. Well @toml helpfully +added that we could just take the old hashes and rehash them in the more secure +hashing algorithm, thus transforming the hash from SHA-256 to +SHA-256+SomeBetterAlg. This may spur on an MSC in the future that supports +this, unless it is just an implementation detail. ## Conclusion From 1343e19a6d36bc624091320182c10452da046727 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 20 Jun 2019 14:36:47 +0100 Subject: [PATCH 0548/1250] Specify hash algorithm and fallback considerations --- proposals/2134-identity-hash-lookup.md | 44 ++++++++++++++++++-------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 8ccfcfce..43154d7c 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -61,23 +61,28 @@ identity server requires before sending it hashes. Thus a new endpoint must be added: ``` -GET /_matrix/identity/v2/lookup_pepper +GET /_matrix/identity/v2/hash_details ``` This endpoint takes no parameters, and simply returns the current pepper as a JSON object: ``` { - "pepper": "matrixrocks" + "pepper": "matrixrocks", + "algorithm": "sha256", } ``` -In addition, the pepper the client used must be appended as a parameter to the -new `/lookup` and `/bulk_lookup` endpoints, ensuring that the client is using -the right one. If it does not match what the server has on file (which may be -the case is it rotated right after the client's request for it), then client -will know to query the pepper again instead of just getting a response saying -no contacts are registered on that identity server. +Clients should request this endpoint every time before making a +`/(bulk_)lookup`, to handle identity servers which may rotate their pepper +values frequently. + +In addition, the pepper and hashing algorithm the client used must be a request +body field for the new `/lookup` and `/bulk_lookup` endpoints, ensuring that +the client is using the right parameters. If it does not match what the server +has on file (which may be the case is it rotated right after the client's +request for it), then the client will know to query the hash details again +instead of assuming that no contacts are registered on that identity server. Thus, a call to `/bulk_lookup` would look like the following: @@ -97,22 +102,33 @@ Thus, a call to `/bulk_lookup` would look like the following: "BJaLI0RrLFDMbsk0eEp5BMsYDYzvOzDneQP/9NTemYA" ] ], - "pepper": "matrixrocks" + "pepper": "matrixrocks", + "algorithm": "sha256" } ``` If the pepper does not match the server's, the client should receive a `400 -M_INVALID_PARAM` with the error `Provided pepper value does not match -'$server_pepper'`. Clients should ensure they don't enter an infinite loop if -they receive this error more than once even after changing to the correct -pepper. +M_INVALID_PARAM` with the error `Provided pepper does not match +'$server_pepper'`. If the algorithm does not match the server's, the client +should receive a `400 M_INVALID_PARAM` with the error `Provided algorithm does +not match '$server_algorithm'`. Clients should ensure they don't enter an +infinite loop if they receive these errors more than once even after changing +to the correct pepper and hash. No parameter changes will be made to /bind, but identity servers should keep a hashed value for each address it knows about in order to process lookups quicker. It is the recommendation that this is done during the act of binding. +## Fallback considerations + `v1` versions of these endpoints may be disabled at the discretion of the -implementation, and should return a `M_FORBIDDEN` `errcode` if so. +implementation, and should return a HTTP 403 with a `M_FORBIDDEN` `errcode` if +so. + +If an identity server is too old and a HTTP 404 is received when accessing the +`v2` endpoint, they should fallback to the `v1` endpoint instead. However, +clients should be aware that plain-text 3pids are required, and should ask for +user consent accordingly. ## Tradeoffs From 23af87e9fc898daffd3823490578f9c46442b85e Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 20 Jun 2019 17:41:19 +0100 Subject: [PATCH 0549/1250] Proposal for IS & IM TOS API --- proposals/2140-terms-of-service-2.md | 203 +++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 proposals/2140-terms-of-service-2.md diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md new file mode 100644 index 00000000..8c2ee75b --- /dev/null +++ b/proposals/2140-terms-of-service-2.md @@ -0,0 +1,203 @@ +# MSCXXXX: Terms of Service API for Identity Servers and Integration Managers + +MSC1692 introduces a method for homeservers to require that users read and +agree to certain documents before being permitted to use the service. This +proposal introduces a corresponding method that can be used with Identity +Servers and Integration Managers. + +The challenge here is that Identity Servers do not require any kind of user +login to access the service and so are unable to track what users have agreed +to what terms in the way that Homeservers do. We thereforce cannot re-use the +same method for Identity Servers without fundamentally changing the Identity +Service API. + +Requirements for this proposal are: + * ISs and IMs should be able to give multiple documents a user must agree to + abide by + * Each document shoud be versioned + * ISs and IMs must be able to prevent users from using the service if they + have not provided agreement. + * A user should only have to agree to each version of each document once for + their Matrix ID, ie. having agreed to a set of terms in one client, they + should not have to agree to them again when using a different client. + +## Proposal + +Throuhgout this proposal, $prefix will be used to refer to the prefix of the +API in question, ie. `/_matrix/identity/api/v1` for the IS API and +`/_matrix/integrations/v1` for the IM API. + +This proposal introduces: + * The `$prefix/terms` endpoint + * The `m.third_party_terms` section in account data + * The `X-TERMS-TOKEN` HTTP header + +### Terms API + +New API endpoints will be introduced: + +#### `GET $prefix/terms`: +This returns a set of documents that the user must agree to abide by in order +to use the service. Its response is similar to the structure used in the +`m.terms` UI auth flow of the Client/Server API: + +```json +{ + "policies": { + "terms_of_service": { + "version": "2.0", + "en": { + "name": "Terms of Service", + "url": "https://example.org/somewhere/terms-2.0-en.html" + }, + "fr": { + "name": "Conditions d'utilisation", + "url": "https://example.org/somewhere/terms-2.0-fr.html" + } + } + } +} +``` + +Each document (ie. key/value pair in the 'policies' object) MUST be +uniquely identified by its URL. It is therefore strongly recommended +that the URL contains the version number of the document. The name +and version keys, however, are used only to provide a human-readable +description of the document to the user. + +In the IM API, the client should provide authentication for this endpoint. + +#### `POST $prefix/terms`: +Requests to this endpoint have a single key, `user_accepts` whose value is +a list of URLs (given by the `url` field in the GET response) of documents that +the user has agreed to: + +```json +{ + "user_accepts": ["https://example.org/somewhere/terms-2.0-en.html"] +} +``` + +In the IM API, the client should provide authentication for this endpoint. + +The clients MUST include the correct URL for the language of the document that +was presented to the user and they agreed to. How servers store or serialise +acceptance into the `acceptance_token` is not defined, eg. they may internally +transform all URLs to the URL of the English-language version of each document +if the server deems it appropriate to do so. Servers should accept agreement of +any one language of each document as sufficient, regardless of what language a +client is operating in: users should not have to re-consent to documents if +they change their client to a different language. + +The response MAY contain a `acceptance_token` which, if given, is an +opaque string that the client must store for user in subsequent requests +to any endpoint to the same server. + +If the server has stored the fact that the user has agreed to these terms, +(which implies the user is authenticated) it can supply no `acceptance_token`. +The server may instead choose to supply an `acceptance_token`, for example if, +as in the IS API, the user is unauthenticated and therefore the server is +unable to store the fact a user has agreed to a set of terms. + +The `acceptance_token` is opaque and it is up to the server how it computes it, +but the server must be able to given an `acceptance_token`, compute whether it +constitutes agreement to a given set of terms. For example, the simplest (but +most verbose) implemenation would be to make the `acceptance_token` the JSON +array of documents as provided in the request. A smarter implementation may be +a simple hash, or even cryptograhic hash if desired. + +### Third-Party Terms Account Data + +This proposal also defines the `m.third_party_terms` section in User Account +Data in the client/server API that clients SHOULD use to track what sets of +terms the user has consented to. This has an array of URLs under the 'accepted' +key to which the user has agreed to. + +An `m.third_party_terms` section therefore resembles the following: + +```json +{ + "accepted": [ + "https://example.org/somewhere/terms-1.2-en.html", + "https://example.org/somewhere/privacy-1.2-en.html" + ] +} +``` + +Whenever a client submits a `POST $prefix/terms` request to an IS or IM, it +SHOULD update this account data section adding any the URLs of any additional +documents that the user agreed to to this list. + +### Terms Acceptance in the API + +Any request to any endpoint in the IS and IM APIs, with the exception of +`/_matrix/identity/api/v1` may return a `M_TERMS_NOT_SIGNED` errcode. This +indicates that the user must agree to (new) terms in order to use or continue +to use the service. + +The client uses the `GET $prefix/terms` endpoint to get the latest set of terms +that must be agreed to. It then cross-references this set of documents against +the `m.third_party_terms` account data and presents to the user any documents +that they have not already agreed to, along with UI for them to indicate their +agreement. Once the user has indicated their agreement, then, and only then, +must the client use the `POST $prefix/terms` API to signal to the server the +set of documents that the user has agreed to. + +If the server returns an `acceptance_token`, the client should include this +token in the `X-TERMS-TOKEN` HTTP header in all subsequent requests to an +endpoint on the API with the exception of `/_matrix/identity/api/v1`. + +Both making the `POST $prefix/terms` request and providing an `X-TERMS-TOKEN` +header signal that the user consents to the terms contained within the +corresponding documents. That is to say, if a client or user obtains an +acceptance token via means other than a response to the `POST $perfix/terms` +API, inclusion of the acceptance token in an `X-TERMS-TOKEN` header in a +request still constitutes agreement to the terms in the corresponding +documents. + +## Tradeoffs + +This introduces a different way of accepting terms from the client/server API +which uses User-Interactive Authentication. In the client/server API, the use +of UI auth allows terms acceptance to be integrated into the registration flow +in a simple and backwards-compatible way. Indtroducing the UI Auth mechanism +into these other APIs would add significant complexity, so this functionality +has been provided with simpler, dedicated endpoints. + +## Potential issues + +If the server does not authentcate users, some mechanism is required to track +users agreement to terms. The introduction of an extra HTTP header on all +requests adds overhead to every request and complexity to the client to add a +custom header. + + +## Security considerations + +The `acceptance_token` is, in effect, a cookie and could be used to identify +users of the service. Users of the Integration manager must be authenticated +anyway, so this is irrelevant for the IM API. It could allow an Identity Server +to identify users where it may otherwise not be able to do so (if a client was +careful to mask other identifying HTTP headers). Given most requests to the IS +API, by their nature, include 3pids which, even if hashed, will make users +easily identifiable, this probably does not add any significant concern. + +It is assumed that once servers publish a given version of a document at a +given URL, the contents of that URL will not change. This could be mitigated by +identifying documents based on a hash of their contents rather than their URLs. +Agreement to terms in the client/server API makes this assumption, so this +proposal aims to be consistent. + + +## Conclusion + +This proposal adds an error response to all endpoints on the API and a custom +HTTP header on all requests that is used to signal agreement to a set of terms +and conditions. The use of the header is only necessary if the server has no +other means of tracking acceptance of terms per-user. The IS API is not +authenticated so ISes will have no choice but to use the header. The IM API is +authenticated so IMs may either use the header or store acceptance per-user. + +A separate endpoint is specified with a GET request for retrieving the set +of terms required and a POST to indicate that the user consents to those +terms. From 32c7fc638dfb31eb05f484fc0c933cef7b604dc5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 20 Jun 2019 17:44:28 +0100 Subject: [PATCH 0550/1250] you have a number now --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 8c2ee75b..77d44e60 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -1,4 +1,4 @@ -# MSCXXXX: Terms of Service API for Identity Servers and Integration Managers +# MSC2140: Terms of Service API for Identity Servers and Integration Managers MSC1692 introduces a method for homeservers to require that users read and agree to certain documents before being permitted to use the service. This From cf48030d1fe7c3e180cd5a5617261fa508dbad59 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 20 Jun 2019 17:48:21 +0100 Subject: [PATCH 0551/1250] One more tradeoff --- proposals/2140-terms-of-service-2.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 77d44e60..bf322676 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -164,6 +164,14 @@ in a simple and backwards-compatible way. Indtroducing the UI Auth mechanism into these other APIs would add significant complexity, so this functionality has been provided with simpler, dedicated endpoints. +The `m.third_party_terms` section contains only URLs of the documents that +have been agreed to. This loses information like the name and version of +the document, but: + * It would be up to the clients to copy this information correctly into + account data. + * Having just the URLs makes it much easier for clients to make a list + of URLs and find documents not already agreed to. + ## Potential issues If the server does not authentcate users, some mechanism is required to track From 276e2b6843b9d27e7782222cf66d2c34f6c528f9 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 21 Jun 2019 09:14:24 +0100 Subject: [PATCH 0552/1250] Typo Co-Authored-By: Travis Ralston --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index bf322676..b678881a 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -90,7 +90,7 @@ client is operating in: users should not have to re-consent to documents if they change their client to a different language. The response MAY contain a `acceptance_token` which, if given, is an -opaque string that the client must store for user in subsequent requests +opaque string that the client must store for use in subsequent requests to any endpoint to the same server. If the server has stored the fact that the user has agreed to these terms, From d4ca0c237a7b744ffc05003b3a84b31f0b064367 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 21 Jun 2019 09:25:16 +0100 Subject: [PATCH 0553/1250] Specify ID grammar and add comma --- proposals/2140-terms-of-service-2.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index b678881a..dbdad334 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -99,12 +99,13 @@ The server may instead choose to supply an `acceptance_token`, for example if, as in the IS API, the user is unauthenticated and therefore the server is unable to store the fact a user has agreed to a set of terms. -The `acceptance_token` is opaque and it is up to the server how it computes it, -but the server must be able to given an `acceptance_token`, compute whether it -constitutes agreement to a given set of terms. For example, the simplest (but -most verbose) implemenation would be to make the `acceptance_token` the JSON -array of documents as provided in the request. A smarter implementation may be -a simple hash, or even cryptograhic hash if desired. +The `acceptance_token` is an opaque string contining characters +`[a-zA-Z0-9._-]`. It is up to the server how it computes it, but the server +must be able to, given an `acceptance_token`, compute whether it constitutes +agreement to a given set of terms. For example, the simplest (but most verbose) +implemenation would be to make the `acceptance_token` the JSON array of +documents as provided in the request. A smarter implementation may be a simple +hash, or even cryptograhic hash if desired. ### Third-Party Terms Account Data From 9ca3ccc81ce0ddfcf529b6c9445a2d11887707c4 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 21 Jun 2019 09:35:26 +0100 Subject: [PATCH 0554/1250] Add requirments section for de-duping between services. --- proposals/2140-terms-of-service-2.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index dbdad334..066a1184 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -20,6 +20,11 @@ Requirements for this proposal are: * A user should only have to agree to each version of each document once for their Matrix ID, ie. having agreed to a set of terms in one client, they should not have to agree to them again when using a different client. + * Documents should be de-duplicated between services. If two or more services + are hosted by the same organisation, the organistation should have the + option to give their users a single document that encompasses both services + (bearing in mind that the user must be able to opt-out of components of a + service whilst still being able to use the service without that component). ## Proposal From 1fea604ba9fc79071124181523e6800666194f3c Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 21 Jun 2019 11:32:23 +0100 Subject: [PATCH 0555/1250] Don't define error message --- proposals/2134-identity-hash-lookup.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 43154d7c..8c7a0aca 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -108,12 +108,7 @@ Thus, a call to `/bulk_lookup` would look like the following: ``` If the pepper does not match the server's, the client should receive a `400 -M_INVALID_PARAM` with the error `Provided pepper does not match -'$server_pepper'`. If the algorithm does not match the server's, the client -should receive a `400 M_INVALID_PARAM` with the error `Provided algorithm does -not match '$server_algorithm'`. Clients should ensure they don't enter an -infinite loop if they receive these errors more than once even after changing -to the correct pepper and hash. +M_INVALID_PARAM`. No parameter changes will be made to /bind, but identity servers should keep a hashed value for each address it knows about in order to process lookups From e3b2ad38b5630c38dafad7e18178c6f0f9f98cfd Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 21 Jun 2019 12:17:01 +0100 Subject: [PATCH 0556/1250] pepper -> lookup_pepper --- proposals/2134-identity-hash-lookup.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 8c7a0aca..f85df971 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -68,11 +68,14 @@ This endpoint takes no parameters, and simply returns the current pepper as a JS ``` { - "pepper": "matrixrocks", + "lookup_pepper": "matrixrocks", "algorithm": "sha256", } ``` +`lookup_pepper` was chosen in order to account for pepper values being returned +for other endpoints in the future. + Clients should request this endpoint every time before making a `/(bulk_)lookup`, to handle identity servers which may rotate their pepper values frequently. From c63edc7b97703383e0989eaea5c242124c8a9998 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 21 Jun 2019 14:12:50 +0100 Subject: [PATCH 0557/1250] Clean up wording around peppers and hashes --- proposals/2134-identity-hash-lookup.md | 97 +++++++++++++------------- 1 file changed, 47 insertions(+), 50 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index f85df971..686a3787 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -28,37 +28,15 @@ other endpoints): - `/_matrix/identity/v2/lookup` - `/_matrix/identity/v2/bulk_lookup` -`address` should no longer be in a plain-text format, but will now take a hash -value, and the resulting digest should be encoded in unpadded base64. For -example: +`address` MUST no longer be in a plain-text format, but rather will be a peppered hash +value, and the resulting digest MUST be encoded in unpadded base64. -```python -address = "user@example.org" -pepper = "matrix" -digest = hashlib.sha256((pepper + address).encode()).digest() -result_address = unpaddedbase64.encode_base64(digest) -print(result_address) -CpvOgBf0hFzdqZD4ASvWW0DAefErRRX5y8IegMBO98w -``` - -SHA-256 has been chosen as it is [currently used -elsewhere](https://matrix.org/docs/spec/server_server/r0.1.2#adding-hashes-and-signatures-to-outgoing-events) -in the Matrix protocol. Additionally a -[pepper](https://en.wikipedia.org/wiki/Pepper_(cryptography)) must be prepended -to the data before hashing in order to serve as a weak defense against existing -rainbow tables. This pepper will be specified by the identity server in order -to prevent a single rainbow table being generated for all identity servers. As -time goes on, this algorithm may be changed provided a spec bump is performed. -Then, clients making a request to `/lookup` must use the hashing algorithm -defined in whichever version of the CS spec they and the IS have agreed to -speaking. - -Identity servers can specify their own peppers, which can be handy if a rainbow -table is released for their current one. Identity servers could also set a -timer for rotating this value to further impede rainbow table publishing. As -such, it must be possible for clients to be able to query what pepper an -identity server requires before sending it hashes. Thus a new endpoint must be -added: +Identity servers must specify their own hashing algorithms (from a list of +specified values) and peppers, which will be useful if a rainbow table is +released for their current one. Identity servers could also set a timer for +rotating the pepper value to further impede rainbow table publishing. As such, +it must be possible for clients to be able to query what pepper an identity +server requires before sending it hashes. A new endpoint must be added: ``` GET /_matrix/identity/v2/hash_details @@ -73,21 +51,39 @@ This endpoint takes no parameters, and simply returns the current pepper as a JS } ``` -`lookup_pepper` was chosen in order to account for pepper values being returned -for other endpoints in the future. +The name `lookup_pepper` was chosen in order to account for pepper values being +returned for other endpoints in the future. -Clients should request this endpoint every time before making a -`/(bulk_)lookup`, to handle identity servers which may rotate their pepper -values frequently. +Clients should request this endpoint each time before making a `/lookup` or +`/(bulk_)lookup` request, to handle identity servers which may rotate their +pepper values frequently. -In addition, the pepper and hashing algorithm the client used must be a request -body field for the new `/lookup` and `/bulk_lookup` endpoints, ensuring that -the client is using the right parameters. If it does not match what the server -has on file (which may be the case is it rotated right after the client's -request for it), then the client will know to query the hash details again -instead of assuming that no contacts are registered on that identity server. +An example of generating a hash using the above hash and pepper is as follows: -Thus, a call to `/bulk_lookup` would look like the following: +```python +address = "user@example.org" +pepper = "matrixrocks" +digest = hashlib.sha256((pepper + address).encode()).digest() +result_address = unpaddedbase64.encode_base64(digest) +print(result_address) +vNjEQuRCOmBp/KTuIpZ7RUJgPAbVAyqa0Uzh770tQaw +``` + +SHA-256 should be the first specified hash function. It has been chosen as it +is [currently used +elsewhere](https://matrix.org/docs/spec/server_server/r0.1.2#adding-hashes-and-signatures-to-outgoing-events) +in the Matrix protocol, and is reasonably secure as of 2019. + +When performing a lookup, the pepper and hashing algorithm the client used must +be part of the request body. If they do not match what the server has on file +(which may be the case if the pepper was rotated right after the client's +request for it), then the server can inform the client that they need to query +the hash details again, instead of just returning an empty response, which +clients would assume to mean that no contacts are registered on that identity +server. + +Thus, an example client request to `/bulk_lookup` would look like the +following: ``` { @@ -110,17 +106,19 @@ Thus, a call to `/bulk_lookup` would look like the following: } ``` -If the pepper does not match the server's, the client should receive a `400 +If the pepper does not match the server's, the server should return a `400 M_INVALID_PARAM`. No parameter changes will be made to /bind, but identity servers should keep a hashed value for each address it knows about in order to process lookups quicker. It is the recommendation that this is done during the act of binding. +Be wary that these hashes will need to be changed whenever the server's pepper +is rotated. ## Fallback considerations `v1` versions of these endpoints may be disabled at the discretion of the -implementation, and should return a HTTP 403 with a `M_FORBIDDEN` `errcode` if +implementation, and should return a HTTP 400 with a `M_DEPRECATED` `errcode` if so. If an identity server is too old and a HTTP 404 is received when accessing the @@ -128,13 +126,12 @@ If an identity server is too old and a HTTP 404 is received when accessing the clients should be aware that plain-text 3pids are required, and should ask for user consent accordingly. - ## Tradeoffs -* This approach means that the client now needs to calculate a hash by itself, but the belief - is that most languages provide a mechanism for doing so. -* There is a small cost incurred by doing hashes before requests, but this is outweighed by - the privacy implications of sending plain-text addresses. +* This approach means that the client now needs to calculate a hash by itself, + but the belief is that most languages provide a mechanism for doing so. +* There is a small cost incurred by performing hashes before requests, but this + is outweighed by the privacy implications of sending plain-text addresses. ## Potential issues @@ -151,7 +148,7 @@ address will have to be encoded when used as a parameter value. ## Other considered solutions Ideally identity servers would never receive plain-text addresses, however it -is necessary for the identity server to send an email/sms message during a +is necessary for the identity server to send email/sms messages during a bind, as it cannot trust a homeserver to do so as the homeserver may be lying. Additionally, only storing 3pid hashes at rest instead of the plain-text versions is impractical if the hashing algorithm ever needs to be changed. From 2383a55720374181d726bec475aba46943fa60a3 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 21 Jun 2019 15:40:26 +0100 Subject: [PATCH 0558/1250] 404 for deprecated endpoint --- proposals/2134-identity-hash-lookup.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 686a3787..0f7fca27 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -118,8 +118,7 @@ is rotated. ## Fallback considerations `v1` versions of these endpoints may be disabled at the discretion of the -implementation, and should return a HTTP 400 with a `M_DEPRECATED` `errcode` if -so. +implementation, and should return a HTTP 404 if so. If an identity server is too old and a HTTP 404 is received when accessing the `v2` endpoint, they should fallback to the `v1` endpoint instead. However, From 53f025edfc6ecd126a5ce0fe42f02edcbc7d0bc6 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 21 Jun 2019 15:42:11 +0100 Subject: [PATCH 0559/1250] Specify optional pepper rotation period --- proposals/2134-identity-hash-lookup.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 0f7fca27..138646ff 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -34,9 +34,12 @@ value, and the resulting digest MUST be encoded in unpadded base64. Identity servers must specify their own hashing algorithms (from a list of specified values) and peppers, which will be useful if a rainbow table is released for their current one. Identity servers could also set a timer for -rotating the pepper value to further impede rainbow table publishing. As such, -it must be possible for clients to be able to query what pepper an identity -server requires before sending it hashes. A new endpoint must be added: +rotating the pepper value to further impede rainbow table publishing (the +recommended period is every 30m, which should be enough for a client to +complete the hashing of all of a user's contacts, but also be nowhere near as +long enough to create a sophisticated rainbow table). As such, it must be +possible for clients to be able to query what pepper an identity server +requires before sending it hashes. A new endpoint must be added: ``` GET /_matrix/identity/v2/hash_details From 21e93a123ede06ef47fd1391fab87efc250a7f18 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 21 Jun 2019 11:36:16 -0600 Subject: [PATCH 0560/1250] Naming and capitalization --- proposals/2134-identity-hash-lookup.md | 27 +++++++++++++------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 138646ff..dd2b8cc0 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -2,21 +2,21 @@ [Issue #2130](https://github.com/matrix-org/matrix-doc/issues/2130) has been recently created in response to a security issue brought up by an independent -party. To summarise the issue, lookups (of matrix user ids) are performed using -non-hashed 3pids (third-party IDs) which means that the identity server can -identify and record every 3pid that the user wants to check, whether that +party. To summarise the issue, lookups (of Matrix user IDs) are performed using +non-hashed 3PIDs (third-party IDs) which means that the identity server can +identify and record every 3PID that the user wants to check, whether that address is already known by the identity server or not. -If the 3pid is hashed, the identity service could not determine the address +If the 3PID is hashed, the identity server could not determine the address unless it has already seen that address in plain-text during a previous call of the /bind mechanism. Note that in terms of privacy, this proposal does not stop an identity service -from mapping hashed 3pids to users, resulting in a social graph. However, the -identity of the 3pid will at least remain a mystery until /bind is used. +from mapping hashed 3PIDs to users, resulting in a social graph. However, the +identity of the 3PID will at least remain a mystery until /bind is used. This proposal thus calls for the Identity Service’s /lookup API to use hashed -3pids instead of their plain-text counterparts. +3PIDs instead of their plain-text counterparts. ## Proposal @@ -125,7 +125,7 @@ implementation, and should return a HTTP 404 if so. If an identity server is too old and a HTTP 404 is received when accessing the `v2` endpoint, they should fallback to the `v1` endpoint instead. However, -clients should be aware that plain-text 3pids are required, and should ask for +clients should be aware that plain-text 3PIDs are required, and should ask for user consent accordingly. ## Tradeoffs @@ -137,10 +137,10 @@ user consent accordingly. ## Potential issues -This proposal does not force an identity service to stop handling plain-text -requests, because a large amount of the matrix ecosystem relies upon this +This proposal does not force an identity server to stop handling plain-text +requests, because a large amount of the Matrix ecosystem relies upon this behavior. However, a conscious effort should be made by all users to use the -privacy respecting endpoints outlined above. Identity services may disallow use +privacy respecting endpoints outlined above. Identity servers may disallow use of the v1 endpoint. Unpadded base64 has been chosen to encode the value due to its ubiquitous @@ -152,7 +152,7 @@ address will have to be encoded when used as a parameter value. Ideally identity servers would never receive plain-text addresses, however it is necessary for the identity server to send email/sms messages during a bind, as it cannot trust a homeserver to do so as the homeserver may be lying. -Additionally, only storing 3pid hashes at rest instead of the plain-text +Additionally, only storing 3PID hashes at rest instead of the plain-text versions is impractical if the hashing algorithm ever needs to be changed. Bloom filters are an alternative method of providing private contact discovery, @@ -162,7 +162,7 @@ are explored in https://signal.org/blog/contact-discovery/ Signal's eventual solution of using SGX is considered impractical for a Matrix-style setup. While a bit out of scope for this MSC, there has been debate over preventing -3pids as being kept as plain-text on disk. The argument against this was that +3PIDs as being kept as plain-text on disk. The argument against this was that if the hashing algorithm (in this case SHA-256) was broken, we couldn't update the hashing algorithm without having the plaintext 3PIDs. Well @toml helpfully added that we could just take the old hashes and rehash them in the more secure @@ -176,4 +176,3 @@ This proposal outlines an effective method to stop bulk collection of user's contact lists and their social graphs without any disastrous side effects. All functionality which depends on the lookup service should continue to function unhindered by the use of hashes. - From e3ff80291f1607c7f2cf662da1a9f9c55c0cb429 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 24 Jun 2019 11:47:00 +0100 Subject: [PATCH 0561/1250] http err codes and hash wording fixes --- proposals/2134-identity-hash-lookup.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 138646ff..94e534fd 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -72,8 +72,8 @@ print(result_address) vNjEQuRCOmBp/KTuIpZ7RUJgPAbVAyqa0Uzh770tQaw ``` -SHA-256 should be the first specified hash function. It has been chosen as it -is [currently used +SHA-256 MUST be supported at a minimum. It has been chosen as it is [currently +used elsewhere](https://matrix.org/docs/spec/server_server/r0.1.2#adding-hashes-and-signatures-to-outgoing-events) in the Matrix protocol, and is reasonably secure as of 2019. @@ -123,10 +123,10 @@ is rotated. `v1` versions of these endpoints may be disabled at the discretion of the implementation, and should return a HTTP 404 if so. -If an identity server is too old and a HTTP 404 is received when accessing the -`v2` endpoint, they should fallback to the `v1` endpoint instead. However, -clients should be aware that plain-text 3pids are required, and should ask for -user consent accordingly. +If an identity server is too old and a HTTP 404, 405 or 501 is received when +accessing the `v2` endpoint, they should fallback to the `v1` endpoint instead. +However, clients should be aware that plain-text 3pids are required, and should +ask for user consent accordingly. ## Tradeoffs From 02ac0f3b339b7df4db2180a7e690431762382335 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 24 Jun 2019 11:56:04 +0100 Subject: [PATCH 0562/1250] Give the user control! --- proposals/2134-identity-hash-lookup.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 9aa5fe7c..a2b6a26f 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -58,7 +58,7 @@ The name `lookup_pepper` was chosen in order to account for pepper values being returned for other endpoints in the future. Clients should request this endpoint each time before making a `/lookup` or -`/(bulk_)lookup` request, to handle identity servers which may rotate their +`/bulk_lookup` request, to handle identity servers which may rotate their pepper values frequently. An example of generating a hash using the above hash and pepper is as follows: @@ -125,8 +125,9 @@ implementation, and should return a HTTP 404 if so. If an identity server is too old and a HTTP 404, 405 or 501 is received when accessing the `v2` endpoint, they should fallback to the `v1` endpoint instead. -However, clients should be aware that plain-text 3pids are required, and should -ask for user consent accordingly. +However, clients should be aware that plain-text 3pids are required, and MUST +ask for user consent to send 3pids in plain-text, and be clear about where they +are being sent to. ## Tradeoffs From a63e4420eb9030d4afb5ac036c9617e5247e466e Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 24 Jun 2019 13:17:58 +0100 Subject: [PATCH 0563/1250] Linkify Co-Authored-By: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 066a1184..66efa708 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -1,6 +1,6 @@ # MSC2140: Terms of Service API for Identity Servers and Integration Managers -MSC1692 introduces a method for homeservers to require that users read and +[MSC1692](https://github.com/matrix-org/matrix-doc/issues/1692) introduces a method for homeservers to require that users read and agree to certain documents before being permitted to use the service. This proposal introduces a corresponding method that can be used with Identity Servers and Integration Managers. From 4ba9b2a59910ac14d69f92be34e8b123011ea6d5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 24 Jun 2019 13:18:41 +0100 Subject: [PATCH 0564/1250] perfix --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 66efa708..b43cadf2 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -156,7 +156,7 @@ endpoint on the API with the exception of `/_matrix/identity/api/v1`. Both making the `POST $prefix/terms` request and providing an `X-TERMS-TOKEN` header signal that the user consents to the terms contained within the corresponding documents. That is to say, if a client or user obtains an -acceptance token via means other than a response to the `POST $perfix/terms` +acceptance token via means other than a response to the `POST $prefix/terms` API, inclusion of the acceptance token in an `X-TERMS-TOKEN` header in a request still constitutes agreement to the terms in the corresponding documents. From 25558014580b411249ae3699d798dc9408997978 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 24 Jun 2019 14:56:48 +0100 Subject: [PATCH 0565/1250] m.third_party_terms -> m.accepted_terms as it will have the HS's terms too --- proposals/2140-terms-of-service-2.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index b43cadf2..8851eda3 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -34,7 +34,7 @@ API in question, ie. `/_matrix/identity/api/v1` for the IS API and This proposal introduces: * The `$prefix/terms` endpoint - * The `m.third_party_terms` section in account data + * The `m.accepted_terms` section in account data * The `X-TERMS-TOKEN` HTTP header ### Terms API @@ -114,12 +114,12 @@ hash, or even cryptograhic hash if desired. ### Third-Party Terms Account Data -This proposal also defines the `m.third_party_terms` section in User Account +This proposal also defines the `m.accepted_terms` section in User Account Data in the client/server API that clients SHOULD use to track what sets of terms the user has consented to. This has an array of URLs under the 'accepted' key to which the user has agreed to. -An `m.third_party_terms` section therefore resembles the following: +An `m.accepted_terms` section therefore resembles the following: ```json { @@ -143,7 +143,7 @@ to use the service. The client uses the `GET $prefix/terms` endpoint to get the latest set of terms that must be agreed to. It then cross-references this set of documents against -the `m.third_party_terms` account data and presents to the user any documents +the `m.accepted_terms` account data and presents to the user any documents that they have not already agreed to, along with UI for them to indicate their agreement. Once the user has indicated their agreement, then, and only then, must the client use the `POST $prefix/terms` API to signal to the server the @@ -170,7 +170,7 @@ in a simple and backwards-compatible way. Indtroducing the UI Auth mechanism into these other APIs would add significant complexity, so this functionality has been provided with simpler, dedicated endpoints. -The `m.third_party_terms` section contains only URLs of the documents that +The `m.accepted_terms` section contains only URLs of the documents that have been agreed to. This loses information like the name and version of the document, but: * It would be up to the clients to copy this information correctly into From 8ae47557c9a9e82e2333894be04583b7d968ca47 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 24 Jun 2019 15:22:19 +0100 Subject: [PATCH 0566/1250] s/Third Party/Accepted/ --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 8851eda3..f4d78a9d 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -112,7 +112,7 @@ implemenation would be to make the `acceptance_token` the JSON array of documents as provided in the request. A smarter implementation may be a simple hash, or even cryptograhic hash if desired. -### Third-Party Terms Account Data +### Accepted Terms Account Data This proposal also defines the `m.accepted_terms` section in User Account Data in the client/server API that clients SHOULD use to track what sets of From abb407145abe1a51f1ba4d4b7c07e000039791e3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 24 Jun 2019 15:30:19 +0100 Subject: [PATCH 0567/1250] HS docs must be added too also, unbind must not error when called by HSes and proxy terms token --- proposals/2140-terms-of-service-2.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index f4d78a9d..6c5bb6a5 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -130,16 +130,19 @@ An `m.accepted_terms` section therefore resembles the following: } ``` -Whenever a client submits a `POST $prefix/terms` request to an IS or IM, it -SHOULD update this account data section adding any the URLs of any additional -documents that the user agreed to to this list. +Whenever a client submits a `POST $prefix/terms` request to an IS or IM or +completes an `m.terms` flow on the HS, it SHOULD update this account data +section adding any the URLs of any additional documents that the user agreed to +to this list. ### Terms Acceptance in the API Any request to any endpoint in the IS and IM APIs, with the exception of `/_matrix/identity/api/v1` may return a `M_TERMS_NOT_SIGNED` errcode. This indicates that the user must agree to (new) terms in order to use or continue -to use the service. +to use the service. The `_matrix/identity/api/v1/3pid/unbind` must also not +return the `M_TERMS_NOT_SIGNED` if the request has a valid signature from a +Homeserver. The client uses the `GET $prefix/terms` endpoint to get the latest set of terms that must be agreed to. It then cross-references this set of documents against @@ -153,6 +156,11 @@ If the server returns an `acceptance_token`, the client should include this token in the `X-TERMS-TOKEN` HTTP header in all subsequent requests to an endpoint on the API with the exception of `/_matrix/identity/api/v1`. +The client must also include the X-TERMS-TOKEN on any request to the Homeserver +where it specifies an Identity Server to be used by the Homeserver. Homeservers +must read this header from the request headers of any such endpoint and add it +to the request headers of any request it makes to the Identity Server. + Both making the `POST $prefix/terms` request and providing an `X-TERMS-TOKEN` header signal that the user consents to the terms contained within the corresponding documents. That is to say, if a client or user obtains an From ee10576d609081cca217282692b0c002e660bfab Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 24 Jun 2019 15:43:19 +0100 Subject: [PATCH 0568/1250] Update with feedback --- proposals/2134-identity-hash-lookup.md | 27 ++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index a2b6a26f..2240b640 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -45,7 +45,8 @@ requires before sending it hashes. A new endpoint must be added: GET /_matrix/identity/v2/hash_details ``` -This endpoint takes no parameters, and simply returns the current pepper as a JSON object: +This endpoint takes no parameters, and simply returns supported hash algorithms +and pepper as a JSON object: ``` { @@ -72,8 +73,8 @@ print(result_address) vNjEQuRCOmBp/KTuIpZ7RUJgPAbVAyqa0Uzh770tQaw ``` -SHA-256 MUST be supported at a minimum. It has been chosen as it is [currently -used +SHA-256 MUST be supported by both servers and clients at a minimum. It has been +chosen as it is [currently used elsewhere](https://matrix.org/docs/spec/server_server/r0.1.2#adding-hashes-and-signatures-to-outgoing-events) in the Matrix protocol, and is reasonably secure as of 2019. @@ -104,7 +105,7 @@ following: "BJaLI0RrLFDMbsk0eEp5BMsYDYzvOzDneQP/9NTemYA" ] ], - "pepper": "matrixrocks", + "lookup_pepper": "matrixrocks", "algorithm": "sha256" } ``` @@ -144,8 +145,8 @@ behavior. However, a conscious effort should be made by all users to use the privacy respecting endpoints outlined above. Identity servers may disallow use of the v1 endpoint. -Unpadded base64 has been chosen to encode the value due to its ubiquitous -support in many languages, however it does mean that special characters in the +Unpadded base64 has been chosen to encode the value due to use in many other +portions of the spec. However, it does mean that special characters in the address will have to be encoded when used as a parameter value. ## Other considered solutions @@ -160,16 +161,22 @@ Bloom filters are an alternative method of providing private contact discovery, however does not scale well due to clients needing to download a large filter that needs updating every time a new bind is made. Further considered solutions are explored in https://signal.org/blog/contact-discovery/ Signal's eventual -solution of using SGX is considered impractical for a Matrix-style setup. +solution of using Software Guard Extensions (detailed in +https://signal.org/blog/private-contact-discovery/) is considered impractical +for a federated network, as it requires specialized hardware. While a bit out of scope for this MSC, there has been debate over preventing 3PIDs as being kept as plain-text on disk. The argument against this was that if the hashing algorithm (in this case SHA-256) was broken, we couldn't update -the hashing algorithm without having the plaintext 3PIDs. Well @toml helpfully +the hashing algorithm without having the plaintext 3PIDs. @lampholder helpfully added that we could just take the old hashes and rehash them in the more secure hashing algorithm, thus transforming the hash from SHA-256 to -SHA-256+SomeBetterAlg. This may spur on an MSC in the future that supports -this, unless it is just an implementation detail. +SHA-256+SomeBetterAlg. However @erikjohnston then pointed out that if +`BrokenAlgo(a) == BrokenAlgo(b)` then `SuperGreatHash(BrokenAlgo(a)) == +SuperGreatHash(BrokenAlgo(b))`, so all you'd need to do is find a match in the +broken algo, and you'd break the new algorithm as well. This means that you +would need the plaintext 3pids to encode a new hash, and thus storing them +hashed on disk is not possible. ## Conclusion From 36a35a33cc975c3a594048cb8cd94d09f36d0f79 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 24 Jun 2019 16:59:58 +0100 Subject: [PATCH 0569/1250] Clarify how the spec defines hashing algs --- proposals/2134-identity-hash-lookup.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 2240b640..a2b3f157 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -46,12 +46,12 @@ GET /_matrix/identity/v2/hash_details ``` This endpoint takes no parameters, and simply returns supported hash algorithms -and pepper as a JSON object: +and peppers as a JSON object: ``` { "lookup_pepper": "matrixrocks", - "algorithm": "sha256", + "algorithms": ["sha256"], } ``` @@ -60,9 +60,11 @@ returned for other endpoints in the future. Clients should request this endpoint each time before making a `/lookup` or `/bulk_lookup` request, to handle identity servers which may rotate their -pepper values frequently. +pepper values frequently. Clients must choose one of the given hash algorithms +to encrypt the 3pid during lookup. -An example of generating a hash using the above hash and pepper is as follows: +An example of generating a hash using SHA-256 and the provided pepper is as +follows: ```python address = "user@example.org" @@ -73,10 +75,12 @@ print(result_address) vNjEQuRCOmBp/KTuIpZ7RUJgPAbVAyqa0Uzh770tQaw ``` -SHA-256 MUST be supported by both servers and clients at a minimum. It has been -chosen as it is [currently used -elsewhere](https://matrix.org/docs/spec/server_server/r0.1.2#adding-hashes-and-signatures-to-outgoing-events) -in the Matrix protocol, and is reasonably secure as of 2019. +Possible hashing algorithms will be defined in the Matrix specification, and an +Identity Server can choose to implement one or all of them. Later versions of +the specification may deprecate algorithms when necessary. Currently the only +listed hashing algorithm is SHA-256 as defined by [RFC +4634](https://tools.ietf.org/html/rfc4634) and Identity Servers and clients +MUST agree to its use with the string `sha256`. When performing a lookup, the pepper and hashing algorithm the client used must be part of the request body. If they do not match what the server has on file From 0a4c83ddb9107ed5f8420dfd0df09bc8b4025d19 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 24 Jun 2019 17:54:23 +0100 Subject: [PATCH 0570/1250] no plural. 3pid -> 3PID --- proposals/2134-identity-hash-lookup.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index a2b3f157..f8389e44 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -45,8 +45,8 @@ requires before sending it hashes. A new endpoint must be added: GET /_matrix/identity/v2/hash_details ``` -This endpoint takes no parameters, and simply returns supported hash algorithms -and peppers as a JSON object: +This endpoint takes no parameters, and simply returns any supported hash +algorithms and pepper as a JSON object: ``` { @@ -61,7 +61,7 @@ returned for other endpoints in the future. Clients should request this endpoint each time before making a `/lookup` or `/bulk_lookup` request, to handle identity servers which may rotate their pepper values frequently. Clients must choose one of the given hash algorithms -to encrypt the 3pid during lookup. +to encrypt the 3PID during lookup. An example of generating a hash using SHA-256 and the provided pepper is as follows: @@ -130,8 +130,8 @@ implementation, and should return a HTTP 404 if so. If an identity server is too old and a HTTP 404, 405 or 501 is received when accessing the `v2` endpoint, they should fallback to the `v1` endpoint instead. -However, clients should be aware that plain-text 3pids are required, and MUST -ask for user consent to send 3pids in plain-text, and be clear about where they +However, clients should be aware that plain-text 3PIDs are required, and MUST +ask for user consent to send 3PIDs in plain-text, and be clear about where they are being sent to. ## Tradeoffs @@ -179,7 +179,7 @@ SHA-256+SomeBetterAlg. However @erikjohnston then pointed out that if `BrokenAlgo(a) == BrokenAlgo(b)` then `SuperGreatHash(BrokenAlgo(a)) == SuperGreatHash(BrokenAlgo(b))`, so all you'd need to do is find a match in the broken algo, and you'd break the new algorithm as well. This means that you -would need the plaintext 3pids to encode a new hash, and thus storing them +would need the plaintext 3PIDs to encode a new hash, and thus storing them hashed on disk is not possible. ## Conclusion From fae6883cc03341b5eb2c417abd013201875c2279 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 25 Jun 2019 10:18:11 +0100 Subject: [PATCH 0571/1250] Update with review comments --- proposals/2134-identity-hash-lookup.md | 34 +++++++++++++------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index f8389e44..ccbc38b9 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -11,7 +11,7 @@ If the 3PID is hashed, the identity server could not determine the address unless it has already seen that address in plain-text during a previous call of the /bind mechanism. -Note that in terms of privacy, this proposal does not stop an identity service +Note that in terms of privacy, this proposal does not stop an identity server from mapping hashed 3PIDs to users, resulting in a social graph. However, the identity of the 3PID will at least remain a mystery until /bind is used. @@ -32,13 +32,13 @@ other endpoints): value, and the resulting digest MUST be encoded in unpadded base64. Identity servers must specify their own hashing algorithms (from a list of -specified values) and peppers, which will be useful if a rainbow table is +specified values) and pepper, which will be useful if a rainbow table is released for their current one. Identity servers could also set a timer for rotating the pepper value to further impede rainbow table publishing (the -recommended period is every 30m, which should be enough for a client to +recommended period is every 30 minutes, which should be enough for a client to complete the hashing of all of a user's contacts, but also be nowhere near as long enough to create a sophisticated rainbow table). As such, it must be -possible for clients to be able to query what pepper an identity server +possible for clients to be able to query what pepper the identity server requires before sending it hashes. A new endpoint must be added: ``` @@ -80,12 +80,16 @@ Identity Server can choose to implement one or all of them. Later versions of the specification may deprecate algorithms when necessary. Currently the only listed hashing algorithm is SHA-256 as defined by [RFC 4634](https://tools.ietf.org/html/rfc4634) and Identity Servers and clients -MUST agree to its use with the string `sha256`. +MUST agree to its use with the string `sha256`. SHA-256 was chosen as it is +currently used throughout the Matrix spec, as well as its properties of being +quick to hash. While this reduces the resources necessary to generate a rainbow +table for attackers, a fast hash is necessary if particularly slow mobile +clients are going to be hashing thousands of contacts. When performing a lookup, the pepper and hashing algorithm the client used must be part of the request body. If they do not match what the server has on file (which may be the case if the pepper was rotated right after the client's -request for it), then the server can inform the client that they need to query +request for it), then the server must inform the client that they need to query the hash details again, instead of just returning an empty response, which clients would assume to mean that no contacts are registered on that identity server. @@ -117,20 +121,16 @@ following: If the pepper does not match the server's, the server should return a `400 M_INVALID_PARAM`. -No parameter changes will be made to /bind, but identity servers should keep a -hashed value for each address it knows about in order to process lookups -quicker. It is the recommendation that this is done during the act of binding. -Be wary that these hashes will need to be changed whenever the server's pepper -is rotated. +No parameter changes will be made to /bind. ## Fallback considerations `v1` versions of these endpoints may be disabled at the discretion of the -implementation, and should return a HTTP 404 if so. +implementation, and should return a HTTP 403 if so. If an identity server is too old and a HTTP 404, 405 or 501 is received when accessing the `v2` endpoint, they should fallback to the `v1` endpoint instead. -However, clients should be aware that plain-text 3PIDs are required, and MUST +However, clients should be aware that plain-text 3PIDs are required, and SHOULD ask for user consent to send 3PIDs in plain-text, and be clear about where they are being sent to. @@ -147,11 +147,10 @@ This proposal does not force an identity server to stop handling plain-text requests, because a large amount of the Matrix ecosystem relies upon this behavior. However, a conscious effort should be made by all users to use the privacy respecting endpoints outlined above. Identity servers may disallow use -of the v1 endpoint. +of the v1 endpoint, as per above. Unpadded base64 has been chosen to encode the value due to use in many other -portions of the spec. However, it does mean that special characters in the -address will have to be encoded when used as a parameter value. +portions of the spec. ## Other considered solutions @@ -180,7 +179,8 @@ SHA-256+SomeBetterAlg. However @erikjohnston then pointed out that if SuperGreatHash(BrokenAlgo(b))`, so all you'd need to do is find a match in the broken algo, and you'd break the new algorithm as well. This means that you would need the plaintext 3PIDs to encode a new hash, and thus storing them -hashed on disk is not possible. +hashed on disk would require a transition period where 3pids were reuploaded in +a strong hash variant. ## Conclusion From f951f312e1ac610b4bcf2d3af1422633d0e13a12 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 25 Jun 2019 10:30:29 +0100 Subject: [PATCH 0572/1250] Fix terrible wording --- proposals/2134-identity-hash-lookup.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index ccbc38b9..b9a53cb0 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -160,11 +160,11 @@ bind, as it cannot trust a homeserver to do so as the homeserver may be lying. Additionally, only storing 3PID hashes at rest instead of the plain-text versions is impractical if the hashing algorithm ever needs to be changed. -Bloom filters are an alternative method of providing private contact discovery, -however does not scale well due to clients needing to download a large filter -that needs updating every time a new bind is made. Further considered solutions -are explored in https://signal.org/blog/contact-discovery/ Signal's eventual -solution of using Software Guard Extensions (detailed in +Bloom filters are an alternative method of providing private contact discovery. +However, they do not scale well due to requiring clients to download a large +filter that needs updating every time a new bind is made. Further considered +solutions are explored in https://signal.org/blog/contact-discovery/. Signal's +eventual solution of using Software Guard Extensions (detailed in https://signal.org/blog/private-contact-discovery/) is considered impractical for a federated network, as it requires specialized hardware. From 96e43aaf45469998cfa65f097b099fbac5042b14 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 25 Jun 2019 10:37:45 +0100 Subject: [PATCH 0573/1250] Define what characters lookup_pepper can consist of --- proposals/2134-identity-hash-lookup.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index b9a53cb0..34e9b0a6 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -56,7 +56,8 @@ algorithms and pepper as a JSON object: ``` The name `lookup_pepper` was chosen in order to account for pepper values being -returned for other endpoints in the future. +returned for other endpoints in the future. The contents of `lookup_pepper` +MUST match the regular expression `[a-zA-Z0-9]*`. Clients should request this endpoint each time before making a `/lookup` or `/bulk_lookup` request, to handle identity servers which may rotate their From 2c09580e2798f0cd51590174040df6bde2b996a4 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 25 Jun 2019 11:14:35 +0100 Subject: [PATCH 0574/1250] line wrap --- proposals/2140-terms-of-service-2.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 6c5bb6a5..42a1ea38 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -1,9 +1,10 @@ # MSC2140: Terms of Service API for Identity Servers and Integration Managers -[MSC1692](https://github.com/matrix-org/matrix-doc/issues/1692) introduces a method for homeservers to require that users read and -agree to certain documents before being permitted to use the service. This -proposal introduces a corresponding method that can be used with Identity -Servers and Integration Managers. +[MSC1692](https://github.com/matrix-org/matrix-doc/issues/1692) introduces a +method for homeservers to require that users read and agree to certain +documents before being permitted to use the service. This proposal introduces a +corresponding method that can be used with Identity Servers and Integration +Managers. The challenge here is that Identity Servers do not require any kind of user login to access the service and so are unable to track what users have agreed From 6f374dc981b6330d59cf5f45022f0176ce19cf16 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 25 Jun 2019 14:58:15 +0100 Subject: [PATCH 0575/1250] Re-write for OpenID auth --- proposals/2140-terms-of-service-2.md | 143 +++++++++++++++------------ 1 file changed, 80 insertions(+), 63 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 42a1ea38..7b6dd4dc 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -6,16 +6,15 @@ documents before being permitted to use the service. This proposal introduces a corresponding method that can be used with Identity Servers and Integration Managers. -The challenge here is that Identity Servers do not require any kind of user -login to access the service and so are unable to track what users have agreed -to what terms in the way that Homeservers do. We thereforce cannot re-use the -same method for Identity Servers without fundamentally changing the Identity -Service API. - Requirements for this proposal are: * ISs and IMs should be able to give multiple documents a user must agree to abide by * Each document shoud be versioned + * ISes and IMs must, for each request that they handle, know that the user + making the request has agreed to their data being used. This need not be + absolute proof (we will always have to trust that the client actually + showed the document to the user) but it must be reasonably demonstrable that + the user has given informed consent for the client to use that service. * ISs and IMs must be able to prevent users from using the service if they have not provided agreement. * A user should only have to agree to each version of each document once for @@ -27,16 +26,61 @@ Requirements for this proposal are: (bearing in mind that the user must be able to opt-out of components of a service whilst still being able to use the service without that component). +Identity Servers do not currently require any kind of user login to access the +service and so are unable to track what users have agreed to what terms in the +way that Homeservers do. + ## Proposal Throuhgout this proposal, $prefix will be used to refer to the prefix of the -API in question, ie. `/_matrix/identity/api/v1` for the IS API and +API in question, ie. `/_matrix/identity/v2` for the IS API and `/_matrix/integrations/v1` for the IM API. +Note the removal of the `/api` prefix and migration to v2 in the IS API +following convention from +[MSC2134](https://github.com/matrix-org/matrix-doc/issues/2134). + This proposal introduces: * The `$prefix/terms` endpoint * The `m.accepted_terms` section in account data - * The `X-TERMS-TOKEN` HTTP header + +This proposal relies on both Integration Managers and Identity Servers being +able to identity users by their mxid and store the fact that a given mxid has +indicated that they accept the terms given. Integration Managers already +identity users in this way by authenticating them using the OpenID endpoint on +the Homeserver. This proposal introduces the same mechanism to Identity Servers +and adds authentication to accross the Identity Service API. + +### IS API Authentication + +All current endpoints within `/_matrix/identity/api/v1/` will be duplicated +into `/_matrix/identity/v2`. + +Any request to any endpoint within `/_matrix/identity/v2`, with the exception of +`/_matrix/identity/v2` and the new `/_matrix/identity/v2/account/register` may +return an error with `M_UNAUTHORIZED` errcode with HTTP status code 401. This +indicates that the user must authenticate with OpenID and supply a valid +`access_token`. + +The existing endpoints under `/_matrix/identity/api/v1/` continue to be unauthenticated. +ISes may support the old v1 API for as long as they wish. Clients must update to use +the v2 API as soon as possible. + +OpenID authentication in the IS API will work the same as in the Integration Manager +API, as specified in [MSC1961](https://github.com/matrix-org/matrix-doc/issues/1961). + +### IS Register API + +The following new APIs will be introduced to support OpenID auth as per +[MSC1961](https://github.com/matrix-org/matrix-doc/issues/1961): + + * `/_matrix/identity/v2/account/register` + * `/_matrix/identity/v2/account` + * `/_matrix/identity/v2/account/logout` + +Note again the removal of the `/api` prefix and migration to v2 following +convention from +[MSC2134](https://github.com/matrix-org/matrix-doc/issues/2134). ### Terms API @@ -71,7 +115,7 @@ that the URL contains the version number of the document. The name and version keys, however, are used only to provide a human-readable description of the document to the user. -In the IM API, the client should provide authentication for this endpoint. +The client should provide authentication for this endpoint. #### `POST $prefix/terms`: Requests to this endpoint have a single key, `user_accepts` whose value is @@ -84,7 +128,7 @@ the user has agreed to: } ``` -In the IM API, the client should provide authentication for this endpoint. +The client should provide authentication for this endpoint. The clients MUST include the correct URL for the language of the document that was presented to the user and they agreed to. How servers store or serialise @@ -95,24 +139,6 @@ any one language of each document as sufficient, regardless of what language a client is operating in: users should not have to re-consent to documents if they change their client to a different language. -The response MAY contain a `acceptance_token` which, if given, is an -opaque string that the client must store for use in subsequent requests -to any endpoint to the same server. - -If the server has stored the fact that the user has agreed to these terms, -(which implies the user is authenticated) it can supply no `acceptance_token`. -The server may instead choose to supply an `acceptance_token`, for example if, -as in the IS API, the user is unauthenticated and therefore the server is -unable to store the fact a user has agreed to a set of terms. - -The `acceptance_token` is an opaque string contining characters -`[a-zA-Z0-9._-]`. It is up to the server how it computes it, but the server -must be able to, given an `acceptance_token`, compute whether it constitutes -agreement to a given set of terms. For example, the simplest (but most verbose) -implemenation would be to make the `acceptance_token` the JSON array of -documents as provided in the request. A smarter implementation may be a simple -hash, or even cryptograhic hash if desired. - ### Accepted Terms Account Data This proposal also defines the `m.accepted_terms` section in User Account @@ -138,12 +164,17 @@ to this list. ### Terms Acceptance in the API -Any request to any endpoint in the IS and IM APIs, with the exception of -`/_matrix/identity/api/v1` may return a `M_TERMS_NOT_SIGNED` errcode. This -indicates that the user must agree to (new) terms in order to use or continue -to use the service. The `_matrix/identity/api/v1/3pid/unbind` must also not -return the `M_TERMS_NOT_SIGNED` if the request has a valid signature from a -Homeserver. +Any request to any endpoint in the IM API, and the `_matrix/identity/v2/` +namespace of the IS API, with the exception of `/_matrix/identity/v2` itself, +may return: + + * `M_UNAUTHORIZED` errcode with HTTP status code 401. This indicates that + the user must authenticate with OpenID and supply a valid `access_token`. + * `M_TERMS_NOT_SIGNED` errcode. This indicates that the user must agree to + (new) terms in order to use or continue to use the service. + +The `_matrix/identity/v2/3pid/unbind` must not return either of these +errors if the request has a valid signature from a Homeserver. The client uses the `GET $prefix/terms` endpoint to get the latest set of terms that must be agreed to. It then cross-references this set of documents against @@ -153,25 +184,17 @@ agreement. Once the user has indicated their agreement, then, and only then, must the client use the `POST $prefix/terms` API to signal to the server the set of documents that the user has agreed to. -If the server returns an `acceptance_token`, the client should include this -token in the `X-TERMS-TOKEN` HTTP header in all subsequent requests to an -endpoint on the API with the exception of `/_matrix/identity/api/v1`. - -The client must also include the X-TERMS-TOKEN on any request to the Homeserver -where it specifies an Identity Server to be used by the Homeserver. Homeservers -must read this header from the request headers of any such endpoint and add it -to the request headers of any request it makes to the Identity Server. - -Both making the `POST $prefix/terms` request and providing an `X-TERMS-TOKEN` -header signal that the user consents to the terms contained within the -corresponding documents. That is to say, if a client or user obtains an -acceptance token via means other than a response to the `POST $prefix/terms` -API, inclusion of the acceptance token in an `X-TERMS-TOKEN` header in a -request still constitutes agreement to the terms in the corresponding -documents. - ## Tradeoffs +The Identity Service API previously did not require authentication, and OpenID +is reasonably complex, adding a significant burden to both clients and servers. +A custom HTTP Header was also considered that could be added to assert that the +client agrees to a particular set of terms. We decided against this in favour +of re-using existing primitives that already exist in the Matrix ecosystem. +Custom HTTP Headers are not used anywhere else within Matrix. This also gives a +very simple and natural way for ISes to enforce that users may only bind 3pids +to their own mxids. + This introduces a different way of accepting terms from the client/server API which uses User-Interactive Authentication. In the client/server API, the use of UI auth allows terms acceptance to be integrated into the registration flow @@ -189,21 +212,15 @@ the document, but: ## Potential issues -If the server does not authentcate users, some mechanism is required to track -users agreement to terms. The introduction of an extra HTTP header on all -requests adds overhead to every request and complexity to the client to add a -custom header. - +This change is not backwards compatible: clients implementing older versions of +the specification will expect to be able to access all IS API endpoints without +authentication. Care should be taken to manage the rollout of authentication +on IS APIs. ## Security considerations -The `acceptance_token` is, in effect, a cookie and could be used to identify -users of the service. Users of the Integration manager must be authenticated -anyway, so this is irrelevant for the IM API. It could allow an Identity Server -to identify users where it may otherwise not be able to do so (if a client was -careful to mask other identifying HTTP headers). Given most requests to the IS -API, by their nature, include 3pids which, even if hashed, will make users -easily identifiable, this probably does not add any significant concern. +Requiring authentication on the IS API means it will no longer be possible to +use it anonymously. It is assumed that once servers publish a given version of a document at a given URL, the contents of that URL will not change. This could be mitigated by From 4f83cc1c244b78d9c34abde492116f4dcdae4047 Mon Sep 17 00:00:00 2001 From: Sorunome Date: Tue, 25 Jun 2019 16:19:29 +0200 Subject: [PATCH 0576/1250] moved client spoiler conversion to potential issues --- proposals/2010-spoilers.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/2010-spoilers.md b/proposals/2010-spoilers.md index 40feed29..fc470fcc 100644 --- a/proposals/2010-spoilers.md +++ b/proposals/2010-spoilers.md @@ -52,10 +52,6 @@ however that wouldn't be HTML-compliant. Instead of limiting the proposed `data-mx-spoiler` attribute only to the ``-tag it could be added to all tags, however it might make implementations for clients more complicated. -Clients would have to come up with a way how to input spoilers. This could be done, for example, -by adding a custom markdown tag (like discord does), so that you do `Text ||spoiler||`, however -that doesn't take a spoiler reason into account. - ## Potential issues Depending on context it might make sense to put other events, such as `m.image`, into spoilers, too. This MSC doesn't address that at all. Using @@ -63,5 +59,9 @@ too. This MSC doesn't address that at all. Using This MSC doesn't take HTML block elements into account. +Clients would have to come up with a way how to input spoilers. This could be done, for example, +by adding a custom markdown tag (like discord does), so that you do `Text ||spoiler||`, however +that doesn't take a spoiler reason into account. + ## Security considerations The spoiler reason needs to be properly escaped when rendered. From 0dae2d5812d0d22350c9237b84634e81e0306b24 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 25 Jun 2019 15:52:55 +0100 Subject: [PATCH 0577/1250] GET terms must be unauthed. Detail process for new auth (don't register until consent given). Specifically mention the authentication header. --- proposals/2140-terms-of-service-2.md | 55 +++++++++++++++++++++------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 7b6dd4dc..67e6a2eb 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -56,11 +56,15 @@ and adds authentication to accross the Identity Service API. All current endpoints within `/_matrix/identity/api/v1/` will be duplicated into `/_matrix/identity/v2`. -Any request to any endpoint within `/_matrix/identity/v2`, with the exception of -`/_matrix/identity/v2` and the new `/_matrix/identity/v2/account/register` may -return an error with `M_UNAUTHORIZED` errcode with HTTP status code 401. This -indicates that the user must authenticate with OpenID and supply a valid -`access_token`. +Any request to any endpoint within `/_matrix/identity/v2`, with the exception +of `/_matrix/identity/v2` and the new `/_matrix/identity/v2/account/register` +and `GET /_matrix/identity/v2/terms` may return an error with `M_UNAUTHORIZED` +errcode with HTTP status code 401. This indicates that the user must +authenticate with OpenID and supply a valid `access_token`. + +These endpoints require authentication by the client supplying an access token +either via an `Authorization` header with a `Bearer` token or an `access_token` +query parameter. The existing endpoints under `/_matrix/identity/api/v1/` continue to be unauthenticated. ISes may support the old v1 API for as long as they wish. Clients must update to use @@ -115,7 +119,7 @@ that the URL contains the version number of the document. The name and version keys, however, are used only to provide a human-readable description of the document to the user. -The client should provide authentication for this endpoint. +This endpoint does *not* require authentication. #### `POST $prefix/terms`: Requests to this endpoint have a single key, `user_accepts` whose value is @@ -128,7 +132,7 @@ the user has agreed to: } ``` -The client should provide authentication for this endpoint. +This endpoint requires authentication. The clients MUST include the correct URL for the language of the document that was presented to the user and they agreed to. How servers store or serialise @@ -164,6 +168,22 @@ to this list. ### Terms Acceptance in the API +Before any requests are made to an Identity Server or Integration Manager, +the client must use the `GET $prefix/terms` endpoint to fetch the set of +documents that the user must agree to in order to use the service. + +It then cross-references this set of documents against the `m.accepted_terms` +account data and presents to the user any documents that they have not already +agreed to, along with UI for them to indicate their agreement. Once the user +has indicated their agreement, it adds these URLs to `m.accepted_terms` account +data. Once this has succeeded, then, and only then, must the client perform +OpenID authentication, getting a token from the Homeserver and submitting this +to the service using the `register` endpoint. + +Having done this, if the user agreed to any new documents, it performs a `POST +$prefix/terms` request to signal to the server the set of documents that the +user has agreed to. + Any request to any endpoint in the IM API, and the `_matrix/identity/v2/` namespace of the IS API, with the exception of `/_matrix/identity/v2` itself, may return: @@ -176,13 +196,20 @@ may return: The `_matrix/identity/v2/3pid/unbind` must not return either of these errors if the request has a valid signature from a Homeserver. -The client uses the `GET $prefix/terms` endpoint to get the latest set of terms -that must be agreed to. It then cross-references this set of documents against -the `m.accepted_terms` account data and presents to the user any documents -that they have not already agreed to, along with UI for them to indicate their -agreement. Once the user has indicated their agreement, then, and only then, -must the client use the `POST $prefix/terms` API to signal to the server the -set of documents that the user has agreed to. +In summary, the process for using a service that has not previously been used +in the current login sessions is: + + * `GET $prefix/terms` + * Compare result with `m.accepted_terms` account data, get set of documents + pending agreement + * If non-empty, show this set of documents to the user and wait for the user + to indicate their agreement. + * Add the newly agreed documents to `m.accepted_terms` + * On success, or if there were no documents pending agreement, get an OpenID + token from the Homeserver and submit this token to the `register` endpoint. + Store the resulting access token. + * If the set of documents pending agreement was non-empty, Perform a + `POST $prefix/terms` request to the servcie with these documents. ## Tradeoffs From 4997abc4b7cd36722003be98f7efae8d37f3f476 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 25 Jun 2019 16:47:10 +0100 Subject: [PATCH 0578/1250] as as -> as --- specification/client_server_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 9b16abc3..39a2fd3d 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1314,7 +1314,7 @@ to keep moving forwards. Filtering --------- -Filters can be created on the server and can be passed as as a parameter to APIs +Filters can be created on the server and can be passed as a parameter to APIs which return events. These filters alter the data returned from those APIs. Not all APIs accept filters. From e88a074c9ff9f2fa2f9c1aa129a0376a0bc5c617 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 25 Jun 2019 17:02:39 +0100 Subject: [PATCH 0579/1250] Add changelog --- changelogs/client_server/newsfragments/2148.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2148.misc diff --git a/changelogs/client_server/newsfragments/2148.misc b/changelogs/client_server/newsfragments/2148.misc new file mode 100644 index 00000000..d5514131 --- /dev/null +++ b/changelogs/client_server/newsfragments/2148.misc @@ -0,0 +1 @@ +Fix a small duplicated "as". From 9e0d8b9cb29807d2e16b2332dc59f7b0aaad1fb2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 25 Jun 2019 17:17:39 +0100 Subject: [PATCH 0580/1250] Use M_CONSENT_NOT_GIVEN No idea where I got the other one from: we already have one in the spec, so use it. --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 67e6a2eb..b0b15b07 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -190,7 +190,7 @@ may return: * `M_UNAUTHORIZED` errcode with HTTP status code 401. This indicates that the user must authenticate with OpenID and supply a valid `access_token`. - * `M_TERMS_NOT_SIGNED` errcode. This indicates that the user must agree to + * `M_CONSENT_NOT_GIVEN` errcode. This indicates that the user must agree to (new) terms in order to use or continue to use the service. The `_matrix/identity/v2/3pid/unbind` must not return either of these From df88b13ce13690fb46e8a587d81f4011019c0acc Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Tue, 25 Jun 2019 18:15:02 +0100 Subject: [PATCH 0581/1250] Update proposals/2134-identity-hash-lookup.md Co-Authored-By: Hubert Chathi --- proposals/2134-identity-hash-lookup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 34e9b0a6..ba1d974e 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -29,7 +29,7 @@ other endpoints): - `/_matrix/identity/v2/bulk_lookup` `address` MUST no longer be in a plain-text format, but rather will be a peppered hash -value, and the resulting digest MUST be encoded in unpadded base64. +value encoded in unpadded base64. Identity servers must specify their own hashing algorithms (from a list of specified values) and pepper, which will be useful if a rainbow table is From dfb37fcce1932fed58700a21b336687bba061a1e Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 25 Jun 2019 18:55:18 +0100 Subject: [PATCH 0582/1250] update with feedback --- proposals/2134-identity-hash-lookup.md | 30 ++++++++++++-------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index ba1d974e..94cd4e48 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -31,15 +31,11 @@ other endpoints): `address` MUST no longer be in a plain-text format, but rather will be a peppered hash value encoded in unpadded base64. -Identity servers must specify their own hashing algorithms (from a list of -specified values) and pepper, which will be useful if a rainbow table is -released for their current one. Identity servers could also set a timer for -rotating the pepper value to further impede rainbow table publishing (the -recommended period is every 30 minutes, which should be enough for a client to -complete the hashing of all of a user's contacts, but also be nowhere near as -long enough to create a sophisticated rainbow table). As such, it must be -possible for clients to be able to query what pepper the identity server -requires before sending it hashes. A new endpoint must be added: +Identity servers must specify the hashing algorithms and a pepper that they +support, which will allow for rotation if a rainbow table is ever released +coinciding with their current hash and pepper. As such, it must be possible for +clients to be able to query what pepper the identity server requires before +sending it hashes. A new endpoint must be added: ``` GET /_matrix/identity/v2/hash_details @@ -64,13 +60,13 @@ Clients should request this endpoint each time before making a `/lookup` or pepper values frequently. Clients must choose one of the given hash algorithms to encrypt the 3PID during lookup. -An example of generating a hash using SHA-256 and the provided pepper is as -follows: +Peppers are appended to the end of the 3PID before hashing. An example of +generating a hash using SHA-256 and the provided pepper is as follows: ```python address = "user@example.org" pepper = "matrixrocks" -digest = hashlib.sha256((pepper + address).encode()).digest() +digest = hashlib.sha256((address + pepper).encode()).digest() result_address = unpaddedbase64.encode_base64(digest) print(result_address) vNjEQuRCOmBp/KTuIpZ7RUJgPAbVAyqa0Uzh770tQaw @@ -119,15 +115,17 @@ following: } ``` -If the pepper does not match the server's, the server should return a `400 -M_INVALID_PARAM`. +If the algorithm does not match the server's, the server should return a 400 +`M_INVALID_PARAM`. If the pepper does not match the server's, the server should +return a new error code, 400 `M_INVALID_PEPPER`. A new error code is not +defined for an invalid algorithm as that is considered a client bug. No parameter changes will be made to /bind. ## Fallback considerations `v1` versions of these endpoints may be disabled at the discretion of the -implementation, and should return a HTTP 403 if so. +implementation, and should return a 403 `M_FORBIDDEN` error if so. If an identity server is too old and a HTTP 404, 405 or 501 is received when accessing the `v2` endpoint, they should fallback to the `v1` endpoint instead. @@ -180,7 +178,7 @@ SHA-256+SomeBetterAlg. However @erikjohnston then pointed out that if SuperGreatHash(BrokenAlgo(b))`, so all you'd need to do is find a match in the broken algo, and you'd break the new algorithm as well. This means that you would need the plaintext 3PIDs to encode a new hash, and thus storing them -hashed on disk would require a transition period where 3pids were reuploaded in +hashed on disk would require a transition period where 3PIDs were reuploaded in a strong hash variant. ## Conclusion From 0fd4fe254207badb98be9eb1fc968db8913bc323 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 26 Jun 2019 10:55:44 +0100 Subject: [PATCH 0583/1250] Add algo/pepper to err resp --- proposals/2134-identity-hash-lookup.md | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 34e9b0a6..accadc25 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -28,8 +28,10 @@ other endpoints): - `/_matrix/identity/v2/lookup` - `/_matrix/identity/v2/bulk_lookup` -`address` MUST no longer be in a plain-text format, but rather will be a peppered hash -value, and the resulting digest MUST be encoded in unpadded base64. +`address` MUST no longer be in a plain-text format, but rather will be a +peppered hash value, and the resulting digest MUST be encoded in URL-safe +unpadded base64 (similar to [room version 4's event +IDs](https://matrix.org/docs/spec/rooms/v4#event-ids)). Identity servers must specify their own hashing algorithms (from a list of specified values) and pepper, which will be useful if a rainbow table is @@ -119,8 +121,23 @@ following: } ``` -If the pepper does not match the server's, the server should return a `400 -M_INVALID_PARAM`. +If the algorithm does not match the server's, the server should return a `400 +M_INVALID_PARAM`. If the pepper does not match the server's, the server should +return a new error code, 400 `M_INVALID_PEPPER`. A new error code is not +defined for an invalid algorithm as that is considered a client bug. Each of +these error responses should contain the correct `algorithm` and +`lookup_pepper` fields. This is to prevent the client from needing to query +`/hash_details` again, thus saving a round-trip. An example response to an +incorrect pepper would be: + +``` +{ + "error": "Incorrect value for lookup_pepper", + "errcode": "M_INVALID_PEPPER", + "algorithm": "sha256", + "lookup_pepper": "matrixrocks" +} +``` No parameter changes will be made to /bind. From 57094276ce01e324b174a74c40b63ea8afdc0ba8 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 26 Jun 2019 14:36:15 +0100 Subject: [PATCH 0584/1250] Typing hard is Co-Authored-By: Travis Ralston --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index b0b15b07..a483607b 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -21,7 +21,7 @@ Requirements for this proposal are: their Matrix ID, ie. having agreed to a set of terms in one client, they should not have to agree to them again when using a different client. * Documents should be de-duplicated between services. If two or more services - are hosted by the same organisation, the organistation should have the + are hosted by the same organisation, the organisation should have the option to give their users a single document that encompasses both services (bearing in mind that the user must be able to opt-out of components of a service whilst still being able to use the service without that component). From af691b5a8ad09ea82cfc49f596eae90448aa4725 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 26 Jun 2019 14:37:06 +0100 Subject: [PATCH 0585/1250] Clarify this applies to 2134 Co-Authored-By: Travis Ralston --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index a483607b..b508a9e2 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -54,7 +54,7 @@ and adds authentication to accross the Identity Service API. ### IS API Authentication All current endpoints within `/_matrix/identity/api/v1/` will be duplicated -into `/_matrix/identity/v2`. +into `/_matrix/identity/v2`, noting that MSC2134 changes the behaviour of lookups. Authentication is still expected on MSC2134's proposed endpoints. Any request to any endpoint within `/_matrix/identity/v2`, with the exception of `/_matrix/identity/v2` and the new `/_matrix/identity/v2/account/register` From 1d75828c71bb442ceed735c4ee6593171a08319c Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 26 Jun 2019 14:45:25 +0100 Subject: [PATCH 0586/1250] Clarify what to do if no (new) docs --- proposals/2140-terms-of-service-2.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index b508a9e2..ad617508 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -174,11 +174,13 @@ documents that the user must agree to in order to use the service. It then cross-references this set of documents against the `m.accepted_terms` account data and presents to the user any documents that they have not already -agreed to, along with UI for them to indicate their agreement. Once the user -has indicated their agreement, it adds these URLs to `m.accepted_terms` account -data. Once this has succeeded, then, and only then, must the client perform -OpenID authentication, getting a token from the Homeserver and submitting this -to the service using the `register` endpoint. +agreed to, along with UI for them to indicate their agreement. If there are no +such documents (ie. if the `policies` dict is empty or the user has already +agreed to all documents) the client proceeds to perform the OpenID +registration. Once the user has indicated their agreement, it adds these URLs +to `m.accepted_terms` account data. Once this has succeeded, then, and only +then, must the client perform OpenID authentication, getting a token from the +Homeserver and submitting this to the service using the `register` endpoint. Having done this, if the user agreed to any new documents, it performs a `POST $prefix/terms` request to signal to the server the set of documents that the From ba7047ce7746733f77dbf4d6163767304690a2c7 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 26 Jun 2019 14:51:11 +0100 Subject: [PATCH 0587/1250] Clarify we must be accepting HS auth Co-Authored-By: Travis Ralston --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index ad617508..631ff5e8 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -196,7 +196,7 @@ may return: (new) terms in order to use or continue to use the service. The `_matrix/identity/v2/3pid/unbind` must not return either of these -errors if the request has a valid signature from a Homeserver. +errors if the request has a valid signature from a Homeserver, and is being authenticated as such. In summary, the process for using a service that has not previously been used in the current login sessions is: From 4edf826c9371aad7c5c22fec7434a1889d66b74c Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 26 Jun 2019 14:52:19 +0100 Subject: [PATCH 0588/1250] Capitalise on our identifiers --- proposals/2140-terms-of-service-2.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 631ff5e8..fc7d33b2 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -45,7 +45,7 @@ This proposal introduces: * The `m.accepted_terms` section in account data This proposal relies on both Integration Managers and Identity Servers being -able to identity users by their mxid and store the fact that a given mxid has +able to identity users by their MXID and store the fact that a given MXID has indicated that they accept the terms given. Integration Managers already identity users in this way by authenticating them using the OpenID endpoint on the Homeserver. This proposal introduces the same mechanism to Identity Servers @@ -221,8 +221,8 @@ A custom HTTP Header was also considered that could be added to assert that the client agrees to a particular set of terms. We decided against this in favour of re-using existing primitives that already exist in the Matrix ecosystem. Custom HTTP Headers are not used anywhere else within Matrix. This also gives a -very simple and natural way for ISes to enforce that users may only bind 3pids -to their own mxids. +very simple and natural way for ISes to enforce that users may only bind 3PIDs +to their own MXIDs. This introduces a different way of accepting terms from the client/server API which uses User-Interactive Authentication. In the client/server API, the use From 6273868323ab19ed42edaaa7d8d4ac5f738e718f Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 26 Jun 2019 15:05:43 +0100 Subject: [PATCH 0589/1250] Clarify v1 API deprecation --- proposals/2140-terms-of-service-2.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index fc7d33b2..6963c965 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -66,9 +66,11 @@ These endpoints require authentication by the client supplying an access token either via an `Authorization` header with a `Bearer` token or an `access_token` query parameter. -The existing endpoints under `/_matrix/identity/api/v1/` continue to be unauthenticated. -ISes may support the old v1 API for as long as they wish. Clients must update to use -the v2 API as soon as possible. +The existing endpoints under `/_matrix/identity/api/v1/` continue to be +unauthenticated but will be deprecated. ISes may support the old v1 API for as +long as they wish. Once ISes remove support for the old APIs, those endpoints +must return HTTP Status 404. Clients must update to use the v2 API as soon as +possible. OpenID authentication in the IS API will work the same as in the Integration Manager API, as specified in [MSC1961](https://github.com/matrix-org/matrix-doc/issues/1961). From 58cf083a6a93e273385cad5a1621895ca15272f5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 26 Jun 2019 15:31:11 +0100 Subject: [PATCH 0590/1250] backwards compat --- proposals/2140-terms-of-service-2.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 6963c965..7018e364 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -243,10 +243,8 @@ the document, but: ## Potential issues -This change is not backwards compatible: clients implementing older versions of -the specification will expect to be able to access all IS API endpoints without -authentication. Care should be taken to manage the rollout of authentication -on IS APIs. +This change deprecates all v1 endpoints and so will require clients to update +to continue working. ## Security considerations From 2694bb1090d565a10ef934a45ce01ae06a009804 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 26 Jun 2019 17:41:21 +0100 Subject: [PATCH 0591/1250] Add really horrible custom HTTP header for giving the IS token to the HS --- proposals/2140-terms-of-service-2.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 7018e364..ed1269a9 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -75,6 +75,12 @@ possible. OpenID authentication in the IS API will work the same as in the Integration Manager API, as specified in [MSC1961](https://github.com/matrix-org/matrix-doc/issues/1961). +When clients supply an identity server to the Homeserver in order for the Homeserver +to make calls to the IS on its behalf, it must also supply its access token for the +Identity Server either as the `is_token` query parameter or a bearer token in the +`X-Identity-Authorization` HTTP header with the same syntax as an `Authorizationn` +header. + ### IS Register API The following new APIs will be introduced to support OpenID auth as per From 21b9eaf8de06d2562c6326dedda66e334f03d6b0 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 26 Jun 2019 17:56:41 +0100 Subject: [PATCH 0592/1250] No custom HTTP headers Use the obvious way: in the same place as the ID server address --- proposals/2140-terms-of-service-2.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index ed1269a9..00a6ba52 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -77,9 +77,13 @@ API, as specified in [MSC1961](https://github.com/matrix-org/matrix-doc/issues/1 When clients supply an identity server to the Homeserver in order for the Homeserver to make calls to the IS on its behalf, it must also supply its access token for the -Identity Server either as the `is_token` query parameter or a bearer token in the -`X-Identity-Authorization` HTTP header with the same syntax as an `Authorizationn` -header. +Identity Server alongside in the `is_token` key of the same JSON object. That is, +in the main request object for a `requestToken` request and in the `threepidCreds` +object when supplying 3PID credentials (eg. in the `m.email.identity` UI auth stage). +Exxceptions to this are any requests where the only IS operation the Homeserver may +perform is unbinding, ie. `/_matrix/client/r0/account/deactivate` and +`/_matrix/client/r0/account/3pid/delete`, in which case the unbind is authenticated +by a signed request from the Homeserver. ### IS Register API From 6260871a21a00cd9959396c6ad07797fe526f089 Mon Sep 17 00:00:00 2001 From: Sorunome Date: Thu, 27 Jun 2019 13:07:08 +0200 Subject: [PATCH 0593/1250] spoiler fallback to uploaded media --- proposals/2010-spoilers.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/proposals/2010-spoilers.md b/proposals/2010-spoilers.md index fc470fcc..7b128078 100644 --- a/proposals/2010-spoilers.md +++ b/proposals/2010-spoilers.md @@ -22,8 +22,9 @@ the spoiler by setting the attribute string. It could be rendered, for example, ![Spoiler rendering idea](https://user-images.githubusercontent.com/2433620/59299700-95063480-8c8d-11e9-9348-3e2c8bc94bdc.gif) -The plain-text fallback could be rendered as `(Spoiler: )` and -`(Spoiler for : )` respectively. +To preserve the semantics of a spoiler in the plaintext fallback it is recommended to upload the contents of the spoiler +as a text file and then link this: `[Spoiler](mxc://someserver/somefile)` and +`[Spoiler for reason](mxc://someserver/somefile)` respectively. ### Example Without reason: @@ -32,7 +33,7 @@ Without reason: "msgtype": "m.text", "format": "org.matrix.custom.html", "body": "Hello there, the movie was (Spoiler: awesome)", - "formatted_body": "Hello there, the movie was awesome" + "formatted_body": "Hello there, the movie was [Spoiler](mxc://someserver/somefile)" } ``` With reason: @@ -41,7 +42,7 @@ With reason: "msgtype": "m.text", "format": "org.matrix.custom.html", "body": "Hey (Spoiler for movie: the movie was awesome)", - "formatted_body": "Hey the movie was awesome" + "formatted_body": "Hey [Spoiler for movie](mxc://someserver/somefile)" } ``` From 540aab82a18bc65aef87cd2b434231d5ce50578e Mon Sep 17 00:00:00 2001 From: Sorunome Date: Thu, 27 Jun 2019 13:09:15 +0200 Subject: [PATCH 0594/1250] accidentally formatted the wrong entry --- proposals/2010-spoilers.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/2010-spoilers.md b/proposals/2010-spoilers.md index 7b128078..df7fd6c1 100644 --- a/proposals/2010-spoilers.md +++ b/proposals/2010-spoilers.md @@ -32,8 +32,8 @@ Without reason: { "msgtype": "m.text", "format": "org.matrix.custom.html", - "body": "Hello there, the movie was (Spoiler: awesome)", - "formatted_body": "Hello there, the movie was [Spoiler](mxc://someserver/somefile)" + "body": "Hello there, the movie was [spoiler](mxc://someserver/somefile)", + "formatted_body": "Hello there, the movie was awesome" } ``` With reason: @@ -41,8 +41,8 @@ With reason: { "msgtype": "m.text", "format": "org.matrix.custom.html", - "body": "Hey (Spoiler for movie: the movie was awesome)", - "formatted_body": "Hey [Spoiler for movie](mxc://someserver/somefile)" + "body": "Hey [Spoiler for movie](mxc://someserver/somefile)", + "formatted_body": "Hey the movie was awesome" } ``` From b5326de1c4c9d894d668cc4e5ec031226b7ad442 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 27 Jun 2019 16:34:46 +0100 Subject: [PATCH 0595/1250] Exclude requestToken endpoints from auth requirement --- proposals/2140-terms-of-service-2.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 00a6ba52..22bdb1f4 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -57,12 +57,20 @@ All current endpoints within `/_matrix/identity/api/v1/` will be duplicated into `/_matrix/identity/v2`, noting that MSC2134 changes the behaviour of lookups. Authentication is still expected on MSC2134's proposed endpoints. Any request to any endpoint within `/_matrix/identity/v2`, with the exception -of `/_matrix/identity/v2` and the new `/_matrix/identity/v2/account/register` -and `GET /_matrix/identity/v2/terms` may return an error with `M_UNAUTHORIZED` -errcode with HTTP status code 401. This indicates that the user must -authenticate with OpenID and supply a valid `access_token`. - -These endpoints require authentication by the client supplying an access token +of `/_matrix/identity/v2`, any `requestToken` endpoint and the new +`/_matrix/identity/v2/account/register` and `GET /_matrix/identity/v2/terms` +may return an error with `M_UNAUTHORIZED` errcode with HTTP status code 401. +This indicates that the user must authenticate with OpenID and supply a valid +`access_token`. + +`requestToken` endpoints are excluded from the auth check because they are used +in the registration process before the user has an MXID and therefore cannot +log in with OpenID. It is up to the IS to manage its privacy obligations +appropriately when fulfilling these requests, bearing in mind that the user has +not explictly incicated their agreement to any documents, and may abort the +registration process without doing so. + +All other endpoints require authentication by the client supplying an access token either via an `Authorization` header with a `Bearer` token or an `access_token` query parameter. From 10a6a59a12924243c2a321df111eec64d01f0234 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 27 Jun 2019 16:58:22 +0100 Subject: [PATCH 0596/1250] Deprecate `bind_email` / `bind_msisdn` --- proposals/2140-terms-of-service-2.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 22bdb1f4..74923e64 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -93,6 +93,13 @@ perform is unbinding, ie. `/_matrix/client/r0/account/deactivate` and `/_matrix/client/r0/account/3pid/delete`, in which case the unbind is authenticated by a signed request from the Homeserver. +### HS Register API + +The `bind_email` and `bind_msisdn` options to `/_matrix/client/r0/register` in +the client/server API will be deprecated. Due to the fact that +`/_matrix/identity/v2/3pid/bind` requires authentication, it will no longer be +possible for the Homeserver to bind 3PIDs as part of the registration process. + ### IS Register API The following new APIs will be introduced to support OpenID auth as per From f95197b4228aec45111c75923bca8f499a38eff7 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 27 Jun 2019 17:30:36 +0100 Subject: [PATCH 0597/1250] make the many-anded sentence a list --- proposals/2140-terms-of-service-2.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 74923e64..b06b38eb 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -57,9 +57,13 @@ All current endpoints within `/_matrix/identity/api/v1/` will be duplicated into `/_matrix/identity/v2`, noting that MSC2134 changes the behaviour of lookups. Authentication is still expected on MSC2134's proposed endpoints. Any request to any endpoint within `/_matrix/identity/v2`, with the exception -of `/_matrix/identity/v2`, any `requestToken` endpoint and the new -`/_matrix/identity/v2/account/register` and `GET /_matrix/identity/v2/terms` -may return an error with `M_UNAUTHORIZED` errcode with HTTP status code 401. +of: + * `/_matrix/identity/v2` + * any `requestToken` endpoint + * The new `/_matrix/identity/v2/account/register` + * The new `GET /_matrix/identity/v2/terms` + +...may return an error with `M_UNAUTHORIZED` errcode with HTTP status code 401. This indicates that the user must authenticate with OpenID and supply a valid `access_token`. From 4be283ccb3c25008e53f987c94c3749c40baea14 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 27 Jun 2019 17:31:15 +0100 Subject: [PATCH 0598/1250] Typing Co-Authored-By: Travis Ralston --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index b06b38eb..cd6be68b 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -71,7 +71,7 @@ This indicates that the user must authenticate with OpenID and supply a valid in the registration process before the user has an MXID and therefore cannot log in with OpenID. It is up to the IS to manage its privacy obligations appropriately when fulfilling these requests, bearing in mind that the user has -not explictly incicated their agreement to any documents, and may abort the +not explicitly indicated their agreement to any documents, and may abort the registration process without doing so. All other endpoints require authentication by the client supplying an access token From e80753e56c70001bb71ac490f063993479db2440 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 27 Jun 2019 18:24:42 -0600 Subject: [PATCH 0599/1250] Add .well-known discovery --- proposals/1957-integrations-discovery.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/proposals/1957-integrations-discovery.md b/proposals/1957-integrations-discovery.md index fd6bc8f9..cef17098 100644 --- a/proposals/1957-integrations-discovery.md +++ b/proposals/1957-integrations-discovery.md @@ -106,6 +106,30 @@ Integration managers shown in this way must be treated like widgets, regardless this means exposing the Widget API to the manager and applying necessary scoping to keep the manager as an account widget rather than a room widget. +#### Discovering a manager by only the domain name + +Clients may wish to ask users for a single canonical domain name so they can find the manager to add +to the user's account transparently. Similar to the .well-known discovery done by servers (and clients +during login), clients which have an integrations domain (eg: "example.org") make a regular HTTPS +request to `https://example.org/.well-known/matrix/integrations` which returns an object which looks +like the following: +```json +{ + "m.integrations_widget": { + "url": "https://integrations.example.org/ui?displayName=$matrix_display_name", + "data": { + "api_url": "https://integrations.example.org" + } + } +} +``` + +The response should be parsed as JSON. If the endpoint returns an error or is missing the `m.integrations_widget` +property, the client should assume there is no integrations manager running on that domain. The +`m.integrations_widget` is an object which has the exact same format as the account widget for +an integration manager, described above. The client should wrap the object verbatim into the appropriate +account data location. + ## Tradeoffs From d8283b9cdf15f3b37990f67f2d7c49d5b863f9af Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 27 Jun 2019 20:44:49 -0600 Subject: [PATCH 0600/1250] Add option to use query string --- proposals/1961-integrations-auth.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/1961-integrations-auth.md b/proposals/1961-integrations-auth.md index 863ea325..cf69af27 100644 --- a/proposals/1961-integrations-auth.md +++ b/proposals/1961-integrations-auth.md @@ -8,7 +8,8 @@ manager. This proposal covers the authentication portion of that API. All specified APIs (except `/register`) will take an `Authorization` header with a `Bearer` token returned from a call to `/register`. This token is used to authorize the request and to identify who is making the -request. +request. The token may also be specified as the `access_token` query string parameter, similar to the +Client-Server API. #### POST /_matrix/integrations/v1/account/register From bfd8e52c234d367c9adc4ec686fc77b3b2f02c1d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 27 Jun 2019 20:45:23 -0600 Subject: [PATCH 0601/1250] Formatting --- proposals/1961-integrations-auth.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/1961-integrations-auth.md b/proposals/1961-integrations-auth.md index cf69af27..7f735607 100644 --- a/proposals/1961-integrations-auth.md +++ b/proposals/1961-integrations-auth.md @@ -11,7 +11,7 @@ from a call to `/register`. This token is used to authorize the request and to i request. The token may also be specified as the `access_token` query string parameter, similar to the Client-Server API. -#### POST /_matrix/integrations/v1/account/register +#### POST `/_matrix/integrations/v1/account/register` Exchanges an OpenID object for a token which can be used to authorize future requests to the manager. @@ -31,7 +31,7 @@ to the `matrix_server_name` provided in the original OpenID object. Applications which register for a token are responsible for tracking which integration manager they are for. This can usually be done by tracking the hostname of the integration manager and matching a token with it. -#### GET /_matrix/integrations/v1/account +#### GET `/_matrix/integrations/v1/account` Gets information about the token's owner, such as the user ID for which it belongs. @@ -56,7 +56,7 @@ here. Preferably, custom information is stored under a namespaced key like so: } ``` -#### POST /_matrix/integrations/v1/account/logout +#### POST `/_matrix/integrations/v1/account/logout` Logs the token out, rendering it useless for future requests. From 83bb3861ba2926bd711930d1d0e89ff08087383e Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 28 Jun 2019 09:31:53 +0100 Subject: [PATCH 0602/1250] line wrap --- proposals/2140-terms-of-service-2.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index cd6be68b..69696946 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -54,7 +54,8 @@ and adds authentication to accross the Identity Service API. ### IS API Authentication All current endpoints within `/_matrix/identity/api/v1/` will be duplicated -into `/_matrix/identity/v2`, noting that MSC2134 changes the behaviour of lookups. Authentication is still expected on MSC2134's proposed endpoints. +into `/_matrix/identity/v2`, noting that MSC2134 changes the behaviour of +lookups. Authentication is still expected on MSC2134's proposed endpoints. Any request to any endpoint within `/_matrix/identity/v2`, with the exception of: From 45d630951c6c81aaa7796c08e348e71ac6290f72 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 28 Jun 2019 09:32:15 +0100 Subject: [PATCH 0603/1250] back to M_TERMS_NOT_SIGNED --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 69696946..5bcb58a7 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -224,7 +224,7 @@ may return: * `M_UNAUTHORIZED` errcode with HTTP status code 401. This indicates that the user must authenticate with OpenID and supply a valid `access_token`. - * `M_CONSENT_NOT_GIVEN` errcode. This indicates that the user must agree to + * `M_TERMS_NOT_SIGNED` errcode. This indicates that the user must agree to (new) terms in order to use or continue to use the service. The `_matrix/identity/v2/3pid/unbind` must not return either of these From 786d5bc281baf8ecbb79e4bf27ead5ab7adbde58 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 28 Jun 2019 10:25:24 +0100 Subject: [PATCH 0604/1250] rewrite UI auth tradeoffs --- proposals/2140-terms-of-service-2.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 5bcb58a7..f84c026c 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -259,9 +259,10 @@ to their own MXIDs. This introduces a different way of accepting terms from the client/server API which uses User-Interactive Authentication. In the client/server API, the use of UI auth allows terms acceptance to be integrated into the registration flow -in a simple and backwards-compatible way. Indtroducing the UI Auth mechanism -into these other APIs would add significant complexity, so this functionality -has been provided with simpler, dedicated endpoints. +in a simple and backwards-compatible way. Another option here would be to use +UI Auth on the register endpoint. This would also not allow users to register +before accepting the terms. However, this would then make the OpenID +registration process different and non-standard. The `m.accepted_terms` section contains only URLs of the documents that have been agreed to. This loses information like the name and version of From fe14d3c9f0928c037784f029f68af9fa7cd15757 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 28 Jun 2019 18:07:24 +0100 Subject: [PATCH 0605/1250] Spec terms response --- proposals/2140-terms-of-service-2.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index f84c026c..befa655d 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -175,6 +175,9 @@ any one language of each document as sufficient, regardless of what language a client is operating in: users should not have to re-consent to documents if they change their client to a different language. +The server responds with an empty JSON object. The server must not assume that +the client will agree to all documents in a single request. + ### Accepted Terms Account Data This proposal also defines the `m.accepted_terms` section in User Account From 6f81d3774b61e9482c729d1f5894d2803c2d3d35 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 1 Jul 2019 16:23:28 +0100 Subject: [PATCH 0606/1250] New hashing method --- proposals/2134-identity-hash-lookup.md | 426 +++++++++++++++++++------ 1 file changed, 328 insertions(+), 98 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 2892ea4e..e6593224 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -3,120 +3,112 @@ [Issue #2130](https://github.com/matrix-org/matrix-doc/issues/2130) has been recently created in response to a security issue brought up by an independent party. To summarise the issue, lookups (of Matrix user IDs) are performed using -non-hashed 3PIDs (third-party IDs) which means that the identity server can -identify and record every 3PID that the user wants to check, whether that -address is already known by the identity server or not. +plain-text 3PIDs (third-party IDs) which means that the identity server can +identify and record every 3PID that the user has in their contacts, whether +that email address or phone number is already known by the identity server or +not. If the 3PID is hashed, the identity server could not determine the address unless it has already seen that address in plain-text during a previous call of -the /bind mechanism. +the /bind mechanism (without significant resources to reverse the hashes). -Note that in terms of privacy, this proposal does not stop an identity server -from mapping hashed 3PIDs to users, resulting in a social graph. However, the -identity of the 3PID will at least remain a mystery until /bind is used. - -This proposal thus calls for the Identity Service’s /lookup API to use hashed -3PIDs instead of their plain-text counterparts. +This proposal thus calls for the Identity Service API's /lookup endpoint to use +a back-and-forth mechanism of passing partial hashed 3PIDs instead of their +plain-text counterparts, which should leak mess less data to either party. ## Proposal This proposal suggests making changes to the Identity Service API's lookup -endpoints. Due to the nature of this proposal, the new endpoints should be on a -`v2` path (we also drop the `/api` in order to preserve consistency across -other endpoints): +endpoints. Instead of the `/lookup` and `/bulk_lookup` endpoints, this proposal +replaces them with endpoints `/lookup` and `/lookup_hashes`. Additionally, the +endpoints should be on a `v2` path, to avoid confusion with the original +`/lookup`. We also drop the `/api` in order to preserve consistency across +other endpoints: - `/_matrix/identity/v2/lookup` -- `/_matrix/identity/v2/bulk_lookup` +- `/_matrix/identity/v2/lookup_hashes` + +A third endpoint is added for clients to request information about the form +the server expects hashes in. + +- `/_matrix/identity/v2/hash_details` + +The following back-and-forth occurs between the client and server. -`address` MUST no longer be in a plain-text format, but rather will be a -peppered hash value, and the resulting digest MUST be encoded in URL-safe -unpadded base64 (similar to [room version 4's event -IDs](https://matrix.org/docs/spec/rooms/v4#event-ids)). +Let's say the client wants to check the following 3PIDs: -Identity servers must specify the hashing algorithms and a pepper that they -support, which will allow for rotation if a rainbow table is ever released -coinciding with their current hash and pepper. As such, it must be possible for -clients to be able to query what pepper the identity server requires before -sending it hashes. A new endpoint must be added: + alice@example.com + bob@example.com + carl@example.com + +1 234 567 8910 + denny@example.com -``` -GET /_matrix/identity/v2/hash_details -``` +The client will hash each 3PID as a concatenation of the medium and address, +separated by a space and a pepper appended to the end. Note that phone numbers +should be formatted as defined by +https://matrix.org/docs/spec/appendices#pstn-phone-numbers, before being +hashed). -This endpoint takes no parameters, and simply returns any supported hash -algorithms and pepper as a JSON object: + "alice@example.com" -> "email alice@example.com" + "bob@example.com" -> "email bob@example.com" + "carl@example.com" -> "email carl@example.com" + "+1 234 567 8910" -> "msisdn 12345678910" + "denny@example.com" -> "email denny@example.com" -``` -{ - "lookup_pepper": "matrixrocks", - "algorithms": ["sha256"], -} -``` +Hashes must be peppered in order to reduce both the information a client gains +during the process, and attacks the identity server can perform (namely sending +a rainbow table of hashes back in the response to `/lookup`). The resulting +digest MUST be encoded in URL-safe unpadded base64 (similar to [room version +4's event IDs](https://matrix.org/docs/spec/rooms/v4#event-ids)). + +In order for clients to know the pepper and hashing algorithm they should use, +Identity Servers must make the information available on the `/hash_details` +endpoint: + + GET /_matrix/identity/v2/hash_details + + { + "lookup_pepper": "matrixrocks", + "algorithms": ["sha256"] + } The name `lookup_pepper` was chosen in order to account for pepper values being returned for other endpoints in the future. The contents of `lookup_pepper` MUST match the regular expression `[a-zA-Z0-9]*`. -Clients should request this endpoint each time before making a `/lookup` or -`/bulk_lookup` request, to handle identity servers which may rotate their -pepper values frequently. Clients must choose one of the given hash algorithms -to encrypt the 3PID during lookup. - -Peppers are appended to the end of the 3PID before hashing. An example of -generating a hash using SHA-256 and the provided pepper is as follows: - -```python -address = "user@example.org" -pepper = "matrixrocks" -digest = hashlib.sha256((address + pepper).encode()).digest() -result_address = unpaddedbase64.encode_base64(digest) -print(result_address) -vNjEQuRCOmBp/KTuIpZ7RUJgPAbVAyqa0Uzh770tQaw -``` - -Possible hashing algorithms will be defined in the Matrix specification, and an -Identity Server can choose to implement one or all of them. Later versions of -the specification may deprecate algorithms when necessary. Currently the only -listed hashing algorithm is SHA-256 as defined by [RFC -4634](https://tools.ietf.org/html/rfc4634) and Identity Servers and clients -MUST agree to its use with the string `sha256`. SHA-256 was chosen as it is -currently used throughout the Matrix spec, as well as its properties of being -quick to hash. While this reduces the resources necessary to generate a rainbow -table for attackers, a fast hash is necessary if particularly slow mobile -clients are going to be hashing thousands of contacts. + The client should append the pepper to the end of the 3pid string before + hashing. + + "email alice@example.com" -> "email alice@example.commatrixrocks" + "email bob@example.com" -> "email bob@example.commatrixrocks" + "email carl@example.com" -> "email carl@example.commatrixrocks" + "msisdn 12345678910" -> "msisdn 12345678910matrixrocks" + "email denny@example.com" -> "email denny@example.commatrixrocks" + +Clients SHOULD request this endpoint each time before performing a lookup, to +handle identity servers which may rotate their pepper values frequently. +Clients MUST choose one of the given hash algorithms to encrypt the 3PID during +lookup. + +Note that possible hashing algorithms will be defined in the Matrix +specification, and an Identity Server can choose to implement one or all of +them. Later versions of the specification may deprecate algorithms when +necessary. Currently the only listed hashing algorithm is SHA-256 as defined by +[RFC 4634](https://tools.ietf.org/html/rfc4634) and Identity Servers and +clients MUST agree to its use with the string `sha256`. SHA-256 was chosen as +it is currently used throughout the Matrix spec, as well as its properties of +being quick to hash. While this reduces the resources necessary to generate a +rainbow table for attackers, a fast hash is necessary if particularly slow +mobile clients are going to be hashing thousands of contact details. When performing a lookup, the pepper and hashing algorithm the client used must be part of the request body. If they do not match what the server has on file -(which may be the case if the pepper was rotated right after the client's +(which may be the case if the pepper was changed right after the client's request for it), then the server must inform the client that they need to query the hash details again, instead of just returning an empty response, which clients would assume to mean that no contacts are registered on that identity server. -Thus, an example client request to `/bulk_lookup` would look like the -following: - -``` -{ - "threepids": [ - [ - "email", - "vNjEQuRCOmBp/KTuIpZ7RUJgPAbVAyqa0Uzh770tQaw" - ], - [ - "msisdn", - "0VnvYk7YZpe08fP/CGqs3f39QtRjqAA2lPd14eLZXiw" - ], - [ - "email", - "BJaLI0RrLFDMbsk0eEp5BMsYDYzvOzDneQP/9NTemYA" - ] - ], - "lookup_pepper": "matrixrocks", - "algorithm": "sha256" -} -``` - If the algorithm does not match the server's, the server should return a `400 M_INVALID_PARAM`. If the pepper does not match the server's, the server should return a new error code, 400 `M_INVALID_PEPPER`. A new error code is not @@ -127,14 +119,252 @@ Each of these error responses should contain the correct `algorithm` and `/hash_details` again, thus saving a round-trip. An example response to an incorrect pepper would be: -``` -{ - "error": "Incorrect value for lookup_pepper", - "errcode": "M_INVALID_PEPPER", - "algorithm": "sha256", - "lookup_pepper": "matrixrocks" -} -``` + { + "error": "Incorrect value for lookup_pepper", + "errcode": "M_INVALID_PEPPER", + "algorithm": "sha256", + "lookup_pepper": "matrixrocks" + } + +Now comes time for the lookup. Once hashing has been performed using the +defined hashing algorithm, the client sends the first `k` characters of each +hash in an array, deduplicating any matching entries. + +`k` is a value chosen by the client. It is a tradeoff between leaking the +hashes of 3PIDs that the Identity Server doesn't know about, and the amount of +hashing the server must perform. In addition to k, the client can also set a +`max_k` that it is comfortable with. The recommended values are `k = 4` and +`max_k = 6` (see below for the reasoning behind this). Let's say the client +chooses these values. + + NOTE: Example numbers, not real hash values. + + "email alice@example.commatrixrocks" -> "70b1b5637937ab99f6aad01f694b3665541a5b9cbdfe54880462b3f1ad35d1f4" + "email bob@example.commatrixrocks" -> "21375b56a47c2cdc41a0596549a16ec51b64d26eb47b8e915d45b18ed17b72ff" + "email carl@example.commatrixrocks" -> "758afda64cb6a86ee6d540fa7c8b803a2479863e369cbafd71ffd376beef5d5f" + "msisdn 12345678910matrixrocks" -> "21375b3f1b61c975b13c8cecd6481a82e239e6aad644c29dc815836188ae8351" + "email denny@example.commatrixrocks" -> "70b1b5637937ab9846a94a8015e12313643a2f5323ca8f5b4ed6982fc8c3619b" + + Note that pairs (bob@example.com, 12345678910) and (alice@example.com, denny@example.com) + have the same leading characters in their hashed representations. + + POST /_matrix/identity/v2/lookup + + { + "hashes": [ + "70b1", + "2137", + "758a" + ], + "algorithm": "sha256", + "pepper": "matrixrocks" + } + +The identity server, upon receiving these partial hashes, can see that the +client chose `4` as its `k` value, which is the length of the shortest hash +prefix. The identity server has a "minimum k", which is a function of the +amount of 3PID hashes it currently holds and protects it against computing too +many per lookup. Let's say the Identity Server's `min_k = 5` (again, see below +for details). + +The client's `k` value (4) is less than the Identity Server's `min_k` (5), so +it will reject the lookup with the following error: + + { + "errcode": "M_HASH_TOO_SHORT", + "error": "Sent partial hashes are too short", + "minimum_length": "5" + } + +The client then knows it must send values of at least length 5. It's `max_k` is +6, so this is fine. The client sends the values again with `k = 5`: + + POST /_matrix/identity/v2/lookup + + { + "hashes": [ + "70b1b", + "21375", + "758af" + ], + "algorithm": "sha256", + "pepper": "matrixrocks" + } + +The Identity Server sees the hashes are within an acceptable length (5 >= 5), +then checks which hashes it knows of that match the given leading values. It +will then return the next few characters (`n`; implementation-specific; lower +means less information leaked to clients at the result of potentially more +hashing to be done) of each that match: + + The identity server found the following hashes that contain the leading + characters: + + 70b1b5637937ab99f6aad01f694b3665541a5b9cbdfe54880462b3f1ad35d1f4 + 70b1b1b28dcfcc179a54983f46e1753c3fcdb0884d06fad741582c0180b56fc9 + 21375b3f1b61c975b13c8cecd6481a82e239e6aad644c29dc815836188ae8351 + + And if n = 7, the identity server will send back the following payload: + + { + "hashes": { + "70b1b": ["5637937", "1b28dcf"], + "21375": ["b3f1b61"] + } + } + +The client can then deduce which hashes actually lead to Matrix IDs. In this +case, 70b1b5637937 are the leading characters of "alice@example.com" and +"denny@example.com", while 21375b3f1b61 are the leading characters of +"+12345678910" whereas 70b1b1b28dcf does not match any of the hashes the client +has locally, so it is ignored. "bob@example.com" and "carl@example.com" do not +seem to have Matrix IDs associated with them. + +Finally, the client salts and hashes 3PID hashes that it believes are +associated with Matrix IDs and sends them to the identity server on the +`/lookup_hashes` endpoint. Instead of hashing the 3PIDs again, clients should +reuse the peppered hash that was previously sent to the server. Salting is +performed to prevent an identity server generating a rainbow table to reverse +any non-Matrix 3PIDs that slipped in. Salts MUST match the regular expression +`[a-zA-Z0-9]*`. + + Computed previously: + + "email alice@example.commatrixrocks" + becomes + "70b1b5637937ab99f6aad01f694b3665541a5b9cbdfe54880462b3f1ad35d1f4" + + The client should generate a salt. Let's say it generates "salt123". This + value is appended to the hash. + + "70b1b5637937ab99f6aad01f694b3665541a5b9cbdfe54880462b3f1ad35d1f4" + becomes + "70b1b5637937ab99f6aad01f694b3665541a5b9cbdfe54880462b3f1ad35d1f4salt123" + + And then hashed: + + "70b1b5637937ab99f6aad01f694b3665541a5b9cbdfe54880462b3f1ad35d1f4salt123" + becomes + "1f64ed6ac9d6da86b65bcc68a39c7c4d083f77193ec7e5adc4b09617f8d0d81a" + +A new salt is generated and applied to each hash **prefix** individually. Doing +so requires the identity server to only rehash the 3PIDs whose unsalted hashes +matched the earlier prefixes (in the case of 70b1b, hashes 5637937... and +1b28dcf...). This adds only a small multiplier of additional hashes needing to +be performed by the Identity Server (the median number of hashes that fit each +prefix, a function of the chosen `k` value). + +An attacker would now need to create a new rainbow table per hash prefix, per +lookup. This reduces the attack surface significantly to only very targeted +attacks. + + POST /_matrix/identity/v2/lookup_hashes + + { + "hashes": { + "70b1b": { + "1": "1f64ed6ac9d6da86b65bcc68a39c7c4d083f77193ec7e5adc4b09617f8d0d81a", + "2": "a32e1c1f3b9e118eab196b0807443871628eace587361b7a02adfb2b77b8d620" + }, + "21375": { + "1": "372bf27a4e7e952d1e794f78f8cdfbff1a3ab2f59c6d44e869bfdd7dd1de3948" + } + }, + "salts": { + "70b1b": "salt123", + "21375": "salt234" + } + } + +The server reads the prefixes and only rehashes those 3PIDs that match these +hashes (being careful to continue to enforce its `min_k` requirement), and +returns them: + + { + "mappings": { + "70b1b": { + "2": "@alice:example.com" + }, + "21375": { + "1": "@fred:example.com" + } + } + } + +The client can now display which 3PIDs link to which Matrix IDs. + +### How to pick k + +The `k` value is a tradeoff between the privacy of the user's contacts, and the +resource-intensiveness of lookups for the identity server. Clients would rather +have a smaller `k`, while servers a larger `k`. A larger `k` also allows the +identity server to learn more about the contacts the client has that are not +Matrix users. Ideally we'd like to balance these two, and with the value also +being a factor of how many records an identity server has, there's no way to +simply give a single `k` value that should be used from the spec. + +Instead, we can have the client and identity server decide it amongst +themselves. The identity server should pick a `k` value based on how many 3PIDs +records they have, and thus how much hashes they will need to perform. An ideal +value can be calculated from the following function: + + C <= N / (64 ^ k) + + Where N is the number of 3PID records an identity server has, k is the number of + characters to truncate each hash to, and C is the median number of hashing rounds + an identity server will need to perform per hash (denoted complexity). 64 is the + number of possible characters per byte in a hash, as hash digests are encoded in + url-safe base64. + + Identity servers should choose a complexity value they're comfortable with. + Let's say 5 (for reference, HIBP's service has set their k value for a complexity + of 478: https://blog.cloudflare.com/validating-leaked-passwords-with-k-anonymity/) + + When C is set (implementation specific), k can then be solved for: + + k >= - log(C/N) + ---------- + - log(64) + + Taking HIBP's amount of passwords as an example, 600,000,000, as N and solving for k, we get: + + k >= 4.47 + + We round k to 5 for it to be a whole number. + + As this is quite a lot of records, we advise clients to start with k = 4, and go from there. + + For reference, a very small identity server with only 600 records would produce a + minimum k of 0.628, or 1. + + From this we can see that even low k values scale to quite a lot of records. + +Clients themselves should pick a reasonable default `k`, and a maximum value +that they are comfortable extending towards if the identity server requests a +higher minimum number. If the identity server requests too high of a minimum +number, clients will need to inform the user, either with an error message, or +more advanced clients could allow users to tweak their k values. + +--- + +Past what they already knew, from this exchange the client and server have learned: + +Client: + +* Unsalted, peppered partial 3PID hash "70b1b1b28dcf" + of some matrix user + (harder to crack, and new rainbow table needed) +* alice@example.com -> @alice:example.com (required) +* +1 234 567 8910 -> @fred:example.com (required) + +Server: + +* Partial hash "758af" (likely useless) +* The server knows some salted hash + 70b1b5637937ab9846a94a8015e12313643a2f5323ca8f5b4ed6982fc8c3619bf + (crackable, new rainbow table needed) + +--- No parameter changes will be made to /bind. @@ -151,10 +381,10 @@ are being sent to. ## Tradeoffs -* This approach means that the client now needs to calculate a hash by itself, - but the belief is that most languages provide a mechanism for doing so. * There is a small cost incurred by performing hashes before requests, but this is outweighed by the privacy implications of sending plain-text addresses. +* Identity services will need to perform a lot of hashing, however with + authentication being added in MSC 2140, effective rate-limiting is possible. ## Potential issues @@ -186,14 +416,14 @@ for a federated network, as it requires specialized hardware. While a bit out of scope for this MSC, there has been debate over preventing 3PIDs as being kept as plain-text on disk. The argument against this was that if the hashing algorithm (in this case SHA-256) was broken, we couldn't update -the hashing algorithm without having the plaintext 3PIDs. @lampholder helpfully +the hashing algorithm without having the plain-text 3PIDs. @lampholder helpfully added that we could just take the old hashes and rehash them in the more secure hashing algorithm, thus transforming the hash from SHA-256 to SHA-256+SomeBetterAlg. However @erikjohnston then pointed out that if `BrokenAlgo(a) == BrokenAlgo(b)` then `SuperGreatHash(BrokenAlgo(a)) == SuperGreatHash(BrokenAlgo(b))`, so all you'd need to do is find a match in the broken algo, and you'd break the new algorithm as well. This means that you -would need the plaintext 3PIDs to encode a new hash, and thus storing them +would need the plain-text 3PIDs to encode a new hash, and thus storing them hashed on disk would require a transition period where 3PIDs were reuploaded in a strong hash variant. From 922a20ba2625cb7205b01817ad383e471b27ebfa Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 1 Jul 2019 16:30:07 +0100 Subject: [PATCH 0607/1250] small fixes --- proposals/2134-identity-hash-lookup.md | 39 +++++++++++++------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index e6593224..ec2beb47 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -47,7 +47,7 @@ The client will hash each 3PID as a concatenation of the medium and address, separated by a space and a pepper appended to the end. Note that phone numbers should be formatted as defined by https://matrix.org/docs/spec/appendices#pstn-phone-numbers, before being -hashed). +hashed). First the client must prepend the medium to the address: "alice@example.com" -> "email alice@example.com" "bob@example.com" -> "email bob@example.com" @@ -57,9 +57,7 @@ hashed). Hashes must be peppered in order to reduce both the information a client gains during the process, and attacks the identity server can perform (namely sending -a rainbow table of hashes back in the response to `/lookup`). The resulting -digest MUST be encoded in URL-safe unpadded base64 (similar to [room version -4's event IDs](https://matrix.org/docs/spec/rooms/v4#event-ids)). +a rainbow table of hashes back in the response to `/lookup`). In order for clients to know the pepper and hashing algorithm they should use, Identity Servers must make the information available on the `/hash_details` @@ -126,9 +124,11 @@ incorrect pepper would be: "lookup_pepper": "matrixrocks" } -Now comes time for the lookup. Once hashing has been performed using the -defined hashing algorithm, the client sends the first `k` characters of each -hash in an array, deduplicating any matching entries. +Now comes time for the lookup. Note that the resulting hash digest MUST be +encoded in URL-safe unpadded base64 (similar to [room version 4's event +IDs](https://matrix.org/docs/spec/rooms/v4#event-ids)). Once hashing has been +performed using the defined hashing algorithm, the client sends the first `k` +characters of each hash in an array, deduplicating any matching entries. `k` is a value chosen by the client. It is a tradeoff between leaking the hashes of 3PIDs that the Identity Server doesn't know about, and the amount of @@ -137,7 +137,7 @@ hashing the server must perform. In addition to k, the client can also set a `max_k = 6` (see below for the reasoning behind this). Let's say the client chooses these values. - NOTE: Example numbers, not real hash values. + NOTE: Example digests, not real hash values. "email alice@example.commatrixrocks" -> "70b1b5637937ab99f6aad01f694b3665541a5b9cbdfe54880462b3f1ad35d1f4" "email bob@example.commatrixrocks" -> "21375b56a47c2cdc41a0596549a16ec51b64d26eb47b8e915d45b18ed17b72ff" @@ -145,8 +145,9 @@ chooses these values. "msisdn 12345678910matrixrocks" -> "21375b3f1b61c975b13c8cecd6481a82e239e6aad644c29dc815836188ae8351" "email denny@example.commatrixrocks" -> "70b1b5637937ab9846a94a8015e12313643a2f5323ca8f5b4ed6982fc8c3619b" - Note that pairs (bob@example.com, 12345678910) and (alice@example.com, denny@example.com) - have the same leading characters in their hashed representations. + Also note that pairs (bob@example.com, 12345678910) and (alice@example.com, + denny@example.com) have the same leading characters in their hashed + representations. POST /_matrix/identity/v2/lookup @@ -214,9 +215,9 @@ hashing to be done) of each that match: } The client can then deduce which hashes actually lead to Matrix IDs. In this -case, 70b1b5637937 are the leading characters of "alice@example.com" and -"denny@example.com", while 21375b3f1b61 are the leading characters of -"+12345678910" whereas 70b1b1b28dcf does not match any of the hashes the client +case, `70b1b5637937` are the leading characters of "alice@example.com" and +"denny@example.com", while `21375b3f1b61` are the leading characters of +"+12345678910" and `70b1b1b28dcf` does not match any of the hashes the client has locally, so it is ignored. "bob@example.com" and "carl@example.com" do not seem to have Matrix IDs associated with them. @@ -247,12 +248,12 @@ any non-Matrix 3PIDs that slipped in. Salts MUST match the regular expression becomes "1f64ed6ac9d6da86b65bcc68a39c7c4d083f77193ec7e5adc4b09617f8d0d81a" -A new salt is generated and applied to each hash **prefix** individually. Doing -so requires the identity server to only rehash the 3PIDs whose unsalted hashes -matched the earlier prefixes (in the case of 70b1b, hashes 5637937... and -1b28dcf...). This adds only a small multiplier of additional hashes needing to -be performed by the Identity Server (the median number of hashes that fit each -prefix, a function of the chosen `k` value). +A new salt is generated per **hash prefix** and applied to each hash +individually. Doing so requires the identity server to only rehash the 3PIDs +whose unsalted hashes matched the earlier prefixes (in the case of `70b1b`, +hashes `5637937...` and `1b28dcf...`). This adds only a small multiplier of +additional hashes needing to be performed by the Identity Server (the median +number of hashes that fit each prefix, a function of the chosen `k` value). An attacker would now need to create a new rainbow table per hash prefix, per lookup. This reduces the attack surface significantly to only very targeted From 8af35be13faff18010407f135d9b894fdded5768 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 Jul 2019 10:56:12 +0100 Subject: [PATCH 0608/1250] Typo Co-Authored-By: Travis Ralston --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index befa655d..e47584bb 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -47,7 +47,7 @@ This proposal introduces: This proposal relies on both Integration Managers and Identity Servers being able to identity users by their MXID and store the fact that a given MXID has indicated that they accept the terms given. Integration Managers already -identity users in this way by authenticating them using the OpenID endpoint on +identify users in this way by authenticating them using the OpenID endpoint on the Homeserver. This proposal introduces the same mechanism to Identity Servers and adds authentication to accross the Identity Service API. From 2d11217d4ed1282d4c80e97faffd544de2b34bcb Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 Jul 2019 10:56:32 +0100 Subject: [PATCH 0609/1250] Typo Co-Authored-By: Travis Ralston --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index e47584bb..2beeafbc 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -49,7 +49,7 @@ able to identity users by their MXID and store the fact that a given MXID has indicated that they accept the terms given. Integration Managers already identify users in this way by authenticating them using the OpenID endpoint on the Homeserver. This proposal introduces the same mechanism to Identity Servers -and adds authentication to accross the Identity Service API. +and adds authentication across the Identity Service API. ### IS API Authentication From 5374030cc0644dadb40bb53a7cde63cb58353376 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 Jul 2019 10:59:08 +0100 Subject: [PATCH 0610/1250] Drop application/x-form-www-urlencoded in v2 --- proposals/2140-terms-of-service-2.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 2beeafbc..0d4a9f7c 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -56,6 +56,8 @@ and adds authentication across the Identity Service API. All current endpoints within `/_matrix/identity/api/v1/` will be duplicated into `/_matrix/identity/v2`, noting that MSC2134 changes the behaviour of lookups. Authentication is still expected on MSC2134's proposed endpoints. +Support for `application/x-form-www-urlencoded` parameters in requests will +be dropped from all endpoints. Any request to any endpoint within `/_matrix/identity/v2`, with the exception of: From f02e4c2e9cae69d6cb2a7ffe0dc08edffde30a13 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 Jul 2019 11:00:39 +0100 Subject: [PATCH 0611/1250] both registers are excluded from auth Co-Authored-By: Travis Ralston --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 0d4a9f7c..e4a3083b 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -63,7 +63,7 @@ Any request to any endpoint within `/_matrix/identity/v2`, with the exception of: * `/_matrix/identity/v2` * any `requestToken` endpoint - * The new `/_matrix/identity/v2/account/register` + * The new `$prefix/account/register` endpoint * The new `GET /_matrix/identity/v2/terms` ...may return an error with `M_UNAUTHORIZED` errcode with HTTP status code 401. From d00dfb78226b2015633aac4b612f8ea28b9fefdd Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 Jul 2019 11:04:06 +0100 Subject: [PATCH 0612/1250] exclude submittoken too --- proposals/2140-terms-of-service-2.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index e4a3083b..568a50df 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -62,20 +62,21 @@ be dropped from all endpoints. Any request to any endpoint within `/_matrix/identity/v2`, with the exception of: * `/_matrix/identity/v2` - * any `requestToken` endpoint + * any `requestToken` or `submitToken` endpoint * The new `$prefix/account/register` endpoint * The new `GET /_matrix/identity/v2/terms` + * `$prefix/logout` ...may return an error with `M_UNAUTHORIZED` errcode with HTTP status code 401. This indicates that the user must authenticate with OpenID and supply a valid `access_token`. -`requestToken` endpoints are excluded from the auth check because they are used -in the registration process before the user has an MXID and therefore cannot -log in with OpenID. It is up to the IS to manage its privacy obligations -appropriately when fulfilling these requests, bearing in mind that the user has -not explicitly indicated their agreement to any documents, and may abort the -registration process without doing so. +`requestToken` and `submitToken` endpoints are excluded from the auth check +because they are used in the registration process before the user has an MXID +and therefore cannot log in with OpenID. It is up to the IS to manage its +privacy obligations appropriately when fulfilling these requests, bearing in +mind that the user has not explicitly indicated their agreement to any +documents, and may abort the registration process without doing so. All other endpoints require authentication by the client supplying an access token either via an `Authorization` header with a `Bearer` token or an `access_token` From 03e6ab0103fad0cf80d31ef0d4003f577bd130d3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 Jul 2019 11:11:50 +0100 Subject: [PATCH 0613/1250] re-word double openid --- proposals/2140-terms-of-service-2.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 568a50df..2e874ee8 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -215,10 +215,11 @@ account data and presents to the user any documents that they have not already agreed to, along with UI for them to indicate their agreement. If there are no such documents (ie. if the `policies` dict is empty or the user has already agreed to all documents) the client proceeds to perform the OpenID -registration. Once the user has indicated their agreement, it adds these URLs -to `m.accepted_terms` account data. Once this has succeeded, then, and only -then, must the client perform OpenID authentication, getting a token from the -Homeserver and submitting this to the service using the `register` endpoint. +registration. If there are new terms documents, the client prompts the user for +agreement, then once the user has indicated their agreement, it adds these URLs +to `m.accepted_terms` account data and then proceeds with OpenID +authentication, getting a token from the Homeserver and submitting this to the +service using the `register` endpoint. Having done this, if the user agreed to any new documents, it performs a `POST $prefix/terms` request to signal to the server the set of documents that the From 7f653648045fded42b8e2321de52ed996dc81da2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 Jul 2019 11:13:12 +0100 Subject: [PATCH 0614/1250] Typo Co-Authored-By: Travis Ralston --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 2e874ee8..f7b43376 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -96,7 +96,7 @@ to make calls to the IS on its behalf, it must also supply its access token for Identity Server alongside in the `is_token` key of the same JSON object. That is, in the main request object for a `requestToken` request and in the `threepidCreds` object when supplying 3PID credentials (eg. in the `m.email.identity` UI auth stage). -Exxceptions to this are any requests where the only IS operation the Homeserver may +Exceptions to this are any requests where the only IS operation the Homeserver may perform is unbinding, ie. `/_matrix/client/r0/account/deactivate` and `/_matrix/client/r0/account/3pid/delete`, in which case the unbind is authenticated by a signed request from the Homeserver. From ac6b9bdb7ccf316ee77f65c3bd07edaed4a927f2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 Jul 2019 11:16:25 +0100 Subject: [PATCH 0615/1250] s/deprecate/remove/ --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index f7b43376..152f28d3 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -104,7 +104,7 @@ by a signed request from the Homeserver. ### HS Register API The `bind_email` and `bind_msisdn` options to `/_matrix/client/r0/register` in -the client/server API will be deprecated. Due to the fact that +the client/server API will be removed. Due to the fact that `/_matrix/identity/v2/3pid/bind` requires authentication, it will no longer be possible for the Homeserver to bind 3PIDs as part of the registration process. From 79dbad2914b1feeff57a908556fc95254c4de112 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 Jul 2019 11:17:27 +0100 Subject: [PATCH 0616/1250] remove acceptance token mention --- proposals/2140-terms-of-service-2.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 152f28d3..cb373678 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -170,12 +170,9 @@ the user has agreed to: This endpoint requires authentication. The clients MUST include the correct URL for the language of the document that -was presented to the user and they agreed to. How servers store or serialise -acceptance into the `acceptance_token` is not defined, eg. they may internally -transform all URLs to the URL of the English-language version of each document -if the server deems it appropriate to do so. Servers should accept agreement of -any one language of each document as sufficient, regardless of what language a -client is operating in: users should not have to re-consent to documents if +was presented to the user and they agreed to. Servers should accept agreement +of any one language of each document as sufficient, regardless of what language +a client is operating in: users should not have to re-consent to documents if they change their client to a different language. The server responds with an empty JSON object. The server must not assume that From 10858bf83b6c01cf8962d63d20f4db3c57e5fde6 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 Jul 2019 11:22:41 +0100 Subject: [PATCH 0617/1250] set account data after registration --- proposals/2140-terms-of-service-2.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index cb373678..0ee4ae20 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -197,9 +197,10 @@ An `m.accepted_terms` section therefore resembles the following: ``` Whenever a client submits a `POST $prefix/terms` request to an IS or IM or -completes an `m.terms` flow on the HS, it SHOULD update this account data -section adding any the URLs of any additional documents that the user agreed to -to this list. +completes an `m.terms` flow on the HS (or as soon as possible afterwards, ie. +after registration is complete), it SHOULD update this account data section +adding any the URLs of any additional documents that the user agreed to to this +list. ### Terms Acceptance in the API From 4c72c37b80aefef94c2ab1bc30719351e2f88ece Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 Jul 2019 11:24:51 +0100 Subject: [PATCH 0618/1250] slash Co-Authored-By: Travis Ralston --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 0ee4ae20..40278b37 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -223,7 +223,7 @@ Having done this, if the user agreed to any new documents, it performs a `POST $prefix/terms` request to signal to the server the set of documents that the user has agreed to. -Any request to any endpoint in the IM API, and the `_matrix/identity/v2/` +Any request to any endpoint in the IM API, and the `/_matrix/identity/v2/` namespace of the IS API, with the exception of `/_matrix/identity/v2` itself, may return: From e28f7aad7203fab769ea0c18638fdfd10275e6f3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 Jul 2019 11:25:12 +0100 Subject: [PATCH 0619/1250] slash Co-Authored-By: Travis Ralston --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 40278b37..e5fd21d6 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -232,7 +232,7 @@ may return: * `M_TERMS_NOT_SIGNED` errcode. This indicates that the user must agree to (new) terms in order to use or continue to use the service. -The `_matrix/identity/v2/3pid/unbind` must not return either of these +The `/_matrix/identity/v2/3pid/unbind` endpoint must not return either of these errors if the request has a valid signature from a Homeserver, and is being authenticated as such. In summary, the process for using a service that has not previously been used From d15c9df115a09b02cee265063cc328072a4ddaf2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 Jul 2019 11:25:26 +0100 Subject: [PATCH 0620/1250] fullstop Co-Authored-By: Travis Ralston --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index e5fd21d6..4a69ee03 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -240,7 +240,7 @@ in the current login sessions is: * `GET $prefix/terms` * Compare result with `m.accepted_terms` account data, get set of documents - pending agreement + pending agreement. * If non-empty, show this set of documents to the user and wait for the user to indicate their agreement. * Add the newly agreed documents to `m.accepted_terms` From 1a669348d8de4e83675e4847abbc67595ac0863b Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 Jul 2019 11:27:46 +0100 Subject: [PATCH 0621/1250] http status code --- proposals/2140-terms-of-service-2.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 4a69ee03..dbdb19f6 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -229,8 +229,9 @@ may return: * `M_UNAUTHORIZED` errcode with HTTP status code 401. This indicates that the user must authenticate with OpenID and supply a valid `access_token`. - * `M_TERMS_NOT_SIGNED` errcode. This indicates that the user must agree to - (new) terms in order to use or continue to use the service. + * `M_TERMS_NOT_SIGNED` errcode with HTTP status code 403. This indicates + that the user must agree to (new) terms in order to use or continue to + use the service. The `/_matrix/identity/v2/3pid/unbind` endpoint must not return either of these errors if the request has a valid signature from a Homeserver, and is being authenticated as such. From 3aaf181db24dd0d722c51fc079d90cbcdff30383 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 2 Jul 2019 14:03:35 -0400 Subject: [PATCH 0622/1250] rename some things and add clarification --- proposals/1946-secure_server-side_storage.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index 8487d6d4..dff7a5c7 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -66,7 +66,7 @@ the backup's `auth_data` to see of the key config is the same? ##### `m.secret_storage.v1.curve25519-aes-sha2` The public key is stored in the `pubkey` property of the `m.secret_storage.key.[key -ID]` `account_data`. +ID]` `account_data` as a base64-encoded string. The data is encrypted and MACed as follows: @@ -117,7 +117,7 @@ ID]` account-data: "passphrase": { "algorithm": "m.pbkdf2", "salt": "MmMsAlty", - "rounds": 100000 + "iterations": 100000 }, ... } @@ -125,8 +125,8 @@ ID]` account-data: **`m.pbkdf2`** -The key is generated using PBKDF2 using the salt given in the `salt` -parameter, and the number of rounds given in the `rounds` parameter. +The key is generated using PBKDF2 using the salt given in the `salt` parameter, +and the number of iterations given in the `iterations` parameter. ### Sharing @@ -136,7 +136,7 @@ shared key, devices can send secrets to each other, encrypted using olm. To request a secret, a client sends a `m.secret.request` event with `action` set to `request` to other devices, and `name` set to the name of the secret that it wishes to retrieve. A device that wishes to share the secret will -reply with a `m.secret.share` event, encrypted using olm. When the original +reply with a `m.secret.send` event, encrypted using olm. When the original client obtains the secret, it sends a `m.secret.request` event with `action` set to `cancel_request` to all devices other than the one that it received the secret from. @@ -165,7 +165,7 @@ unencrypted to-device event. request for a secret. If the secret is requested multiple times, it should be reused. It should also reused in order to cancel a request. -##### `m.secret.share` +##### `m.secret.send` Sent by a client to share a secret with another device, in response to an `m.secret.request` event. Typically it is encrypted as an `m.room.encrypted` From 53bd384f2ec87f2bde7c8f3bc1da3ee785cef96e Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 3 Jul 2019 09:59:38 +0100 Subject: [PATCH 0623/1250] Clarify salting --- proposals/2134-identity-hash-lookup.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index ec2beb47..3711d9c8 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -236,13 +236,14 @@ any non-Matrix 3PIDs that slipped in. Salts MUST match the regular expression "70b1b5637937ab99f6aad01f694b3665541a5b9cbdfe54880462b3f1ad35d1f4" The client should generate a salt. Let's say it generates "salt123". This - value is appended to the hash. + value is appended to the base64-representation of the hash digest of the + initial 3pid and pepper. "70b1b5637937ab99f6aad01f694b3665541a5b9cbdfe54880462b3f1ad35d1f4" becomes "70b1b5637937ab99f6aad01f694b3665541a5b9cbdfe54880462b3f1ad35d1f4salt123" - And then hashed: + Which is then hashed: "70b1b5637937ab99f6aad01f694b3665541a5b9cbdfe54880462b3f1ad35d1f4salt123" becomes From 8033ab1c86d239f5c614cc837973a22cb446bd40 Mon Sep 17 00:00:00 2001 From: reivilibre Date: Wed, 3 Jul 2019 10:36:16 +0100 Subject: [PATCH 0624/1250] Fix Push Gateway API example: Field renamed to event_id I believe this was forgotten in: 71cb646541ed2611e8f623fc28fac55b3aa73fbb --- api/push-gateway/push_notifier.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/push-gateway/push_notifier.yaml b/api/push-gateway/push_notifier.yaml index 4a6cb8f7..754c325a 100644 --- a/api/push-gateway/push_notifier.yaml +++ b/api/push-gateway/push_notifier.yaml @@ -57,7 +57,7 @@ paths: type: object example: { "notification": { - "id": "$3957tyerfgewrf384", + "event_id": "$3957tyerfgewrf384", "room_id": "!slw48wfj34rtnrf:example.com", "type": "m.room.message", "sender": "@exampleuser:matrix.org", From 4c65660b96335339d08e558856b6a2dd6a6fc9c8 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 3 Jul 2019 10:59:38 +0100 Subject: [PATCH 0625/1250] Clarify `.m.rule.room_one_to_one` push rule This clarifies the `.m.rule.room_one_to_one` push rule by adding a condition on event type. Some parts of the spec already had this info, while others were missing it. Synapse has had this behaviour since the push rule appeared. Fixes https://github.com/matrix-org/matrix-doc/issues/2150 --- api/client-server/pushrules.yaml | 9 +++++++-- event-schemas/examples/m.push_rules | 9 +++++++-- specification/modules/push.rst | 5 +++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/api/client-server/pushrules.yaml b/api/client-server/pushrules.yaml index e23c9189..a1cbc354 100644 --- a/api/client-server/pushrules.yaml +++ b/api/client-server/pushrules.yaml @@ -159,8 +159,13 @@ paths: ], "conditions": [ { - "is": "2", - "kind": "room_member_count" + "kind": "room_member_count", + "is": "2" + }, + { + "kind": "event_match", + "key": "type", + "pattern": "m.room.message" } ], "default": true, diff --git a/event-schemas/examples/m.push_rules b/event-schemas/examples/m.push_rules index e4f0a959..34bc2fe6 100644 --- a/event-schemas/examples/m.push_rules +++ b/event-schemas/examples/m.push_rules @@ -107,8 +107,13 @@ ], "conditions": [ { - "is": "2", - "kind": "room_member_count" + "kind": "room_member_count", + "is": "2" + }, + { + "kind": "event_match", + "key": "type", + "pattern": "m.room.message" } ], "default": true, diff --git a/specification/modules/push.rst b/specification/modules/push.rst index 33ca7fd7..b16ed8a6 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -563,6 +563,11 @@ Definition: { "kind": "room_member_count", "is": "2" + }, + { + "kind": "event_match", + "key": "type", + "pattern": "m.room.message" } ], "actions": [ From 9208c5cd13e8006a8bb01a4c4e6537db04b2dd3f Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 3 Jul 2019 11:34:00 +0100 Subject: [PATCH 0626/1250] Add changelog --- changelogs/client_server/newsfragments/2152.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2152.clarification diff --git a/changelogs/client_server/newsfragments/2152.clarification b/changelogs/client_server/newsfragments/2152.clarification new file mode 100644 index 00000000..03fde9ff --- /dev/null +++ b/changelogs/client_server/newsfragments/2152.clarification @@ -0,0 +1 @@ +Clarify the conditions for the ``.m.rule.room_one_to_one`` push rule. From 4d31ddc8c9bb1058c5a24ccf9884b13ef6fdb4a7 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 3 Jul 2019 15:09:06 -0400 Subject: [PATCH 0627/1250] additions and clarifications - indicate how to use MSC 1946 to store/share private keys - add signing by devices to enable migrating from device verifications - add information about signature upload failures and M_INVALID_SIGNATURE code - add security consideration --- proposals/1756-cross-signing.md | 85 ++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 13 deletions(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 5595b2b4..ec3edc33 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -57,18 +57,37 @@ store it at all. Clients will need to balance the security of the keys with the usability of signing users and devices when performing key verification. The private halves of a user's cross-signing keys be stored encrypted on the -server so that they may be retrieved by new devices. FIXME: explain how to do -this via MSC 1946 +server so that they may be retrieved by new devices, or shared between devices +using [MSC 1946](https://github.com/matrix-org/matrix-doc/pull/1946). When +handled in this way, the keys must be base64-encoded, and use the names +`m.cross_signing.master`, `m.cross_signing.self_signing`, and +`m.cross_signing.user_signing` for the master, self-signing, and user-signing +keys, respectively. ### Signature distribution -Currently, users will only be allowed to see signatures made by her own master, -self-signing or user-signing keys, or signatures made by other users' master or -self-signing keys about their own devices. This is done in order to preserve -the privacy of social connections. Future proposals may define mechanisms for +Currently, users will only be allowed to see signatures made by their own +master, self-signing or user-signing keys, signatures of their own master key +made by their own devices, signatures made by other users' master or +self-signing keys about their own devices, or signatures made of other users' +master keys by their own devices. This is done in order to preserve the +privacy of social connections. Future proposals may define mechanisms for distributing signatures to other users in order to allow for other web-of-trust use cases. +### Migrating from device verifications + +Users who have verified individual devices may wish to migrate these +verifications to use cross-signing instead. In order to aid with this, +signatures of a user's master key, made by their own devices, may be uploaded +to the server. If another client sees that the user's master key has a valid +signature from a device that was previously verified, then the client MAY +choose to trust and sign the master key. The client SHOULD take precautions to +ensure that a stolen device cannot be used to cause it to trust a malicious +master key. For example, a client could prompt the user before signing the +master key, or it could only do this migration on the first master key that it +sees from a user. + ### API description #### Uploading signing keys @@ -126,7 +145,8 @@ properties: "`ed25519:`" followed by the unpadded base64 encoding of the public key, and whose value is the unpadded base64 encoding of the public key. * `signatures` ({string: {string: string}}): signatures of the key. A - self-signing or user-signing key must be signed by the master key. + self-signing or user-signing key MUST be signed by the master key. A master + key MAY be signed by a device. In order to ensure that there will be no collisions in the `signatures` property, the server must respond with an error (FIXME: what error?) if any of @@ -136,7 +156,8 @@ keys, the server must respond with an error (FIXME: what error?). If a self-signing or user-signing key is uploaded, it must be signed by the master key that is included in the request, or the current master key if no -master key is included. +master key is included. If the signature from the master key is incorrect, the +server should respond with an error code of `M_INVALID_SIGNATURE`. After uploading cross-signing keys, they will be included under the `/keys/query` endpoint under the `master_keys`, `self_signing_keys` and @@ -287,10 +308,11 @@ others users who share an encrypted room with that user. #### Uploading signatures -Signatures of keys can be uploaded using `/keys/signatures/upload`. +Signatures of device keys can be uploaded using `/keys/signatures/upload`. For example, Alice signs one of her devices (HIJKLMN) (using her self-signing -key), and signs Bob's master key (using her user-signing key). +key), her own master key (using her HIJKLMN device), Bob's master key (using +her user-signing key). `POST /keys/signatures/upload` @@ -313,6 +335,18 @@ key), and signs Bob's master key (using her user-signing key). "ed25519:base64+self+signing+public+key": "base64+signature+of+HIJKLMN" } } + }, + "base64+master+public+key": { + "user_id": "@alice:example.com", + "usage": ["master"], + "keys": { + "ed25519:base64+master+public+key": "base64+master+public+key" + }, + "signatures": { + "@alice:example.com": { + "ed25519:HIJKLMN": "base64+signature+of+master+key" + } + } } }, "@bob:example.com": { @@ -332,9 +366,23 @@ key), and signs Bob's master key (using her user-signing key). } ``` -After Alice uploads a signature for her own devices, her signature will be -included in the results of the `/keys/query` request when *anyone* requests her -keys: +response: + +``` json +{ + "failures": {} +} +``` + +The response contains a `failures` property, which is a map of user ID to +device ID to failure reason, if any of the uploaded keys failed. The +homeserver should verify that the signature is correct. If it is not, the +homeserver should set the corresponding entry in `failures` to a JSON object +with the `errcode` property set to `M_INVALID_SIGNATURE`. + +After Alice uploads a signature for her own devices or master key, her +signature will be included in the results of the `/keys/query` request when +*anyone* requests her keys: `POST /keys/query` @@ -382,6 +430,11 @@ response: "usage": ["master"], "keys": { "ed25519:base64+master+public+key": "base64+master+public+key" + }, + "signatures": { + "@alice:example.com": { + "ed25519:HIJKLMN": "base64+signature+of+master+key" + } } }, "self_signing_key": { @@ -484,6 +537,12 @@ deleted and replaced. An attacker who is able to both steal a user's device and control their homeserver could prevent that device from being marked as untrusted. +An attacker may be able to upload a large number of signatures in a DoS attack +against clients or servers, similar to the [attack against the SKS keyserver +network](https://gist.github.com/rjhansen/67ab921ffb4084c865b3618d6955275f). +Since clients are only sent a subset of signatures, and the attestation graph +is limited, a DoS attack is less likely to be successful in this case. + ## Conclusion This proposal presents an alternative cross-signing mechanism to MSC1680, From f4a1e0288419f16500ed047df91cb4ddfc63445e Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 4 Jul 2019 16:28:15 +0100 Subject: [PATCH 0628/1250] simple method once more --- proposals/2134-identity-hash-lookup.md | 319 +++++-------------------- 1 file changed, 59 insertions(+), 260 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 3711d9c8..76f527cb 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -13,22 +13,20 @@ unless it has already seen that address in plain-text during a previous call of the /bind mechanism (without significant resources to reverse the hashes). This proposal thus calls for the Identity Service API's /lookup endpoint to use -a back-and-forth mechanism of passing partial hashed 3PIDs instead of their -plain-text counterparts, which should leak mess less data to either party. +hashed 3PIDs instead of their plain-text counterparts, which will leak less +data to identity servers. ## Proposal This proposal suggests making changes to the Identity Service API's lookup -endpoints. Instead of the `/lookup` and `/bulk_lookup` endpoints, this proposal -replaces them with endpoints `/lookup` and `/lookup_hashes`. Additionally, the -endpoints should be on a `v2` path, to avoid confusion with the original -`/lookup`. We also drop the `/api` in order to preserve consistency across -other endpoints: +endpoints. Instead, this proposal consolidates them into a single `/lookup` +endpoint. Additionally, the endpoint should be on a `v2` path, to avoid +confusion with the original `/lookup`. We also drop the `/api` in order to +preserve consistency across other endpoints: - `/_matrix/identity/v2/lookup` -- `/_matrix/identity/v2/lookup_hashes` -A third endpoint is added for clients to request information about the form +A second endpoint is added for clients to request information about the form the server expects hashes in. - `/_matrix/identity/v2/hash_details` @@ -127,248 +125,43 @@ incorrect pepper would be: Now comes time for the lookup. Note that the resulting hash digest MUST be encoded in URL-safe unpadded base64 (similar to [room version 4's event IDs](https://matrix.org/docs/spec/rooms/v4#event-ids)). Once hashing has been -performed using the defined hashing algorithm, the client sends the first `k` -characters of each hash in an array, deduplicating any matching entries. +performed using the defined hashing algorithm, the client sends each hash in an +array. -`k` is a value chosen by the client. It is a tradeoff between leaking the -hashes of 3PIDs that the Identity Server doesn't know about, and the amount of -hashing the server must perform. In addition to k, the client can also set a -`max_k` that it is comfortable with. The recommended values are `k = 4` and -`max_k = 6` (see below for the reasoning behind this). Let's say the client -chooses these values. - - NOTE: Example digests, not real hash values. - - "email alice@example.commatrixrocks" -> "70b1b5637937ab99f6aad01f694b3665541a5b9cbdfe54880462b3f1ad35d1f4" - "email bob@example.commatrixrocks" -> "21375b56a47c2cdc41a0596549a16ec51b64d26eb47b8e915d45b18ed17b72ff" - "email carl@example.commatrixrocks" -> "758afda64cb6a86ee6d540fa7c8b803a2479863e369cbafd71ffd376beef5d5f" - "msisdn 12345678910matrixrocks" -> "21375b3f1b61c975b13c8cecd6481a82e239e6aad644c29dc815836188ae8351" - "email denny@example.commatrixrocks" -> "70b1b5637937ab9846a94a8015e12313643a2f5323ca8f5b4ed6982fc8c3619b" - - Also note that pairs (bob@example.com, 12345678910) and (alice@example.com, - denny@example.com) have the same leading characters in their hashed - representations. + "email alice@example.commatrixrocks" -> "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs" + "email bob@example.commatrixrocks" -> "r0-6x3rp9zIWS2suIque-wXTnlv9sc41fatbRMEOwQE" + "email carl@example.commatrixrocks" -> "ryr10d1K8fcFVxALb3egiSquqvFAxQEwegXtlHoQFBw" + "msisdn 12345678910matrixrocks" -> "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens" + "email denny@example.commatrixrocks" -> "bxt8rtRaOzMkSk49zIKE_NfqTndHvGbWHchZskW3xmY" POST /_matrix/identity/v2/lookup { "hashes": [ - "70b1", - "2137", - "758a" + "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs", + "r0-6x3rp9zIWS2suIque-wXTnlv9sc41fatbRMEOwQE", + "ryr10d1K8fcFVxALb3egiSquqvFAxQEwegXtlHoQFBw", + "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens", + "bxt8rtRaOzMkSk49zIKE_NfqTndHvGbWHchZskW3xmY" ], "algorithm": "sha256", "pepper": "matrixrocks" } -The identity server, upon receiving these partial hashes, can see that the -client chose `4` as its `k` value, which is the length of the shortest hash -prefix. The identity server has a "minimum k", which is a function of the -amount of 3PID hashes it currently holds and protects it against computing too -many per lookup. Let's say the Identity Server's `min_k = 5` (again, see below -for details). - -The client's `k` value (4) is less than the Identity Server's `min_k` (5), so -it will reject the lookup with the following error: - - { - "errcode": "M_HASH_TOO_SHORT", - "error": "Sent partial hashes are too short", - "minimum_length": "5" - } - -The client then knows it must send values of at least length 5. It's `max_k` is -6, so this is fine. The client sends the values again with `k = 5`: - - POST /_matrix/identity/v2/lookup - - { - "hashes": [ - "70b1b", - "21375", - "758af" - ], - "algorithm": "sha256", - "pepper": "matrixrocks" - } - -The Identity Server sees the hashes are within an acceptable length (5 >= 5), -then checks which hashes it knows of that match the given leading values. It -will then return the next few characters (`n`; implementation-specific; lower -means less information leaked to clients at the result of potentially more -hashing to be done) of each that match: - - The identity server found the following hashes that contain the leading - characters: - - 70b1b5637937ab99f6aad01f694b3665541a5b9cbdfe54880462b3f1ad35d1f4 - 70b1b1b28dcfcc179a54983f46e1753c3fcdb0884d06fad741582c0180b56fc9 - 21375b3f1b61c975b13c8cecd6481a82e239e6aad644c29dc815836188ae8351 - - And if n = 7, the identity server will send back the following payload: - - { - "hashes": { - "70b1b": ["5637937", "1b28dcf"], - "21375": ["b3f1b61"] - } - } - -The client can then deduce which hashes actually lead to Matrix IDs. In this -case, `70b1b5637937` are the leading characters of "alice@example.com" and -"denny@example.com", while `21375b3f1b61` are the leading characters of -"+12345678910" and `70b1b1b28dcf` does not match any of the hashes the client -has locally, so it is ignored. "bob@example.com" and "carl@example.com" do not -seem to have Matrix IDs associated with them. - -Finally, the client salts and hashes 3PID hashes that it believes are -associated with Matrix IDs and sends them to the identity server on the -`/lookup_hashes` endpoint. Instead of hashing the 3PIDs again, clients should -reuse the peppered hash that was previously sent to the server. Salting is -performed to prevent an identity server generating a rainbow table to reverse -any non-Matrix 3PIDs that slipped in. Salts MUST match the regular expression -`[a-zA-Z0-9]*`. - - Computed previously: - - "email alice@example.commatrixrocks" - becomes - "70b1b5637937ab99f6aad01f694b3665541a5b9cbdfe54880462b3f1ad35d1f4" - - The client should generate a salt. Let's say it generates "salt123". This - value is appended to the base64-representation of the hash digest of the - initial 3pid and pepper. - - "70b1b5637937ab99f6aad01f694b3665541a5b9cbdfe54880462b3f1ad35d1f4" - becomes - "70b1b5637937ab99f6aad01f694b3665541a5b9cbdfe54880462b3f1ad35d1f4salt123" - - Which is then hashed: - - "70b1b5637937ab99f6aad01f694b3665541a5b9cbdfe54880462b3f1ad35d1f4salt123" - becomes - "1f64ed6ac9d6da86b65bcc68a39c7c4d083f77193ec7e5adc4b09617f8d0d81a" - -A new salt is generated per **hash prefix** and applied to each hash -individually. Doing so requires the identity server to only rehash the 3PIDs -whose unsalted hashes matched the earlier prefixes (in the case of `70b1b`, -hashes `5637937...` and `1b28dcf...`). This adds only a small multiplier of -additional hashes needing to be performed by the Identity Server (the median -number of hashes that fit each prefix, a function of the chosen `k` value). - -An attacker would now need to create a new rainbow table per hash prefix, per -lookup. This reduces the attack surface significantly to only very targeted -attacks. - - POST /_matrix/identity/v2/lookup_hashes - - { - "hashes": { - "70b1b": { - "1": "1f64ed6ac9d6da86b65bcc68a39c7c4d083f77193ec7e5adc4b09617f8d0d81a", - "2": "a32e1c1f3b9e118eab196b0807443871628eace587361b7a02adfb2b77b8d620" - }, - "21375": { - "1": "372bf27a4e7e952d1e794f78f8cdfbff1a3ab2f59c6d44e869bfdd7dd1de3948" - } - }, - "salts": { - "70b1b": "salt123", - "21375": "salt234" - } - } - -The server reads the prefixes and only rehashes those 3PIDs that match these -hashes (being careful to continue to enforce its `min_k` requirement), and -returns them: +The identity server, upon receiving these hashes, can simply compare against +the hashes of the 3PIDs it stores. The server then responds with the Matrix +IDs of those that match: { "mappings": { - "70b1b": { - "2": "@alice:example.com" - }, - "21375": { - "1": "@fred:example.com" - } + "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs": "@alice:example.com", + "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens": "@fred:example.com" } } The client can now display which 3PIDs link to which Matrix IDs. -### How to pick k - -The `k` value is a tradeoff between the privacy of the user's contacts, and the -resource-intensiveness of lookups for the identity server. Clients would rather -have a smaller `k`, while servers a larger `k`. A larger `k` also allows the -identity server to learn more about the contacts the client has that are not -Matrix users. Ideally we'd like to balance these two, and with the value also -being a factor of how many records an identity server has, there's no way to -simply give a single `k` value that should be used from the spec. - -Instead, we can have the client and identity server decide it amongst -themselves. The identity server should pick a `k` value based on how many 3PIDs -records they have, and thus how much hashes they will need to perform. An ideal -value can be calculated from the following function: - - C <= N / (64 ^ k) - - Where N is the number of 3PID records an identity server has, k is the number of - characters to truncate each hash to, and C is the median number of hashing rounds - an identity server will need to perform per hash (denoted complexity). 64 is the - number of possible characters per byte in a hash, as hash digests are encoded in - url-safe base64. - - Identity servers should choose a complexity value they're comfortable with. - Let's say 5 (for reference, HIBP's service has set their k value for a complexity - of 478: https://blog.cloudflare.com/validating-leaked-passwords-with-k-anonymity/) - - When C is set (implementation specific), k can then be solved for: - - k >= - log(C/N) - ---------- - - log(64) - - Taking HIBP's amount of passwords as an example, 600,000,000, as N and solving for k, we get: - - k >= 4.47 - - We round k to 5 for it to be a whole number. - - As this is quite a lot of records, we advise clients to start with k = 4, and go from there. - - For reference, a very small identity server with only 600 records would produce a - minimum k of 0.628, or 1. - - From this we can see that even low k values scale to quite a lot of records. - -Clients themselves should pick a reasonable default `k`, and a maximum value -that they are comfortable extending towards if the identity server requests a -higher minimum number. If the identity server requests too high of a minimum -number, clients will need to inform the user, either with an error message, or -more advanced clients could allow users to tweak their k values. - ---- - -Past what they already knew, from this exchange the client and server have learned: - -Client: - -* Unsalted, peppered partial 3PID hash "70b1b1b28dcf" - of some matrix user - (harder to crack, and new rainbow table needed) -* alice@example.com -> @alice:example.com (required) -* +1 234 567 8910 -> @fred:example.com (required) - -Server: - -* Partial hash "758af" (likely useless) -* The server knows some salted hash - 70b1b5637937ab9846a94a8015e12313643a2f5323ca8f5b4ed6982fc8c3619bf - (crackable, new rainbow table needed) - ---- - -No parameter changes will be made to /bind. +No parameter changes will be made to /bind as part of this proposal. ## Fallback considerations @@ -377,35 +170,34 @@ implementation, and should return a 403 `M_FORBIDDEN` error if so. If an identity server is too old and a HTTP 404, 405 or 501 is received when accessing the `v2` endpoint, they should fallback to the `v1` endpoint instead. -However, clients should be aware that plain-text 3PIDs are required, and SHOULD -ask for user consent to send 3PIDs in plain-text, and be clear about where they -are being sent to. +However, clients should be aware that plain-text 3PIDs are required for the +`v1` endpoint, and SHOULD ask for user consent to send 3PIDs in plain-text, and +be clear about where they are being sent to. ## Tradeoffs * There is a small cost incurred by performing hashes before requests, but this is outweighed by the privacy implications of sending plain-text addresses. -* Identity services will need to perform a lot of hashing, however with - authentication being added in MSC 2140, effective rate-limiting is possible. ## Potential issues -This proposal does not force an identity server to stop handling plain-text -requests, because a large amount of the Matrix ecosystem relies upon this -behavior. However, a conscious effort should be made by all users to use the -privacy respecting endpoints outlined above. Identity servers may disallow use -of the v1 endpoint, as per above. +Hashes are still reversible with a rainbow table, but hopefully the provided +pepper, which can be rotated by identity servers at will, should help mitigate +this to some extent. -Unpadded base64 has been chosen to encode the value due to use in many other -portions of the spec. +Additionally, this proposal does not stop an identity server from storing +plain-text 3PIDs. There is a GDPR argument in keeping email addresses, such +that if a breach happens, users must be notified of such. Ideally this would be +done over Matrix, but people may've stuck their email in an identity server and +then left Matrix forever. Perhaps if only hashes were being stored on the +identity server then that isn't considered personal information? In any case, a +discussion for another MSC. ## Other considered solutions Ideally identity servers would never receive plain-text addresses, however it is necessary for the identity server to send email/sms messages during a bind, as it cannot trust a homeserver to do so as the homeserver may be lying. -Additionally, only storing 3PID hashes at rest instead of the plain-text -versions is impractical if the hashing algorithm ever needs to be changed. Bloom filters are an alternative method of providing private contact discovery. However, they do not scale well due to requiring clients to download a large @@ -415,23 +207,30 @@ eventual solution of using Software Guard Extensions (detailed in https://signal.org/blog/private-contact-discovery/) is considered impractical for a federated network, as it requires specialized hardware. -While a bit out of scope for this MSC, there has been debate over preventing -3PIDs as being kept as plain-text on disk. The argument against this was that -if the hashing algorithm (in this case SHA-256) was broken, we couldn't update -the hashing algorithm without having the plain-text 3PIDs. @lampholder helpfully -added that we could just take the old hashes and rehash them in the more secure -hashing algorithm, thus transforming the hash from SHA-256 to -SHA-256+SomeBetterAlg. However @erikjohnston then pointed out that if -`BrokenAlgo(a) == BrokenAlgo(b)` then `SuperGreatHash(BrokenAlgo(a)) == -SuperGreatHash(BrokenAlgo(b))`, so all you'd need to do is find a match in the -broken algo, and you'd break the new algorithm as well. This means that you -would need the plain-text 3PIDs to encode a new hash, and thus storing them -hashed on disk would require a transition period where 3PIDs were reuploaded in -a strong hash variant. +k-anonymity was considered as an alternative, in which the identity server +would never receive a full hash of a 3PID that it did not already know about. +While this has been considered plausible, it comes with heightened resource +requirements (much more hashing by the identity server). The conclusion was +that it may not provide more privacy if an identity server decided to be evil, +however it would significantly raise the resource requirements to run an evil +identity server. + +Discussion and a walk-through of what a client/identity-server interaction would +look like are documented [in this Github +comment](https://github.com/matrix-org/matrix-doc/pull/2134#discussion_r298691748). + +Additionally, a radical model was also considered where the first portion of +the above scheme was done with an identity server, and the second would be done +with various homeservers who originally reported the 3PID to the identity +server. While interesting and a more decentralised model, some attacks are +still possible if the identity server is running an evil homeserver which it +can direct the client to send its hashes to. Discussion on this matter has +taken place in the MSC-specific room [starting at this +message](https://matrix.to/#/!LlraCeVuFgMaxvRySN:amorgan.xyz/$4wzTSsspbLVa6Lx5cBq6toh6P3TY3YnoxALZuO8n9gk?via=amorgan.xyz&via=matrix.org&via=matrix.vgorcum.com). ## Conclusion -This proposal outlines an effective method to stop bulk collection of user's +This proposal outlines a simple method to stop bulk collection of user's contact lists and their social graphs without any disastrous side effects. All functionality which depends on the lookup service should continue to function unhindered by the use of hashes. From 30dcc28f9b7280f88cc6898182ffa3891c1b18e7 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 4 Jul 2019 18:38:31 +0100 Subject: [PATCH 0629/1250] try & clarify that HS signature isn't the only acceptable auth for unbind --- proposals/2140-terms-of-service-2.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index dbdb19f6..2f6c88d8 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -91,15 +91,16 @@ possible. OpenID authentication in the IS API will work the same as in the Integration Manager API, as specified in [MSC1961](https://github.com/matrix-org/matrix-doc/issues/1961). -When clients supply an identity server to the Homeserver in order for the Homeserver -to make calls to the IS on its behalf, it must also supply its access token for the -Identity Server alongside in the `is_token` key of the same JSON object. That is, -in the main request object for a `requestToken` request and in the `threepidCreds` -object when supplying 3PID credentials (eg. in the `m.email.identity` UI auth stage). -Exceptions to this are any requests where the only IS operation the Homeserver may -perform is unbinding, ie. `/_matrix/client/r0/account/deactivate` and -`/_matrix/client/r0/account/3pid/delete`, in which case the unbind is authenticated -by a signed request from the Homeserver. +When clients supply an identity server to the Homeserver in order for the +Homeserver to make calls to the IS on its behalf, it must also supply its +access token for the Identity Server alongside in the `is_token` key of the +same JSON object. That is, in the main request object for a `requestToken` +request and in the `threepidCreds` object when supplying 3PID credentials (eg. +in the `m.email.identity` UI auth stage). Exceptions to this are any requests +where the only IS operation the Homeserver may perform is unbinding, ie. +`/_matrix/client/r0/account/deactivate` and +`/_matrix/client/r0/account/3pid/delete`, in which case the unbind will be +authenticated by a signed request from the Homeserver. ### HS Register API From 370266942488f56f1fb4aab5d4bab1e3b0989d9d Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 5 Jul 2019 15:59:29 +0100 Subject: [PATCH 0630/1250] update from comments --- proposals/2134-identity-hash-lookup.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 76f527cb..33bda297 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -10,11 +10,16 @@ not. If the 3PID is hashed, the identity server could not determine the address unless it has already seen that address in plain-text during a previous call of -the /bind mechanism (without significant resources to reverse the hashes). +the [/bind +mechanism](https://matrix.org/docs/spec/identity_service/r0.2.1#post-matrix-identity-api-v1-3pid-bind) +(without significant resources to reverse the hashes). -This proposal thus calls for the Identity Service API's /lookup endpoint to use -hashed 3PIDs instead of their plain-text counterparts, which will leak less -data to identity servers. +This proposal thus calls for the Identity Service API's +[/lookup](https://matrix.org/docs/spec/identity_service/r0.2.1#get-matrix-identity-api-v1-lookup) +endpoint to use hashed 3PIDs instead of their plain-text counterparts (and to +deprecate both it and +[/bulk_lookup](https://matrix.org/docs/spec/identity_service/r0.2.1#post-matrix-identity-api-v1-bulk-lookup)), +which will leak less data to identity servers. ## Proposal @@ -161,14 +166,16 @@ IDs of those that match: The client can now display which 3PIDs link to which Matrix IDs. -No parameter changes will be made to /bind as part of this proposal. +No parameter changes will be made to +[/bind](https://matrix.org/docs/spec/identity_service/r0.2.1#post-matrix-identity-api-v1-3pid-bind) +as part of this proposal. ## Fallback considerations `v1` versions of these endpoints may be disabled at the discretion of the implementation, and should return a 403 `M_FORBIDDEN` error if so. -If an identity server is too old and a HTTP 404, 405 or 501 is received when +If an identity server is too old and a HTTP 400 or 404 is received when accessing the `v2` endpoint, they should fallback to the `v1` endpoint instead. However, clients should be aware that plain-text 3PIDs are required for the `v1` endpoint, and SHOULD ask for user consent to send 3PIDs in plain-text, and From bf8a1e5d5f14855470ba607976ed4ae4f1c1898c Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 5 Jul 2019 18:11:42 +0100 Subject: [PATCH 0631/1250] Add way to get the HS to bind/unbind existing 3pids --- proposals/2140-terms-of-service-2.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 2f6c88d8..e203ffcf 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -41,8 +41,14 @@ following convention from [MSC2134](https://github.com/matrix-org/matrix-doc/issues/2134). This proposal introduces: + * A v2 API prefix, with authentication, for the Identity Service * The `$prefix/terms` endpoint * The `m.accepted_terms` section in account data + * `POST /_matrix/client/r0/account/3pid/unbind` endpoints on the client/server + API + +This proposal removes: + * The `bind_email` and `bind_msisdn` on the Homeserver `/register` endpoint This proposal relies on both Integration Managers and Identity Servers being able to identity users by their MXID and store the fact that a given MXID has @@ -252,6 +258,20 @@ in the current login sessions is: * If the set of documents pending agreement was non-empty, Perform a `POST $prefix/terms` request to the servcie with these documents. +### `POST /_matrix/client/r0/account/3pid/unbind` + +A client uses this client/server API endpoint to request that the Homeserver +removes the given 3PID from the given Identity Server, or all Identity Servers. +Takes parameters the same parameters as +`POST /_matrix/client/r0/account/3pid/delete`, ie. `id_server`, `medium`, +`address` and the newly added `is_token`. + +Returns the same as `POST /_matrix/client/r0/account/3pid/delete`. + +Clients may add IS bindings for 3PIDs that already exist on the user's +Homeserver account by using the `POST /_matrix/client/r0/account/3pid` +to re-add the 3PID. + ## Tradeoffs The Identity Service API previously did not require authentication, and OpenID From 701d340da18b9fbfdc98f4f5aff1f8e6ea2e7f54 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 5 Jul 2019 19:00:15 +0100 Subject: [PATCH 0632/1250] Remove exception for request/submitToken --- proposals/2140-terms-of-service-2.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index e203ffcf..9608093a 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -68,7 +68,6 @@ be dropped from all endpoints. Any request to any endpoint within `/_matrix/identity/v2`, with the exception of: * `/_matrix/identity/v2` - * any `requestToken` or `submitToken` endpoint * The new `$prefix/account/register` endpoint * The new `GET /_matrix/identity/v2/terms` * `$prefix/logout` @@ -77,13 +76,6 @@ of: This indicates that the user must authenticate with OpenID and supply a valid `access_token`. -`requestToken` and `submitToken` endpoints are excluded from the auth check -because they are used in the registration process before the user has an MXID -and therefore cannot log in with OpenID. It is up to the IS to manage its -privacy obligations appropriately when fulfilling these requests, bearing in -mind that the user has not explicitly indicated their agreement to any -documents, and may abort the registration process without doing so. - All other endpoints require authentication by the client supplying an access token either via an `Authorization` header with a `Bearer` token or an `access_token` query parameter. From dd8a6549c9bfb149c40ef8e83d978c624590a003 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 8 Jul 2019 11:55:37 +0100 Subject: [PATCH 0633/1250] Address review comments --- proposals/2134-identity-hash-lookup.md | 175 ++++++++++++++----------- 1 file changed, 96 insertions(+), 79 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 33bda297..f1df605f 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -9,10 +9,12 @@ that email address or phone number is already known by the identity server or not. If the 3PID is hashed, the identity server could not determine the address -unless it has already seen that address in plain-text during a previous call of -the [/bind +unless it has already seen that address in plain-text during a previous call +of the [/bind mechanism](https://matrix.org/docs/spec/identity_service/r0.2.1#post-matrix-identity-api-v1-3pid-bind) -(without significant resources to reverse the hashes). +(without significant resources to reverse the hashes). This helps prevent +bulk collection of user's contact lists by the identity server and reduces +its ability to build social graphs. This proposal thus calls for the Identity Service API's [/lookup](https://matrix.org/docs/spec/identity_service/r0.2.1#get-matrix-identity-api-v1-lookup) @@ -25,7 +27,7 @@ which will leak less data to identity servers. This proposal suggests making changes to the Identity Service API's lookup endpoints. Instead, this proposal consolidates them into a single `/lookup` -endpoint. Additionally, the endpoint should be on a `v2` path, to avoid +endpoint. Additionally, the endpoint is to be on a `v2` path, to avoid confusion with the original `/lookup`. We also drop the `/api` in order to preserve consistency across other endpoints: @@ -40,11 +42,13 @@ The following back-and-forth occurs between the client and server. Let's say the client wants to check the following 3PIDs: - alice@example.com - bob@example.com - carl@example.com - +1 234 567 8910 - denny@example.com +``` +alice@example.com +bob@example.com +carl@example.com ++1 234 567 8910 +denny@example.com +``` The client will hash each 3PID as a concatenation of the medium and address, separated by a space and a pepper appended to the end. Note that phone numbers @@ -52,55 +56,59 @@ should be formatted as defined by https://matrix.org/docs/spec/appendices#pstn-phone-numbers, before being hashed). First the client must prepend the medium to the address: - "alice@example.com" -> "email alice@example.com" - "bob@example.com" -> "email bob@example.com" - "carl@example.com" -> "email carl@example.com" - "+1 234 567 8910" -> "msisdn 12345678910" - "denny@example.com" -> "email denny@example.com" +``` +"alice@example.com" -> "email alice@example.com" +"bob@example.com" -> "email bob@example.com" +"carl@example.com" -> "email carl@example.com" +"+1 234 567 8910" -> "msisdn 12345678910" +"denny@example.com" -> "email denny@example.com" +``` Hashes must be peppered in order to reduce both the information a client gains during the process, and attacks the identity server can perform (namely sending a rainbow table of hashes back in the response to `/lookup`). In order for clients to know the pepper and hashing algorithm they should use, -Identity Servers must make the information available on the `/hash_details` +Identity servers must make the information available on the `/hash_details` endpoint: - GET /_matrix/identity/v2/hash_details +``` +GET /_matrix/identity/v2/hash_details - { - "lookup_pepper": "matrixrocks", - "algorithms": ["sha256"] - } +{ + "lookup_pepper": "matrixrocks", + "algorithms": ["sha256"] +} +``` The name `lookup_pepper` was chosen in order to account for pepper values being returned for other endpoints in the future. The contents of `lookup_pepper` MUST match the regular expression `[a-zA-Z0-9]*`. - The client should append the pepper to the end of the 3pid string before - hashing. +``` +The client should append the pepper to the end of the 3PID string before +hashing. - "email alice@example.com" -> "email alice@example.commatrixrocks" - "email bob@example.com" -> "email bob@example.commatrixrocks" - "email carl@example.com" -> "email carl@example.commatrixrocks" - "msisdn 12345678910" -> "msisdn 12345678910matrixrocks" - "email denny@example.com" -> "email denny@example.commatrixrocks" +"email alice@example.com" -> "email alice@example.commatrixrocks" +"email bob@example.com" -> "email bob@example.commatrixrocks" +"email carl@example.com" -> "email carl@example.commatrixrocks" +"msisdn 12345678910" -> "msisdn 12345678910matrixrocks" +"email denny@example.com" -> "email denny@example.commatrixrocks" +``` Clients SHOULD request this endpoint each time before performing a lookup, to handle identity servers which may rotate their pepper values frequently. Clients MUST choose one of the given hash algorithms to encrypt the 3PID during lookup. -Note that possible hashing algorithms will be defined in the Matrix -specification, and an Identity Server can choose to implement one or all of -them. Later versions of the specification may deprecate algorithms when -necessary. Currently the only listed hashing algorithm is SHA-256 as defined by -[RFC 4634](https://tools.ietf.org/html/rfc4634) and Identity Servers and -clients MUST agree to its use with the string `sha256`. SHA-256 was chosen as -it is currently used throughout the Matrix spec, as well as its properties of -being quick to hash. While this reduces the resources necessary to generate a -rainbow table for attackers, a fast hash is necessary if particularly slow -mobile clients are going to be hashing thousands of contact details. +At a minimum, clients and identity servers MUST support SHA-256 as defined by +[RFC 4634](https://tools.ietf.org/html/rfc4634), identified by the +`algorithm` value `"sha256"`. SHA-256 was chosen as it is currently used +throughout the Matrix spec, as well as its properties of being quick to hash. +While this reduces the resources necessary to generate a rainbow table for +attackers, a fast hash is necessary if particularly slow mobile clients are +going to be hashing thousands of contact details. Other algorithms can be +negotiated by the client and server at their discretion. When performing a lookup, the pepper and hashing algorithm the client used must be part of the request body. If they do not match what the server has on file @@ -112,20 +120,23 @@ server. If the algorithm does not match the server's, the server should return a `400 M_INVALID_PARAM`. If the pepper does not match the server's, the server should -return a new error code, 400 `M_INVALID_PEPPER`. A new error code is not +return a new error code, `400 M_INVALID_PEPPER`. A new error code is not defined for an invalid algorithm as that is considered a client bug. -Each of these error responses should contain the correct `algorithm` and -`lookup_pepper` fields. This is to prevent the client from needing to query -`/hash_details` again, thus saving a round-trip. An example response to an -incorrect pepper would be: - - { - "error": "Incorrect value for lookup_pepper", - "errcode": "M_INVALID_PEPPER", - "algorithm": "sha256", - "lookup_pepper": "matrixrocks" - } +The `M_INVALID_PEPPER` error response should contain the correct `algorithm` +and `lookup_pepper` fields. This is to prevent the client from needing to +query `/hash_details` again, thus saving a round-trip. `M_INVALID_PARAM` does +not include these fields. An example response to an incorrect pepper would +be: + +``` +{ + "error": "Incorrect value for lookup_pepper", + "errcode": "M_INVALID_PEPPER", + "algorithm": "sha256", + "lookup_pepper": "matrixrocks" +} +``` Now comes time for the lookup. Note that the resulting hash digest MUST be encoded in URL-safe unpadded base64 (similar to [room version 4's event @@ -133,36 +144,40 @@ IDs](https://matrix.org/docs/spec/rooms/v4#event-ids)). Once hashing has been performed using the defined hashing algorithm, the client sends each hash in an array. - "email alice@example.commatrixrocks" -> "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs" - "email bob@example.commatrixrocks" -> "r0-6x3rp9zIWS2suIque-wXTnlv9sc41fatbRMEOwQE" - "email carl@example.commatrixrocks" -> "ryr10d1K8fcFVxALb3egiSquqvFAxQEwegXtlHoQFBw" - "msisdn 12345678910matrixrocks" -> "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens" - "email denny@example.commatrixrocks" -> "bxt8rtRaOzMkSk49zIKE_NfqTndHvGbWHchZskW3xmY" - - POST /_matrix/identity/v2/lookup - - { - "hashes": [ - "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs", - "r0-6x3rp9zIWS2suIque-wXTnlv9sc41fatbRMEOwQE", - "ryr10d1K8fcFVxALb3egiSquqvFAxQEwegXtlHoQFBw", - "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens", - "bxt8rtRaOzMkSk49zIKE_NfqTndHvGbWHchZskW3xmY" - ], - "algorithm": "sha256", - "pepper": "matrixrocks" - } +``` +"email alice@example.commatrixrocks" -> "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs" +"email bob@example.commatrixrocks" -> "r0-6x3rp9zIWS2suIque-wXTnlv9sc41fatbRMEOwQE" +"email carl@example.commatrixrocks" -> "ryr10d1K8fcFVxALb3egiSquqvFAxQEwegXtlHoQFBw" +"msisdn 12345678910matrixrocks" -> "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens" +"email denny@example.commatrixrocks" -> "bxt8rtRaOzMkSk49zIKE_NfqTndHvGbWHchZskW3xmY" + +POST /_matrix/identity/v2/lookup + +{ + "hashes": [ + "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs", + "r0-6x3rp9zIWS2suIque-wXTnlv9sc41fatbRMEOwQE", + "ryr10d1K8fcFVxALb3egiSquqvFAxQEwegXtlHoQFBw", + "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens", + "bxt8rtRaOzMkSk49zIKE_NfqTndHvGbWHchZskW3xmY" + ], + "algorithm": "sha256", + "pepper": "matrixrocks" +} +``` The identity server, upon receiving these hashes, can simply compare against the hashes of the 3PIDs it stores. The server then responds with the Matrix IDs of those that match: - { - "mappings": { - "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs": "@alice:example.com", - "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens": "@fred:example.com" - } - } +``` +{ + "mappings": { + "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs": "@alice:example.com", + "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens": "@fred:example.com" + } +} +``` The client can now display which 3PIDs link to which Matrix IDs. @@ -173,7 +188,7 @@ as part of this proposal. ## Fallback considerations `v1` versions of these endpoints may be disabled at the discretion of the -implementation, and should return a 403 `M_FORBIDDEN` error if so. +implementation, and should return a `403 M_FORBIDDEN` error if so. If an identity server is too old and a HTTP 400 or 404 is received when accessing the `v2` endpoint, they should fallback to the `v1` endpoint instead. @@ -186,11 +201,13 @@ be clear about where they are being sent to. * There is a small cost incurred by performing hashes before requests, but this is outweighed by the privacy implications of sending plain-text addresses. -## Potential issues +## Security Considerations -Hashes are still reversible with a rainbow table, but hopefully the provided -pepper, which can be rotated by identity servers at will, should help mitigate -this to some extent. +Hashes are still reversible with a rainbow table, but the provided pepper, +which can be rotated by identity servers at will, should help mitigate this. +Phone numbers (with their relatively short possible address space of 12 +numbers), short email addresses, and addresses of both type that have been +leaked in database dumps are more susceptible to hash reversal. Additionally, this proposal does not stop an identity server from storing plain-text 3PIDs. There is a GDPR argument in keeping email addresses, such From 1963a24832eeb4539fbcdc7449cc0bded4bfff13 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 8 Jul 2019 13:27:38 +0100 Subject: [PATCH 0634/1250] fix attacks paragraph --- proposals/2134-identity-hash-lookup.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index f1df605f..2ac074af 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -64,9 +64,12 @@ hashed). First the client must prepend the medium to the address: "denny@example.com" -> "email denny@example.com" ``` -Hashes must be peppered in order to reduce both the information a client gains -during the process, and attacks the identity server can perform (namely sending -a rainbow table of hashes back in the response to `/lookup`). +Hashes must be peppered in order to reduce both the information an identity +server gains during the process, and attacks the client can perform. Clients +will have to generate a full rainbow table specific to the set pepper to +obtain all registered MXIDs, while the server has to generate a full rainbow +table with the specific pepper to get the plaintext 3pids for non-matrix +users. In order for clients to know the pepper and hashing algorithm they should use, Identity servers must make the information available on the `/hash_details` From ed67e26037650b2781661bbe78f3593209778c5c Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 8 Jul 2019 17:02:33 +0100 Subject: [PATCH 0635/1250] pepper must not be an empty string, append medium --- proposals/2134-identity-hash-lookup.md | 45 +++++++++++++++----------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 2ac074af..18ecece7 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -54,14 +54,14 @@ The client will hash each 3PID as a concatenation of the medium and address, separated by a space and a pepper appended to the end. Note that phone numbers should be formatted as defined by https://matrix.org/docs/spec/appendices#pstn-phone-numbers, before being -hashed). First the client must prepend the medium to the address: +hashed). First the client must append the medium to the address: ``` -"alice@example.com" -> "email alice@example.com" -"bob@example.com" -> "email bob@example.com" -"carl@example.com" -> "email carl@example.com" -"+1 234 567 8910" -> "msisdn 12345678910" -"denny@example.com" -> "email denny@example.com" +"alice@example.com" -> "alice@example.com email" +"bob@example.com" -> "bob@example.com email" +"carl@example.com" -> "carl@example.com email" +"+1 234 567 8910" -> "12345678910 msisdn" +"denny@example.com" -> "denny@example.com email" ``` Hashes must be peppered in order to reduce both the information an identity @@ -84,19 +84,20 @@ GET /_matrix/identity/v2/hash_details } ``` -The name `lookup_pepper` was chosen in order to account for pepper values being -returned for other endpoints in the future. The contents of `lookup_pepper` -MUST match the regular expression `[a-zA-Z0-9]*`. +The name `lookup_pepper` was chosen in order to account for pepper values +being returned for other endpoints in the future. The contents of +`lookup_pepper` MUST match the regular expression `[a-zA-Z0-9]+`. If +`lookup_pepper` is an empty string, clients MUST cease the lookup operation. ``` The client should append the pepper to the end of the 3PID string before hashing. -"email alice@example.com" -> "email alice@example.commatrixrocks" -"email bob@example.com" -> "email bob@example.commatrixrocks" -"email carl@example.com" -> "email carl@example.commatrixrocks" -"msisdn 12345678910" -> "msisdn 12345678910matrixrocks" -"email denny@example.com" -> "email denny@example.commatrixrocks" +"alice@example.com email" -> "alice@example.com emailmatrixrocks" +"bob@example.com email" -> "bob@example.com emailmatrixrocks" +"carl@example.com email" -> "carl@example.com emailmatrixrocks" +"12345678910 msdisn" -> "12345678910 msisdnmatrixrocks" +"denny@example.com email" -> "denny@example.com emailmatrixrocks" ``` Clients SHOULD request this endpoint each time before performing a lookup, to @@ -148,11 +149,13 @@ performed using the defined hashing algorithm, the client sends each hash in an array. ``` -"email alice@example.commatrixrocks" -> "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs" -"email bob@example.commatrixrocks" -> "r0-6x3rp9zIWS2suIque-wXTnlv9sc41fatbRMEOwQE" -"email carl@example.commatrixrocks" -> "ryr10d1K8fcFVxALb3egiSquqvFAxQEwegXtlHoQFBw" -"msisdn 12345678910matrixrocks" -> "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens" -"email denny@example.commatrixrocks" -> "bxt8rtRaOzMkSk49zIKE_NfqTndHvGbWHchZskW3xmY" +NOTE: Hashes are not real values + +"alice@example.com emailmatrixrocks" -> "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs" +"bob@example.com emailmatrixrocks" -> "r0-6x3rp9zIWS2suIque-wXTnlv9sc41fatbRMEOwQE" +"carl@example.com emailmatrixrocks" -> "ryr10d1K8fcFVxALb3egiSquqvFAxQEwegXtlHoQFBw" +"12345678910 msisdnmatrixrocks" -> "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens" +"denny@example.com emailmatrixrocks" -> "bxt8rtRaOzMkSk49zIKE_NfqTndHvGbWHchZskW3xmY" POST /_matrix/identity/v2/lookup @@ -212,6 +215,10 @@ Phone numbers (with their relatively short possible address space of 12 numbers), short email addresses, and addresses of both type that have been leaked in database dumps are more susceptible to hash reversal. +Mediums and peppers are appended to the address as to prevent a common prefix +for each plain-text string, which prevents attackers from pre-computing bits +of a stream cipher. + Additionally, this proposal does not stop an identity server from storing plain-text 3PIDs. There is a GDPR argument in keeping email addresses, such that if a breach happens, users must be notified of such. Ideally this would be From 9ed19a37ada6dd085ecc717b2d80d01bc369acd0 Mon Sep 17 00:00:00 2001 From: Alexey Andreyev Date: Mon, 8 Jul 2019 16:30:54 +0300 Subject: [PATCH 0636/1250] Client-server: Fix upload keys example request Contributes to #1733 Signed-off-by: Alexey Andreyev --- api/client-server/definitions/device_keys.yaml | 2 +- api/client-server/keys.yaml | 4 ++-- api/server-server/user_keys.yaml | 4 ++-- changelogs/client_server/newsfragments/2157.clarification | 1 + changelogs/server_server/newsfragments/2157.clarification | 1 + 5 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2157.clarification create mode 100644 changelogs/server_server/newsfragments/2157.clarification diff --git a/api/client-server/definitions/device_keys.yaml b/api/client-server/definitions/device_keys.yaml index 888c93a4..41504aba 100644 --- a/api/client-server/definitions/device_keys.yaml +++ b/api/client-server/definitions/device_keys.yaml @@ -33,7 +33,7 @@ properties: type: string description: |- The encryption algorithms supported by this device. - example: ["m.olm.curve25519-aes-sha256", "m.megolm.v1.aes-sha"] + example: ["m.olm.v1.curve25519-aes-sha2", "m.megolm.v1.aes-sha2"] keys: type: object description: |- diff --git a/api/client-server/keys.yaml b/api/client-server/keys.yaml index cce0edca..69e39def 100644 --- a/api/client-server/keys.yaml +++ b/api/client-server/keys.yaml @@ -217,8 +217,8 @@ paths: "user_id": "@alice:example.com", "device_id": "JLAFKJWSCS", "algorithms": [ - "m.olm.v1.curve25519-aes-sha256", - "m.megolm.v1.aes-sha" + "m.olm.v1.curve25519-aes-sha2", + "m.megolm.v1.aes-sha2" ], "keys": { "curve25519:JLAFKJWSCS": "3C5BFWi2Y8MaVvjM8M22DBmh24PmgR0nPvJOIArzgyI", diff --git a/api/server-server/user_keys.yaml b/api/server-server/user_keys.yaml index ea59de2d..93237d80 100644 --- a/api/server-server/user_keys.yaml +++ b/api/server-server/user_keys.yaml @@ -180,8 +180,8 @@ paths: "user_id": "@alice:example.com", "device_id": "JLAFKJWSCS", "algorithms": [ - "m.olm.v1.curve25519-aes-sha256", - "m.megolm.v1.aes-sha" + "m.olm.v1.curve25519-aes-sha2", + "m.megolm.v1.aes-sha2" ], "keys": { "curve25519:JLAFKJWSCS": "3C5BFWi2Y8MaVvjM8M22DBmh24PmgR0nPvJOIArzgyI", diff --git a/changelogs/client_server/newsfragments/2157.clarification b/changelogs/client_server/newsfragments/2157.clarification new file mode 100644 index 00000000..5c1d549b --- /dev/null +++ b/changelogs/client_server/newsfragments/2157.clarification @@ -0,0 +1 @@ +Clarify the encryption algorithms supported by the device of the device keys example. diff --git a/changelogs/server_server/newsfragments/2157.clarification b/changelogs/server_server/newsfragments/2157.clarification new file mode 100644 index 00000000..0acf7495 --- /dev/null +++ b/changelogs/server_server/newsfragments/2157.clarification @@ -0,0 +1 @@ + Clarify the encryption algorithms supported by the device of the user keys query example. From 5df86dabe0f58f8552a6c5f0839664b547bd6045 Mon Sep 17 00:00:00 2001 From: Jimmy Cuadra Date: Tue, 9 Jul 2019 01:12:07 -0700 Subject: [PATCH 0637/1250] Clarify the purpose of reference hashes. The server-server specification describes a "reference hash" of an event and how to calculate it, but is otherwise not mentioned anywhere else in the document. This change adds a sentence to explain that they are used for event identifiers in later room versions, which are described in other documents. Signed-off-by: Jimmy Cuadra --- changelogs/server_server/newsfragments/2159.clarification | 1 + specification/server_server_api.rst | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/server_server/newsfragments/2159.clarification diff --git a/changelogs/server_server/newsfragments/2159.clarification b/changelogs/server_server/newsfragments/2159.clarification new file mode 100644 index 00000000..d7b79ccf --- /dev/null +++ b/changelogs/server_server/newsfragments/2159.clarification @@ -0,0 +1 @@ +Clarify the purpose of reference hashes. diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 03c624ab..2e96dc85 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -1134,7 +1134,8 @@ Calculating the reference hash for an event ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The *reference hash* of an event covers the essential fields of an event, -including content hashes. It is calculated as follows. +including content hashes. It is used for event identifiers in room versions 3 and +higher. It is calculated as follows. 1. The event is put through the redaction algorithm. From 52643a92c6981e04e68d9d5b4be34edff1509d9c Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Tue, 9 Jul 2019 17:54:45 +0100 Subject: [PATCH 0638/1250] Less confusing wording on Application Service's Legacy Routes (#2160) https://matrix.org/docs/spec/application_service/r0.1.1#legacy-routes The "becomes" wording made it a little bit confusing for which was the new route and which was the old. --- .../newsfragments/2160.clarification | 1 + specification/application_service_api.rst | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) create mode 100644 changelogs/application_service/newsfragments/2160.clarification diff --git a/changelogs/application_service/newsfragments/2160.clarification b/changelogs/application_service/newsfragments/2160.clarification new file mode 100644 index 00000000..3e9c1c02 --- /dev/null +++ b/changelogs/application_service/newsfragments/2160.clarification @@ -0,0 +1 @@ +Clearer wording for the legacy routes section. diff --git a/specification/application_service_api.rst b/specification/application_service_api.rst index 11a07839..302f0980 100644 --- a/specification/application_service_api.rst +++ b/specification/application_service_api.rst @@ -213,14 +213,14 @@ should fall back to the older endpoints for the application service. The older endpoints have the exact same request body and response format, they just belong at a different path. The equivalent path for each is as follows: -* ``/_matrix/app/v1/transactions/{txnId}`` becomes ``/transactions/{txnId}`` -* ``/_matrix/app/v1/users/{userId}`` becomes ``/users/{userId}`` -* ``/_matrix/app/v1/rooms/{roomAlias}`` becomes ``/rooms/{roomAlias}`` -* ``/_matrix/app/v1/thirdparty/protocol/{protocol}`` becomes ``/_matrix/app/unstable/thirdparty/protocol/{protocol}`` -* ``/_matrix/app/v1/thirdparty/user/{user}`` becomes ``/_matrix/app/unstable/thirdparty/user/{user}`` -* ``/_matrix/app/v1/thirdparty/location/{location}`` becomes ``/_matrix/app/unstable/thirdparty/location/{location}`` -* ``/_matrix/app/v1/thirdparty/user`` becomes ``/_matrix/app/unstable/thirdparty/user`` -* ``/_matrix/app/v1/thirdparty/location`` becomes ``/_matrix/app/unstable/thirdparty/location`` +* ``/_matrix/app/v1/transactions/{txnId}`` should fall back to ``/transactions/{txnId}`` +* ``/_matrix/app/v1/users/{userId}`` should fall back to ``/users/{userId}`` +* ``/_matrix/app/v1/rooms/{roomAlias}`` should fall back to ``/rooms/{roomAlias}`` +* ``/_matrix/app/v1/thirdparty/protocol/{protocol}`` should fall back to ``/_matrix/app/unstable/thirdparty/protocol/{protocol}`` +* ``/_matrix/app/v1/thirdparty/user/{user}`` should fall back to ``/_matrix/app/unstable/thirdparty/user/{user}`` +* ``/_matrix/app/v1/thirdparty/location/{location}`` should fall back to ``/_matrix/app/unstable/thirdparty/location/{location}`` +* ``/_matrix/app/v1/thirdparty/user`` should fall back to ``/_matrix/app/unstable/thirdparty/user`` +* ``/_matrix/app/v1/thirdparty/location`` should fall back to ``/_matrix/app/unstable/thirdparty/location`` Homeservers should periodically try again for the newer endpoints because the application service may have been updated. From a3d2d14dae745b5460809b62b1fa46027154ae90 Mon Sep 17 00:00:00 2001 From: Jimmy Cuadra Date: Tue, 9 Jul 2019 15:25:23 -0700 Subject: [PATCH 0639/1250] Rephrase explanation of the purpose of reference hashes and link to the room version spec. Signed-off-by: Jimmy Cuadra --- specification/server_server_api.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 2e96dc85..62f6916a 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -1134,8 +1134,9 @@ Calculating the reference hash for an event ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The *reference hash* of an event covers the essential fields of an event, -including content hashes. It is used for event identifiers in room versions 3 and -higher. It is calculated as follows. +including content hashes. It is used for event identifiers in some room versions. +See the `room version specification`_ for more information. It is calculated as +follows. 1. The event is put through the redaction algorithm. From 9bb6ad80d1c01e6d1588cf77f05fc84af1260e98 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 10 Jul 2019 16:13:38 +0100 Subject: [PATCH 0640/1250] typo --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 9608093a..fa89f603 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -248,7 +248,7 @@ in the current login sessions is: token from the Homeserver and submit this token to the `register` endpoint. Store the resulting access token. * If the set of documents pending agreement was non-empty, Perform a - `POST $prefix/terms` request to the servcie with these documents. + `POST $prefix/terms` request to the service with these documents. ### `POST /_matrix/client/r0/account/3pid/unbind` From 3514437d24399462fef62b9c32e15a57eefe13fd Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 12 Jul 2019 11:37:38 +0100 Subject: [PATCH 0641/1250] Ability for client/server to decide on no hashing --- proposals/2134-identity-hash-lookup.md | 31 +++++++++++++++++--------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 18ecece7..3f869f0d 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -86,8 +86,9 @@ GET /_matrix/identity/v2/hash_details The name `lookup_pepper` was chosen in order to account for pepper values being returned for other endpoints in the future. The contents of -`lookup_pepper` MUST match the regular expression `[a-zA-Z0-9]+`. If -`lookup_pepper` is an empty string, clients MUST cease the lookup operation. +`lookup_pepper` MUST match the regular expression `[a-zA-Z0-9]+` (unless no +hashing is being performed, as described below). If `lookup_pepper` is an +empty string, clients MUST cease the lookup operation. ``` The client should append the pepper to the end of the 3PID string before @@ -102,8 +103,8 @@ hashing. Clients SHOULD request this endpoint each time before performing a lookup, to handle identity servers which may rotate their pepper values frequently. -Clients MUST choose one of the given hash algorithms to encrypt the 3PID during -lookup. +Clients MUST choose one of the given hash algorithms to encrypt the 3PID +during lookup. At a minimum, clients and identity servers MUST support SHA-256 as defined by [RFC 4634](https://tools.ietf.org/html/rfc4634), identified by the @@ -114,13 +115,21 @@ attackers, a fast hash is necessary if particularly slow mobile clients are going to be hashing thousands of contact details. Other algorithms can be negotiated by the client and server at their discretion. -When performing a lookup, the pepper and hashing algorithm the client used must -be part of the request body. If they do not match what the server has on file -(which may be the case if the pepper was changed right after the client's -request for it), then the server must inform the client that they need to query -the hash details again, instead of just returning an empty response, which -clients would assume to mean that no contacts are registered on that identity -server. +There are certain situations when an identity server cannot be expected to +compare hashed 3PID values; When a server is connected to a backend provider +such as LDAP, there is no way for the identity server to efficiently pull all +of the addresses and hash them. For this case, the `algorithm` field of `GET +/hash_details` may be set to `"none"`, and `lookup_pepper` will be an empty +string. No hashing will be performed if the client and server decide on this, +and 3PIDs will be sent in plain-text, similar to the v1 `/lookup` API. + +When performing a lookup, the pepper and hashing algorithm the client used +must be part of the request body (even when using the `"none"` algorithm +value). If they do not match what the server has on file (which may be the +case if the pepper was changed right after the client's request for it), then +the server must inform the client that they need to query the hash details +again, instead of just returning an empty response, which clients would +assume to mean that no contacts are registered on that identity server. If the algorithm does not match the server's, the server should return a `400 M_INVALID_PARAM`. If the pepper does not match the server's, the server should From f474b31f5f8b74604ae652ec62eb3090615a80ee Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 12 Jul 2019 11:54:45 +0100 Subject: [PATCH 0642/1250] typo Co-Authored-By: J. Ryan Stinnett --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index fa89f603..b840932c 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -51,7 +51,7 @@ This proposal removes: * The `bind_email` and `bind_msisdn` on the Homeserver `/register` endpoint This proposal relies on both Integration Managers and Identity Servers being -able to identity users by their MXID and store the fact that a given MXID has +able to identify users by their MXID and store the fact that a given MXID has indicated that they accept the terms given. Integration Managers already identify users in this way by authenticating them using the OpenID endpoint on the Homeserver. This proposal introduces the same mechanism to Identity Servers From 6e061b1baf8e03de4b01525b9aa39d4eb7e82c8b Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 12 Jul 2019 11:55:11 +0100 Subject: [PATCH 0643/1250] unnecessary capital Co-Authored-By: J. Ryan Stinnett --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index b840932c..21caa305 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -268,7 +268,7 @@ to re-add the 3PID. The Identity Service API previously did not require authentication, and OpenID is reasonably complex, adding a significant burden to both clients and servers. -A custom HTTP Header was also considered that could be added to assert that the +A custom HTTP header was also considered that could be added to assert that the client agrees to a particular set of terms. We decided against this in favour of re-using existing primitives that already exist in the Matrix ecosystem. Custom HTTP Headers are not used anywhere else within Matrix. This also gives a From 25a47afa329d39538b0856a1b6df3b4bec293197 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 12 Jul 2019 11:55:40 +0100 Subject: [PATCH 0644/1250] unnecessary capital mk. 2 Co-Authored-By: J. Ryan Stinnett --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 21caa305..eb4fd75c 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -271,7 +271,7 @@ is reasonably complex, adding a significant burden to both clients and servers. A custom HTTP header was also considered that could be added to assert that the client agrees to a particular set of terms. We decided against this in favour of re-using existing primitives that already exist in the Matrix ecosystem. -Custom HTTP Headers are not used anywhere else within Matrix. This also gives a +Custom HTTP headers are not used anywhere else within Matrix. This also gives a very simple and natural way for ISes to enforce that users may only bind 3PIDs to their own MXIDs. From 78d46b289097f67adf27b35fcc14dd1fdc0ae379 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Sun, 14 Jul 2019 20:20:09 +0100 Subject: [PATCH 0645/1250] Proposal to move the `redacts` key to a sane place --- proposals/2174-move-redacts-key.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 proposals/2174-move-redacts-key.md diff --git a/proposals/2174-move-redacts-key.md b/proposals/2174-move-redacts-key.md new file mode 100644 index 00000000..d93deaf5 --- /dev/null +++ b/proposals/2174-move-redacts-key.md @@ -0,0 +1,8 @@ +# MSC2174: move the `redacts` property to `content` + +`m.room.redaction` events currently have an *event-level* property `redacts` +which gives the event ID of the event being redacted. + +The presence of this field at the event level, rather than under the `content` +key, is anomalous. This MSC proposes that, in a future room version, the +`redacts` property be moved under the `content` key. From b09d48a9f764baf0624757e06b325c001215356a Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Sun, 14 Jul 2019 20:22:39 +0100 Subject: [PATCH 0646/1250] Spec link --- proposals/2174-move-redacts-key.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proposals/2174-move-redacts-key.md b/proposals/2174-move-redacts-key.md index d93deaf5..ca3083a6 100644 --- a/proposals/2174-move-redacts-key.md +++ b/proposals/2174-move-redacts-key.md @@ -1,7 +1,8 @@ # MSC2174: move the `redacts` property to `content` -`m.room.redaction` events currently have an *event-level* property `redacts` -which gives the event ID of the event being redacted. +[`m.room.redaction`](https://matrix.org/docs/spec/client_server/r0.5.0#m-room-redaction) +events currently have an *event-level* property `redacts` which gives the event +ID of the event being redacted. The presence of this field at the event level, rather than under the `content` key, is anomalous. This MSC proposes that, in a future room version, the From cd5549d483782d9171f3c810974786b7672a9d95 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Sun, 14 Jul 2019 22:50:46 +0100 Subject: [PATCH 0647/1250] Proposal to update the redaction algorithm --- proposals/2176-update-redaction-rules.md | 48 ++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 proposals/2176-update-redaction-rules.md diff --git a/proposals/2176-update-redaction-rules.md b/proposals/2176-update-redaction-rules.md new file mode 100644 index 00000000..a939178a --- /dev/null +++ b/proposals/2176-update-redaction-rules.md @@ -0,0 +1,48 @@ +# MSC2176: Update the redaction rules + +The current [redaction +algorithm](https://matrix.org/docs/spec/client_server/r0.5.0#redactions) is now +somewhat dated. This MSC proposes a number of changes to the rules which will +improve the security and reliability of the Matrix protocol. + +## Proposal + +The following changes will require a new room version, since changes to the +redaction algorithm also change the way that [event +hashes](https://matrix.org/docs/spec/server_server/r0.1.2#calculating-the-reference-hash-for-an-event) +(and hence event IDs) are calculated. + +The following *event* keys should be *removed* from the list of those to be +preserved by a redaction: + + * `membership` + * `prev_state` + +(Note this refers to the *event-level* `membership` property, rather than the +similarly-named sub-property under the `content` key.) + +Ratinale: neither of the above properties have defined meanings in the Matrix +protocol, so there is no reason for them to be special-cased in this way. + +The following should be added to the list of subkeys of the content property +which should be preserved: + + * `m.room.redaction` should allow the `redacts` key (assuming + [MSC2174](https://github.com/matrix-org/matrix-doc/pull/2174) is merged). + Rationale: currently, redacting a redaction can lead to inconsistent results + among homservers, depending on whether they receive the `m.room.redaction` + result before or after it is redacted (and therefore may or may not redact + the original event). + + * `m.room.create` should allow the `room_version` key. Currently, redacting an + `m.room.create` event will make the room revert to a v1 room. + + * `m.room.power_levels` should allow the `notifications` key. Rationale: + symmetry with the other `power_levels` settings. (Maybe? See + https://github.com/matrix-org/matrix-doc/issues/1601#issuecomment-511237744.) + + +## Potential issues + +What if there is spam in sub-properties of the `notifications` property of +power-levels? Should we not be able to redact it? From a1de6ff63445c0e59233875a9c53eee6efc9a9e5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 15 Jul 2019 10:20:25 +0100 Subject: [PATCH 0648/1250] Hopefully clarify some bits --- proposals/2140-terms-of-service-2.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index eb4fd75c..1120373f 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -76,9 +76,8 @@ of: This indicates that the user must authenticate with OpenID and supply a valid `access_token`. -All other endpoints require authentication by the client supplying an access token -either via an `Authorization` header with a `Bearer` token or an `access_token` -query parameter. +Clients authenticate either via an `Authorization` header with a `Bearer` token +or an `access_token` query parameter. The existing endpoints under `/_matrix/identity/api/v1/` continue to be unauthenticated but will be deprecated. ISes may support the old v1 API for as @@ -142,6 +141,17 @@ to use the service. Its response is similar to the structure used in the "name": "Conditions d'utilisation", "url": "https://example.org/somewhere/terms-2.0-fr.html" } + }, + "privacy_policy": { + "version": "1.2", + "en": { + "name": "Privacy Policy", + "url": "https://example.org/somewhere/privaacy-1.2-en.html" + }, + "fr": { + "name": "Politique de confidentialité", + "url": "https://example.org/somewhere/privacy-1.2-fr.html" + } } } } From d9269b084f6fbb6e95364c9bb919596919f3a3f3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 15 Jul 2019 16:58:24 +0100 Subject: [PATCH 0649/1250] Exclude pubkey endpoints from auth --- proposals/2140-terms-of-service-2.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 1120373f..557376cc 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -68,6 +68,7 @@ be dropped from all endpoints. Any request to any endpoint within `/_matrix/identity/v2`, with the exception of: * `/_matrix/identity/v2` + * `/_matrix/identity/v2/pubkey/*` * The new `$prefix/account/register` endpoint * The new `GET /_matrix/identity/v2/terms` * `$prefix/logout` From 1f786ae6dc2f74069cd008fe69fc2b08ac8be3dc Mon Sep 17 00:00:00 2001 From: Sorunome Date: Mon, 15 Jul 2019 20:52:24 +0200 Subject: [PATCH 0650/1250] commit image into repo, fix typo --- proposals/2010-spoilers.md | 4 ++-- proposals/images/2010-spoiler-example.gif | Bin 0 -> 55001 bytes 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 proposals/images/2010-spoiler-example.gif diff --git a/proposals/2010-spoilers.md b/proposals/2010-spoilers.md index df7fd6c1..cf969902 100644 --- a/proposals/2010-spoilers.md +++ b/proposals/2010-spoilers.md @@ -5,7 +5,7 @@ For example, when discussing a new movie or a TV series, not everyone might have In such cases it would make sense to add a spoiler so that only those who have seen the movie or don't mind spoilers read the content. Another example would be e.g. in mental health communities where certain people have certain -triggers. People could put talking about abuse or thelike into a spoiler, to not accidentally +triggers. People could put talking about abuse or the like into a spoiler, to not accidentally trigger anyone just reading along the conversation. Furthermore this is helpful for bridging to other networks that already have a spoiler feature. @@ -20,7 +20,7 @@ It adds a new attribute, `data-mx-spoiler`, to the `` tag. If the attribut contents of the span tag should be rendered as a spoiler. Optionally, you can specify a reason for the spoiler by setting the attribute string. It could be rendered, for example, similar to this: -![Spoiler rendering idea](https://user-images.githubusercontent.com/2433620/59299700-95063480-8c8d-11e9-9348-3e2c8bc94bdc.gif) +![Spoiler rendering idea](images/2010-spoiler-example.gif) To preserve the semantics of a spoiler in the plaintext fallback it is recommended to upload the contents of the spoiler as a text file and then link this: `[Spoiler](mxc://someserver/somefile)` and diff --git a/proposals/images/2010-spoiler-example.gif b/proposals/images/2010-spoiler-example.gif new file mode 100644 index 0000000000000000000000000000000000000000..3716bd7755940ea959cab8d162b90e365358a181 GIT binary patch literal 55001 zcmeFYXH=7KzqXl#gcOnxI#M)9ZxTSN0-<*dAiWq6>0szxLg+;Zy$J;A)d*4r4WOVD z0YNDOVnILwv4HruFg$zD?7ioGXTHr^^X199KV+?Z$V#s3cPH0z9;czPfvTEY5%4PD z2T&ex@;C-Sp-{9Wij|FnU4fm8hoAe@8E#E3UVb570U=&99$tH{Q#fTlLE(R0$`|-G z^#o3f2x7$q@uvm#j0FwN1ud)vZ3G0p_)ZIno)!{6t#szJo%3lo{xha$u)^Y4cTa4v zfRM2GSy8F8V&~2}Vb2DK3yaGMTb>b)i5C%<77>>bNlF(LmlloSqm?Ngb!JD1TmAUg?5@qO!ty6$Rysisw}n zmDLngwH3WZ&MT{)SJgUy!QlMm^GYhJN*4^2)zp>Mw3OAfmDRPCU6qu5R8%e+s$RIL zdI7I$Dye=^LtR7bf|kw&ZS#wPCr`CBE~#tc@tQhDS~@yfI(k~s7x6kecwIyMb!}}w zX&qfX9eq6=LxPU;1w8|OeM2LCBNKfyNBt;0gCqk(Vyf~l388Ntrn!ovKLrG>e%g}tgpp7|x)%a`oE374G+zBYsmOX~_N8+#{Pr>l0h z#`ZQ=4#YsmW_zb=k(P*gxLi4Kr;FyyZl2cHTTRm8ia;-4K zqp-NFsO)x8d0lDKSb3pGIjym(ww;#iU(?uGR}$6Ga<7Hnf9KwV&g#&v{zv!QqVGQ# z8*Gkw&=vb&c#1JJJT&%vbaLTock=l3^5pF5?8~?F!|5+qHebE@^!ojm_3@lHo8R7T zfB&%abNgA|&V13%*S~w8zwR$r?5|aQTdDZIRCe&H^6*u~kE5fXYgNa`$3n*}7W$X1 zb+rll3g>W4z>{$h`U!?006>7uzh>iKV*-F312|v;Ms(UxB8)@I`3b#xBo!lUa?9xM z?Z=tCioPpP?$(UuV0AMDj5}(d=1W*NJ3sBHn<&Oz9lvGVSwB^-8uD@FX=lT9m8_{6 zOGI|ngOE433PI!dn&uj`lzQP2Icoz^-+%8aHeav2%S#x^5Hz**XbSwa|0bpe3_Tj73z~ZUbV^rbef$%;1S0EN%4~!6q zIr-|huky;#<{jH}jZW(K7j~zh9LnymaKMqIRMxSzRj1aR_ILA)M3#kK-`5YK?p=J8 zlJJHJf{--JQY+kD8C-MvS*VU1xc}ob%w_WU{yFreomZTySbL%__>AXdUd3Eb*N=-l zg5r%^ZX!mR%m}jhI$4RUGe`6D)>#S)7fS{}OQPri&~*_eGleDZ$2m5?Ip=0k8qOGP zs0x@3n;=o&YvueqE%7l09gIPoff4qT&UT1!TuJ%9&9QJ%K#BMWf<}T9GK|F3o{KGn zhH#!f6}gXgD*e)X1f{YJyE>^Z5FBP_pi@aAKvXeoNu_W+<`LxLcZ@bGKe&;C z2zc<6iB0u97E|WivF!=fz|4ZcK8L5Uw2RKP_cc*moksF5+rt26$i;-4%GLIYXw`QG z@5~iS2WF>i2EKeNHxTC?NA}U zTk2X_3!6&T;%f-zJI%jT^fv-qyOL6PQ*Pnt-LzVy432#2C9dY0!iG0fretghc~oUk zzW$P`pf+h3H77-)q=PE(dUtgZwQcwjcIO1V)IOE*P#n=p$Llo`8%D&xQ^_F23PvY) zHDz*M9r~a%Tj8w7jGkES<+Ch`S3E!&G6H&PcPwivMk)+N?-7%jWY@7&kPxqYLc5_D ziB5lXR**ib&Fb=f)<9(N!yNn`9?Yux=;z%h#9tos8uKM|BJ(BOHx|XU$j+O}%k~s9 zoaOwNn_8hkb<+kM=a1=~AVC025JODee7{@uyvxBT>KDuYNU~fd;|1b;rTiFw74P8( zHQDZIjd2eK1A0khWJ<1sXpL6Aj>H3*V69&**8WNRG!5o+A>2(%S|b74q>eJAhm2JS zK}`D6m7${nwlcpvZ9AV1d>Jw%4MWO8+W(k+Iub5cFh>%|XD98gQN^YBEp6s|lZh%? zzp`FUDVBJJ4x#jRqID`B*Y|yB)s{#A^>R>jy4Ecw5Ja*LDG}hnh!+PC;b5Aw_{P8ooJf|5H_}WaSw?7lpDMsScw2thnG$3$F67VF? zXjDO}mUGd;Omj~NeJwVTZvc=gAUg!$P#xhc>xIb8kb%69QkV?S*I*%PIXml<;hW?X zfiZdHxqWSpk=|rnGh4>8o;Wpe(u4h`eAz&N_o-L*9tweOH{D>uTphezJQt}TwD;FS z&n#^rjUJ&E@>lDPv{4)*H_MiO_S8G0Q4VEA1A9J>q{l-R*WB+SH1~)3Xi}nz;ni?^ z{0QFw2E?RFn7kSt67pJ^s zA4An)I_wl!l88tURAFX_BMlKm0y8f;Dmh@x(6g;zWB&a%q3KmSk60#6)(d|i% zMnhsu=<^9I9yke}QF5wKmK)N;d&Hzq?Ri;>8Plb-Bnvz3n_h$(UiF)gq|VBN%K28S)_psnk{q*>U*c>o9P2q4Q9=RoW;pc+B@D3fa?9@;D%{!PMoUNkl){rZwE<)5??a z=1%pYkG4wtHrz9KsOHfSYX%|d%n<{sJ_AIVv@E}%blrXR;@s7)U(2hvyZYl@WUj{j za-xeBLuzGZeXaeju%AD?Gq1E4gfd(HHu_`uYh6Oz#PaK7cNNB z!A~1OIf}^lsC?eO4_&0_rIvT+I(Z&^a|uW{&+-se{5k1u@hwj}b{Ud+>KMHGr#&;^ zHlQu97_2y>&E}6xmhyNrZCgU&q>XYl| zf1a1v%9Ze&gF1b?9_K9?h#}lj1QD>{Wh1*c$DJPte^U;jo&6^9_dQr{iT?H>nxht2o9d+2%! zG)bhXIOb9#9|-|h8ufL@E#V0}LxOygV{%q!*WhHpbhIsnb6hY;N!8^odqZ#ETt%`J z@5;>2y^iYSKYql{;t7?#ZzFSYftkgBSU4{w&b?S?R=F7WmV0`*MQhdd$6Kd4_tf6y zSLoCS_cc)5cR;P50=Mt*Yrb|n6T$t`JTOf0@0a-Of%p8Z`=L$=>%4|X$c(mxq8tx+ zCqo~%NCiL}&+_!`gS3MaSezH#S>apYk6yD=Sq$e7=MB@Qg4#n;Xd_GTqdo)1Yz$>x zM+CumY@1WLc~)Ww;eAQ>RRe44_I($WWlqe{(6$cJ;Te|wK_S`KbYZMp3FU3xh8 z6Ae{+QjOlflPK^z`%lJ1#rrC;hn!CW_R>BN{t2T(qjBUYT)Zza-mW1`tl0ORLAdv3 zJb@>HU>L+{pMX(K;Q9fv-S^dBXF9)5q7hWsI|lm0ObDEg>Qlj7!?6e_us9JzjW%N)$l?AA5xbi=_6$>B*u`^? zMcObT3sp$3#^MNANRk9(?Z@@mv50V3e0XnK)G?MEhe^-lO^+r(qhOIP#IWCD5LTWz z|4n89EIkefOI(M>5z@K*E3TP)mKnW}t$cXd2$YwH2GZx772GGp_+tjhW!?La{-aNpE&}e9F7-EAU zqT3kKz(5Dl05kyWtO4fXX2<~sC4y(#m|=lqvftTf!!fMyNFk={=t3I6oq;x{0$$<~ zkOV{)L$G}Y{)oZsk3kNtBhYwICm#8T0jq03@WEsJX}R5)#33?*uMZ5z!yB={$>Pu% zFXoV~8^EKq9NzeEW0~B?c2S!}2{GOfoAr$1g~+=`;cU>1U~EQyNkQHgv{n_CvR_c^ zozb|(T*B*pOAHdXmEILuz_bW8+b&4KXEaDa0~azimr^r-qyiS=pZ65*8|IUY^S`JR zhf2mr*vD}!K&)wCeHxPtJvebAnC}gssTj};0E6UN%y2*;1z|?bYs6xz@W}RkHZ@hu zg(s-{ILsE7`A=ks-WI9{hk1ny-G{}-5LiX9n1^JPYEP-tR_PZS9CVju1&5hs1kBR? zTY4ZMHx_P5;3G_80Upjl&O?)tP-+SS4|2i+rwEiPOz9i|24%pSX#jsJ3;TY6IwsKc z2juy&Vd`gbGE*Z|DJnlYGTa9mq1G4ZbBg3uoJJx*qt^>-VTI)QunI>d`0#4 zkG5jDaf_Cb9#HRLv1u_Wd~8v1sJ=m$D;)zcU_8I6#{OkzW{~YTmTo*;QjMh@hhnEQ zJ(+<+`ygW_06ZQEok0RSAl+1eDIUpA2TpD>JyU^fbVnGd<&)H)AGa$n9K#c=iu2VS zs?9f<4b?JGe6(MsO_$)bV@cZ8(hScinhT*I?ne>JIL%zL&?AaW{Yd6&F077hHulNj zZ!Xv@g?{C^?Sh3c8kvR{qr^?voAGe*+Z35JN>*u}J_y!K0M!=f6%b;0f@9{+*7L>(FVC21E;gJJ79tsAjq4#huh_57^F>Ch5mD7uQezOgDjv! z#ta)CQ2|p}O!Roeqji9nK1gQ2;;mR_)nY_uNlWpQ{F^2T)+*KQMRABh!}PjWhtT9KbZeJgx%d-?xeCc5NDscQlUcH7Y!%dh#!fr0oEqHx_+u3O|Ud z68dzvV5_<-qf#Y3y{y+q>Qf*3*9~Rkc&>&(t?fA7^nPGOb!tXqPGn24aq&%~RMqXw zs(Pk!C@4|XYv?Y@LlyH9Uk;}tKFpv$;*k2sdFWYNl$|t-;gb+%OQu;Ix)95}g~PNF zYhS$@e9iyhGjHtr40?x%N|P+ZIo3QmDuJ&9Jji>ki40!5(#_T_mfo9GN4sEqdqeJY4yK`8>CZrQwti>D#N2P z`(la%#+nmS;@_(T`m1Gbd&ON^xX=G2F6BvTJ8U4@FjMvSqx)%bOA$fS_oKw5+Cu6v zKC0~9B#6U{3fE+>P0>cIz;Jcd2PuA}W5oqSSnM8t_8!>-#6Qw$^a zHiBZ6Ay>t#?wEwV^70n$A(y`-ZyraCW%(z7ibn^V-EN8BbJ)TB;bR{YcO}X=)?V{P zLW6JBk6zgfx{?}ZWiXyv>|?T!{`W_C&T{jxAB`F6%hzy?$P+GeYa)?%e2>}pVbOSv z^SE1T;Sm1>09uu~nJ@7vP{Y8V)a_6h%Tea(n#u6xYuX|8rAe{hrrZMnON0yMkrL+<~%FWdk;kA3L3v^-zktrY$=!_{Y0q@_Esr zD?)bKca(@aBz7pd;blF3b-6IToHexd0x^eJ&{IT$Vhiw(AhFVcT=fc=TxyEIW!2`G5)L!#I4+N zvFpG2>Sf&OV#Vt6;Offi>e}(2)pfzOw;F5jUDhhUj|<@S%#9O91$wd`TxvMDZTtW^%~}?7k1cSxH)v>8EGBvcz$&{D104W zxsDr+J&$dSEt;qd_f8k{RB3z7qv=&I%=XgBtGWw>XaOfhhhN_G?aU&5+aUVBfbG!B zaPpuXMjf0O0MdTI4SX;9fak&tdYjyXkw-TG91}jq%BA0EzZj;O9wa#yr365ToMtbh zmx*Fo^&z!f2@mu&*=XX?wO-MU4betkR}<;_Wj#$Xm6s z$;^D=Xz=NymN_Sm3&#Z36NsW`&t~NKflZqtmPQ#}rj#)yDi|fgiHT=`Am(kr+Y6W% z1eTTclN&~@2m!UvK;Nfs#;b$iPGADAndV(3n9-sF?=LmFJ$s+|16KMb8NEkD*HSgG z4CL-Q`V~1(I~ws}9lf!B@)H1l#XxV<+nDaMjF1P9BruCJAu~nU2MqKU9k_x+t^im+ z0%A?+sJ$8VBr(8`fMxWx}93i8D?5u0#5`SUL27Ol)hh~UlR4r~^*iQm}W!fi$w92+JvqLm0d)V&)wx~#c zI@21lHhl)oB!qfOPu70;8KYg&98r?qS90@biIik%0i1n{(FLaiw`aa@q7}Z9m^rYl zDiXjw+7~{?m(y~ULaZHF>2&3+Vm_nW@ugqc@u07?L5L7AQVzpDgErx19Vk5*g0fpRZG3qT1Gz!>?;@gfB16okw_M~fVRw!|Y|yVbV2K>Y`SSr$j!jAm^LOvIzDUja z{@VgTgvA#6ksK?1X{!njKG?qvC!+b{`=Y|Zo#)~TGdg>Hk2GHump2?CjtTHJ`okD$ z%=q;0XJ_h$dA`_;qt-DfNJ9J68R#9-<_9WFCFh@vXIqcGLY`@2&J$Px2_lyF!H_yp z=`{3Z?G%)tW)iRETfGb}S=UD;mhTL*PuW;n5va2bU{Q)>2_`Qu5lp^ZNVKLtAJ1kV zv++IBT}=Y7_{wMT7*Yl_AcFTUY~Y7e*rY=_E!{Uv`BZ{GzMsuk@~gZU_MQ=x{~?o0 zR6lf*H}^?J5*2Q=;=Vv?te_h5i^3d9IrqUaFcUE7j+I)^u2dZpUxUY>AS6!AR=S!f z5XEt*u#$q)R*%Fgferrf^*=hC2!st%{K+EFow=;N{7?k9){)yzfaBP@>y8!OFpYD`T&*l zumm6@I580SQ%VAwVcCk*gG ziPX*W^LPbg;i;p*jE>lnge10?C7&Tai#`nkxA;H_rQz#uMn}NU*{qSF2%TX*nLgw9 z)dq`_+H&DHh-s5g>5}45-cR4Dh`<#eaXt*f1Y+u+Cy6^w;Je+|#2y~0D{o~iUU$#R zRL}}9iK;ArGqz2m4`-a~$97ykYuE+K5ceS_fH9;HK(DD+U6-xX^~VR#%|z{e!CT(@ z)oEwzt##lM+4_fz?l}^}shzbeWV@o^x^73mJC6^SUBtI?leoNT+R!sMj!WI$DHaB$ zcCO+8b?<78qC>Ze90PTqx?<0MpN6Uwb>F6j`u=miEq6xM{n~my^!wd;$b7;7?wHtp z|ITTH3jtjVp7#TKUZ-3L?AxrrA9(+>t19-tBZNYr`$>{;k}AN!046Z_-!A}U{{5Bw zZ<|5*WP_jq>?gaV6~OxY+br6aoCsq>h+yl8!$}|r#{T`Y`H@66I4{{_x*#DH1cc$R ziTQ(OQ0!k0V>|_EeR#SFjLoZMw>=c7Lt;AWna{XHE=?o`iJIS3sFh(yq&Cc!?f&zp z-1oETC3q{0_nQH&Wt1wsxTJ`!t|-rugp5nr2b==BEo*WI6n9P7pE}Ht`0bU!(Dn=L zD_xFaynA+j?@3oa@QWLd5j%2cAT21EO#UB98R{e{O9yKFM^eW0|C*G6IK1c6{%=W{ zm`b4DeKSZ6g!%mVi7KH#ZIF^a!^v;ajn~^j&ev8T8 zAeTD4plM|+_gCBT62&VJvzhu2(=?S3w0Zx%lcdbL#dWH`>(c`L>O`ga{cv~h?vPLC zjxH@GtTKGg9F1i!d|rRz!n$y>LSHvqQaPy41^UD0Mj*WQ9@Fz*KCR2M9z*dAfJnsJ zNK5fW*ZW9|Lxngw*#y1xUq|1d>l~Iwe~$so66<6zxA%GiOssL8f>hpGPh`&9X9a*T z*aT$#Bd;?_0^wV4C}_?!9k@RJ`=eBe`o^~zGTmEmnXR+9>fT@)0AO z=NZ;;W*YrWE%6$K3n7Hx+BMvYtV|zfk(;NFpz+|0N3^7~Y~HkZv3^}t)=S1_O|0@q ziP{2NU&-1$&*jG3xBmVdPEzn)u+Ta#@XZm7vF-P{o!XtTRh8v>EG1oEW})s^+x5>= zpPJa`rJHvc9Y$VN@t_1fc2k)*k2)sA%JtY2`x^>E6=Ree|J4q9?=RqaPgr-61yL;LB{~xa_SB;dPWS zgK$lq6S`BqVjJ7|VBT>@s``sqc`L_hVfi<(-Nmb9@ZtQ>aP8h{#OJXIO*4JYDV-Sk zQL=CAw`ZTZ)#Whs!{`Qv9*^vLC4?y#JnTqz8$CtPMUBp*rv<)rYVsgtt1sFiKX;x^ z-IecDke(!sV2*`#FO1p?BZ0%-9El58;sx}F9bsLkK0oZYna+!{_JG{*%vFPeW-$!B9rI6MNx)*ZP+Upc()jfY;qyoJ5_?e z*R?Ld=pn>NUM4Tt;LEsk6xGRUv=FR+7Z?B?1XU#*kAKNHChKxDA@FBSFl1K&2|yXI zrSSR}p%A35antw``)wNJ50I1`ex%Dgwm1y%%qCZv*6cKTGS>S7-RS(TUnEL~)thJH zlgVCHGkaW z;JZWyov)P8>PtaTzGit5d7mJ=8hK)`Ydg{P&w&7G>;nugAdH!Rk2A~pD349_Nbele zK81_zixv=nn_TcjPn=Hz@IiWrb7OPz_xrc{5>Fnph}rcG76vEhBgI9Z!tj^JvqQ>+ ziBfZ_0|M^oyxjSki<@f3I@q_BM|w%TzX-=ql`iUV0tuA0z{ZD$U#H`v-wSIBCcsiY z<|oU&ce)UyY8Xk$P39f+W>M*%&9Z%t4pMbR7BfsfYr`;R5<~21mLL-v2x3f>ya57$ ze-8jkL`nLxHldTh1-@u@5DWnfw$xv^&h#HmkMZYot5m_X)4MRdFdrM)jxG#%WdtH5 zn_RA`KMVLMp)EQtgsCqg^N&B8KJ9q?N5@WGft^F7Yvm^wckoETFzfC8EG`t^OY`0 zqgaD!jsK*J*|Y$YM8N>wDbYZ9mfw7^%xo7;BEdR7^X6rwIafjNv`i8_O#|k^EeD{; zf_32PZ`e-;rwnpC>5KqA>FeEgmS=af^;?%r zeTU%9N|LFr7_vqIxmy?k;CFTa+5EOG`JoL_@Ep2b`F68mtE%h;xmp^2Ofedoz`D?sH7}3SzT_Vq%&%hq|t(8cUf~5PneL6=S0`5+?HBKNU|De9d(_vH2rCqySi0EmG|YV-ZSSF zxjuhm3B(1h?%q&QG{vIAdta^Udl-oB4}vxMOHsfQeE?||4t%BaRu1z+9ESSBmR_Fz z*keS=#YtxT@j1p|3%B*TDLcr&(u0W}M1?ozs3;dKB()&hqo}k?UE$_A{h+Z{MVhvSKN2^X{Mo zcHmah6OF%)>X`#zS8RRVmrZjP%H59YN{>_4abpTa90lPb2lcz#ez$Z74>GQKUp;Vi z9~b*oIqi9=F+K8#S#$Q&B?XU9dSBO3Qv+FFJ|N1x6^zWna{S1?W zb*}i-GcmTHUb?B?p_3CGN+z?20)p@aW-~JA><`e?jCYP_)WSVzA5D6+L;q)@8Z^wk z#>SY3(?r3`K=F_$)JPZ^3%M&EFq2}RPP0GK3t;0?!Y*pP)w7ebOT4`h!=ZN-#7Rl) zB3kua)hvnCT2Rw6u(BU>l>REGF^sY-IJ1Z`ZzH2YxyZ-!H$H`&>A?WL0Q3Rukmm$+ z83wvdK68hN`jMOLw3s|2YW@z3StLP30q7Tcf!i+v9=;$y!eX|CgLt7qKs?f*{>pC~ zYlRKS-c7DB!&h53_Zux0 z?X(*o;cT(;t8=lBdUKeA&ByFP;C#igukxAaEyeE{yiL>BjW=C%O`S7X@o%PS95wIM<(3 z{dSFvys#p62_Gq(d#O(s>7evVSH3MNU%jvBKo{5lJfD)NimX+g(p8;Glu6-GWaZRG zE~%TSX()B7o(qwQOfN7xrELFB@tLrEL?0gd-2j$^pVw7?rXZ*N&V=x!sBB4igd#0F zr|7_>>Y`XCr&}24QREb*n$@S&_FS^*?B3wOEoQt25N z2l?l4>4hlCH$HL&d6m-+mCJdO1;gdbYE{NM;)hQwdh)9NS*jRTlilyDq6Sy}fYZQ^ zw4C9}V>Rg?+gL4~D)c`zOqsY4do`zHHTSYGkZ^{lzgl3q8qJRRA14kBkO#mA!2Z{X zgFvKEU>ss*3_|q?1u3j~i}&suz0?!fq*r43)_@|YaRZ65dOym3;^xW72iKVviC<~Y zlC<7W<+N*uFsN9>m;yGotTBwhgg(#7myFSD z^sd%c^e*u>hyc#y{v3>I4sAXqhj|MqUITG<}(7l=Fg>;N3#L1hQY0CT^`^bgGt0&?v2zFoJ+jf`vV6p<#R)9b1p@yYbs&HufKvee|5_>>An#GWtXXL zfK)jAKfmFW{IlrL`JDVFKp6A6*v6oB9zA9z5vfx|szi*f!vZXv^l0UF0)U+fL+1tP2=0o2Rm;g_AiPM_8?Rb( z#z_*029m*W2DS@+ti~9XY>O z^=3`4_`_2=H@-MnV{FjG(LRUJy=bBIGO53X*(z_G7($l_r|6d;R zM9-bq56LHV#jKZpLRUDXT_=0*zB}=dO)Jg%IyNRs6#dpF`#LwLX}X!G|DWhe_wK9S zkWXt<_j^9SKJk#xSPb-jdG{n=`pUC`zHgf|HKtV-gZ*KhK^=atpADXP$m=7S$7e1* z82I^ZYp&(W^n<})Kla~ERK*WI_;W&6KE0lP`0)7uqAO1v0L)?%{1jWrI`$fJ{4p(& zO-jNg+0oK|F^SjpfaV|=?JX246m4_cNt|-@BGs*~L?|<;PxY)f=SzF8ETKkf1@!XeiRV$6*<3Xj?nHj2(VGT%&m8auR6Vv9D= zzp3y2#;Nq`%g16wi}}XHvVh>9o>xo>yg6vwtZP>*{;oFJRRUFYswFPB9@RJ+vx`a4 zqWdB}YV0+W2lKUU9)A^M~KS%tG`Lt|$mT8Cf?M;QH4iR*RxoH9KE$y~Tg+K(BM z3;y4xR5wrP%Ecc$-=^_U+3z!YJOSUk@1Jh_{@hGu_xl{dQ1)Q{vR%Nz3wy7&gO|<` zy9W!zRN2EtkK%yCCGUo|!)5=T-NRR;G1(t0p)uT;{~pBuISc=G^8fAR|J%v`x0C;G zC;xwS@{RHUa1;D&hT}cXSYFU6kvH(9HEs4#UJ71AD(wPn=(dD;lZoB<^P>Lmb-0^N zW?m+9Wy{~|Ri~OPBF5(`$L|TDNsbGq<@OSd-l89 zVl|wu%w)eDXqdV~h6=p?bK7n(|K@gR+XV5GZ+9o&h{Dl|0VviAp*&#>o(GuZ{k$I! z0TyyWS}|9CGZzm|hnF&BYYnTsTb#gXg>l|ii!Y4I`qewf>=BA{Xw>BkyA3Y4Jyc6|j!sYXg>S0gSk>n}7C-#p0 zl&ouKg}C{)$!mu(3lb$Vcim%6%)TF4-O<=G;IJz;gz%y2p8k!4Y4!HAMmjWOOCxyOZxzQAo_k+=C!;L7I}T#E&NmLBNNL^tk0v)S`b7^sdJtOu z@K>_p#Tc|pc31Hm8nb~R@JXHlsC&2d-D&arW2KtmIh%r?qo?_op00hX4l+*`B}GH; zBsUc_44|xNm-!orKI-FSkl#H}{e?zvftgwB!1>{J#;y!|(SEYhdpAr92`r))n3mV0 z{xa;C$|T_3#_SvM=KkJV$Zf^n5XGx80}uWl@@H`Kx^-03ST~DP=wJ$IW`!nCEs)PK`2qA%Xyu0VG zhac~atp57?t#ac1=eRT3H=^yQt5>XzhFLG7t`(wJZvQLspaB0P@%S~yT*QU!BapKQ zpelNN=RU}eD^g+umE2>MS{#}A!)l945(PwQK+s&?mVFGHK4Mgf3N(%ktFSv!*C{W= zV@2$uZ>(RF*<>#J5n~(?>qB$%+z*h5h{cO1wtRp(iU(Ii;c56J1BvMQVu}eYTK0$% zg%9*qxuK;B!={E+7gKIilO4U|vWc)bQY@E2*qfr@IRigiyJUmLu-f7ErK&dy9 z0N*(22GHP~k5O#)mN7&Y>=R}=Iukz+AaETj+>m6ym9?-LCGvwZ^CQSsB3PU!(aS!X zo^qo_IZgt0^KE1D``+XQ!{9`$-#uoi0W|nFG}_oZ&e0oj8=rH+OmV%;JB!fETa^3I zq@f0iaU^BdK292zQ?U^B#XBw^M_nq0`tCza$*EB=UlySCH7bh)j>R8;vH;*_5_t$f zZfB4=lR>=%W|Rc0%u?O~A@aokFZa&8l@?jKh}b!%!X!wDeR?`~SOVt@*Z~2Br-L^D z$P1GBqWFAK4C@9t^4dC@MgRpd&{FBBCXCC8bChnzk_86tK4}8r;rSbg zM`Yw5C@jE-CG%fZgd$f0sDg|b<8>44iLxu9lrrEO5+zAblU*XCTRvn%OT*?HeSh=D zx-9xWT*&%rpIzir`rR8*s#Y@3Q|kKiS{yF!nFNATnp}E{rOYQgjhgLxc$4Z7-NqdI z#=b1cxUAbayQ?Xw*0}tB6Xgg7WjD?}D7N~MY9&Wyi6MZ_s9hFt$Ze+ORgn>#$%rR7 z7JH?1E}QhVnS^Z&RAMGQa})LOm|(erkJ3s{(CJGP#UYmopjQr-t3NB4?LZ6$s=x-7 zY=^S;u^gJo6(zHD0-PTKz!LlL0sz=)J^l#+G-40J)1h)R$oMqGiGDsuA{VS9kYy|t z2TTq1%q`rpol&K|#&Hfj3t3fAxcJBHLWi95{iWZ$%MMf#_2jY#v{L2q zWGbWVt}={Dril2K-Nhry(#srS(T{lI^r9)cy(tKXGDF`S!?L=;^qfGtAxa{W8^}~sEFzJO&7yS3BP_+y^Cr-z)-XC-d)yb;l$6?c1Ai1HnU-yD7pK}^V_H^PgFW#< z0YCz(j@nw9-g;nGLZFTG~wI5G@1Z@@O$sSo~v31N|GpYI5T(=ONodU?c zLIp=Qrb>&}b8a9i@D537ApFVDF2RvcVD0-f-2*sHDxFkTkvxX#p;|@%Q~A)llIt2e zPQ8)qT4VYGT|y~Abf0Aza4ntG#GQ=vDQgmCFb@$e$vopQD@x-?B<3iU_$bv|64&lz z;ZTq?7SsKBpgl;)0hG1hgWm@=6Ug0|AlNT5t_l6L3BtfbvP@2vF8`@9LL=SkB^_1X zn2>y8*<$-d@qI-TcU@=D%sotZ2yoGT#Lcp_zv(O>-fF2nNDKhhOX`>dfUhyY60~ME z^=hu@PVrv}F&N6NjcRKQz=sxN0Hwa`r#_GhPTMZ4>KR;0jTVxM%{q3tw<3kGEH9n) zZM#M60@7iguS#7P!(_*@Ev2$+eA;dk5O~LE36HZ_rRxmik_Ayt5LULcPz-@ zn1&wiYj+g%?>Ie1WqVmJk`qqCpj{gJDTBP~074sD_R!E4+nEwvkmoazK~ywXvM6WR z(5Zo;n2-6VRMCxTC_4g3Ak8Y!w_Yl$!}}BxslwuM3MohK@GiYYN=F7efYP=gFH4J~ zdW#!IWA%6f|G;WwRFk~RgLk&d92y>8sgD8lg}ps2c^6Z93jnwEWAy>Rzn4>ld1_s4 z1Np+41NUz_?7&j7N$>b#asSj_+G3`dQRZ2mIM+u#=b>gF)8W_s zVV=~8VM$W#QN*oQD^$NtAL;&7OQ1F0tz|Pn!5&)nBeC5e*}@(=_rc$)_r@wL+1)#| z(J*l8N05Q^Js+9isP)zy4B!|8sK>@>{Tf>`yctM!`^gRPT`y_%jFwxx(KhM(80zUu zaC_a8V^9nYp-sqcGV7~Mk$8iHWP$^Z9tU^_i}xhTrba{?#+SwBR>V$A9wgA5L1kfC zTKn!7KDcNUd%qJ1km7kZ7tY)p9y9aHUnU}v-*dciGB_*T&zBgs0ISg}hXxY6mTBM# zV%M#ivS0iGzKpm(+*hqh-cvjQ(mbBiA7=iMcp`qR;ptxN^|mJzAvo)~5c^^)rq}<* z{ho2>(O|PNug$~jGd9zRglUVLL5reZX3Sx3sdE#Xt^A{I4DPU)`VgX*cdBx@Da}ib zx4Shfm=eouLwn%A+j?goqLTIkNQIpK;Caqqyt5~^r}%nwJ;a3^5y$LLfW9QlE;}qbe$DadFtJNzBqgM{OJgnLRuU2?< z7JL1*MFj`~05h{ef&k5RroV-2+e#i)aVvm!PinY_Y53a4lt)p~`nI4qEM;{mV0uOH z&Fb#zKajOYFI@GDoOu7P{(9j$+_mFdK9&BiIIlKPdAX>b6R_7{0eEZFuNrdcN$o0X0?L(*N`+ytPZjU!YT{k5m zAkV#4tM%4H98=o0O=rkuvgVd^_GVOI*Pmk?DBfbregnh)c#HaADdol%kb#ENw{rKa zF%VNIZZfqJok;|gYkn*b0WjkMjg=ppvp+J^6>I-~Tnz?vXnwk<`H6nxQ*Y%bd^G@# z1+wFS9CRQb0QAUphmW)~jNW;$_X&-aKCJyTlg%@*_h}3b%CG<}R_-opf>tbc_^3M* zdpon5dr|VcLxH;@bkKSFo;r=`lLeC^?xe{FTG9kz_jfrMJ9>J1zt=bg-hJW+fVMT6 z)YqA`2w+&%zScU^?%zEb`Yx6Z{CRHgkL#EFYoA6eK#F)KO#;}E1}0#>3f%#lkidrI zeU{IAiuljMG$6XFr;pv#+3%uGx{eRqfx>i<`aaVcEl6L{iz_n_7b>J51rfah z)}nnCnfb~w1KYua0jNsB@li{bWS+aSPQj@eDuoBosn(DdHEbqF|@ zrI*aoO^3o~;1E@o)q8CJ*{Hbo`V&9>n>qn(LV%E5B7$kb&$%bEUP7!1Up4Ve((B*Z z=|AP}G9BQVC|6jx6VNo$(YgP%4*UCm)?tf2vtduVo$G+@V?4zE%764N@CcAL=mmgv zht5(h2dtR})v-cch|Fyb(C?RyM|*+;$!;zL$jNCQP<@pdj`5pRBh0`mE`-!_ijYeH z;Lh;9ZrOyiy#lp}jhA?{j+-w1PHaMZeB85+chVN6MDd0jocE)5W&+lgv-mHD(Xi*1 zKC}xeV&E?eGGYF9fUvJCcVAt#`gpn7rp@(nnawBLc9+2$5Ps#MJZHGGOG26-R0iS?y=oeoF!CbwoA@7|r0_Q*wl@`fC%c4KJN} zR&lWPR2Z7gujJWpr1mv&G=nXDMGea)=PN*DJr*|k)_rvZ7s~oBiYbp=s*<*0Rm8ig z=q?-{5^*u^i0O0&_{&?7MavxKM~rmNT7_1CO9$%0fUzmHadp?@RN-dwnJa%||2f#b z@MJ?2*uD<;lrLQux?EyJX1|R6CyCc?Clgkoh+W23?6N<33QT*ib`=zL+XN4a5J)sr z7_U77DNg;fFRZV1aiS)B_W98;LNsG0A^GJ>E*TtkzS@L>63U}h7&K3S&mOQZGM#3D zj~FzEMh+yG24}QB=1XfGvAD3ee19Lg@WBL&juKO4KkL)0_kR%gmTzq~>b7qJ!7T|+ zk>IYyr6mv`xVsehQmhmyGz9nHZo#!^kwS}Gf#Rh=DPEw!3zPya^kp;Wnrp9l&RP4~ z`@_Dj^A{vvp7D(5zVGoH-xTmaIksv`eXVz=QH9C!H!zhOY(!akY63E4j&X;1U*KoD z(4M%*jorz@4!bDX{1n%0BkBF`um3-+Vc1iqC695%X}_RE6X@~SHZ}41&Z3z-8WUV+ zRVf48WKFKTV?+Ww&!QiAV^iI;xu)W_sh`^Z)L9bX-oc;c-(KcnV>pCkCqdKx6gu}e z`I456Mx{fNs*lu5B5kP%n-oca`V}Ba7&bDE^Wed^ir6qc7aZcu%tbYFCRc(vh{;ST zA!j`gWM20CT3}P&f{JW`POWfLmB^EQlO{mxd^S1en(6)w(&LMRLLCZK1uaLqR;Bqv zdmBNj6i&Z1V}}Y*OR;Y@TNn-6cDr1PzknPWETdKXft|jeu^-<6#_?z^xiA2ss^bRX zJIM3vdpBW3h0NM@>*Zyj3sNiqfFLP!owiaNwwC0x%gj@o^9J+b?ZU^MQQaEu5=0%e zTmUX65`{PB;l8Nmjx?jnx#&VuSZy?ua&{C?p$+BMcOFr#x#b7Z)z(6I*(K)`&R6-o+#X% zW3S4B&tON^{{$0V7%-74g^gS3GX4pg6MaJJ54(?E{MDuI$hW6~a-|3eizWP%+sw-y zv-ZQ3iMo?D!_c@5$zENk=y(7|VLQ{9o z;O%DW1+ll`P}Qs9(tttkgk83zPSVN@OW;TJ87L4NCq2V;389K&KJ*bG9vh8*l!mkt z%Px?I7EU_HlhzQ5zO-p7iha)S6jE2S1Tvii*1*>1@2S%N~ z?DrsN?qahEOPcwdQG~NtW|x+;X=ZvWs0h0dM9D|B7^x-~Ba(`nLu5djLD&1Ay*77Tg(h{|(Ve-wu_4LxNR2 z!=Kp*nV1x0011#L4+xmb6)@urI)GY5GDm6 z_W|7*N+?1ZS~jRg{!T9kwnmIdV{dT(`8yE2&do+?&&-Ui?oHsgUE^d zc+?mC5~#|Bej{u4zStfG1gv&RV47`urPzQtN)eX<0l2*7 z<OL?H!cIoYC}vF4n)Ice2QKU2H(ZBdm` zd0s}YrB-#ev3CauU47Sn7Y}5{n+nPhPFj9H^}e8yBK!Kya-Ng|IG5uSPM>J@lD3#5 zmZY35W*#8Nxmr~0?dDUqf`-i@J4Eo!C^HQkdNXiT#_ouHrHIwSHq*TGsX2}00M^_o z{6j9&E4ttcUMvTiut84p`ntj~epYMy42YIA5pYNnU>-{p-@vZ3Q@GdEc>cl21 zBxIN1oll7VyRUcc$pCWjx=Gxh=B*(0zu zazeJhMaJY!z^M*OZLog(WjHnz17r2Kz`l!&Jt2D?uWGdZ3(*`in3NKFtqgNophVc@ zY(YwAaoA|++F{*3;pq{0s%`!6b(D@@9f#=d`D5`Y+0I@;wbsGmf#XR&Ske%P^%Wlh z@nZp(#EG|a5GHB)zu`%-r`yY?&b&h=do9qw;?=|N}gx)1J^k)UZxm) z0KxrXmyz}Yq5~>x6oS{(y-=R8Knr#10da2G$bHzw=K!Hd$WT(Z=g7+k4%XJBYb&s5jpTD>CAAaL*5&z0$#rL5 z_Res|L!OGQ8sw&E%=;V*aV*5!jODRD5#K^Sz@G)j;ysd3bgSFXVh(p5!~gyBwR%!| z*Tpvp)h%a@|w|+K3zfH zXGc=3^JM@sFrBAR1IE;ax9fuHQ<@`WUdMDXa%;Tt-sCMF!*o{g7*z}syXgfi@2|Qn z0TPkxoW*kweOYh6woeuVTRB((Dhm6DBy`Rr9D2q$CGHY5@2z~IrtK#--L6R|U*8uW z<+<3agT@}7z>B`V+>@o~o{7=9z*1Nfsp@vmWlvvJ5d2$ya{#~r7zEJ%>r_qve$R$P z<503`jd{cRqyNc}1*ZN=Nd@gakY;$6Wn11D6D zw6&PHdb-neg2F3?BXuhFk7&8Aq0bI62SpNcsK_8YFdkG?&ima=OJuE9nsPs}!nJ)| z7Og?=-#x$lV(4Hz8bg9-Y@};VJ7O<`OH2L1HkTe)9)j%_Gr7$rVD%7z_1s9J11$Nd3=+K`mPd_C>-7Zt={c zCIsKCr-OExW`XYqhU;C3x!AIi-v|19u5>Ml^3%Itp9PIdU?U=JE59|ld=$&Z1$Uat z$b^$HxMW3(t^?d~9#?&mq9xmCBlcOd;1A3#Mn5dM6s1W7o#jAH)e>zu5WvGo;#Rf7 zOq)DHXo+Xp7bIQs7$(L-G_a&BW8uB3#_sQ5-W6XS%MkHRJ!AdIgULL(2 zx^k<}Ewg?L$(4+|?N8zjI2zFAvOUsImMFvVZ? zLSmVwT}|>1V&&~_t`)78NCS_8uVW0e9P_d9np9HiWN}*~>_~XBmcq1XT;Ej4Ia{>5 z;K`$PX&tHn;KSQxJED42v_x7d5r=1^pE5LB0xQb*y2RFS0I4cI=0g&h35b~K!zZXw z>{BQK;33c|UrSQK9`ai+0(fTG?=19_-8pa>7Tp=V$i?6-#u3!Q9}p5aeP!R>N~u?s z;f(GbWzg^>As5WBh>bD1K7s%}8aF6OnN5%<@nlFG_4Rz$hljl4sXRJy zsFbWwdXPI7!8_L6j3`1r8b>0c{{~09I1iA|AC=H7p<+!vl_`PX4e~T^V&FtQD8VX% zQmj?s1M0gMj<;6t3h7HR6=c|ZE9oK7zu-Z5u&Mz zhOjPKk%&Rupaj>Dvu=c?oCmA}f>CU-YI`Ux-W+Y>$Oh4%##@h^ zC48qnl5iXOnb{`wqf!=%xWhH-FkmKUjl4xJ zd$FeDg>?j14xGLtnn%@Foy0l~1*FKX2*u;e(yTqV|y~|q*0(*>>`;8gIq1WZ#Mrq<|efX5YU=GIz zO15M4_V>ARz^`$=^;k1(0rNU^4)(wniNmIZE;x#uu+{m92u{Q_zclC8QDxK~P5{3M zMCcJb$~w>0pUalf{H0}-+^Uc;@GZsDIUWo|J@~D)uk_&eOsrR|22znc4gj0QB)64w zlcg)XRR)4*0TohH2Rb3Y=S#@jtK-x2)dLY{wO#Xkl=1sp&kHPZjQ? z3?V4gE+EwexMepDB`0yt4gVr)a~p$ZF7)#7d0UF1lQztEa(1W;Q-N8sOqOgq6;Si{ zvVuN*>O=;+_#+v-7VnrxiPw(95&CZwq$h$?%t2g zfC5ZC{^d5KqTC6E?Ma7CxYGs~pJR#@eNfxva^q&E_)@3$sb8&|MJ%~|W$AFTHs{L` zefFP5>5-JXvDq}x^O?*sW3r%DO`>t{R$Oq0(EyX$lH<7&{mIxUB%aR(4=bSv2q%+v z8cv@eiEG+k5nhvzLCctO>L;7NAEWGprnt>blW^(*DdcS3ffU&pDqNqWofhi>-x^QeUX-k>er$YE*~TX8wGAN#?Btua*D`T__3=obAi~P zIAnwCapwj0g|?iXgzVD#R;pm>*QjW0HE#Hwt5wd=deKQ8xsoQ5G`&ZrMDn&-GsGdl z3Tu0u!35R)H$Tjhw0jSFD+HjHkn*?{ z4#{KtN8zp0>!(&(lE;DD#(=cU4TOS=z!E>xg(GiU>=J~@GYDl{P?ahQ z=c)OUEjUrVtg-fl;?EiTTwC=dI9}d;LCTepJGLM#hHy2k)H};osxt})3?@HHP@!Zy z7fUW;EQofd28s1;(7OsG7dSj;L#c6c{Vm_UKJ~Iyw12Eu%Qazp?@gpp=$H*iOftK| z$)o!@QxPZMvSx;J{N@u8nans}12oUdwRj0zjFfHqNT2JeF^!a# zP~puH`*$ict(9S^L&8CE!YJ%_h6+xh5!q@Z@v|rDmj~MakfaPDaLBG|&fcHl|%|v}`G8f6~0^D~G&7)VhT`9J6>MEw0q-v6u;iPhJ zY}z?ACxFWRRB=73oE&0_CP44`f2fh+y&7eJQYA7M^rGeB6n9uqIOnD*|Di^lLl9j) zVU7VE`}f|hRJuGl>?Y9da)SZk^RXYAQ0IF|(lY8BoYu1FYaKE+?{`{~cIvs8q*?V= zHKOuPWn1=hTSI)KBQV}4xQ-I96JYz+V1ODZa)u*234laN)kqkmh|6)5euWbWB3PdM zgz3+Vtkj#KUn$Nm7y;Ig&?Qn@JCRu>oPj?y3{jWmh6)x72o(h<(m^s}iJv(3@nI%7 zA4wG2(Nl@L8Lh5F2N?kjYAX6nZLM z=5Bz0V2X6#21ejiYnfXf*1XS9HbfR0Me-xQHX}SWeZX{mgEUkACMqw|K9~RitrbMl z7)~+Q(pO@GIx@YOi6%*{H|!ruSYmoI36lH>bi$;`$|t^TvMo>KBBNcjqs0q(({@58DL-qIt^ugz~aam1M?y`hJ&1 zx^N_z^twuz%KLJL&F<(7vl`Qz0I^^%k_HlpCyBblz7iqc&v*&e%7_8zVv}DESA@ln zecoMp6S59)ds?#WG6=S5soQa%mgrZEq4KIOUT*Nvb6qFNN#~ za&5L0qK>vKEq`s`3*%6{K;p77)h7@uD`io4pGJu!mXZq3DJ8lp6Ft1gV!WtUPALbo z;ct|Jg<_CHOhOR=tXV91{MZneY%}MRKrB@ia+uHJEZ%GqOVcqnEEFsnBYnF?g^TlF zc^5VS8^9Jw|IazYJ!gil&kR5V`d@WWsHJe?W3Q3_n+}Tq$bRw6LhrL*WHlnZh;qqN zC5akwfMK0!ijKs@&kCBrpF4{W_*1Oor1$eo>B z&7({Vq+04WvpL&1`K_>!o+x!4m3pdC=K_r+mVEgr4nU2Mc2ZI8i%$O!Lz9Hgjk3?( z<}sSMZ^MqoCFegIFgZN$&X+P-G&WjOmFki8C1#WJm=EhG z3mlmlq6H4Camj53x(OWsPN?l#<}V{WW1au z9*jcL3FJ*Imr3@*q`qjDVNSS$OBs)NU!)b6dYwZWlcpFu?kH<&vI=qkyf|+{H0avO z06xbI%vgGHZIiw93NmEP-iZI;#QxLOE|c#IE5?@{rt`7RWc!ocM+;R~-pe4!FXH5hrqeE0lw&7xF zUTEuQSz1)&8~<^4rUv&Ksf!JnaM~wNTDi08vXv*}O8L6x8ZoJ0UWRMG6=wD|(Lm>wrbNwSj6;6(*dIYqOfrpZD!tBfx> zq$c$eq%W^0$4;>mxxeFKgck3prXgr2Sm_M=y4WT}1Q6M5zH1XeJ~;oO%C6DWn9%f^ElQnWl~D~d80QFM zYtsX0Nn@-Uz-&MHi%GlEa_Lu2qorR?EHk!{vF@D4DAs3L3$fjQDl(kK?odVpwBQ&< z*jb#OycPrY|0N-33A^cN+JBdj|6jAK|H~hz0gwSaf!zNTw%2(7-75CK%5^qn37Gz? zT&Hs99!@dwuW}t{WT@nSmh1de*cMzmK`Q?<)LN!d_h6nD0-?8lrq25HEt`J2O7nKME6bzCs49WF1p!=ya z7(8%|=UMz4sl~O3K;cRlap3ZNvLxr2p=Klz**ps`L9Q~!tqoGn>cWT*9#w1$rPU2l zB+X!cx(1e-@my?+0Et+GhN@x~7 zQse4F`WUe|cl3(F8>IBGXD_>@FfuJPS3aLA2ZB!IH zNgp){W-jKJh#4sIx0n}p#yPB4+Tp#B{S9BC_s-|=p%rBjxbuyt6BKD{IPLl#dePo1 z9GHKd7eO|zI`a~j^`$+WRLxp1R;m?#=^H4dqxaZzhmIiPn3_rjaF3yGXtj-@N=k(o z9)Hh029iH<_jpjABw53_pmXRxw>L#ko=F2ZsR<(0m$Lw8yZ|(Rle{g*bE;2HwRJ7< z2Yh$3i8!Am*s$2c9o{5!S-b@U&hccHgZCwaJnpHvkBet~S2!!`k=;yfYd1T^6`gkf zK8pbY2m#SRrGG6v{uM$eL#zL{WmszQwlrb?+cK>GCWQX~cwUVUX+>EFU4b{lTA%Ji z=r*L|Z=NFC|1E?*@U-IpAcW4?A!wFbpiB{PW72l;zFf1|CRFNv@$MEEC`soAt zk-xg;t0-Pm_Ws(Hc2U;diX_evw!jLgD}4zLSX~a6D)Q@a8!b}or}tk&zgxt&e*TF* z)=CN2#-%iB);eZ2yqEeLQv@tJupnXvZ_G})u^sQLO6wwE2x?Jp7sC{`EILZ>veN;2 z{>j+I8g;0UV;3L{t}04BL9C`yZf@h8#C)?IsHPyR-7 z#4%Kk?nEj59ccI5!@y^R!J`0(Pn~2DyjccXAK}RQ86Lh(@9w?AOQ!?713G$TJd&+R z!5Y-^SH#-WSy$E?G=snoCS=lIs-x^i*>hvrG`K=!(a7R}`unpE)*uZ$>fcPiJ!-F2 zfVAJyP`{_omcF~Ei7A%jeev2LoVIS#ydsdl0cOAnTt)+R)Fo6Dr z*Ywusq#4xek@!{mlWAHOQSw|wnPucXh%I7B~M z30Bo@NxPQPk0un;JgM%EW{LIuaWdm_f%rKsFvaRa>G{6 z(}hA+1+^(pU5`=v!ESXit#jc0F-NlaTd}q&^p+=A3X;FO|J6nFNQur+Y-*SWp-Yw`Y}jv~kG>U%Lw~mo+-<5=t@;YECk0%Hvabd^ zp-kMGhZ!((C;h=R ziA@{6G9!gW(hTF3*+^G*`w`^h+bo8o8A$>(Ipnp+%F4y)d)>ltbZ{-=gUw~Vi-ZUz z4~N}EcZb-=3b4h^&0tcpWX$?*93|T%3z2p|u}R-RO#LYy|D7bkyYl{O6k{UnJwokE5&QVa?&@+Z4za`P;&Ze%VX`NnUm_aY zgo*-Fc8Td+pBcK-m2np0!FA&1(qb-bI0XgvF`vTW2mI+#7K*|krc9sEx}3otbBh)mM4Ey$`$HL z$})hZi@&hpV)S8OW8KQ#)N;9+%pGI-TO=>V&!u(F_3i^bD>f&Bid(G9<)b)rI%es1 zkL|<08h4;iHqJdkXipEWwmf6ra$5Nm(?=VG4$)LEr;Ro=pVW%w z6d9(fsqBe9VIcWS-+(IV6n6)Kf8WM1L*#K&$a;(F)i9Z(veq^?mHIR*e@j_b8wumc zpHO~+Q7T`|!)28YAJKL;sDj_WO*B}+I)Rk2iURKZ{V$@EYJeCWg+ohI9%7TD*@n`$ zsfl_4bLAE(ahV*$>fF53rCb@6YYBL~m;)1+J7XM35I}j%pZ9)B^OK$HLt!zE8vNF0 zE4Q7AQ~BFWZGDZ1Q$fj5<@)$%t;wf`*!o(ES^6Ors3W*Ia~Frdi~BJjnW`VG%=Am} z+K%k^&Y)oSy>k#>!RzEgxAMI22C zHMm6J;vVHx;;rrWgZt$h+iIiA1iSySOmd_A)ypC=JpgU0%+%}vu{^uxyJT3WsWdy&SN6q6$b9$p!KhENn zJs;~>C{bs@qW(~Q*`fUao%Rr_5LPYVbX1~5@jT+kIhZg}_?=qL+*T<}r(?EIgODe0 zA;sY_fvGH0r!pAv8D@?ix3f_P1yk{IYFnGijDpt%jbR;r+@E-ZWxZ9XesZvmpL#x_ zSe+mC`!4+l_Jl5$T%)A?1U9B%H}G67GJ(WH@o&jABOX@4vM8 zl+4H#nVFR$$T|1r>mSD+8tPuJKYk}w`HAFPJ0&W>6?Q##HGZs)x!rrLLNuN7?xITf z&!Oer@8ys0E;~N{ISIMD*`RpOa6PK~_j&%^?Y{2&-=9AIJv>zN=it@j+o*d$+5hYg z{fAwO|Nq#fbIt$WE+yXnU$9H<-&LKTh=r#Ovqlhzf9<(v_FQ76o~^dIwMO<0p}E{v z|BczRMnm&|!tB|AR%@2<=nu7djMX^2FY1+kEnECoVVi~JGu*f{j6 z`wE1yQd%nMKEvs$}z4`gqr?SU)ERStuuW7&Z#&GKvbouQ|bh?a^-}d~u z*{JwlRn&Vm^?ML_&jvQ3GTWfi7f4<6osv*13j5tG#T51x?phkSBf(wbtJrB;6m+F7 zW#c!I=~@tTrjPs*CGcj9E#z3HQ#t<6FEvVUAeU$q^^+VQRR-srGdwy1A=Y6ucW}?{j6f#s})=#mq#M>`nsx@7uK zyK&}nb*r%xQy#y`Poi8@D@azT1;#KwUjW8DaIXgL&>At);bkMY%=ge5kE-m_{k;Mi zeM_R_3#cqqe-C4-(6cJ3nM(&Yapos?(vFxUS$BN8CuTkz5z|j6cr%;g4|l6d@?tBR z)G@WY_e8FywZ#5EG^zKLWClpG8~|?1;I)vd#u9eH>IH}sTH(Pc)dt(Plw`TXvJL1$ zc+;GO!eMz`O76Ceoq4IMWnO)(B4uw5^D9&Dm%dKnHGh++VS^9_YD~V;#0OM^%$7%0 zm)L`|QCLiYaARwlXH@I-Fn2?{@TS=s)st#{HI@iE93l=$3T$g9rJ=lcf9lDq1Eyn7 zmiO(+yAJ|`w$~(042h~_5(_cG{6d{!k#fz9-Ua;SvsUior}b{P-|?|qOQh-m=?7wC zLtcbIP0K9B;|}w8OSM<)!P$4mFV@>tnVS0cD$k-6k+)6CZ7*Ba(q2g1mN)>sc0>s| zk{y$~_ByjI zc5bH-zzTK@Q9y#JoX0GHA5)M2LIRR)!+uO-{gnHlDvwtC?a21U))^-_+haoOoFy$+ zr+$BXJbCt4*oQ$DZjrIa1!Qc&@v^2z^{NjEy@VnrDWiB!uLujYwIVBVzxLrs#t_t! zxkxWCk^3ymd<<&zlS;7t>u!ZcLAsn3aB$QAd-)r53&t9j`L=+a+2=8t`)Szpe8FER z7m3GfGhmDK2mljLqqmQbb7+(Ko}{aaq)BSh1EW$#l{3{pPxbwATJsn(J9_x0&r+uR zO0l(FG=4_PucUpGOZ5eNHm(t!(3jdu$d%gyq zN&Q&+9KM Bt7(guy2f;)dHotDO_}zO6~?L&baRmE)YS()6U89Sz@$DDg?Hq=t(M z#&BL8ieR6VgxjyzeG+&5nul8P*OXkMcl%m~^#fFuJp1yvGTIhJzPWuzPH@w+NrU>P zDBHF|THWQxEL#twaLL@n2{d#aehX3T%2!Ry)l8>n^oK^Ypy~OtN5b6oiuxC9)$VFk z9ei>8-j}hkMC^C{#`}?5Mz<$YSfdnvQN~bVcKEQEKEX!AFE19sNvx)!W|zeVpb>Od zd%YK<;NDyvt+=VLGGS78NCkak7|}T0HI!8}L~``ga+P>)iIPm);L{{06 zEh2Vmg!y^PV9ya3sHI=!6k6X%9i>uNt*erBW+}DG#m&_pcWk3yAa{H;IUx%Vt<-KV zRd5G{5t-d;E42&XDp5gWEboH>9ld`VRE?UMdZE>NxE!S`muCH@_$4l`ksJIS_%RGw zrx6wjIeLbH=IC2-Km>RU(qRd{{W2L5R87}SD)DgGT_5f7oe9s5aa)w_uVQ%;miQZ@ zalnx;&aM~sfIgKa3bhW3 zI4JD0gvJG5=h)K~;Zw*?NVKDb11S#kAx~I&^Y!_XRhL-R)?v3LKX(bgB@ME^0SCs- z#R@pl$egbZs3yNV(&vcyGEaEit)%be{yDrMmOI>Mf+knIP)Ugw!38Brxg>;ewiD{~{U6`YQuTFW>b%MFT~ z;j*BK4vzaA6jLONVG3F{aU5ojAks$F!4bq%`dJyO`^c zzxc0qU;t=fEV*k_@%Lq$+ta&u346~^;8ALAcq5hP&?ps5gIrprEwUeBZ(Z@ zhT^E)eB0E;tERHLW?wOp#;abA05SM;jU)kWikNEs z+*FIiw$qZ3F9e2jwH|jT9#CR4>QVg~T5p#cRNG^xxNJNny;NG9aU%t!PdVZXi0JW~ z&UX{&W1MAQZMt)Mn7yTRO4EKCP_^|*A$+NjNmArs)wogsa`U56uf6%eWRuTAJV(eX zDBFotUi$dkOliWd;F;%qs(xv*eD$dv%}2L|&bx3*K=K1A;9NNoQ?R%%zd^vKOepHn z&&3wb#^h_M@5gs0{`v(j&N-zv;lrskEbhpepR{h)sI#cxt-=>Y!N5eWoUqwhr&aGR zJV_N(j_7@sSOET*x#>A%X~9s>`clalNhn^*;Ju))#w?GIQ3E{hvn#rHP#s0CyuLJj zA(h&+G$w2~sunJ#4W_o?sto3vfwK7KqfrC_Sp_fclaP#=RK(^nDWRYlF3f(Eq;rP8 zj+>PWbp7CS(Q#;MRir7tg>5vB@fjHUI1*uyD8>dtC|l>0Mkj|}h>lg@^qRXd%i$BL zrJBUk^tq59%dEV@fyP_;q*eM9VVY|1avidRdU$7GS>5Ah$%w}6%^DZ`gW3nOOALLm zQLd1Kd~ZgXmDcxRsjMzW40NcdW#^k(%!&nF9fthpZ*ws-WK2(iTcpRO33SXI~6go ztWSGm&W%uA(m3{uxdi^#CcXmRS-`Sydif$!jD8hjpSqhGLvO2pH1^6yR%7>VxIU9h z_)5ApaHbUa&p{sGG%MaXlX9dKG`cZI?BfA#m@*FF{bhlE0yLX+d|Z7Mn6OLm8Zg3Hf= z1Wi|`gWFSYwqzb?No_e3=*pjQ-hFY-#yLhx9Ove}ySUUaocwdeDV(pimY?}O2;fA= z@wv>Tyu*Qov+U6sSHXt$C@VgVA0^U^;fbb&Tfqelan=?#x1M)@wLV4D`;QULXLYnqrM#$9X0F09!Ta&W z5mrb?2qR1fHCQE}f7C7y-AQi}ZqdJv7~3j7psRXpoz(P7T+ReY-w7u@c^W?8XUmJ| zA2tBlMua$60&Y*aUjJl`?fU?u?jTgvL41s8`d+-dp)$~Vb{rHq$&P=}(Loce>l5Tk zW8!&DH36Y)d}5Yk1(H(dX_4R3&k1~4PV#k(H(PzvWp#X-{NY?W;N`c6 z%-ha?Wd+DvjU2^MSc2$(QjbdSCD^?4w|(%7OOoJxuEeW;`D>V?M3i}anUH_^ieze= z(*a3&Q;2!XR?M3o_*Pixq^Nz+ z&{N!&$iVK@)WqUOP_fo9ZMis-M1ZbK-MG~d%pd_0k9@dxJV3v|;=}JjeqexUl;}tv zPnM6w+aL0ekrch#qHI*MKI#z~sb`DAC&kZukb>42wd&W3+=axxzfYBhl`aL7*Kt0| z*HCPF{xEKWKTWak{Na>EdoID}ew9aZ6%p;8CbjJh!Q|pRS$K)P_`a{-j~Gr3uaiB& zr$qOs(LJ0e*3ue^d-iiq)3)1M&}eb1HdQ>J;?!H+j)T)&Q$z*jlQ_kf=Y~G^T3EcNW?~MPO-7a2N4;P!$!E3)Wp$IHN^y!NTMVwPTwL$nNW0USviA}@A9MbWhfV@L0R`nOZoqgIVneUdYfCOA zJ0jhM7Fxe=qo1$M$@)IcrG{fTT>JiRGF*`I@_kUb%G7mjkiqoy&oyjo;wI3B;Sqa+ z$4hpE=6ImyN*dK(&xi<{4`Ct}=iIvt#4Y`TP+#ZV8}oJT8=sn=z5m9K^nDb*+223>#q59jixNV`CR-E>eg%&e9ZVg- z0S*TN&XuwKOmr{kII2YzlTsc?p?m0B993Xyu-ZtvjWKuvP!?J*n$9(f=C))L%_--G zW>7nLy*wM(7|Ws42KpmM)Z>9TaNP;L3m7rKm!!Djn9o<_0D6P-wJvc^ng5O#Nhm3Q8{ zOSEa2L8XqSO#|%v72rHqtrM}L^$B2JA4z@FbflcA5CToympR_el07~V>JoW|dTrgw zM=`Tow?5x)jg!kP&-!%l!IXEB_RY7{37)~KJ0mv}>9y`X5}IdPowlyEoEj%>b5XGG zNnS^9g>pFiJexyP+i9OT9=w5Q%0nF2d{{X@WtucJ1QfeB9%rkVg;rE;Jhu+Di}rA< zh5$U=cE07AzRVmoS0etEO&#%M_?kL#bR5YJCl6j+^D*SG%hm!7(|%Pfg@~)r*6eoZ zGl4|iSl~CJqnWRy52Y(i9G&O^F?dtg7N&0HT&!VUeRj@F-XH)$o*SRJUZ@GFG@b*# z3Oy?S`A%w8`tPTsobdSJSa$b@(CgAj7N|vOX|%>Zk4K~3FG{$Ie$)U)nl%+c^CW{# zkr{XaIjjclmbw63yGtzsA{*T?)PIccYBGJFXqnH1;){;Ez)Kj!ku2}M7MvrVMEi49 zhsMex0UzQmFtq_*ZC2Q;I9E*Wa%E7}123Dpr^sJlsxnhB+EH$94(6#VRTD}rM{lR1 z-D``U^Bh#Rzu3}nHJwd%Yj{&~X_3}?qI7?#|AA)5v9kdmW}jP~mnSd)qW3&iEg2|1 z42_E}k4|%2>UZqJW?8xS6<4m+jdMxmI_I=#6I%c>i$Z3yklm?Otw5`uRMyGA^8~70 zWosJ7T%qN)@OmGT^A704RX;}s%gMN5+6QSOy}!EL_Nsz7NIZuz8TbCeMb6i!M}76) zcvKfL*0xM`%l(9%7~D24d|O zg)W=#>JwfR<5g7RhnV1ek;1nIqE(n9vN7H4T{82$y9yz`effw+=9M2GNAS*Z z!7BZ)Yq~Ta!zxud&XT3@hopk#GNC`l&r*#JNcNLKB~6j04{<{Im+uOSOEM@u$_vrY z`;;lnkaOpu9rW16xAMYkgpK>3>yA5}QK+3j`k9}*W|x(3u=dHlmj;@(whu$Q@(Rr! zadPCrq>0Tr4JUaNY*&;4EY~8EB|+PJ-?Jpnr9?Ts1Pe0f%s5!CFlHcYV2=lLCS1tN zCyoqS?S_|`gJc&5i(1n|eIgzDT_E>Nv`^@SM{u}`;CPi8^=Fz~=Ty!0sjAi8h1r!mTO?;WtjYcNRQJAI@&*`iPR7 zX$L%*o9^3kZ?@J=ZoCdOZ1D_!g&(zig0wx2`q?_Whtdm459zGgEx~<;oAw_uMN~~E zJTg!~+8>NF%Adt$2kq7TF>KPS>Eq`JGKpKXtOh03weD<9Wz+ayFK@hj80hG#UC>fIin=-1V2~v7Iq|Mn zi=sngVEX08i7kp^-K&kWzmu&fe)cT}vUS0SdHA*;T=Fuw2?O-aoh!O`q;jo!0)r;! zy9c|Pf9&|$iXApM{CUrJchyLlFK;%u4_~Qp5Uq^;^Cjm_L2)Y`0aT9SJZtf={#Tef z<^=+HYMg{w7?(2YHPg=wa}^a)Z8-Vz<8%t0MSr7nQ;QFLE0@QB{71;?$TBB(F3r}v z5iuld#6`-oUo!QWnWISX2%N@+D9{<@eoVVe-XcX;2dpU6GCMbNl#iSxBmxxut=vJc zdcx-G9T+ZZCXcwPhEA42iC=w@R((#dVdS8AEO-A)OU$cemI;*Ot@M2N(Utu7zW~$A z$H(IX9TBB>*Cd|`R%frZ z=}lPr>*#7*7InHp*1j1qo`j#qzlz`{oL+x-I(%xtLS^@Q`Ks=wiJ5ln@Vl}s?z=KZ z)nANF?P^Q8UoDAm96VyV@wI{;NeJM&du>({Q+_T%#oxx5MzQbJn~ZGWb95e8h#(s@ zf3KMfXyCyAzysg=NA1D_&Wa^3T?6PS73Xn;*C09-^0GM_>0#-4pcYl zmFcbO;d~j1P;N7Pt#O95=wwo3p7&_cag(CX60UdF#nKG+@tgpZnZ&@rYG|{A9+0#s zH!WmVH_J;_wF_c1-(5MKced-X{esemiFT~yNuPkOV~(Y|(?zTncS0?1%PFFa%<*Wu zY{pzny15YxkCF?kU6uaD^s}kn5~n)*9d<3d9qGSUzxd)X9yT)Rs-@LDH)3Cnzo%2O z%RWW*Za+6p?HZ{zvDiB{(1|7k*35~@7wV(KmBx7*LPH9phMt`F_24b%bzPXS;Dx{sbS;RtdJd`|fbjJ7H;+0;gE1EHODU*e?tmp! z5PzzW*XwZDTYL6cD{P-o~RCzlzqE zOlx$3ICdfjqZkeUr8kvC=9I_;~? zBn#m;NX69$oCRlX4Q08}`Qfk3wtGi{P?Ft_s8kB+V~U(y6=a^txAkCMP`)Dxz4G}% z8bYO|BYdg(T;m8&Ks)vJpAT?x4hiswj*!O|QluhS+~*3R=ab<#&>QbNI-H>3l3$@Y9tV)t!1pePsCa!?=X0bav+huweg2G4tX? z`;fWB@15c8K9H=ja71y{-DOsmPE5J|{a)Y|0B^E1FktMn5VgZHbQ z%qB-uUt6y7yM0@7I8BG|qzK-Rq?O-_BlMO&*0}_jNMs)@J6dElOvtbNzSFDv#OnKI z?Yj{9TP|ARQEUqGJlNx$pxmT9KR__%k+H;X+9Rt=a=zo%Z-XfL0oAe*LxrL@qL+*0 z+v6p!E1vw&ArF(+er6_p|JNt3x58at9wh2*zvAF>?~>TO-v0AP|Iwmup?~fD*bgD^ zq(6BoGn~Be{6vCY@<6#M^mGCEw%HJOao&RDdjF=w1j*J!q3}YT`7jfV2xr~pLDt9kPdp>Z{Ei*BC z>gl(m(mQ%1+A9(lP2cR3d4W-*Kr2|@%Wp#Uy2zmEIGYR43idF=zmvm~%9S)M(K90({of^hc+0eMAoh^1cki)Q4^yF@`+)4U0t?Kgo zmkv@NDl+}F9(vX%J=cE1wBtTpy*MOptW#gt;`74XZL-g(mPBQPw&sg@2Ef&HytcgK z68YXzOet;QR(>8ygyG$tT)90^9#A9D(a6|ruWsg3I{AD-OX_arBbAIRhJ2WYbkz>4 z*6`D+mXnSFx#yp?%b)@UiRDTns6UgodWqMou#qycvRMfOn0XXdpR5-aVt3!5sJo}; zNLbr%#^vnZas#_YV^nhxv3*$jr0zOS-Iqn#F)WMhwDBlm2bS{3ERCQsB(E%xT2ZrN z6SMkEf-Reybsg7K{^qdRsfoor@E{Ed_sRh*SDa3GKlQRt6b4=1bL)aMpX5lXyC%ND za>Bg1yju!u@gw{Ewj~D{9Z~k%X-<(pyTaHC(!f^LS$hRMmmR%TC-h~qaWvBGO8lo_o{U~1c z>uYdBlDG)yljbQ~%p3kS)8i#m&a3*%6%Z{IopHqzfjbFIUkx!le=@A~L-Ih+>*NJ& z!oqNiga>*D11Hiuvi!I6zgPRfP_T4%b8%8r+j@nG zS&HbXs6WHyvbXDnPaRWyoUZEs7*&aVK0NUvJiAntUe32N?-b`(a%nWI)2EA1*RwZi zz38i@%OiPos8}Y{Dv;^O)OwyW#K&uY<&k_dcg|(^U-H;|J@p;>I#Ci#mq&8i@kmVO z;yUSy?|6pKo>%bgzY@tG zdpv1Ze&k9G1wT_TAS%6dZG3y>sPh7W4>?IV%_)%=zzhOAzZ26O_YKGZHP$V&YkwS{ z7Egg(1f@f?{sc^eHZJo01OCDWh|&eY_5SS>3?1FSL<7##Cm-oP(Pw98H7_^)FLeLk z$?g9{_rrX(Tze7X|B3Fee^jQW927m6=UL0C{hyLmI58f(gV5K#z=(!0_CL`5E9K2y z!8TBKjA=0iGz>@5eIl$3PJ*!ss#zAxche=SqJ-%_x%1imE^*|sWWU&_#i6h@Yhe4# z=hwaII8(nVM-|sTFTtN|4|`QN1}J>~jucwU`={b&sgiL~BUu7!USn4td5yg64t+by zmVNM%@Px?t;kawhCFk2A&)#&G^Ir%XJfGX(hO7ADa!0WI66{2I&-c$M{c%So3cc~4 zwo8Nyj33?qZAA4}FZab6q~?g8%HTd+9!g~wR--wVoeOaAbB`$~Y$yv4BVAhXDUfUs za+&McL519&F-9{L3h%o`&e|NfTs|sM#ltyJFvbf~N=6#X$o=TkF zKHS3@(~9@FVj|;Ni!{MBiC&e2nHro^w+*NvDL&SE&CEL(wOrIu80~SzLM3J;Uv^SU z_%h~AgGXM-)`kbM`;qCpLg&!Hjf&_X?dlMLQ6_Ng);F2PIOa4-Q6|+*ykRchK6j+X zk$x|68_V_9UIpGvG~}x~H8@_Rcs2Q!daU@%6$kUiV7Ln$V~4L4!;ZAjjd6b({PN7P z%E>i3j$+WfpS~{x8=rOHr9<5J8@6vf)ac)CYFzp5*MRAfoWGXn!i|-JIWw3WZQ^sW z>J2`0el)LQZ(E?9wW~B<{||nZ+cEOX$i0K8nPi?^YnS(Rk8WhVPv@KTt46FS0E6U*MpT`vtI{qLqws=^o82nhL6ArlSg9 zbK8GBe-DpXOFP%im7Sk~d(&xa1B7D`*kb}v`~)_x$J0UY`kf<`wtB5fDsZ=nb| zdJz-fx5|uo_|7&fl@*!)ROtNC7U)xh{*d{3;?h-{2o#~^XgNjDGe16p_rd)>(W^`? z=9k9fkJ!fE5gWoIcxWP_L9dGC^)&A}@0|U7|3>Pc&CS}YA|3Y~?aL!ZRqb0yPsEQY zvm6IebBPSi5OO9TbS;79c=vWLJ$_(B%vk6Paua8`#oE-K@d#Yl=qi-H6Lzq@7#GQ_0VXgFNi1W>+A1-2)gX4LJ^ILzy~zr zc+(S~q?Q*g+tSIguPuDCe|iY-Qc{`MtB65Z!pnuI+paTHp|OdS1!I}+ypo+HafPah z`-EfqmNtthWMnm(PECIpA+*pm14|;J4mD@vT*mCMgGLn7ETMQ!%d*H5;=ix3`BJUA1 z?sbFX^0=kns-+)PMo7$Ce(6P*`7H>kXN8$zV1ym-ISe#{`I^Z9PKdxF6}E;6k4&4v zR$Y@#s21W3zrk~wqz0whxI%M9=D>&}HsmxKxMvFJzGgaImn{+atThQdj38n#G*qn; zT#jFv=L{l;Ed-w?FN95SmPz8gGbOB?blt`aZWGvuA4ejwO!lUx#0~GDPYZG2t`Lq`pC>Tx5;eU7*B`PJ^`#Vpa?OQI$^(y4%e_`$= z*OhQNI>??)+2ZUZDC{AtoP_Sic-jeaygSd5)kf@75M8DRqPBWyI-e{nQw7%{fS&Mv zy`7_l2JQ|)5$uCWOa(9=O9CCnvcu%nBQ7=JT|Lv&!ID5RU^Q&nget`vDNzPzh zI96Kd#~KL`I|3Nf!ol5yOo+W5Sa9bC2Tc#(}X zh=HR=?X`7VZ~uT7T6-*mN&UpRu?h77=9D0ZC#3_1iD83o$&!sFE>o2{7EDfEJ}tH~eL~*DygX*X>mPMu3Gb`6;Sa$l&IU zyu$sA0O@0(eqtMLg$7)%1vTJJW~)z*B-k4WuFPumTo?M*#89<`x7I($1td6b<3LRZ z8n_e@*CphoItv*F!L47u2qn*{$Ra?6cah0nhH&ebAH#PkD(N;x?o@9C;mo5;4_j_3 z4dzwy+qCRVbq`)Y|F!M>=&_UL?ENqA>YVVEJ0lq}DX2%(R;NttOWGd@Jo}1lQKB$> zG;@0X?Pj^qs&(0+oNy;QB$J7ITJBc1HgXu%ZH1M4SVi_6wsU>vRILC8I2z1qVKe+D zN0P%t_Jq#C@!5teKx?~Nye)?ibH}LHJ={l<3}IC6S_t?qg0)Zw{m^qA_`nMc;9*R7 zTWKCv&JM^;3Q(}a^jQUb(^E8a1xMr7#|*o7YMSK@YkzvC*osUj9FD;(#E|w*S@>G4 z7oHj2i;exJS;s5O>~m^w*Kx4()Fzk4?dSTR?94LfEV{?EhUO9s8!fkPpOmqSZ!_?k z>W;TgJEc?cDVVGWWIIy^8}FUFX%KUs_ws2Vja@Z7*Y~_=kM-dO3ptiAfrL5 zAr*LQ{raMkr2@Uk;L+%(@zGmW?J2Hh7kBtHB_U0p>uYj%iulc%3#WV1c*4)C9_60c z@l0;}g6f`CRvwZg@M|h^X$Emgl@)6@4XU?7aHPb5`jj|Glrr^}N}#yr1+E0Dj9Kx4 zB6U}R(wJVZrFr&ZTqD2or)SzYXvEPVW^PxyW*}`mjXRfL*q;;AHK^QJo$fWOGUt?i z?1FqRSh-hAx3Opr6_1KWOT>7B$o#<;%`O!}TvX2j?`yOO3HELLj%M0yFPxyOH z6z6DGp%T8JADN0>oRw^Cl)P;#cFC5!8X#@GD{5$)l5#=o@vMTC3Il#ntbjfxaZ45@ zE9kN!Te*VbOCYbBito>ePDkX0)+jLMiz(pIdQVk#s&iBV)pNCYr^AK#jszr+2TJKq z1IzDa?Ho)*qD$ z02sEzv1&B-4%SX3=@X^p;1t#NFvX(>f!2ds!^P^U8BnIX11b$FLL z-KAP}TCHUUScY6HU|#Evs`t{V*XygbLe<%3K!W<}gLLX_UFxix>s-z2nV9P%V;iDN z8w7&tPnXu4Q6UyfkOa9#Vjske3_16s9$#9gc%;-2D@Td?(U_;xRNw-3jjhKLAy>B` z_7teg4wSIebi*8Kk8MmTZ9G$2cg>~gr$AHdk7jB{t;Nd*Q$%A$EXL&}+9{#4in1mlJ2wpTig!HApp zezdp{pu-suY*?KQBLw@yuaH`)ORJopW@bb+eVJ@MC~b$DLnCS_YtzgY=51Z((1qr< zC}KD~jv7T^d@Xm=3xL)2K{opstizbym}?t|5J^hZwhI_=Xy0wB`Q?0;ucck8zbdkb zg+BElxdZm(WevgK8X&W%O~ECPc9cC{nZEgdDsC%HG#sIrFFYe%>StaHf<|Ih6L%}5?;Ke zaTa`&c1yg}&mHg%N4MWwqO%w<|73#9BY=-PEJt#kkQSJ6S!dc3JZ%S_)8A>C*=fUa z^Fa_4$pVQZvb#1j;XC#I^fJuQF2BOVewMJeQ4w*}N-vuC)-=nXLzaoKjs<{~uZ67? z52njbHMJn#ll>kdfG-GucoytS^ZwPzFrQw1gf$LF0Cc4>&@|lV>^(jg7>EeIO{0Gx zizS6wjC_4F*biT+tZY)fHKEaEP1vB3gMeYwSW zb-E`VElE7v5)Gn@xa)=jzMlopqHoPT@Ah1* zv^jI%e)_UoGZaMYqKmmpQoGz1*$au_rhWz)1n`i`@XLj5g$W1+fDKs|`K1o8;Csfc z6s7LIH~j-4(~Xi8=K9RrKhyt8ZDC5;Th4+5*CB3GtP=f<>WBx&`t^!mJ|IwG;Q$S6 zNefZvweF`fZ$r*3(iDjh5SE!PkTJJ->(kE7+1r(clp2!jeMxfPpO`VpX%^8VR%V%L zmWAoAA4c5z8A+}TKTF`gkrgivIo1ix3fN&2y-7y%^KO0jUdMI+=?#^f3Klm% zy@Qx~&B*G;(oc?ug0N7D{s(hGqd^Eplm5<-SEG!qUE$a+0e&{= zuph=KNVE9RLk^}{WOmxc!CbJdQ`AH3N-Jieaerlgr%Ve=wy44HZJ{@w~w#`Y& z`1YP)HOX>7lE&7))X^<8BdOHmaDsJ;i&_#i`l4^fbg`3hyYqAz4RdTv`ZqXzn#DEq z>2GH?5CW=8o8QQK^fG>E2+>}OZU58DW^tQ-=Gpx}K9!`f(=W3IH%pJ6 z74%aO92OPxi_|+_Ve|OcFF}3H$Cz2WKUCHdjKAvKij(ho#@F^VcE$yO^-Z=hvve{2 zWV8+LMU?fnd;?pc7eEB|-o;An&H!`A9g(Sfk_g84w7!=V#G8HU80HoJ=LjC$?I^_JIe zW}q6V=T>b`uCZmTTK%YXY+em*Zp`efGq7GGh^#|{*3Mk3^SiO;cf7&l_+Ocx&_C;5 zay4NmHzKc9iMnh=-`IdU9}2oIt}eXO~~s3Tmai~g_LZ5x0EM1a3! zMUVe&DrEqWM9Nu4Q{c%^v!&hfS?d3Tswk zx#;k+Srw#%_s~@FHJ%Pga6fTbL-J>iziU12{mVio%c;{nv2jwfj@QhsvO@>_B1@gZ z$AE0B~p?oiC>x8vQpnG&>hZrS%DsUXV5;JP}dyl7NE0sCJjmH|e9 z;J-}l`nQQoG~~a$IZgTNP3HJwyq94H%P|f61Njo;bS8CZv>1Nz!PR~1JOfV~PaRuH z@PY(DD*%A~h)&CcV9LZ*z+P&hgboCA>nHw^@FXzI6ho$DUgPv7h7-(FUE0#r8|NEf zx3Ana$8XP9Gdyx1cAEcScMCKZ>Qgp<%(M@@=FSRqeR$9=%JPTx$9dnS1XWNEhenApkvhjYGJ(mmnGySmP>`^!we49h6AY(i{juq zB~Ip4gxLLnhNhK~ERIX87MGN77-gYZMgxnlu}v1x6@HRRY}PGG8P2W5H(u~JEP>SI z(q5Z7r+`?7as1%qjT##I>y{*Cz=Y3z zf0s7LN(4M)GqFQvX0hk{uN-+T{>(d62AEpm{9lbJcLK@(%* zjV0LVI!Pb~?R$1;r%IX8y{Z>!goGN?-2GpSSRzQEeA`zJg>HHVVWe+B3N}SHE{ECO zseiMzb(kh*5w084Ys_?$+xeEcr<+c@%wDZXA95T3zAfE z!b3sQ)KyVYwtqB7E(7)e7r;R`;wIe)dE{Rs;0)Ub*RzZVgmsbP@n23?DDkPQ+$RT+ zhffKAj6NrWy9F5oM3_vOw5w{((nbDb^{*=(P1pkyH)N4ooFWJGXD4yepIwJc2?SRe z`kIqHC*MdkSaGmJ@pD90$<}RcuhM5r^EXjRk;}e{9Pgx&MwlkN62A@XZn>55t-b;y9h(d7&< zKq6ITJ`77C-HwH7A+bOnAZes=iG9cEqdO@Mv}d8T1N2R`GXQAXBBw66)A>};nXVvW zvvoy%qR$d`hXEFCQF;6|kpx)~7F~E8+kffv!fk0r*3Y_~l0wfX*c zZ4LtH?qy(d_~6e`Dw+h}*n8(Q`Gzlz@!2my%;cL~b$&*d7cz1;aukE~*)88~dOV0K zX>DYsNIcOH8{B>&@m+cXht>x3lfC3{d{HXn?|sy%ws)_B=#rpfSegpBy4LjlcZQM7 zASwU>uvh>91p@KP!KWFSkgL0CQ0$#g&VBoSch5C=62M>>1}K`=q_L8ILm*@%VCy}W z=rgVaUwQkg@fw6)&BU5xbn#L{U|1b|Go;l)?xK2?5PJc``1WSpR9 zK8&nAA}8a~gttsYQK!duwZE=D$hWApe%(piT4?(x!T$f)?)$&-!e4T#7=ZqbMBk*D z|8H_CmGbM@>XA%-)gYn9cKeZRdi(0``1#t2d>OlD*QVW9pduyj$#S#Xf7@68jhw2p zai)geQgoZ_41AJf{g>?KndcqSGMGOR(iQahy8BRuutj(43wleDKE2)Dw)nTDSYdI8 z-oA?d`j6>t%O2|TkdF-oeUPxkk$8$|DAnU_LPTXT$hiOFHF}qDii|eX?~BX>OtB11 z1ZP#;;}9ML5n)=!$3@3_!x9y8=O&P^I_2Jfpt?iqeo#!u8b8`qB;0p;?-e(Re48(* znQ}SmD{V9<-|6VE+L*0eXLDvK-0n?piDFkul5$#$~Z-c zXXKUXj$-IN-0$FDp@OX^$Rc+z1aB0h}+a>_N$3_Xu=gakzV|AHwG}pwK6_UP1fQ6G)bcigk(j-0N@5!*BvgI|WM1OOCXyjVnoi zUM(XTRBKfw7;1v3%|_CRxE3yNA5WY1t|>`L;(!Ve@xhBmS@ZtIUAzJaY`_ovSlEQ0 zP-$V+A)cv}?Vnv&UjPTl{VO>6d$+RUtLgWL3{uLlXNNMBz#xH)Y($J?X7b5<*&j?( z=tFDD^9#5<%qX9_tzXE3@`^#GE)k&rVImJ>N-QXly)b56B!UxeRBU1A8mku?6Kd?@X?OlTiu{1rz3a}l;=m9^TEVj1Y?YhKW3mNS~c``e$rSn}k1 z5upGwojxqbup_~!OvC?4i3(`GqKvCr%TcH%O?Ac>_neA*RPPp|;s2;wr)=_7%xtBq zSv;L17i>!8%ag4<3g@mUjB#3jRJQUf{zRlmU3D_?FyHL9;7!~?ApTgY$@Nmwa$^-_84gx`)QM$TzE#O>M2Vz^xLeF@}mN~)7a@SuT#>q z1$IFk&lV^~GIc&Y#u&K$n1;R~H)B<@#suDohlH>Ji$byb7D&%Eyu_zSxh$ZbwII=; zA|u_Q1yB$a=VYr)SlDUv-7GKq^9_C}06!ZIsR}Y;5>t1)7m6bi&K$V8@6p2Rj__;!6jF8SP7>3N_6v zWy*jWx6>||a~1Mwj07}uLuDQTj2;@z&jQTE-P^Z;_Xi2))u+sKJ}rpZdg2mweVyNZ zlgU@|q@Yg7ef6HWL5CU+2hPb@JGPs;Ni{*TT|0q>JR>d*Oa2xuJ=~)}%m;;*6ROfz zj&I&;f1o8lKMxm_rW2N64455eiO0rjoCSGd>JWp8)M4Vc4NB8!Ei z^T8k}+gzT>VDtzmPu3ZDmB!Dq2$jzbO3JsOQ`2S_@~_^SSE~BV-rOmso2@p18a1EV z+SWxf_1DRAUHnp*!Zx=q!_@@zcYsrDm|oOEWo}XPnB*y~os9C3l3cT6{?8KN$j?@L zcs54}A(cP4bx$A3l8rTr%vtc|j(TBZ^vpzttc1`*l6M9j-8zb28=>KQvt71Qznyv02k z$-%}mvJgl?7cZwdK)r)Fk^-=)+C4qiP5D#&FVm1*~7|@yFKjV|`^C|-9bzmBq zMcTWgR$-6O8L?NjZdk&s-<#Ac*%a@&h`UQ59dix6{coPhzGJpUN{_+2R|~)LL0KkQ z&o3gklH6?Kl-#?3-`%;uJP%x}M3C#8yuWYbKmcBzv%y^TJNmQ0z7sSRTzf z3tWV;poWblSFkxCcL>qMW~p14QJUFD1OMg*zzU7^R#93RMzUJ4S|*A61Ep)W`XRDP zH;gVYkOBvsXO`PZZ{&hlXirzLm)sc>;DY}+Eq@<_4`8N0h9SVPO&{x_XSc72!gNfF z*pMW<1dMPdj4}*-B)AO*q>rF`R&nqyoQx4@5oXWF=6`!vWxyRg zT7m0;2(~A}gRy&B2vdoRIgMHa-5*#BWf;v=;&YRj3o%>_+ge7C-L=m}bs7yhUUO{` z=5YqeGMp3A4)B$#25gzuADvsX9LRMDwVF8Va>e;4*M>t4Me$GLZ3A1uP7L~~`YkWp zOr>+_pdqIIZ5IVVA|H+`~E5PZV@dvSZ!eek(2?r5UXw=stCC$hS`leDfj48Mh$7%#)(gAA8<2;-9Wv_|LKu)jK$tqLV8N%aM#;y7^yQ?fW& zk}$t;=ndx-H@LDcbi!btm0!uD+Onhfo%oY9#VE{-%El83>q0Hx6}5>OI-qVB(yeOJ zic+#8Z)1BfUfC@{zx0rjlLbwa)%zzShF@@sKOt-oovWRyywUdaS}TxA6?w-Z#mrfY zvtK0)E_7m?Eq9a)wbSIv64pLkBrX)oCRRUupIfPFN1WSa!%U(K%UvJr`(_mGER6e0 zd?+wwO*l2<*HqslT^l~g6!|fF=5FCrEVV{ zX)MOlzs?bAe{A;0qrb5wO*;@CE|2+_U-nHCOVsLwOUs1%rJ}4&?~Gj*x+&&FxWKP& zf?{{bWjsS{!i|I~QfXWkXP_5(`R(IzBRLE&Y7zxPTdPv|Pnr9>ID~_iZIP~0q~YuP z(4}!~xdJCNP&;srOJAyDb^UBifJCxEl#|&rb4Fh^9wwm^_Je1Ilsh@~gpL_tfeSFQ zL1h*U!Da$pIxwm!xP`Z_0praBb&*OhWljEB(D0}GU*OXv? z9yc-BfQ?89)939MclQK_FX1as#_W<$v_v)W$eIxi=W1su_+rA`+2qPifj@=96QI$c-5-FGRfsm>-^#dsZkAy6GU` zcfD!V_}rCe%P@XtjNg(ut{0OpkO!Sl6^&ai%H;;duaDZM9ZH?ST@(|0dM2pHbH3ce zXVn1Z52bQjXE=X*YHSoS_RP{!7@8tLAioeYu8y3chlfV1Tt!01h8-;NzOfMFMYtIL z6zHJC@ce^w1+QI+;+O&xF|lw%b^%FMN*0M(Yo&h$Cv@~ZV!viB$TqxwBg!(WKn3Qykg71H@}K6m^_mObu+iB z-eDKg3Z08rm*{MKkz!>O%L;5IKdyD|9;{kyI88j6h+StQXevGj9Kh(qj%n`!5?USH z`$LkgT#qaU#kc9)@*#!J7I)Z=Y;nj58eB1M)W%*1LbtS1AQLlECd1B*{A%N0R;T1i zVUK@Dj&WeZp29T^^#EyWaE|EFXZEI;8#;kWLB>ARzHgWp$?fb*n?Em+SDec(dDn;J zS?`&aD-m@is>RuB>&> zW~%z%+ZQ@G9L$aIwaeLvHDklF9f#MQ>GSZbVTDPFJFs!x=@9c?SS537$GZln#CS1TKP`A3P48lJXn`*0 z2+IHnA5>c^9Zs~W)Ydk>yB|bU(0LGgxttFfFkK1li>l?@#mW*Nz!plox^UJV3=gC9 z;BA4)9_kzg3U?2KXUefTDL(trp`?$nPcp2xG6gg*&NI(Pc1|dVe2s(7E1&T7)GM^9 zvplqo`WW!C#_W4j{zbyw^aq=Mx&E0D^dvU(0Q4dpEaqj)&GUtu#=&B>Tp^hE&6C&V z5)>$R^I@8Uy0RE0bNb1ByL3jxh|S&*sJ}cj;v`qK@C@tGIqqoQ_=v8vrs=o`Ha722 z8*yr!faIB9W!)Px>vQv)O~Rr(O5#QCX^|mv&+v#`u^?sx5jzM+VEGu>-t%O5 zoV$eAXBD8~ub!kX71|+FoNctBjRcS72V1rZ)>TmV%e+4H0{X&t!Q6U+C zV$j^e03vNDl~v*s-sxTP2%ij|8zVz~hfQGQf-QVOq)+5aiRxrEPJ0ovpeL9i>0zD# z+B8qWd8O9>Nrgoo#;iBbbL2Y8J4!80e3_l3Q-PnUUSr{Jwr|283KVP_CMjuOQRAni zU@>|PH?(W~tj?+jKOy!u8@1$9x#yNDC(>sd&cT;}zMrP|@^GS+(j+1@=7T~583 zkn!hbUO(^0het6L4yJxQ5IEt|DXg0znhCmn(QHlFdOwtV)1Jz8EM;Ti@M|i9J~{yZ z^5@-#+Ln669jT7^NR5v)vy&||uLW}@40EVQu*dz;-o1{l3`Z}%+OA*7yD=cN|8?v~ z&G()5Bi>KKy}Wk|5mM=zD$=FcT} zNus?jG>Xx+pM<_RMOe9vI@=2R+Ao&c@$jBG>ln$M!{N~w?hxGWFuY;x^IM?M@!||L z8G9|VV8X}ExqIlwV;*i>g4PBuCv zKGQMG413|u^IQ(_-*CqkzGq;ZQ~KQBl-DM*z+@_R&&WiFyc5vgoU+KN9n;86?AffB z&xdVwf4GUoj6){+MgExz|DWe5_JBJ5NB%!D4(=Y@04)*zS5GBunR;bENjTu|U;@DS zBV1+eF>NFV4HY@iG%Yv*7PE5{a=ujqN|f^!7b;14`ryjPt?^f~yOq~;77O6F{d3BZ zOnP>x1AlCWEQ8y^1lnY7Zn&05u=nTp(?nKLFhoHDZJtqZMVspQ?>+>bFaklK_aS=e zeF*#%8PaPM3WAI1ouS?nh&zTgUO%=fyjQS3j zawSCTIuRv65HuYwxEi@W2gXH8J&X%`z3 z$kGPbGL88C^U^*4ma%)q!?3TLnh<<@#oeFZ>GPA7rypD~GTavs7dPC@Ir;@Z6r%`V zT>vfNE@1dg5-teIkWs-{__Bb%7JQVC;MzEnVlT8goQl@z7)H{Cz6~#%);3mWU^{z; z*uQ?9Udd9sf8fQYco*qSfhrT5)k5i?J!2k3(8{K>9AgTZG-+$21)BV?|gaiLuclW;! zmMH583H(D3$ATnbcK<&s^C?;H@eNNZ|I*Mm=QdbY|En@TS37gV>ThMKA zYwL#53G>#UQ@y8dw3S>4L`ax!zPT5dbbbb9-Qf2zw)@Mw@%*1{zXdeYdDN;uOmkL@ zW(g=b?!h?Y6Sn3jhcb^uPoMPjNo~_U4}6JFVW-cNj8`5FjqPnIMCJe;1G-;!0hr8E za96VNAgkH|ewfo7yG%(mmkA%{+-dgx z7j22#Enci9%Plh3h{qNy=E-@=)ifc6OAQGyWoIL>;_M_PTlJ>#I-fMWvGy!G_~VSH z%e(ShFCg2GC={e)yr(fLsG!Lh6O1i8{rn#|ET$_re42uvn_=#uYXMjRe z*+y53hY1!y2xf^W2U=Y*vg}<-$UGK@nKr8dY0>zUCTgp#&N_#74`k?YR~hnn)Got> z!p6lITf%ydmPbp1qLh=9PEJ$7WMqJxK%v^+p|ngQ?+0E%T?|oQiCJma3@oW+F$kBlRY?_V)v;Kt;9vtT~t^`=rpi)rWlxoaA9@s>~u~kNjN{9GF^aVu=DV+ zBt3?KSh)Z_5TcBRL^0B`@`B5+14{iwPNLo?2&JvVu%XM)=cem2;Zb{S7*OBm}MD-!I}f+j_=rzXbcyz2pJGY;V?0sp*Kwy7RO#kZ%nnL{34IU zMmSGx>gbDq(!wT8GYx|t7S2ZB9)cb3=Ot=lF-uf~HN*ObhwMyd-`H{e`v!oF9=8dY zwm)nw&RnbC4F+Lug9>LcQ5rf9Bq~-$7?~`?+jxo?0-j}3rS2I$^sJXy};bopmoxD{vKXD66 zJI$e&tZl5H2%tR^nKqXUq8arO%?ZenaNf>hU%jTK?uPpEyA_6vf z`u>U7+ZC}UOP+f4ycoy9^BdKj=*@Mt;g&2q70|2*Fu#D=_o*F6e{Hi-17uNnH@x z9`-dtSNEI*548nz?5n8`Bk(S+;yv;etw7FsVA6q_;edRwbfigpPdH=UIdshY`&6;1 z1fW<<(^c6F5`nU4iL{TnM|s8dA(&7j>0__ z+DS-+QG`etWK$x1!x)Cj zzpd7vc;3X$RzKwWYt!H09{5vOgT?FqPUFT(rtI_4LvEjb)a$-&x*0ttc>P2DsOo_1 zqjSbX?w<-qb!WP`Vm2&1Zo8goY+BCp-=FfBV`bF)#zrMFS}uVF4`^^}YQm|sDX6Z~ zz&{Hy|K~x-|NjmE4gnbc$(i;4FUkM@l4t?|zzV?VF^~bk@$3KD&@xa!bPj14&(;7M$odKZ literal 0 HcmV?d00001 From 36cb8ed894895a6bd1e7ab3755f6adde6ec77d21 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 16 Jul 2019 10:44:02 +0100 Subject: [PATCH 0651/1250] none -> m.none --- proposals/2134-identity-hash-lookup.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 3f869f0d..09e4748a 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -119,12 +119,12 @@ There are certain situations when an identity server cannot be expected to compare hashed 3PID values; When a server is connected to a backend provider such as LDAP, there is no way for the identity server to efficiently pull all of the addresses and hash them. For this case, the `algorithm` field of `GET -/hash_details` may be set to `"none"`, and `lookup_pepper` will be an empty +/hash_details` may be set to `"m.none"`, and `lookup_pepper` will be an empty string. No hashing will be performed if the client and server decide on this, and 3PIDs will be sent in plain-text, similar to the v1 `/lookup` API. When performing a lookup, the pepper and hashing algorithm the client used -must be part of the request body (even when using the `"none"` algorithm +must be part of the request body (even when using the `"m.none"` algorithm value). If they do not match what the server has on file (which may be the case if the pepper was changed right after the client's request for it), then the server must inform the client that they need to query the hash details From 9ebcff5758d43e18d4062334f873c678660eb54d Mon Sep 17 00:00:00 2001 From: Sorunome Date: Tue, 16 Jul 2019 17:11:07 +0200 Subject: [PATCH 0652/1250] fix typo, add section on html details element --- proposals/2010-spoilers.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/proposals/2010-spoilers.md b/proposals/2010-spoilers.md index cf969902..1d9f4dc9 100644 --- a/proposals/2010-spoilers.md +++ b/proposals/2010-spoilers.md @@ -53,6 +53,12 @@ however that wouldn't be HTML-compliant. Instead of limiting the proposed `data-mx-spoiler` attribute only to the ``-tag it could be added to all tags, however it might make implementations for clients more complicated. +Alternatively the [details](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details) tag could +be used. This, however, is a block element, and the spoilers are span elements. Furthermore +semantically there is a slight difference: with the details tag you hide something for a person +as it uses up a lot of screen space, while with a spoiler you hide something as a person might not +want to see it. + ## Potential issues Depending on context it might make sense to put other events, such as `m.image`, into spoilers, too. This MSC doesn't address that at all. Using @@ -60,7 +66,7 @@ too. This MSC doesn't address that at all. Using This MSC doesn't take HTML block elements into account. -Clients would have to come up with a way how to input spoilers. This could be done, for example, +Clients would have to come up with a way to input spoilers. This could be done, for example, by adding a custom markdown tag (like discord does), so that you do `Text ||spoiler||`, however that doesn't take a spoiler reason into account. From 15994c61a54c1010a7a422ce9e39ca04db422bdf Mon Sep 17 00:00:00 2001 From: Luca Becker Date: Tue, 16 Jul 2019 17:33:13 +0200 Subject: [PATCH 0653/1250] Clarification regarding authorisation rules The rules for m.room.power_levels power were somewhat unclear regarding the behaviour towards the always present keys, such as kick and ban. Additionally, it is now also clarified that in the users and events dictionary also added and removed keys are taken into consideration. --- specification/rooms/v1.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index b5ef217a..ba25fa21 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -243,14 +243,15 @@ The rules are as follows: #. 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: + #. For the keys ``users_default``, ``events_default``, + ``state_default``, ``ban``, ``redact``, ``kick``, ``invite`` check if they were changed. + For each of the changed keys, as well as + each entry being added, changed or removed under the ``events`` or ``users`` keys: - i. If the current value is higher than the ``sender``'s current power level, + i. If the current value is present and higher than the ``sender``'s current power level, reject. - #. If the new value is higher than the ``sender``'s current power level, + #. If the new value is present and higher than the ``sender``'s current power level, reject. #. For each entry being changed under the ``users`` key, other than the From b49a95024580e77bf45e04913f4bab4aded8e932 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 16 Jul 2019 19:26:02 +0100 Subject: [PATCH 0654/1250] Update proposals/2176-update-redaction-rules.md fix typo Co-Authored-By: Kitsune Ral --- proposals/2176-update-redaction-rules.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2176-update-redaction-rules.md b/proposals/2176-update-redaction-rules.md index a939178a..d32c9cda 100644 --- a/proposals/2176-update-redaction-rules.md +++ b/proposals/2176-update-redaction-rules.md @@ -21,7 +21,7 @@ preserved by a redaction: (Note this refers to the *event-level* `membership` property, rather than the similarly-named sub-property under the `content` key.) -Ratinale: neither of the above properties have defined meanings in the Matrix +Rationale: neither of the above properties have defined meanings in the Matrix protocol, so there is no reason for them to be special-cased in this way. The following should be added to the list of subkeys of the content property From d324cac847507f9527ce53cd224fa6bc0f873015 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 16 Jul 2019 19:32:34 +0100 Subject: [PATCH 0655/1250] preserve powerlevel --- proposals/2176-update-redaction-rules.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/proposals/2176-update-redaction-rules.md b/proposals/2176-update-redaction-rules.md index d32c9cda..14c97da0 100644 --- a/proposals/2176-update-redaction-rules.md +++ b/proposals/2176-update-redaction-rules.md @@ -37,9 +37,16 @@ which should be preserved: * `m.room.create` should allow the `room_version` key. Currently, redacting an `m.room.create` event will make the room revert to a v1 room. - * `m.room.power_levels` should allow the `notifications` key. Rationale: - symmetry with the other `power_levels` settings. (Maybe? See - https://github.com/matrix-org/matrix-doc/issues/1601#issuecomment-511237744.) + * `m.room.power_levels` should allow: + + * the `invite` key. Rationale: this is required to authenticate + `m.room.member` events with the `invite` membership. Currently, redacting + a `power_levels` event will mean that such events cannot be authenticated, + potentially leading to a split-brain room. + + * the `notifications` key. Rationale: symmetry with the other `power_levels` + settings. (Maybe? See + https://github.com/matrix-org/matrix-doc/issues/1601#issuecomment-511237744.) ## Potential issues From 8aece4f6448394ca9dc8635b0d6c1b89809e07e4 Mon Sep 17 00:00:00 2001 From: Luca Becker Date: Wed, 17 Jul 2019 23:26:10 +0200 Subject: [PATCH 0656/1250] Incorporated @richvdh suggestions --- specification/rooms/v1.rst | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index ba25fa21..6d79323f 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -245,14 +245,23 @@ The rules are as follows: #. For the keys ``users_default``, ``events_default``, ``state_default``, ``ban``, ``redact``, ``kick``, ``invite`` check if they were changed. - For each of the changed keys, as well as - each entry being added, changed or removed under the ``events`` or ``users`` keys: + For each of the changed keys: - i. If the current value is present and higher than the ``sender``'s current power level, + i. If the current value is higher than the ``sender``'s current power level, reject. - #. If the new value is present and higher than the ``sender``'s current power level, + #. If the new value is higher than the ``sender``'s current power level, reject. + + #. For each entry being added, changed or removed in both the ``events`` and ``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. + + #. (Note: current/new value can also denote the inferred value from either ``users_default``, ``events_default`` or ``state_default``) #. For each entry being changed under the ``users`` key, other than the ``sender``'s own entry: From 094005dca1fd79796a731d5669c0fe0fe6808e0e Mon Sep 17 00:00:00 2001 From: Luca Becker Date: Thu, 18 Jul 2019 08:55:58 +0200 Subject: [PATCH 0657/1250] Incorporated @turt2live suggestions. Added missing added and removed to the rule, because these keys are not required for m.room.power_levels. Also moved the note down to the Note section. --- specification/rooms/v1.rst | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index 6d79323f..eb453b58 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -244,8 +244,8 @@ The rules are as follows: #. If there is no previous ``m.room.power_levels`` event in the room, allow. #. For the keys ``users_default``, ``events_default``, - ``state_default``, ``ban``, ``redact``, ``kick``, ``invite`` check if they were changed. - For each of the changed keys: + ``state_default``, ``ban``, ``redact``, ``kick``, ``invite`` check if they + were added, changed or removed. For each found alteration: i. If the current value is higher than the ``sender``'s current power level, reject. @@ -253,15 +253,14 @@ The rules are as follows: #. If the new value is higher than the ``sender``'s current power level, reject. - #. For each entry being added, changed or removed in both the ``events`` and ``users`` keys: + #. For each entry being added, changed or removed in both the ``events`` and + ``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. - - #. (Note: current/new value can also denote the inferred value from either ``users_default``, ``events_default`` or ``state_default``) #. For each entry being changed under the ``users`` key, other than the ``sender``'s own entry: @@ -285,15 +284,19 @@ The rules are as follows: .. NOTE:: - Some consequences of these rules: + * 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. + * 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. + * 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. + + * Power levels may also be inferred from defaults. So, mentions of, for example, + the ``sender``'s power level might also refer to a default power level that is + applied. The same holds true for events. Event format ~~~~~~~~~~~~ From 4503327450c1017d1266c363268ceb8c3c670f01 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 22 Jul 2019 15:17:52 +0100 Subject: [PATCH 0658/1250] Add some compatibility hacks. --- proposals/2174-move-redacts-key.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/proposals/2174-move-redacts-key.md b/proposals/2174-move-redacts-key.md index ca3083a6..21212257 100644 --- a/proposals/2174-move-redacts-key.md +++ b/proposals/2174-move-redacts-key.md @@ -7,3 +7,11 @@ ID of the event being redacted. The presence of this field at the event level, rather than under the `content` key, is anomalous. This MSC proposes that, in a future room version, the `redacts` property be moved under the `content` key. + +For backwards-compatibility with *older* clients, servers should add a `redacts` +property to the top level of `m.room.redaction` events in *newer* room versions +when serving such events over the Client-Server API. + +For improved compatibility with *newer* clients, servers should add a `redacts` +property to the `content` of `m.room.redaction` events in *older* room versions +when serving such events over the Client-Server API. From 0444c8016b469540717ec2054799f3d80eb6a700 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 22 Jul 2019 15:33:49 +0100 Subject: [PATCH 0659/1250] review comments --- proposals/2134-identity-hash-lookup.md | 52 +++++++++++++++----------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 09e4748a..3fc92b53 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -65,11 +65,7 @@ hashed). First the client must append the medium to the address: ``` Hashes must be peppered in order to reduce both the information an identity -server gains during the process, and attacks the client can perform. Clients -will have to generate a full rainbow table specific to the set pepper to -obtain all registered MXIDs, while the server has to generate a full rainbow -table with the specific pepper to get the plaintext 3pids for non-matrix -users. +server gains during the process, and attacks the client can perform. [0] In order for clients to know the pepper and hashing algorithm they should use, Identity servers must make the information available on the `/hash_details` @@ -87,13 +83,14 @@ GET /_matrix/identity/v2/hash_details The name `lookup_pepper` was chosen in order to account for pepper values being returned for other endpoints in the future. The contents of `lookup_pepper` MUST match the regular expression `[a-zA-Z0-9]+` (unless no -hashing is being performed, as described below). If `lookup_pepper` is an -empty string, clients MUST cease the lookup operation. +hashing is being performed, as described below). If hashing is being +performed, and `lookup_pepper` is an empty string, clients MUST cease the +lookup operation. -``` The client should append the pepper to the end of the 3PID string before hashing. +``` "alice@example.com email" -> "alice@example.com emailmatrixrocks" "bob@example.com email" -> "bob@example.com emailmatrixrocks" "carl@example.com email" -> "carl@example.com emailmatrixrocks" @@ -106,22 +103,26 @@ handle identity servers which may rotate their pepper values frequently. Clients MUST choose one of the given hash algorithms to encrypt the 3PID during lookup. -At a minimum, clients and identity servers MUST support SHA-256 as defined by -[RFC 4634](https://tools.ietf.org/html/rfc4634), identified by the -`algorithm` value `"sha256"`. SHA-256 was chosen as it is currently used -throughout the Matrix spec, as well as its properties of being quick to hash. -While this reduces the resources necessary to generate a rainbow table for -attackers, a fast hash is necessary if particularly slow mobile clients are -going to be hashing thousands of contact details. Other algorithms can be -negotiated by the client and server at their discretion. +Clients and identity servers MUST support SHA-256 as defined by [RFC +4634](https://tools.ietf.org/html/rfc4634), identified by the `algorithm` +value `"sha256"`. SHA-256 was chosen as it is currently used throughout the +Matrix spec, as well as its properties of being quick to hash. While this +reduces the resources necessary to generate a rainbow table for attackers, a +fast hash is necessary if particularly slow mobile clients are going to be +hashing thousands of contact details. Other algorithms can be negotiated by +the client and server at their discretion. There are certain situations when an identity server cannot be expected to -compare hashed 3PID values; When a server is connected to a backend provider -such as LDAP, there is no way for the identity server to efficiently pull all -of the addresses and hash them. For this case, the `algorithm` field of `GET -/hash_details` may be set to `"m.none"`, and `lookup_pepper` will be an empty -string. No hashing will be performed if the client and server decide on this, -and 3PIDs will be sent in plain-text, similar to the v1 `/lookup` API. +compare hashed 3PID values; for example, when a server is connected to a +backend provider such as LDAP, there is no way for the identity server to +efficiently pull all of the addresses and hash them. For this case, clients +and server MUST also support sending plain-text 3PID values. To agree upon +this, the `algorithm` field of `GET /hash_details` MUST be set to `"m.none"`, +whereas `lookup_pepper` will be an empty string. No hashing will be performed +if the client and server decide on this, and 3PIDs will be sent in +plain-text, similar to the v1 `/lookup` API. When this occurs, it is STRONGLY +RECOMMENDED for the client to prompt the user before continuing, and receive +consent for sending 3PID details in plain-text to the identity server. When performing a lookup, the pepper and hashing algorithm the client used must be part of the request body (even when using the `"m.none"` algorithm @@ -277,3 +278,10 @@ This proposal outlines a simple method to stop bulk collection of user's contact lists and their social graphs without any disastrous side effects. All functionality which depends on the lookup service should continue to function unhindered by the use of hashes. + +## Footnotes + +[0] Clients would have to generate a full rainbow table specific to the set +pepper to obtain all registered MXIDs, while the server would have to +generate a full rainbow table with the specific pepper to get the plaintext +3pids for non-matrix users. From 887cd5e7d056000bc05cee6b28d7d1bf595edfaa Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 22 Jul 2019 16:00:29 +0100 Subject: [PATCH 0660/1250] I really hope someone doesn't invest none-hash --- proposals/2134-identity-hash-lookup.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 3fc92b53..9a5cee11 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -117,7 +117,7 @@ compare hashed 3PID values; for example, when a server is connected to a backend provider such as LDAP, there is no way for the identity server to efficiently pull all of the addresses and hash them. For this case, clients and server MUST also support sending plain-text 3PID values. To agree upon -this, the `algorithm` field of `GET /hash_details` MUST be set to `"m.none"`, +this, the `algorithm` field of `GET /hash_details` MUST be set to `"none"`, whereas `lookup_pepper` will be an empty string. No hashing will be performed if the client and server decide on this, and 3PIDs will be sent in plain-text, similar to the v1 `/lookup` API. When this occurs, it is STRONGLY @@ -125,7 +125,7 @@ RECOMMENDED for the client to prompt the user before continuing, and receive consent for sending 3PID details in plain-text to the identity server. When performing a lookup, the pepper and hashing algorithm the client used -must be part of the request body (even when using the `"m.none"` algorithm +must be part of the request body (even when using the `"none"` algorithm value). If they do not match what the server has on file (which may be the case if the pepper was changed right after the client's request for it), then the server must inform the client that they need to query the hash details From 9e264fedc964c5ed44f39e7ddc23e68c5fd48486 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 22 Jul 2019 16:47:49 +0100 Subject: [PATCH 0661/1250] Updates * preserve *all* of `create` * don't preserve `notifications` or `algorithm`, and add some justifcation. --- proposals/2176-update-redaction-rules.md | 59 ++++++++++++++++++++---- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/proposals/2176-update-redaction-rules.md b/proposals/2176-update-redaction-rules.md index 14c97da0..dea3015f 100644 --- a/proposals/2176-update-redaction-rules.md +++ b/proposals/2176-update-redaction-rules.md @@ -27,6 +27,12 @@ protocol, so there is no reason for them to be special-cased in this way. The following should be added to the list of subkeys of the content property which should be preserved: + * `m.room.create` should preserve *all* content. Rationale: the values in a + `create` event are deliberately intented to last the lifetime of the room, + and if values are redacted, there is no way to add correct settings + afterwards. It therefore seems non-sensical to allow redaction of a `create` + event. + * `m.room.redaction` should allow the `redacts` key (assuming [MSC2174](https://github.com/matrix-org/matrix-doc/pull/2174) is merged). Rationale: currently, redacting a redaction can lead to inconsistent results @@ -34,9 +40,6 @@ which should be preserved: result before or after it is redacted (and therefore may or may not redact the original event). - * `m.room.create` should allow the `room_version` key. Currently, redacting an - `m.room.create` event will make the room revert to a v1 room. - * `m.room.power_levels` should allow: * the `invite` key. Rationale: this is required to authenticate @@ -44,12 +47,50 @@ which should be preserved: a `power_levels` event will mean that such events cannot be authenticated, potentially leading to a split-brain room. - * the `notifications` key. Rationale: symmetry with the other `power_levels` - settings. (Maybe? See - https://github.com/matrix-org/matrix-doc/issues/1601#issuecomment-511237744.) +## Other properties considered for preservation + +Currently it is *not* proposed to add these to the list of properties which are +proposed for a redaction: + + * The `notifications` key of `m.room.power_levels`. Unlike the other + properties in `power_levels`, `notifications` does not play a part in + authorising the events in the room graph. Once the `power_levels` are + replaced, historical values of the `notifications` property are + irrelevant. There is therefore no need for it to be protected from + redactions. + + * The `algorithm` key of `m.room.encryption`. Again, historical values of + `m.room.encryption` have no effect, and servers do not use the value of the + property to authenticate events. + + The effect of redacting an `m.room.redaction` event is much the same as that + of sending a new `m.room.redaction` event with no `algorithm` key. It's + unlikely to be what was intended, but adding rules to the redaction + algorithm will not help this. + +### Background to things not included in the proposal + +The approach taken here has been to minimise the list of properties preserved +by redaction; in general, the list is limited to those which are required by +servers to authenticate events in the room. One reason for this is to simplify +the implementation of servers and clients, but a more important philosophical +reason is as follows. + +Changing the redaction algorithm requires changes to both servers and clients, +so changes are difficult and will happen rarely. Adding additional keys now +sets an awkward precedent. + +It is likely that in the future more properties will be defined which might be +convenient to preserve under redaction. One of the two scenarios would then +happen: + * We would be forced to issue yet more updates to the redaction algorithm, + with a new room versions and mandatory updates to all servers and clients, or: -## Potential issues + * We would end up with an awkward asymmetry between properties which were + preserved under this MSC, and those which were introduced later so were not + preserved. -What if there is spam in sub-properties of the `notifications` property of -power-levels? Should we not be able to redact it? +In short, I consider it important for the elegance of the Matrix protocol that +we do not add unnecessary properties to the list of those to be preserved by +redaction. From d43111cdd2cbfa56f1f3113443b2cf8a1fe30b1d Mon Sep 17 00:00:00 2001 From: Luca Becker Date: Tue, 23 Jul 2019 11:25:34 +0200 Subject: [PATCH 0662/1250] Incorporated @turt2live suggestions. Used **Note** to describe notes around the authorisation rules. Otherwise restored the original state for the consequences from the auth rules. Moved the clarification regarding default power levels up above the auth rules. Removed third sentence. And followed @turt2live's example, but opted for "for users in that room" because the default user power level is applied to all users. --- specification/rooms/v1.rst | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index eb453b58..0b4e4f65 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -109,6 +109,8 @@ The types of state events that affect authorization are: - ``m.room.power_levels`` - ``m.room.third_party_invite`` +**Note:** Power levels are inferred from defaults when not explicitly supplied. For example, mentions of the ``sender``'s power level can also refer to the default power level for users in the room. + The rules are as follows: 1. If type is ``m.room.create``: @@ -282,21 +284,17 @@ The rules are as follows: #. 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. + **Note:** Some consequences of these rules: - * 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. - - * Power levels may also be inferred from defaults. So, mentions of, for example, - the ``sender``'s power level might also refer to a default power level that is - applied. The same holds true for events. + * 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 ~~~~~~~~~~~~ From 577021f12b9edfd3ca0b428fa3774aa540a8b632 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 23 Jul 2019 11:48:01 +0100 Subject: [PATCH 0663/1250] resolve some comments --- proposals/2134-identity-hash-lookup.md | 90 ++++++++++++-------------- 1 file changed, 42 insertions(+), 48 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 9a5cee11..8db758dc 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -1,8 +1,8 @@ # MSC2134: Identity Hash Lookups [Issue #2130](https://github.com/matrix-org/matrix-doc/issues/2130) has been -recently created in response to a security issue brought up by an independent -party. To summarise the issue, lookups (of Matrix user IDs) are performed using +created in response to a security issue brought up by an independent party. +To summarise the issue, lookups (of Matrix user IDs) are performed using plain-text 3PIDs (third-party IDs) which means that the identity server can identify and record every 3PID that the user has in their contacts, whether that email address or phone number is already known by the identity server or @@ -26,10 +26,10 @@ which will leak less data to identity servers. ## Proposal This proposal suggests making changes to the Identity Service API's lookup -endpoints. Instead, this proposal consolidates them into a single `/lookup` -endpoint. Additionally, the endpoint is to be on a `v2` path, to avoid -confusion with the original `/lookup`. We also drop the `/api` in order to -preserve consistency across other endpoints: +endpoints, consolidating them into a single `/lookup` endpoint. The endpoint +is to be on a `v2` path, to avoid confusion with the original `v1` `/lookup`. +The `/api` part is also dropped in order to preserve consistency across other +endpoints: - `/_matrix/identity/v2/lookup` @@ -68,7 +68,7 @@ Hashes must be peppered in order to reduce both the information an identity server gains during the process, and attacks the client can perform. [0] In order for clients to know the pepper and hashing algorithm they should use, -Identity servers must make the information available on the `/hash_details` +identity servers must make the information available on the `/hash_details` endpoint: ``` @@ -104,25 +104,30 @@ Clients MUST choose one of the given hash algorithms to encrypt the 3PID during lookup. Clients and identity servers MUST support SHA-256 as defined by [RFC -4634](https://tools.ietf.org/html/rfc4634), identified by the `algorithm` -value `"sha256"`. SHA-256 was chosen as it is currently used throughout the -Matrix spec, as well as its properties of being quick to hash. While this -reduces the resources necessary to generate a rainbow table for attackers, a -fast hash is necessary if particularly slow mobile clients are going to be -hashing thousands of contact details. Other algorithms can be negotiated by -the client and server at their discretion. +4634](https://tools.ietf.org/html/rfc4634), identified by the value +`"sha256"` in the `algorithms` array. SHA-256 was chosen as it is currently +used throughout the Matrix spec, as well as its properties of being quick to +hash. While this reduces the resources necessary to generate a rainbow table +for attackers, a fast hash is necessary if particularly slow mobile clients +are going to be hashing thousands of contact details. Other algorithms are +negotiated by the client and server at their discretion. There are certain situations when an identity server cannot be expected to compare hashed 3PID values; for example, when a server is connected to a backend provider such as LDAP, there is no way for the identity server to efficiently pull all of the addresses and hash them. For this case, clients and server MUST also support sending plain-text 3PID values. To agree upon -this, the `algorithm` field of `GET /hash_details` MUST be set to `"none"`, -whereas `lookup_pepper` will be an empty string. No hashing will be performed -if the client and server decide on this, and 3PIDs will be sent in -plain-text, similar to the v1 `/lookup` API. When this occurs, it is STRONGLY -RECOMMENDED for the client to prompt the user before continuing, and receive -consent for sending 3PID details in plain-text to the identity server. +this, the `"algorithms"` field of `GET /hash_details` MUST contain the value +`"none"`, and `lookup_pepper` will be an empty string. For this case, the +identity server could only send `"none"` as part of the `"algorithms"` array. +The client can then decide whether it wants to accept this. The identity +server could also send `["none", "sha256"]` and cease from looking up +contacts in LDAP unless `"none"` is decided upon. + +No hashing will be performed if the client and server decide on `"none"`, and +3PIDs will be sent in plain-text, similar to the v1 `/lookup` API. When this +occurs, it is STRONGLY RECOMMENDED for the client to prompt the user before +continuing. When performing a lookup, the pepper and hashing algorithm the client used must be part of the request body (even when using the `"none"` algorithm @@ -132,16 +137,15 @@ the server must inform the client that they need to query the hash details again, instead of just returning an empty response, which clients would assume to mean that no contacts are registered on that identity server. -If the algorithm does not match the server's, the server should return a `400 +If the algorithm is not supported by the server, the server should return a `400 M_INVALID_PARAM`. If the pepper does not match the server's, the server should return a new error code, `400 M_INVALID_PEPPER`. A new error code is not defined for an invalid algorithm as that is considered a client bug. -The `M_INVALID_PEPPER` error response should contain the correct `algorithm` -and `lookup_pepper` fields. This is to prevent the client from needing to -query `/hash_details` again, thus saving a round-trip. `M_INVALID_PARAM` does -not include these fields. An example response to an incorrect pepper would -be: +The `M_INVALID_PEPPER` error response contain the correct `algorithm` and +`lookup_pepper` fields. This is to prevent the client from needing to query +`/hash_details` again, thus saving a request. `M_INVALID_PARAM` does not +include these fields. An example response to an incorrect pepper would be: ``` { @@ -207,10 +211,9 @@ as part of this proposal. implementation, and should return a `403 M_FORBIDDEN` error if so. If an identity server is too old and a HTTP 400 or 404 is received when -accessing the `v2` endpoint, they should fallback to the `v1` endpoint instead. -However, clients should be aware that plain-text 3PIDs are required for the -`v1` endpoint, and SHOULD ask for user consent to send 3PIDs in plain-text, and -be clear about where they are being sent to. +accessing the `v2` endpoint, clients should fallback to the `v1` endpoint +instead. However, clients should be aware that plain-text 3PIDs are required +for the `v1` endpoints, and are strongly encouraged to warn the user of this. ## Tradeoffs @@ -229,14 +232,6 @@ Mediums and peppers are appended to the address as to prevent a common prefix for each plain-text string, which prevents attackers from pre-computing bits of a stream cipher. -Additionally, this proposal does not stop an identity server from storing -plain-text 3PIDs. There is a GDPR argument in keeping email addresses, such -that if a breach happens, users must be notified of such. Ideally this would be -done over Matrix, but people may've stuck their email in an identity server and -then left Matrix forever. Perhaps if only hashes were being stored on the -identity server then that isn't considered personal information? In any case, a -discussion for another MSC. - ## Other considered solutions Ideally identity servers would never receive plain-text addresses, however it @@ -251,16 +246,15 @@ eventual solution of using Software Guard Extensions (detailed in https://signal.org/blog/private-contact-discovery/) is considered impractical for a federated network, as it requires specialized hardware. -k-anonymity was considered as an alternative, in which the identity server -would never receive a full hash of a 3PID that it did not already know about. -While this has been considered plausible, it comes with heightened resource -requirements (much more hashing by the identity server). The conclusion was -that it may not provide more privacy if an identity server decided to be evil, -however it would significantly raise the resource requirements to run an evil -identity server. - -Discussion and a walk-through of what a client/identity-server interaction would -look like are documented [in this Github +k-anonymity was considered as an alternative approach, in which the identity +server would never receive a full hash of a 3PID that it did not already know +about. While this has been considered plausible, it comes with heightened +resource requirements (much more hashing by the identity server). The +conclusion was that it may not provide more privacy if an identity server +decided to be evil, however it would significantly raise the resource +requirements to run an evil identity server. Discussion and a walk-through of +what a client/identity-server interaction would look like are documented [in +this Github comment](https://github.com/matrix-org/matrix-doc/pull/2134#discussion_r298691748). Additionally, a radical model was also considered where the first portion of From b26a9ed1fd7f847a701028efcba55f6aff82d1c3 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 23 Jul 2019 13:28:42 +0100 Subject: [PATCH 0664/1250] Expand on why we can't trust dirty homeservers --- proposals/2134-identity-hash-lookup.md | 30 ++++++++++++++++---------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 8db758dc..5bd4889a 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -234,10 +234,6 @@ of a stream cipher. ## Other considered solutions -Ideally identity servers would never receive plain-text addresses, however it -is necessary for the identity server to send email/sms messages during a -bind, as it cannot trust a homeserver to do so as the homeserver may be lying. - Bloom filters are an alternative method of providing private contact discovery. However, they do not scale well due to requiring clients to download a large filter that needs updating every time a new bind is made. Further considered @@ -257,15 +253,27 @@ what a client/identity-server interaction would look like are documented [in this Github comment](https://github.com/matrix-org/matrix-doc/pull/2134#discussion_r298691748). -Additionally, a radical model was also considered where the first portion of -the above scheme was done with an identity server, and the second would be done -with various homeservers who originally reported the 3PID to the identity -server. While interesting and a more decentralised model, some attacks are -still possible if the identity server is running an evil homeserver which it -can direct the client to send its hashes to. Discussion on this matter has -taken place in the MSC-specific room [starting at this +A radical model was also considered where the first portion of the +k-anonyminity scheme was done with an identity server, and the second would +be done with various homeservers who originally reported the 3PID to the +identity server. While interesting and a more decentralised model, some +attacks are still possible if the identity server is running an evil +homeserver which it can direct the client to send its hashes to. Discussion +on this matter has taken place in the MSC-specific room [starting at this message](https://matrix.to/#/!LlraCeVuFgMaxvRySN:amorgan.xyz/$4wzTSsspbLVa6Lx5cBq6toh6P3TY3YnoxALZuO8n9gk?via=amorgan.xyz&via=matrix.org&via=matrix.vgorcum.com). +Ideally identity servers would never receive plain-text addresses, just +storing and receiving hash values instead. However, it is necessary for the +identity server to have plain-text addresses during a +[bind](https://matrix.org/docs/spec/identity_service/r0.2.1#post-matrix-identity-api-v1-3pid-bind) +call, in order to send a verification email or sms message. It is not +feasible to defer this job to a homeserver, as the identity server cannot +trust that the homeserver has actually performed verification. Thus it may +not be possible to prevent plain-text 3PIDs of registered Matrix users from +being sent to the identity server at least once. Yet, we can still do our +best by coming up with creative ways to prevent non-matrix user 3PIDs from +leaking to the identity server, when they're sent in a lookup. + ## Conclusion This proposal outlines a simple method to stop bulk collection of user's From 9fd6bd318461cba6226fffdbc00f2fac6b839036 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 23 Jul 2019 15:16:27 +0100 Subject: [PATCH 0665/1250] Add details about why this proposal should exist --- proposals/2134-identity-hash-lookup.md | 51 ++++++++++++++++++-------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 5bd4889a..23c155f4 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -6,22 +6,41 @@ To summarise the issue, lookups (of Matrix user IDs) are performed using plain-text 3PIDs (third-party IDs) which means that the identity server can identify and record every 3PID that the user has in their contacts, whether that email address or phone number is already known by the identity server or -not. - -If the 3PID is hashed, the identity server could not determine the address -unless it has already seen that address in plain-text during a previous call -of the [/bind -mechanism](https://matrix.org/docs/spec/identity_service/r0.2.1#post-matrix-identity-api-v1-3pid-bind) -(without significant resources to reverse the hashes). This helps prevent -bulk collection of user's contact lists by the identity server and reduces -its ability to build social graphs. - -This proposal thus calls for the Identity Service API's -[/lookup](https://matrix.org/docs/spec/identity_service/r0.2.1#get-matrix-identity-api-v1-lookup) -endpoint to use hashed 3PIDs instead of their plain-text counterparts (and to -deprecate both it and -[/bulk_lookup](https://matrix.org/docs/spec/identity_service/r0.2.1#post-matrix-identity-api-v1-bulk-lookup)), -which will leak less data to identity servers. +not. In the latter case, an identity server is able to collect email +addresses and phone numbers that have a high probability of being connected +to a real person. It could then use this data for marketing or other +purposes. + +However, if the email addresses and phone numbers are hashed before they are +sent to the identity server, the server would have a more difficult time of +being able to recover the original addresses. This prevents contact +information of non-Matrix users being exposed by the lookup service. + +However, hashing is not perfect. While reversing a hash is not possible, it +is possible to build a [rainbow +table](https://en.wikipedia.org/wiki/Rainbow_table), which could map many +known email addresses and phone numbers to their hash equivalents. When the +identity server receives a hash, it would then be able to look it up in this +table, and find the email address or phone number associated with it. In an +ideal world, one would use a hashing algorithm such as +[bcrypt](https://en.wikipedia.org/wiki/Bcrypt), with many rounds, which would +make building such a rainbow table an extraordinarily expensive process. +Unfortunately, this is impractical for our use case, as it would require +clients to perform many, many rounds of hashing, linearly dependent on their +address book size, which would likely result in lower-end mobile phones +becoming overwhelmed. Thus, we must use a fast hashing algorithm, at the cost +of making rainbow tables easy to build. + +The rainbow table attack is not perfect. While there are only so many +possible phone numbers, and thus it is simple to generate the hash value for +each one, the address space of email addresses is much, much wider. Therefore +if your email address is decently long and is not publicly known to +attackers, it is unlikely that it would be included in a rainbow table. + +Thus the approach of hashing, while adding complexity to implementation and +minor resource consumption of the client and identity server, does provide +added difficultly for the identity server to carry out contact detail +harvesting, which should be considered worthwhile. ## Proposal From 3031df79cc67419c40851afe6eea6985cc18c843 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 23 Jul 2019 16:33:24 +0100 Subject: [PATCH 0666/1250] Add example for none algo --- proposals/2134-identity-hash-lookup.md | 163 +++++++++++++++++-------- 1 file changed, 110 insertions(+), 53 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 23c155f4..d6cb0506 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -2,45 +2,46 @@ [Issue #2130](https://github.com/matrix-org/matrix-doc/issues/2130) has been created in response to a security issue brought up by an independent party. -To summarise the issue, lookups (of Matrix user IDs) are performed using -plain-text 3PIDs (third-party IDs) which means that the identity server can -identify and record every 3PID that the user has in their contacts, whether -that email address or phone number is already known by the identity server or -not. In the latter case, an identity server is able to collect email -addresses and phone numbers that have a high probability of being connected -to a real person. It could then use this data for marketing or other -purposes. - -However, if the email addresses and phone numbers are hashed before they are +To summarise the issue, when a user wants to ask an identity server which of +its contacts have registered a Matrix account, it performs a lookup against +an identity server. The client currently sends all of its contact details in +the form of plain-text addresses, meaning that the identity server can +identify and record every third-party ID (3PID) of the user's contacts. This +allows the identity server is able to collect email addresses and phone +numbers that have a high probability of being connected to a real person. +This data could then be used for marketing, political campaigns, etc. + +However, if these email addresses and phone numbers are hashed before they are sent to the identity server, the server would have a more difficult time of being able to recover the original addresses. This prevents contact -information of non-Matrix users being exposed by the lookup service. - -However, hashing is not perfect. While reversing a hash is not possible, it -is possible to build a [rainbow -table](https://en.wikipedia.org/wiki/Rainbow_table), which could map many -known email addresses and phone numbers to their hash equivalents. When the -identity server receives a hash, it would then be able to look it up in this -table, and find the email address or phone number associated with it. In an -ideal world, one would use a hashing algorithm such as -[bcrypt](https://en.wikipedia.org/wiki/Bcrypt), with many rounds, which would -make building such a rainbow table an extraordinarily expensive process. -Unfortunately, this is impractical for our use case, as it would require -clients to perform many, many rounds of hashing, linearly dependent on their -address book size, which would likely result in lower-end mobile phones -becoming overwhelmed. Thus, we must use a fast hashing algorithm, at the cost -of making rainbow tables easy to build. - -The rainbow table attack is not perfect. While there are only so many -possible phone numbers, and thus it is simple to generate the hash value for -each one, the address space of email addresses is much, much wider. Therefore -if your email address is decently long and is not publicly known to -attackers, it is unlikely that it would be included in a rainbow table. +information of non-Matrix users being exposed to the lookup service. + +Yet, hashing is not perfect. While reversing a hash is not possible, it is +possible to build a [rainbow +table](https://en.wikipedia.org/wiki/Rainbow_table), which maps known email +addresses and phone numbers to their hash equivalents. When the identity +server receives a hash, it is then be able to look it up in its rainbow table +and find the corresponding 3PID. To prevent this, one would use a hashing +algorithm such as [bcrypt](https://en.wikipedia.org/wiki/Bcrypt) with many +rounds, making the construction of a large rainbow table an infeasibly +expensive process. Unfortunately, this is impractical for our use case, as it +would require clients to also perform many, many rounds of hashing, linearly +dependent on the size of their address book, which would likely result in +lower-end mobile phones becoming overwhelmed. We are then forced to use a +fast hashing algorithm, at the cost of making rainbow tables easy to build. + +The rainbow table attack is not perfect, because one does need to know email +addresses and phone numbers to build it. While there are only so many +possible phone numbers, and thus it is relatively inexpensive to generate the +hash value for each one, the address space of email addresses is much, much +wider. If your email address is decently long and is not publicly +known to attackers, it is unlikely that it would be included in a rainbow +table. Thus the approach of hashing, while adding complexity to implementation and -minor resource consumption of the client and identity server, does provide -added difficultly for the identity server to carry out contact detail -harvesting, which should be considered worthwhile. +resource consumption of the client and identity server, does provide added +difficulty for the identity server to carry out contact detail harvesting, +which should be considered worthwhile. ## Proposal @@ -106,8 +107,7 @@ hashing is being performed, as described below). If hashing is being performed, and `lookup_pepper` is an empty string, clients MUST cease the lookup operation. -The client should append the pepper to the end of the 3PID string before -hashing. +If hashing, the client should append the pepper to the end of the 3PID string. ``` "alice@example.com email" -> "alice@example.com emailmatrixrocks" @@ -119,8 +119,8 @@ hashing. Clients SHOULD request this endpoint each time before performing a lookup, to handle identity servers which may rotate their pepper values frequently. -Clients MUST choose one of the given hash algorithms to encrypt the 3PID -during lookup. +Clients MUST choose one of the given `algorithms` values to encrypt the +3PID during lookup. Clients and identity servers MUST support SHA-256 as defined by [RFC 4634](https://tools.ietf.org/html/rfc4634), identified by the value @@ -133,15 +133,11 @@ negotiated by the client and server at their discretion. There are certain situations when an identity server cannot be expected to compare hashed 3PID values; for example, when a server is connected to a -backend provider such as LDAP, there is no way for the identity server to -efficiently pull all of the addresses and hash them. For this case, clients +backend provider such as LDAP, it is not efficient for the identity server to +pull all of the addresses and hash them on lookup. For this case, clients and server MUST also support sending plain-text 3PID values. To agree upon this, the `"algorithms"` field of `GET /hash_details` MUST contain the value -`"none"`, and `lookup_pepper` will be an empty string. For this case, the -identity server could only send `"none"` as part of the `"algorithms"` array. -The client can then decide whether it wants to accept this. The identity -server could also send `["none", "sha256"]` and cease from looking up -contacts in LDAP unless `"none"` is decided upon. +`"none"`. No hashing will be performed if the client and server decide on `"none"`, and 3PIDs will be sent in plain-text, similar to the v1 `/lookup` API. When this @@ -153,7 +149,7 @@ must be part of the request body (even when using the `"none"` algorithm value). If they do not match what the server has on file (which may be the case if the pepper was changed right after the client's request for it), then the server must inform the client that they need to query the hash details -again, instead of just returning an empty response, which clients would +again, as opposed to just returning an empty response, which clients would assume to mean that no contacts are registered on that identity server. If the algorithm is not supported by the server, the server should return a `400 @@ -175,11 +171,11 @@ include these fields. An example response to an incorrect pepper would be: } ``` -Now comes time for the lookup. Note that the resulting hash digest MUST be -encoded in URL-safe unpadded base64 (similar to [room version 4's event +Now comes time for the lookup. We'll first cover an example of the client +choosing the `"sha256"` algorithm. Note that the resulting hash digest MUST +be encoded in URL-safe unpadded base64 (similar to [room version 4's event IDs](https://matrix.org/docs/spec/rooms/v4#event-ids)). Once hashing has been -performed using the defined hashing algorithm, the client sends each hash in an -array. +performed, the client sends each hash in an array. ``` NOTE: Hashes are not real values @@ -193,7 +189,7 @@ NOTE: Hashes are not real values POST /_matrix/identity/v2/lookup { - "hashes": [ + "addresses": [ "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs", "r0-6x3rp9zIWS2suIque-wXTnlv9sc41fatbRMEOwQE", "ryr10d1K8fcFVxALb3egiSquqvFAxQEwegXtlHoQFBw", @@ -206,7 +202,7 @@ POST /_matrix/identity/v2/lookup ``` The identity server, upon receiving these hashes, can simply compare against -the hashes of the 3PIDs it stores. The server then responds with the Matrix +the hashes of the 3PIDs it stores. The server then responds with the Matrix IDs of those that match: ``` @@ -220,6 +216,67 @@ IDs of those that match: The client can now display which 3PIDs link to which Matrix IDs. +For the case of the identity server sending, and the client choosing, +`"none"` as the algorithm, we would do the following. + +The client would first make `GET` a request to `/hash_details`, perhaps +receiving the response: + +``` +{ + "lookup_pepper": "matrixrocks", + "algorithms": ["none", "sha256"] +} +``` + +The client decides that it would like to use `"none"`, and thus ignores the +lookup pepper, as no hashing will occur. Appending a space and the 3PID +medium to each address is still necessary: + +``` +"alice@example.com" -> "alice@example.com email" +"bob@example.com" -> "bob@example.com email" +"carl@example.com" -> "carl@example.com email" +"12345678910" -> "12345678910 msisdn" +"denny@example.com" -> "denny@example.com email" +``` + +The client then sends these off to the identity server in a `POST` request to +`/lookup`: + +``` +POST /_matrix/identity/v2/lookup + +{ + "addresses": [ + "alice@example.com email", + "bob@example.com email", + "carl@example.com email", + "12345678910 msisdn", + "denny@example.com email" + ], + "algorithm": "none", + "pepper": "matrixrocks" +} +``` + +Note that even though we haven't used the `lookup_pepper` value, we still +include the same one sent to us by the identity server in `/hash_details`. +The identity server should still return `400 M_INVALID_PEPPER` if the pepper +is incorrect. This is intended to make implementation simpler. + +Finally, the identity server will check its database for the Matrix user IDs +it has that correspond to these 3PID addresses, and returns them: + +``` +{ + "mappings": { + "alice@example.com email": "@alice:example.com", + "12345678910 msisdn": "@fred:example.com" + } +} +``` + No parameter changes will be made to [/bind](https://matrix.org/docs/spec/identity_service/r0.2.1#post-matrix-identity-api-v1-3pid-bind) as part of this proposal. From 3b8c57e06ca961c6842ab409b64f825b8884c573 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 23 Jul 2019 16:43:55 +0100 Subject: [PATCH 0667/1250] Don't require servers/clients to support "none" --- proposals/2134-identity-hash-lookup.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index d6cb0506..b40f9f28 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -134,10 +134,11 @@ negotiated by the client and server at their discretion. There are certain situations when an identity server cannot be expected to compare hashed 3PID values; for example, when a server is connected to a backend provider such as LDAP, it is not efficient for the identity server to -pull all of the addresses and hash them on lookup. For this case, clients -and server MUST also support sending plain-text 3PID values. To agree upon -this, the `"algorithms"` field of `GET /hash_details` MUST contain the value -`"none"`. +pull all of the addresses and hash them upon lookup. For this case, can also +support receiving plain-text 3PID addresses from clients. To agree upon this, +the value `"none"` can be added to the `"algorithms"` array of `GET +/hash_details`. The client can then choose to send plain-text values by +setting the `"algorithm"` value in `POST /lookup` to `"none"`. No hashing will be performed if the client and server decide on `"none"`, and 3PIDs will be sent in plain-text, similar to the v1 `/lookup` API. When this From c7a23557d4f4f88e09d15317861164db1b2a97b6 Mon Sep 17 00:00:00 2001 From: Luca Becker Date: Tue, 23 Jul 2019 17:57:22 +0200 Subject: [PATCH 0668/1250] Last cosmetic changes switched back to the use of `.. NOTE::` --- specification/rooms/v1.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index 0b4e4f65..02e4f3e4 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -109,7 +109,11 @@ The types of state events that affect authorization are: - ``m.room.power_levels`` - ``m.room.third_party_invite`` -**Note:** Power levels are inferred from defaults when not explicitly supplied. For example, mentions of the ``sender``'s power level can also refer to the default power level for users in the room. +.. NOTE:: + + Power levels are inferred from defaults when not explicitly supplied. + For example, mentions of the ``sender``'s power level can also refer + to the default power level for users in the room. The rules are as follows: @@ -284,11 +288,11 @@ The rules are as follows: #. Otherwise, allow. +.. NOTE:: + Some consequences of these rules: - **Note:** Some consequences of these rules: - - * Unless you are a member of the room, the only permitted operations (apart + * 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. From f4d6b6c26124de47c88ed4c73f788864fb37b97c Mon Sep 17 00:00:00 2001 From: Luca Becker Date: Tue, 23 Jul 2019 17:58:40 +0200 Subject: [PATCH 0669/1250] Fixed broken indentations --- specification/rooms/v1.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index 02e4f3e4..a720b41a 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -292,7 +292,7 @@ The rules are as follows: Some consequences of these rules: - * Unless you are a member of the room, the only permitted operations (apart + * 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. From 8f3e58870830569693afae86c42b44dc8cb30f0b Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 24 Jul 2019 15:27:48 +0100 Subject: [PATCH 0670/1250] pepper is not a secret val. Still needs to be around. --- proposals/2134-identity-hash-lookup.md | 28 +++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index b40f9f28..72bc4e53 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -7,9 +7,9 @@ its contacts have registered a Matrix account, it performs a lookup against an identity server. The client currently sends all of its contact details in the form of plain-text addresses, meaning that the identity server can identify and record every third-party ID (3PID) of the user's contacts. This -allows the identity server is able to collect email addresses and phone -numbers that have a high probability of being connected to a real person. -This data could then be used for marketing, political campaigns, etc. +allows the identity server to collect email addresses and phone numbers that +have a high probability of being connected to a real person. This data could +then be used for marketing, political campaigns, etc. However, if these email addresses and phone numbers are hashed before they are sent to the identity server, the server would have a more difficult time of @@ -71,10 +71,14 @@ denny@example.com ``` The client will hash each 3PID as a concatenation of the medium and address, -separated by a space and a pepper appended to the end. Note that phone numbers -should be formatted as defined by +separated by a space and a pepper appended to the end. Note that phone +numbers should be formatted as defined by https://matrix.org/docs/spec/appendices#pstn-phone-numbers, before being -hashed). First the client must append the medium to the address: +hashed). Note that "pepper" in this proposal simply refers to a public, +opaque string that is used to produce different hash results between identity +servers. Its value is not secret. + +First the client must append the medium to the address: ``` "alice@example.com" -> "alice@example.com email" @@ -102,12 +106,11 @@ GET /_matrix/identity/v2/hash_details The name `lookup_pepper` was chosen in order to account for pepper values being returned for other endpoints in the future. The contents of -`lookup_pepper` MUST match the regular expression `[a-zA-Z0-9]+` (unless no -hashing is being performed, as described below). If hashing is being -performed, and `lookup_pepper` is an empty string, clients MUST cease the -lookup operation. +`lookup_pepper` MUST match the regular expression `[a-zA-Z0-9]+`, whether +hashing is being performed or not. When no hashing is occuring, a pepper +value of at least length 1 is still required. -If hashing, the client should append the pepper to the end of the 3PID string. +If hashing, the client appends the pepper to the end of the 3PID string. ``` "alice@example.com email" -> "alice@example.com emailmatrixrocks" @@ -264,7 +267,8 @@ POST /_matrix/identity/v2/lookup Note that even though we haven't used the `lookup_pepper` value, we still include the same one sent to us by the identity server in `/hash_details`. The identity server should still return `400 M_INVALID_PEPPER` if the pepper -is incorrect. This is intended to make implementation simpler. +is incorrect. This simplifies things and can help ensure the client is +requesting `/hash_details` properly before each lookup request. Finally, the identity server will check its database for the Matrix user IDs it has that correspond to these 3PID addresses, and returns them: From c6dd5951a15cf1be34c8794ffd6ca2657f34af27 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 25 Jul 2019 18:53:32 +0100 Subject: [PATCH 0671/1250] Clients can cache the hash details if they want to --- proposals/2134-identity-hash-lookup.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 72bc4e53..83b0dceb 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -120,10 +120,10 @@ If hashing, the client appends the pepper to the end of the 3PID string. "denny@example.com email" -> "denny@example.com emailmatrixrocks" ``` -Clients SHOULD request this endpoint each time before performing a lookup, to -handle identity servers which may rotate their pepper values frequently. -Clients MUST choose one of the given `algorithms` values to encrypt the -3PID during lookup. +Clients can cache the result of this endpoint, but should re-request it +during an error on `/lookup`, to handle identity servers which may rotate +their pepper values frequently. Clients MUST choose one of the given +`algorithms` values to encrypt the 3PID during lookup. Clients and identity servers MUST support SHA-256 as defined by [RFC 4634](https://tools.ietf.org/html/rfc4634), identified by the value From da876bb340ddd1130bba69afc5b09a3ac40000da Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 25 Jul 2019 18:54:02 +0100 Subject: [PATCH 0672/1250] missing word --- proposals/2134-identity-hash-lookup.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 83b0dceb..0151808b 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -137,11 +137,11 @@ negotiated by the client and server at their discretion. There are certain situations when an identity server cannot be expected to compare hashed 3PID values; for example, when a server is connected to a backend provider such as LDAP, it is not efficient for the identity server to -pull all of the addresses and hash them upon lookup. For this case, can also -support receiving plain-text 3PID addresses from clients. To agree upon this, -the value `"none"` can be added to the `"algorithms"` array of `GET -/hash_details`. The client can then choose to send plain-text values by -setting the `"algorithm"` value in `POST /lookup` to `"none"`. +pull all of the addresses and hash them upon lookup. For this case, identity +servers can also support receiving plain-text 3PID addresses from clients. To +agree upon this, the value `"none"` can be added to the `"algorithms"` array +of `GET /hash_details`. The client can then choose to send plain-text values +by setting the `"algorithm"` value in `POST /lookup` to `"none"`. No hashing will be performed if the client and server decide on `"none"`, and 3PIDs will be sent in plain-text, similar to the v1 `/lookup` API. When this From 0ac70b268accded4d7f1c563eca7048ff95d1658 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 25 Jul 2019 18:55:57 +0100 Subject: [PATCH 0673/1250] Clarify peppering should not happen on none algo --- proposals/2134-identity-hash-lookup.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 0151808b..0eb996be 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -143,10 +143,10 @@ agree upon this, the value `"none"` can be added to the `"algorithms"` array of `GET /hash_details`. The client can then choose to send plain-text values by setting the `"algorithm"` value in `POST /lookup` to `"none"`. -No hashing will be performed if the client and server decide on `"none"`, and -3PIDs will be sent in plain-text, similar to the v1 `/lookup` API. When this -occurs, it is STRONGLY RECOMMENDED for the client to prompt the user before -continuing. +No hashing nor peppering will be performed if the client and server decide on +`"none"`, and 3PIDs will be sent in plain-text, similar to the v1 `/lookup` +API. When this occurs, it is STRONGLY RECOMMENDED for the client to prompt +the user before continuing. When performing a lookup, the pepper and hashing algorithm the client used must be part of the request body (even when using the `"none"` algorithm From 20c72a3649139889d2f86f872972e4a94182ea38 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Thu, 25 Jul 2019 18:56:17 +0100 Subject: [PATCH 0674/1250] Update proposals/2134-identity-hash-lookup.md Co-Authored-By: David Baker --- proposals/2134-identity-hash-lookup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 72bc4e53..1d797086 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -161,7 +161,7 @@ M_INVALID_PARAM`. If the pepper does not match the server's, the server should return a new error code, `400 M_INVALID_PEPPER`. A new error code is not defined for an invalid algorithm as that is considered a client bug. -The `M_INVALID_PEPPER` error response contain the correct `algorithm` and +The `M_INVALID_PEPPER` error response contains the correct `algorithm` and `lookup_pepper` fields. This is to prevent the client from needing to query `/hash_details` again, thus saving a request. `M_INVALID_PARAM` does not include these fields. An example response to an incorrect pepper would be: From 6119b9a50dea51c67790b7ac1916ad9d2f1df472 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 25 Jul 2019 19:03:43 +0100 Subject: [PATCH 0675/1250] *@hobnobbob.com is unlikely to be guessed --- proposals/2134-identity-hash-lookup.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 0eb996be..d6512c5a 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -34,9 +34,9 @@ The rainbow table attack is not perfect, because one does need to know email addresses and phone numbers to build it. While there are only so many possible phone numbers, and thus it is relatively inexpensive to generate the hash value for each one, the address space of email addresses is much, much -wider. If your email address is decently long and is not publicly -known to attackers, it is unlikely that it would be included in a rainbow -table. +wider. If your email address is not share a common mailserver, decently long +or is not publicly known to attackers, it is unlikely that it would be +included in a rainbow table. Thus the approach of hashing, while adding complexity to implementation and resource consumption of the client and identity server, does provide added @@ -306,8 +306,9 @@ for the `v1` endpoints, and are strongly encouraged to warn the user of this. Hashes are still reversible with a rainbow table, but the provided pepper, which can be rotated by identity servers at will, should help mitigate this. Phone numbers (with their relatively short possible address space of 12 -numbers), short email addresses, and addresses of both type that have been -leaked in database dumps are more susceptible to hash reversal. +numbers), short email addresses at popular domains, and addresses of both +type that have been leaked in database dumps are more susceptible to hash +reversal. Mediums and peppers are appended to the address as to prevent a common prefix for each plain-text string, which prevents attackers from pre-computing bits From ffbfde8a09cad00fa178e2dd1817b7cac1abf9e5 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Fri, 26 Jul 2019 11:40:20 +0100 Subject: [PATCH 0676/1250] Update proposals/2134-identity-hash-lookup.md Co-Authored-By: Hubert Chathi --- proposals/2134-identity-hash-lookup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 2abbc5a9..1872af69 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -34,7 +34,7 @@ The rainbow table attack is not perfect, because one does need to know email addresses and phone numbers to build it. While there are only so many possible phone numbers, and thus it is relatively inexpensive to generate the hash value for each one, the address space of email addresses is much, much -wider. If your email address is not share a common mailserver, decently long +wider. If your email address does not use a common mail server, is decently long or is not publicly known to attackers, it is unlikely that it would be included in a rainbow table. From 5580a2a1a9796d68eab2c71dbee3f67d31ebe1ad Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Fri, 26 Jul 2019 11:40:38 +0100 Subject: [PATCH 0677/1250] Update proposals/2134-identity-hash-lookup.md Co-Authored-By: Hubert Chathi --- proposals/2134-identity-hash-lookup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 1872af69..1df58df1 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -70,7 +70,7 @@ carl@example.com denny@example.com ``` -The client will hash each 3PID as a concatenation of the medium and address, +The client will hash each 3PID as a concatenation of the address and medium, separated by a space and a pepper appended to the end. Note that phone numbers should be formatted as defined by https://matrix.org/docs/spec/appendices#pstn-phone-numbers, before being From a17c74f592bafebb7d4d4c8b49318e37ec0d8c92 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 26 Jul 2019 12:00:53 +0100 Subject: [PATCH 0678/1250] switch medium and address around, space between address and pepper --- proposals/2134-identity-hash-lookup.md | 63 +++++++++++++------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 2abbc5a9..8e20d250 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -71,21 +71,21 @@ denny@example.com ``` The client will hash each 3PID as a concatenation of the medium and address, -separated by a space and a pepper appended to the end. Note that phone -numbers should be formatted as defined by +separated by a space and a pepper, also separated by a space, appended to the +end. Note that phone numbers should be formatted as defined by https://matrix.org/docs/spec/appendices#pstn-phone-numbers, before being hashed). Note that "pepper" in this proposal simply refers to a public, opaque string that is used to produce different hash results between identity servers. Its value is not secret. -First the client must append the medium to the address: +First the client must prepend the medium (plus a space) to the address: ``` -"alice@example.com" -> "alice@example.com email" -"bob@example.com" -> "bob@example.com email" -"carl@example.com" -> "carl@example.com email" -"+1 234 567 8910" -> "12345678910 msisdn" -"denny@example.com" -> "denny@example.com email" +"alice@example.com" -> "email alice@example.com" +"bob@example.com" -> "email bob@example.com" +"carl@example.com" -> "email carl@example.com" +"+1 234 567 8910" -> "msisdn 12345678910" +"denny@example.com" -> "email denny@example.com" ``` Hashes must be peppered in order to reduce both the information an identity @@ -110,14 +110,15 @@ being returned for other endpoints in the future. The contents of hashing is being performed or not. When no hashing is occuring, a pepper value of at least length 1 is still required. -If hashing, the client appends the pepper to the end of the 3PID string. +If hashing, the client appends the pepper to the end of the 3PID string, +after a space. ``` -"alice@example.com email" -> "alice@example.com emailmatrixrocks" -"bob@example.com email" -> "bob@example.com emailmatrixrocks" -"carl@example.com email" -> "carl@example.com emailmatrixrocks" -"12345678910 msdisn" -> "12345678910 msisdnmatrixrocks" -"denny@example.com email" -> "denny@example.com emailmatrixrocks" +"alice@example.com email" -> "email alice@example.com matrixrocks" +"bob@example.com email" -> "email bob@example.com matrixrocks" +"carl@example.com email" -> "email carl@example.com matrixrocks" +"12345678910 msdisn" -> "msisdn 12345678910 matrixrocks" +"denny@example.com email" -> "email denny@example.com matrixrocks" ``` Clients can cache the result of this endpoint, but should re-request it @@ -184,11 +185,11 @@ performed, the client sends each hash in an array. ``` NOTE: Hashes are not real values -"alice@example.com emailmatrixrocks" -> "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs" -"bob@example.com emailmatrixrocks" -> "r0-6x3rp9zIWS2suIque-wXTnlv9sc41fatbRMEOwQE" -"carl@example.com emailmatrixrocks" -> "ryr10d1K8fcFVxALb3egiSquqvFAxQEwegXtlHoQFBw" -"12345678910 msisdnmatrixrocks" -> "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens" -"denny@example.com emailmatrixrocks" -> "bxt8rtRaOzMkSk49zIKE_NfqTndHvGbWHchZskW3xmY" +"email alice@example.com matrixrocks" -> "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs" +"email bob@example.com matrixrocks" -> "r0-6x3rp9zIWS2suIque-wXTnlv9sc41fatbRMEOwQE" +"email carl@example.com matrixrocks" -> "ryr10d1K8fcFVxALb3egiSquqvFAxQEwegXtlHoQFBw" +"msisdn 12345678910 matrixrocks" -> "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens" +"email denny@example.com matrixrocks" -> "bxt8rtRaOzMkSk49zIKE_NfqTndHvGbWHchZskW3xmY" POST /_matrix/identity/v2/lookup @@ -238,11 +239,11 @@ lookup pepper, as no hashing will occur. Appending a space and the 3PID medium to each address is still necessary: ``` -"alice@example.com" -> "alice@example.com email" -"bob@example.com" -> "bob@example.com email" -"carl@example.com" -> "carl@example.com email" -"12345678910" -> "12345678910 msisdn" -"denny@example.com" -> "denny@example.com email" +"alice@example.com" -> "email alice@example.com" +"bob@example.com" -> "email bob@example.com" +"carl@example.com" -> "email carl@example.com" +"+1 234 567 8910" -> "msisdn 12345678910" +"denny@example.com" -> "email denny@example.com" ``` The client then sends these off to the identity server in a `POST` request to @@ -253,11 +254,11 @@ POST /_matrix/identity/v2/lookup { "addresses": [ - "alice@example.com email", - "bob@example.com email", - "carl@example.com email", - "12345678910 msisdn", - "denny@example.com email" + "email alice@example.com", + "email bob@example.com", + "email carl@example.com", + "msisdn 12345678910", + "email denny@example.com" ], "algorithm": "none", "pepper": "matrixrocks" @@ -276,8 +277,8 @@ it has that correspond to these 3PID addresses, and returns them: ``` { "mappings": { - "alice@example.com email": "@alice:example.com", - "12345678910 msisdn": "@fred:example.com" + "email alice@example.com": "@alice:example.com", + "msisdn 12345678910": "@fred:example.com" } } ``` From 6660768d85f2f8eac2ec9efa2613884e159d6576 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 26 Jul 2019 12:04:17 +0100 Subject: [PATCH 0679/1250] Don't repeat fast hash bit --- proposals/2134-identity-hash-lookup.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index de11221a..7b3edbc5 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -130,10 +130,7 @@ Clients and identity servers MUST support SHA-256 as defined by [RFC 4634](https://tools.ietf.org/html/rfc4634), identified by the value `"sha256"` in the `algorithms` array. SHA-256 was chosen as it is currently used throughout the Matrix spec, as well as its properties of being quick to -hash. While this reduces the resources necessary to generate a rainbow table -for attackers, a fast hash is necessary if particularly slow mobile clients -are going to be hashing thousands of contact details. Other algorithms are -negotiated by the client and server at their discretion. +hash. There are certain situations when an identity server cannot be expected to compare hashed 3PID values; for example, when a server is connected to a From 4d1f2ea4f40d3fedce718f42c4151fb970fe9aa4 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Fri, 26 Jul 2019 12:05:41 +0100 Subject: [PATCH 0680/1250] Apply suggestions from code review Co-Authored-By: Hubert Chathi --- proposals/2134-identity-hash-lookup.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index de11221a..13cea82e 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -124,7 +124,7 @@ after a space. Clients can cache the result of this endpoint, but should re-request it during an error on `/lookup`, to handle identity servers which may rotate their pepper values frequently. Clients MUST choose one of the given -`algorithms` values to encrypt the 3PID during lookup. +`algorithms` values to hash the 3PID during lookup. Clients and identity servers MUST support SHA-256 as defined by [RFC 4634](https://tools.ietf.org/html/rfc4634), identified by the value @@ -160,7 +160,7 @@ assume to mean that no contacts are registered on that identity server. If the algorithm is not supported by the server, the server should return a `400 M_INVALID_PARAM`. If the pepper does not match the server's, the server should return a new error code, `400 M_INVALID_PEPPER`. A new error code is not -defined for an invalid algorithm as that is considered a client bug. +defined for an unsupported algorithm as that is considered a client bug. The `M_INVALID_PEPPER` error response contains the correct `algorithm` and `lookup_pepper` fields. This is to prevent the client from needing to query @@ -308,7 +308,7 @@ Hashes are still reversible with a rainbow table, but the provided pepper, which can be rotated by identity servers at will, should help mitigate this. Phone numbers (with their relatively short possible address space of 12 numbers), short email addresses at popular domains, and addresses of both -type that have been leaked in database dumps are more susceptible to hash +types that have been leaked in database dumps are more susceptible to hash reversal. Mediums and peppers are appended to the address as to prevent a common prefix From 4c22eb86b50d1fb6bd28d98d9c29037aba2b2cac Mon Sep 17 00:00:00 2001 From: "Olivier Wilkinson (reivilibre)" Date: Mon, 29 Jul 2019 16:30:25 +0100 Subject: [PATCH 0681/1250] MSC for Search Filtering in Federation /publicRooms Signed-off-by: Olivier Wilkinson (reivilibre) --- ...search_filter_in_federation_publicrooms.md | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 proposals/2197-search_filter_in_federation_publicrooms.md diff --git a/proposals/2197-search_filter_in_federation_publicrooms.md b/proposals/2197-search_filter_in_federation_publicrooms.md new file mode 100644 index 00000000..60d35333 --- /dev/null +++ b/proposals/2197-search_filter_in_federation_publicrooms.md @@ -0,0 +1,108 @@ +# MSC2197 – Search Filtering in Public Room Directory over Federation + +This MSC proposes introducing the `POST` method to the `/publicRooms` Federation API endpoint, +including a `filter` argument which allows server-side filtering of rooms. + +We are motivated by the opportunity to make searching the public Room Directory more efficient over +Federation. + +## Motivation + +Although the Client-Server API includes the filtering capability in `/publicRooms`, the Federation API +currently does not. + +This leads to a situation that is wasteful of effort and network traffic for both homeservers; searching +a remote server involves first downloading its entire room list and then filtering afterwards. + +## Proposal + +Having a filtered `/publicRooms` API endpoint means that irrelevant or uninteresting rooms can be +excluded from a room directory query response. In turn, this means that these room directory query +responses can be generated more quickly and then, due to their smaller size, transmitted over the network more quickly, owing to their +smaller size. + +These benefits have been exploited in the Client-Server API, which implements search filtering +using the `filter` JSON body parameter in the `POST` method on the `/publicRooms` endpoint. + +It should be noted that the Client-Server and Federation APIs both currently possess `/publicRooms` +endpoints which, whilst similar, are not equivalent. + +Ignoring the `server` parameter in the Client-Server API, the following specific differences are +noticed: + +* the Federation API endpoint only accepts the `GET` method whereas the Client-Server API accepts + the `POST` method as well. +* the Federation API accepts `third_party_instance_id` and `include_all_networks` parameters through + the `GET` method, whereas the Client-Server API only features these in the `POST` method. + +This MSC proposes to introduce support for the `POST` method in the Federation API's `/publicRooms` +endpoint, with all but one of the parameters from that of the Client-Server API. The copied parameters +shall have the same semantics as they do in the Client-Server API. + +In the interest of clarity, the proposed parameter set is listed below, along with a repetition of the +definitions of used substructures. The response format has been omitted as it is the same as that of +the current Client-Server and Federation APIs, which do not differ in this respect. + +### `POST /_matrix/federation/v1/publicRooms` + +#### Query Parameters + +There are no query parameters. Notably, we intentionally do not inherit the `server` query parameter +from the Client-Server API. + +#### JSON Body Parameters + +* `limit` (`integer`): Limit the number of search results returned. +* `since` (`string`): A pagination token from a previous request, allowing clients to get the next (or previous) batch of rooms. The direction of pagination is specified solely by which token is supplied, rather than via an explicit flag. +* `filter` (`Filter`): Filter to apply to the results. +* `include_all_networks` (`boolean`): Whether or not to include all known networks/protocols from application services on the homeserver. Defaults to false. +* `third_party_instance_id` (`boolean`): The specific third party network/protocol to request from the homeserver. Can only be used if `include_all_networks` is false. + +### `Filter` Parameters + +* `generic_search_term` (`string`): A string to search for in the room metadata, e.g. name, topic, canonical alias etc. (Optional). + +## Tradeoffs + +An alternative approach might be for implementations to carry on as they are but also +cache (and potentially index) remote homeservers' room directories. This would not require +a spec change. + +However, this would be unsatisfactory because it would lead to outdated room directory results and/or +caches that provide no benefit (as room directory searches are generally infrequent enough that a cache +would be outdated before being reused, on small – if not most – homeservers). + +## Potential issues + +### Backwards Compatibility + +After this proposal is implemented, outdated homeservers will still exist which do not support the room +filtering functionality specified in this MSC. In this case, homeservers will have to fall-back to downloading +the entire room directory and performing the filtering themselves, as currently happens. This is not considered +a problem since it will not lead to a situation that is any worse than the current one, and it is expected that +large homeservers – which cause the most work with the current search implementations – would be quick to upgrade +to support this feature once it is available. + +In addition, as the `POST` method was not previously accepted on the `/publicRooms` endpoint over federation, +then it is not a difficult task to use a `405 Method Not Allowed` HTTP response as a signal that fallback is required. + +## Security considerations + +There are no known security considerations. + +## Privacy considerations + +At current, remote homeservers do not learn about what a user has searched for. + +However, under this proposal, in the context of using the Federation API to forward on queries from the Client-Server +API, a client's homeserver would end up sharing the client's search terms with a remote homeserver, which may not be +operated by the same party or even trusted. For example, users' search terms could be logged. + +It is uncertain, to the author of this MSC, what implications this has with regards to legislation, such as GDPR. + +## Conclusion + +By allowing homeservers to pass on search filters, we enable remote homeservers' room directories to be +efficiently searched, because, realistically speaking, only the remote homeserver is in a position to be +able to perform search efficiently, by taking advantage of indexing and other such optimisations. + From 62f7a4f82cb26bfa21e896f2342356bc90e7e36d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 29 Jul 2019 21:06:17 -0600 Subject: [PATCH 0682/1250] Fix/add changelogs The push spec one was missed in https://github.com/matrix-org/matrix-doc/pull/2151 --- changelogs/client_server/newsfragments/2129.clarification | 2 +- changelogs/push_gateway/newsfragments/2151.clarification | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelogs/push_gateway/newsfragments/2151.clarification diff --git a/changelogs/client_server/newsfragments/2129.clarification b/changelogs/client_server/newsfragments/2129.clarification index 82ed4fce..9d67deac 100644 --- a/changelogs/client_server/newsfragments/2129.clarification +++ b/changelogs/client_server/newsfragments/2129.clarification @@ -1 +1 @@ -Remove "required" designation from the ``url`` field of certain ``m`.room.message` msgtypes. +Remove "required" designation from the ``url`` field of certain ``m.room.message`` msgtypes. diff --git a/changelogs/push_gateway/newsfragments/2151.clarification b/changelogs/push_gateway/newsfragments/2151.clarification new file mode 100644 index 00000000..8908eed2 --- /dev/null +++ b/changelogs/push_gateway/newsfragments/2151.clarification @@ -0,0 +1 @@ +Fix ``event_id`` field in push request body. From f1f293678bcf1eaaca05a6748bf85639796e4f2b Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 30 Jul 2019 08:00:48 +0100 Subject: [PATCH 0683/1250] Apply suggestions from code review Co-Authored-By: Travis Ralston Co-Authored-By: Kitsune Ral --- proposals/2176-update-redaction-rules.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/proposals/2176-update-redaction-rules.md b/proposals/2176-update-redaction-rules.md index dea3015f..75bfc971 100644 --- a/proposals/2176-update-redaction-rules.md +++ b/proposals/2176-update-redaction-rules.md @@ -12,7 +12,7 @@ redaction algorithm also change the way that [event hashes](https://matrix.org/docs/spec/server_server/r0.1.2#calculating-the-reference-hash-for-an-event) (and hence event IDs) are calculated. -The following *event* keys should be *removed* from the list of those to be +The following *event* keys are to be *removed* from the list of those to be preserved by a redaction: * `membership` @@ -21,14 +21,14 @@ preserved by a redaction: (Note this refers to the *event-level* `membership` property, rather than the similarly-named sub-property under the `content` key.) -Rationale: neither of the above properties have defined meanings in the Matrix +Rationale: neither of the above properties have defined meanings any more in the Matrix protocol, so there is no reason for them to be special-cased in this way. -The following should be added to the list of subkeys of the content property -which should be preserved: +The following are to be added to the list of subkeys of the content property +which are preserved: - * `m.room.create` should preserve *all* content. Rationale: the values in a - `create` event are deliberately intented to last the lifetime of the room, + * `m.room.create` preserves *all* content. Rationale: the values in a + `create` event are deliberately intended to last the lifetime of the room, and if values are redacted, there is no way to add correct settings afterwards. It therefore seems non-sensical to allow redaction of a `create` event. @@ -63,8 +63,8 @@ proposed for a redaction: `m.room.encryption` have no effect, and servers do not use the value of the property to authenticate events. - The effect of redacting an `m.room.redaction` event is much the same as that - of sending a new `m.room.redaction` event with no `algorithm` key. It's + The effect of redacting an `m.room.encryption` event is much the same as that + of sending a new `m.room.encryption` event with no `algorithm` key. It's unlikely to be what was intended, but adding rules to the redaction algorithm will not help this. From 40e6f82cbdf736841ab45d4e7e7fd9da1159c76e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 30 Jul 2019 12:54:50 -0600 Subject: [PATCH 0684/1250] Push r0.1.1 changelog --- changelogs/push_gateway.rst | 9 +++++++++ changelogs/push_gateway/newsfragments/2151.clarification | 1 - 2 files changed, 9 insertions(+), 1 deletion(-) delete mode 100644 changelogs/push_gateway/newsfragments/2151.clarification diff --git a/changelogs/push_gateway.rst b/changelogs/push_gateway.rst index 33a7683c..2afb2a9e 100644 --- a/changelogs/push_gateway.rst +++ b/changelogs/push_gateway.rst @@ -1,3 +1,12 @@ +r0.1.1 +====== + +Spec Clarifications +------------------- + +- Fix ``event_id`` field in push request body. (`#2151 `_) + + r0.1.0 ====== diff --git a/changelogs/push_gateway/newsfragments/2151.clarification b/changelogs/push_gateway/newsfragments/2151.clarification deleted file mode 100644 index 8908eed2..00000000 --- a/changelogs/push_gateway/newsfragments/2151.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix ``event_id`` field in push request body. From 0b49112399772ffaaff827a2c71828ff12e77551 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 30 Jul 2019 13:02:04 -0600 Subject: [PATCH 0685/1250] Appservices r0.1.2 changelog --- changelogs/application_service.rst | 9 +++++++++ .../application_service/newsfragments/2160.clarification | 1 - 2 files changed, 9 insertions(+), 1 deletion(-) delete mode 100644 changelogs/application_service/newsfragments/2160.clarification diff --git a/changelogs/application_service.rst b/changelogs/application_service.rst index bbc461b2..51a97637 100644 --- a/changelogs/application_service.rst +++ b/changelogs/application_service.rst @@ -1,3 +1,12 @@ +r0.1.2 +====== + +Spec Clarifications +------------------- + +- Clearer wording for the legacy routes section. (`#2160 `_) + + r0.1.1 ====== diff --git a/changelogs/application_service/newsfragments/2160.clarification b/changelogs/application_service/newsfragments/2160.clarification deleted file mode 100644 index 3e9c1c02..00000000 --- a/changelogs/application_service/newsfragments/2160.clarification +++ /dev/null @@ -1 +0,0 @@ -Clearer wording for the legacy routes section. From 26c2ce8a9242bd498646db16c1cc18bec6dc91f4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 30 Jul 2019 13:05:32 -0600 Subject: [PATCH 0686/1250] Server-server r0.1.3 changelog --- changelogs/server_server.rst | 10 ++++++++++ .../server_server/newsfragments/2157.clarification | 1 - .../server_server/newsfragments/2159.clarification | 1 - 3 files changed, 10 insertions(+), 2 deletions(-) delete mode 100644 changelogs/server_server/newsfragments/2157.clarification delete mode 100644 changelogs/server_server/newsfragments/2159.clarification diff --git a/changelogs/server_server.rst b/changelogs/server_server.rst index 11f99a5f..22da543c 100644 --- a/changelogs/server_server.rst +++ b/changelogs/server_server.rst @@ -1,3 +1,13 @@ +r0.1.3 +====== + +Spec Clarifications +------------------- + +- Clarify the encryption algorithms supported by the device of the user keys query example. (`#2157 `_) +- Clarify the purpose of reference hashes. (`#2159 `_) + + r0.1.2 ====== diff --git a/changelogs/server_server/newsfragments/2157.clarification b/changelogs/server_server/newsfragments/2157.clarification deleted file mode 100644 index 0acf7495..00000000 --- a/changelogs/server_server/newsfragments/2157.clarification +++ /dev/null @@ -1 +0,0 @@ - Clarify the encryption algorithms supported by the device of the user keys query example. diff --git a/changelogs/server_server/newsfragments/2159.clarification b/changelogs/server_server/newsfragments/2159.clarification deleted file mode 100644 index d7b79ccf..00000000 --- a/changelogs/server_server/newsfragments/2159.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify the purpose of reference hashes. From 57de107ea914924fb02fc98b607b214b7a1bc3b6 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 31 Jul 2019 11:07:22 +0100 Subject: [PATCH 0687/1250] Move medium back behind the address --- proposals/2134-identity-hash-lookup.md | 56 +++++++++++++------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 5f500b6c..06a8486a 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -78,14 +78,14 @@ hashed). Note that "pepper" in this proposal simply refers to a public, opaque string that is used to produce different hash results between identity servers. Its value is not secret. -First the client must prepend the medium (plus a space) to the address: +First the client must append the medium (plus a space) to the address: ``` -"alice@example.com" -> "email alice@example.com" -"bob@example.com" -> "email bob@example.com" -"carl@example.com" -> "email carl@example.com" -"+1 234 567 8910" -> "msisdn 12345678910" -"denny@example.com" -> "email denny@example.com" +"alice@example.com" -> "alice@example.com email" +"bob@example.com" -> "bob@example.com email" +"carl@example.com" -> "carl@example.com email" +"+1 234 567 8910" -> "12345678910 msisdn" +"denny@example.com" -> "denny@example.com email" ``` Hashes must be peppered in order to reduce both the information an identity @@ -114,11 +114,11 @@ If hashing, the client appends the pepper to the end of the 3PID string, after a space. ``` -"alice@example.com email" -> "email alice@example.com matrixrocks" -"bob@example.com email" -> "email bob@example.com matrixrocks" -"carl@example.com email" -> "email carl@example.com matrixrocks" -"12345678910 msdisn" -> "msisdn 12345678910 matrixrocks" -"denny@example.com email" -> "email denny@example.com matrixrocks" +"alice@example.com email" -> "alice@example.com email matrixrocks" +"bob@example.com email" -> "bob@example.com email matrixrocks" +"carl@example.com email" -> "carl@example.com email matrixrocks" +"12345678910 msdisn" -> "12345678910 msisdn matrixrocks" +"denny@example.com email" -> "denny@example.com email matrixrocks" ``` Clients can cache the result of this endpoint, but should re-request it @@ -182,11 +182,11 @@ performed, the client sends each hash in an array. ``` NOTE: Hashes are not real values -"email alice@example.com matrixrocks" -> "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs" -"email bob@example.com matrixrocks" -> "r0-6x3rp9zIWS2suIque-wXTnlv9sc41fatbRMEOwQE" -"email carl@example.com matrixrocks" -> "ryr10d1K8fcFVxALb3egiSquqvFAxQEwegXtlHoQFBw" -"msisdn 12345678910 matrixrocks" -> "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens" -"email denny@example.com matrixrocks" -> "bxt8rtRaOzMkSk49zIKE_NfqTndHvGbWHchZskW3xmY" +"alice@example.com email matrixrocks" -> "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs" +"bob@example.com email matrixrocks" -> "r0-6x3rp9zIWS2suIque-wXTnlv9sc41fatbRMEOwQE" +"carl@example.com email matrixrocks" -> "ryr10d1K8fcFVxALb3egiSquqvFAxQEwegXtlHoQFBw" +"12345678910 msisdn matrixrocks" -> "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens" +"denny@example.com email matrixrocks" -> "bxt8rtRaOzMkSk49zIKE_NfqTndHvGbWHchZskW3xmY" POST /_matrix/identity/v2/lookup @@ -236,11 +236,11 @@ lookup pepper, as no hashing will occur. Appending a space and the 3PID medium to each address is still necessary: ``` -"alice@example.com" -> "email alice@example.com" -"bob@example.com" -> "email bob@example.com" -"carl@example.com" -> "email carl@example.com" -"+1 234 567 8910" -> "msisdn 12345678910" -"denny@example.com" -> "email denny@example.com" +"alice@example.com" -> "alice@example.com email" +"bob@example.com" -> "bob@example.com email" +"carl@example.com" -> "carl@example.com email" +"+1 234 567 8910" -> "12345678910 msisdn" +"denny@example.com" -> "denny@example.com email" ``` The client then sends these off to the identity server in a `POST` request to @@ -251,11 +251,11 @@ POST /_matrix/identity/v2/lookup { "addresses": [ - "email alice@example.com", - "email bob@example.com", - "email carl@example.com", - "msisdn 12345678910", - "email denny@example.com" + "alice@example.com email", + "bob@example.com email", + "carl@example.com email", + "12345678910 msisdn", + "denny@example.com email" ], "algorithm": "none", "pepper": "matrixrocks" @@ -274,8 +274,8 @@ it has that correspond to these 3PID addresses, and returns them: ``` { "mappings": { - "email alice@example.com": "@alice:example.com", - "msisdn 12345678910": "@fred:example.com" + "alice@example.com email": "@alice:example.com", + "12345678910 msisdn": "@fred:example.com" } } ``` From 9913f5bc298328f0daff702bdbd9ec892fe8c582 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 31 Jul 2019 11:16:58 +0100 Subject: [PATCH 0688/1250] Slightly clarify pepper value --- proposals/2134-identity-hash-lookup.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 06a8486a..28c78918 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -107,8 +107,8 @@ GET /_matrix/identity/v2/hash_details The name `lookup_pepper` was chosen in order to account for pepper values being returned for other endpoints in the future. The contents of `lookup_pepper` MUST match the regular expression `[a-zA-Z0-9]+`, whether -hashing is being performed or not. When no hashing is occuring, a pepper -value of at least length 1 is still required. +hashing is being performed or not. When no hashing is occuring, a valid +pepper value of at least length 1 is still required. If hashing, the client appends the pepper to the end of the 3PID string, after a space. From 33d22c3320892c57e1e83724a67a4d6b716edf8f Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 31 Jul 2019 11:47:03 +0100 Subject: [PATCH 0689/1250] hashes are not stream ciphers --- proposals/2134-identity-hash-lookup.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 28c78918..e156d158 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -309,8 +309,8 @@ types that have been leaked in database dumps are more susceptible to hash reversal. Mediums and peppers are appended to the address as to prevent a common prefix -for each plain-text string, which prevents attackers from pre-computing bits -of a stream cipher. +for each plain-text string, which prevents attackers from pre-computing the +internal state of the hash function ## Other considered solutions From 0c7c48bd12222fef69e30986899be2ea3f515c8e Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Wed, 31 Jul 2019 13:13:38 +0100 Subject: [PATCH 0690/1250] MSC2175: Remove the `creator` field from `m.room.create` events (#2175) Fixes #1193 --- proposals/2175-remove-creator-field.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 proposals/2175-remove-creator-field.md diff --git a/proposals/2175-remove-creator-field.md b/proposals/2175-remove-creator-field.md new file mode 100644 index 00000000..6a9d8f3c --- /dev/null +++ b/proposals/2175-remove-creator-field.md @@ -0,0 +1,17 @@ +# MSC2175: Remove the `creator` field from `m.room.create` events + +[`m.room.create`](https://matrix.org/docs/spec/client_server/r0.5.0#m-room-create) +events have a mandatory `creator` property giving the ID of the user who +created the room. This field is redundant as it is always identical to the +`sender` of the create event. + +This MSC proposes that, in a future room version, this field should be removed +and that the `sender` field be used instead. + +Note that `creator` is mentioned in the [auth +rules](https://matrix.org/docs/spec/rooms/v1#authorization-rules). It can +safely be removed. + +`creator` is also mentioned as a key to be preserved during [Event +redaction](https://matrix.org/docs/spec/client_server/r0.5.0#redactions). It +should be removed from that list. From f989263872e7ccd1cc3463bf7683727c84474b8b Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Wed, 31 Jul 2019 13:14:02 +0100 Subject: [PATCH 0691/1250] MSC2181: Add an Error Code for Signaling a Deactivated User (#2181) --- proposals/2181-user-deactivated-errcode.md | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 proposals/2181-user-deactivated-errcode.md diff --git a/proposals/2181-user-deactivated-errcode.md b/proposals/2181-user-deactivated-errcode.md new file mode 100644 index 00000000..8d2e1893 --- /dev/null +++ b/proposals/2181-user-deactivated-errcode.md @@ -0,0 +1,50 @@ +# Add an Error Code for Signaling a Deactivated User + +Currently, when a user attempts to log in, they will receive an `M_FORBIDDEN` +error code if their password is incorrect. However, if the user's account is +deactivated, they will also receive an `M_FORBIDDEN`, leaving clients in a +state where they are unable to inform the user that the reason they cannot +log in is that their account has been deactivated. This leads to confusion +and password resetting which ultimately results in frustration. + +## Proposal + +This proposal asks to create a new error code, `M_USER_DEACTIVATED`, that may +be returned whenever an action is attempted that requires an activited user, +but the authenticating user is deactivated. The HTTP code to return alongside +is `403`. + +An example of this could be returning `M_USER_DEACTIVATED` on `/login`, when +an identifier of a deactivated user is sent to the homeserver. Whether the +password has to be correct depends on whether the Homeserver implementation +removes login information on deactivation. This is an implementation detail. + +It should be noted that this proposal is not requiring implementations to +return `M_USER_DEACTIVATED` on any endpoints when a request from a +deactivated user appears. Instead it is simply defining the new error code, +recommends that it should be used in situations as described above, and that +the client should understand the meaning of it when it is received. + +## Tradeoffs + +The alternative is to continue returning an `M_FORBIDDEN`, but send back a +different error message. This is undesirable as clients are supposed to treat +the message as an opaque string, and should not be performing any +pattern-matching on it. + +## Potential issues + +None + +## Security considerations + +While the existence of a user was already public knowledge (one can check if +the User ID is available through +[/_matrix/client/r0/register/available](https://matrix.org/docs/spec/client_server/r0.5.0#get-matrix-client-r0-register-available), +this proposal would allow any user to be able to detect if a registered +account has been deactivated, depending on the homeserver's implementation. + +## Conclusion + +Adding `M_USER_DEACTIVATED` would better inform clients about the state of a +user's account, and lead to less confusion when they cannot log in. From af60889eeefaf4b249761009a5bf97a81d9677cf Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Wed, 31 Jul 2019 15:14:38 +0100 Subject: [PATCH 0692/1250] Clarify that /rooms/{roomId}/event/{eventId}'s 404 should be M_NOT_FOUND (#2204) No error code is specified for this endpoint's 404. State that it should be an `M_NOT_FOUND`. --- api/client-server/rooms.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/api/client-server/rooms.yaml b/api/client-server/rooms.yaml index 8af433b2..566e695a 100644 --- a/api/client-server/rooms.yaml +++ b/api/client-server/rooms.yaml @@ -62,6 +62,13 @@ paths: - "$ref": "definitions/event-schemas/schema/core-event-schema/event.yaml" 404: description: The event was not found or you do not have permission to read this event. + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "Event not found." + } + schema: + "$ref": "definitions/errors/error.yaml" tags: - Room participation "/rooms/{roomId}/state/{eventType}/{stateKey}": From 28596a6c7463aee92d480126a5e84aa99a4c51ac Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 31 Jul 2019 15:21:40 +0100 Subject: [PATCH 0693/1250] Add missing changelog for #2204. --- changelogs/client_server/newsfragments/2204.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2204.clarification diff --git a/changelogs/client_server/newsfragments/2204.clarification b/changelogs/client_server/newsfragments/2204.clarification new file mode 100644 index 00000000..7a66b08b --- /dev/null +++ b/changelogs/client_server/newsfragments/2204.clarification @@ -0,0 +1 @@ +Clarify that ``/rooms/:roomId/event/:eventId`` returns a Matrix error. From 395d40314bcbaf39646c03bdada1e7a59efe3ea4 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 31 Jul 2019 16:20:39 -0400 Subject: [PATCH 0694/1250] fix typos and make valid JSON --- proposals/1946-secure_server-side_storage.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index dff7a5c7..7fb426ce 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -21,7 +21,7 @@ prevent homeserver administrators from being able to read it. A user can have multiple keys used for encrypting data. This allows the user to selectively decrypt data on clients. For example, the user could have one key that can decrypt everything, and another key that can only decrypt their user-signing -key for cross-signing. Each key has an ID, and a discription of the key is +key for cross-signing. Each key has an ID, and a description of the key is stored in the user's `account_data` using the `type` `m.secret_storage.key.[key ID]`. The contents of the account data for the key will include an `algorithm` property, which indicates the encryption algorithm used, as well as a `name` @@ -35,12 +35,12 @@ decryption keys for key backups could be stored under the type `m.megolm_backup.v1.recovery_key`, or the self-signing key for cross-signing could be stored under the type `m.cross_signing.self_signing`. -Data will be stored using using the following format: +Data will be stored using the following format: ```json { "encrypted": { - [key ID]: { + "key_id": { "ciphertext": "base64+encoded+encrypted+data", "mac": "base64+encoded+mac" } From d47e13c6d94392583e3d17b18f72ef71250754c5 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 31 Jul 2019 16:20:55 -0400 Subject: [PATCH 0695/1250] this FIXME will be addressed in the key backup MSC --- proposals/1946-secure_server-side_storage.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index 7fb426ce..c0c828f2 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -54,13 +54,6 @@ expected that most encryption schemes would have `ciphertext` and `mac` properties, where the `ciphertext` property is the unpadded base64-encoded ciphertext, and the `mac` is used to ensure the integrity of the data. -FIXME: the key format was chosen so that existing backups could be easily -migrated by just copying the configuration from the backup config to the key -description. However, we need a way of signalling that the key for the backup -is the same as the key for decrypting the other bits. Maybe a special flag in -the account data? Or special case backups somehow, say, have clients inspect -the backup's `auth_data` to see of the key config is the same? - #### Encryption algorithms ##### `m.secret_storage.v1.curve25519-aes-sha2` From bd9efcdf53b9fb8ecf55db6f36db951080d8c715 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 31 Jul 2019 16:22:24 -0400 Subject: [PATCH 0696/1250] add some information and an example --- proposals/1946-secure_server-side_storage.md | 36 ++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index c0c828f2..2f269f23 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -29,6 +29,11 @@ property, which is a human-readable name. The contents will be signed as signed JSON using the user's master cross-signing key. Other properties depend on the encryption algorithm, and are described below. +If a key has the `name` property set to `m.default`, then this key is marked as +the default key for the account. The default key is the one that all secrets +will be encrypted with, and the clients will try to use to decrypt data with, +unless the user specifies otherwise. Only one key can be marked as the default. + Encrypted data can be stored using the `account_data` API. The `type` for the `account_data` is defined by the feature that uses the data. For example, decryption keys for key backups could be stored under the type @@ -80,7 +85,29 @@ The data is encrypted and MACed as follows: (The key HKDF, AES, and HMAC steps are the same as what are used for encryption in olm and megolm.) -FIXME: add an example of `m.secret_storage.key.*`, and of encrypted data. +For example, a key using this algorithm could look like: + +```json +{ + "name": "m.default", + "algorithm": "m.secret_storage.v1.curve25519-aes-sha2", + "pubkey": "base64+public+key" +} +``` + +and data encrypted using this algorithm could look like this: + +```json +{ + "encrypted": { + "key_id": { + "ciphertext": "base64+encoded+encrypted+data", + "ephemeral": "base64+ephemeral+key", + "mac": "base64+encoded+mac" + } + } +} +``` ###### Keys @@ -181,7 +208,12 @@ data to indicate whether it should come down the `/sync` or not. ## Security considerations -Yes. +By storing information encrypted on the server, this allows the server operator +to read the information if they manage to get hold of the decryption keys. +In particular, if the key is based on a passphrase and the passphrase can be +guessed, then the secrets could be compromised. In order to help protect the +secrets, clients should provide feedback to the user when their chosen +passphrase is considered weak. ## Conclusion From 825757ffd8c9f38f588b4d6dadf0a826675ff601 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 31 Jul 2019 16:37:54 -0400 Subject: [PATCH 0697/1250] add information about verifying backup by entering key --- proposals/1219-storing-megolm-keys-serverside.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 09ded1cd..e1ff0740 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -493,7 +493,10 @@ key backup. This proposal does not attempt to protect against that. An attacker who gains access to a user's account can create a new backup version using a key that they control. For this reason, clients SHOULD confirm with users before sending keys to a new backup version or verify that it was -created by a trusted device by checking the signature. +created by a trusted device by checking the signature. One way to confirm the +new backup version if the signature cannot be checked is by asking the user to +enter the recovery key, and confirming that the backup's public key matches +what is expected. Other Issues ------------ From 80adbaff4c69ae342f16c94894e0b46006a77597 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 31 Jul 2019 16:38:20 -0400 Subject: [PATCH 0698/1250] switch to MSC1946 for storing recovery key --- .../1219-storing-megolm-keys-serverside.md | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index e1ff0740..7e074a0d 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -102,8 +102,8 @@ settings. ### Recovery key The recovery key can be saved by the user directly, stored encrypted on the -server (as proposed in -[MSC1687](https://github.com/matrix-org/matrix-doc/issues/1687)), or both. If +server (using the method proposed in +[MSC1946](https://github.com/matrix-org/matrix-doc/issues/1946)), or both. If the key is saved directly by the user, then the code is constructed as follows: 1. The 256-bit curve25519 private key is prepended by the bytes `0x8B` and @@ -124,6 +124,29 @@ results in 0, and ensure that the total length of the decoded string is 35 bytes. Clients must then remove the first two bytes and the last byte, and use the resulting string as the private key to decrypt backups. +If MSC1946 is used to store the key on the server, it must be stored using the +`account_data` `type` `m.megolm_backup.v1`. + +As a special case, if the recovery key is the same as the curve25519 key used +for storing the key, then the contents of the `m.megolm_backup.v1` +`account_data` for that key will be the an object with a `passthrough` property +whose value is `true`. For example, if `m.megolm_backup.v1` is set to: + +```json +{ + "encrypted": { + "key_id": { + "passthrough": true + } + } +} +``` + +means that the recovery key for the backup is the same as the private key for +the key with ID `key_id`. (This is mostly intended to provide a migration path +for for backups that were created using an earlier draft that stored the +recovery information in the `auth_data`.) + ### API #### Backup versions From 36e43ee32620e6936cfe7d758f6f94390e2929b6 Mon Sep 17 00:00:00 2001 From: "Olivier Wilkinson (reivilibre)" Date: Thu, 1 Aug 2019 09:28:30 +0100 Subject: [PATCH 0699/1250] Rewrap lines in MSC2917 to 80 chars wide Signed-off-by: Olivier Wilkinson (reivilibre) --- ...search_filter_in_federation_publicrooms.md | 133 ++++++++++-------- 1 file changed, 78 insertions(+), 55 deletions(-) diff --git a/proposals/2197-search_filter_in_federation_publicrooms.md b/proposals/2197-search_filter_in_federation_publicrooms.md index 60d35333..04413c86 100644 --- a/proposals/2197-search_filter_in_federation_publicrooms.md +++ b/proposals/2197-search_filter_in_federation_publicrooms.md @@ -1,90 +1,109 @@ # MSC2197 – Search Filtering in Public Room Directory over Federation -This MSC proposes introducing the `POST` method to the `/publicRooms` Federation API endpoint, -including a `filter` argument which allows server-side filtering of rooms. +This MSC proposes introducing the `POST` method to the `/publicRooms` Federation +API endpoint, including a `filter` argument which allows server-side filtering +of rooms. -We are motivated by the opportunity to make searching the public Room Directory more efficient over -Federation. +We are motivated by the opportunity to make searching the public Room Directory +more efficient over Federation. ## Motivation -Although the Client-Server API includes the filtering capability in `/publicRooms`, the Federation API -currently does not. +Although the Client-Server API includes the filtering capability in +`/publicRooms`, the Federation API currently does not. -This leads to a situation that is wasteful of effort and network traffic for both homeservers; searching -a remote server involves first downloading its entire room list and then filtering afterwards. +This leads to a situation that is wasteful of effort and network traffic for +both homeservers; searching a remote server involves first downloading its +entire room list and then filtering afterwards. ## Proposal -Having a filtered `/publicRooms` API endpoint means that irrelevant or uninteresting rooms can be -excluded from a room directory query response. In turn, this means that these room directory query -responses can be generated more quickly and then, due to their smaller size, transmitted over the network more quickly, owing to their -smaller size. +Having a filtered `/publicRooms` API endpoint means that irrelevant or +uninteresting rooms can be excluded from a room directory query response. +In turn, this means that these room directory query responses can be generated +more quickly and then, due to their smaller size, transmitted over the network +more quickly, owing to their smaller size. -These benefits have been exploited in the Client-Server API, which implements search filtering -using the `filter` JSON body parameter in the `POST` method on the `/publicRooms` endpoint. +These benefits have been exploited in the Client-Server API, which implements +search filtering using the `filter` JSON body parameter in the `POST` method on +the `/publicRooms` endpoint. -It should be noted that the Client-Server and Federation APIs both currently possess `/publicRooms` -endpoints which, whilst similar, are not equivalent. +It should be noted that the Client-Server and Federation APIs both currently +possess `/publicRooms` endpoints which, whilst similar, are not equivalent. -Ignoring the `server` parameter in the Client-Server API, the following specific differences are -noticed: +Ignoring the `server` parameter in the Client-Server API, the following specific +differences are noticed: -* the Federation API endpoint only accepts the `GET` method whereas the Client-Server API accepts - the `POST` method as well. -* the Federation API accepts `third_party_instance_id` and `include_all_networks` parameters through - the `GET` method, whereas the Client-Server API only features these in the `POST` method. +* the Federation API endpoint only accepts the `GET` method whereas the + Client-Server API accepts the `POST` method as well. +* the Federation API accepts `third_party_instance_id` and + `include_all_networks` parameters through the `GET` method, whereas the + Client-Server API only features these in the `POST` method. -This MSC proposes to introduce support for the `POST` method in the Federation API's `/publicRooms` -endpoint, with all but one of the parameters from that of the Client-Server API. The copied parameters -shall have the same semantics as they do in the Client-Server API. +This MSC proposes to introduce support for the `POST` method in the Federation +API's `/publicRooms` endpoint, with all but one of the parameters from that of +the Client-Server API. The copied parameters shall have the same semantics as +they do in the Client-Server API. -In the interest of clarity, the proposed parameter set is listed below, along with a repetition of the -definitions of used substructures. The response format has been omitted as it is the same as that of -the current Client-Server and Federation APIs, which do not differ in this respect. +In the interest of clarity, the proposed parameter set is listed below, along +with a repetition of the definitions of used substructures. The response format +has been omitted as it is the same as that of the current Client-Server and +Federation APIs, which do not differ in this respect. ### `POST /_matrix/federation/v1/publicRooms` #### Query Parameters -There are no query parameters. Notably, we intentionally do not inherit the `server` query parameter -from the Client-Server API. +There are no query parameters. Notably, we intentionally do not inherit the +`server` query parameter from the Client-Server API. #### JSON Body Parameters * `limit` (`integer`): Limit the number of search results returned. -* `since` (`string`): A pagination token from a previous request, allowing clients to get the next (or previous) batch of rooms. The direction of pagination is specified solely by which token is supplied, rather than via an explicit flag. +* `since` (`string`): A pagination token from a previous request, allowing + clients to get the next (or previous) batch of rooms. The direction of + pagination is specified solely by which token is supplied, rather than via an + explicit flag. * `filter` (`Filter`): Filter to apply to the results. -* `include_all_networks` (`boolean`): Whether or not to include all known networks/protocols from application services on the homeserver. Defaults to false. -* `third_party_instance_id` (`boolean`): The specific third party network/protocol to request from the homeserver. Can only be used if `include_all_networks` is false. +* `include_all_networks` (`boolean`): Whether or not to include all known + networks/protocols from application services on the homeserver. + Defaults to false. +* `third_party_instance_id` (`boolean`): The specific third party + network/protocol to request from the homeserver. + Can only be used if `include_all_networks` is false. ### `Filter` Parameters -* `generic_search_term` (`string`): A string to search for in the room metadata, e.g. name, topic, canonical alias etc. (Optional). +* `generic_search_term` (`string`): A string to search for in the room metadata, +e.g. name, topic, canonical alias etc. (Optional). ## Tradeoffs -An alternative approach might be for implementations to carry on as they are but also -cache (and potentially index) remote homeservers' room directories. This would not require -a spec change. +An alternative approach might be for implementations to carry on as they are but +also cache (and potentially index) remote homeservers' room directories. +This would not require a spec change. -However, this would be unsatisfactory because it would lead to outdated room directory results and/or -caches that provide no benefit (as room directory searches are generally infrequent enough that a cache -would be outdated before being reused, on small – if not most – homeservers). +However, this would be unsatisfactory because it would lead to outdated room +directory results and/or caches that provide no benefit (as room directory +searches are generally infrequent enough that a cache would be outdated before +being reused, on small – if not most – homeservers). ## Potential issues ### Backwards Compatibility -After this proposal is implemented, outdated homeservers will still exist which do not support the room -filtering functionality specified in this MSC. In this case, homeservers will have to fall-back to downloading -the entire room directory and performing the filtering themselves, as currently happens. This is not considered -a problem since it will not lead to a situation that is any worse than the current one, and it is expected that -large homeservers – which cause the most work with the current search implementations – would be quick to upgrade -to support this feature once it is available. +After this proposal is implemented, outdated homeservers will still exist which +do not support the room filtering functionality specified in this MSC. In this +case, homeservers will have to fall-back to downloading the entire room +directory and performing the filtering themselves, as currently happens. +This is not considered a problem since it will not lead to a situation that is +any worse than the current one, and it is expected that large homeservers +– which cause the most work with the current search implementations – +would be quick to upgrade to support this feature once it is available. -In addition, as the `POST` method was not previously accepted on the `/publicRooms` endpoint over federation, -then it is not a difficult task to use a `405 Method Not Allowed` HTTP response as a signal that fallback is required. +In addition, as the `POST` method was not previously accepted on the +`/publicRooms` endpoint over federation, then it is not a difficult task to use +a `405 Method Not Allowed` HTTP response as a signal that fallback is required. ## Security considerations @@ -94,15 +113,19 @@ There are no known security considerations. At current, remote homeservers do not learn about what a user has searched for. -However, under this proposal, in the context of using the Federation API to forward on queries from the Client-Server -API, a client's homeserver would end up sharing the client's search terms with a remote homeserver, which may not be -operated by the same party or even trusted. For example, users' search terms could be logged. +However, under this proposal, in the context of using the Federation API to +forward on queries from the Client-Server API, a client's homeserver would end +up sharing the client's search terms with a remote homeserver, which may not be +operated by the same party or even trusted. For example, users' search terms +could be logged. -It is uncertain, to the author of this MSC, what implications this has with regards to legislation, such as GDPR. +It is uncertain, to the author of this MSC, what implications this has with +regards to legislation, such as GDPR. ## Conclusion -By allowing homeservers to pass on search filters, we enable remote homeservers' room directories to be -efficiently searched, because, realistically speaking, only the remote homeserver is in a position to be -able to perform search efficiently, by taking advantage of indexing and other such optimisations. +By allowing homeservers to pass on search filters, we enable remote homeservers' +room directories to be efficiently searched, because, realistically speaking, +only the remote homeserver is in a position to be able to perform search +efficiently, by taking advantage of indexing and other such optimisations. From 3789d828fd0d767d93a6c801fe8b1c95c32c6de2 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 1 Aug 2019 14:51:26 +0100 Subject: [PATCH 0700/1250] Incorporate solution analysis from the context of attacks --- proposals/2134-identity-hash-lookup.md | 125 +++++++++++++++++++++---- 1 file changed, 105 insertions(+), 20 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 5f500b6c..0881d1cb 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -316,43 +316,128 @@ of a stream cipher. Bloom filters are an alternative method of providing private contact discovery. However, they do not scale well due to requiring clients to download a large -filter that needs updating every time a new bind is made. Further considered -solutions are explored in https://signal.org/blog/contact-discovery/. Signal's -eventual solution of using Software Guard Extensions (detailed in +filter that needs updating every time a new bind is made. + +Further considered solutions are explored in +https://signal.org/blog/contact-discovery/. Signal's eventual solution of +using Software Guard Extensions (detailed in https://signal.org/blog/private-contact-discovery/) is considered impractical for a federated network, as it requires specialized hardware. k-anonymity was considered as an alternative approach, in which the identity server would never receive a full hash of a 3PID that it did not already know -about. While this has been considered plausible, it comes with heightened -resource requirements (much more hashing by the identity server). The -conclusion was that it may not provide more privacy if an identity server -decided to be evil, however it would significantly raise the resource -requirements to run an evil identity server. Discussion and a walk-through of -what a client/identity-server interaction would look like are documented [in -this Github +about. Discussion and a walk-through of what a client/identity-server +interaction would look like are documented [in this Github comment](https://github.com/matrix-org/matrix-doc/pull/2134#discussion_r298691748). +While this solution seems like a win for privacy, its actual benefits are a +lot more naunced. Let's explore them by performing threat-model analysis: + +We consider three attackers: + + 1. A malicious third party trying to discover the identity server mappings + in the homeserver. + + The malicious third party scenario can only be protected against by rate + limiting lookups, given otherwise it looks identical to legitimate traffic. + + 1. An attacker who has stolen an IS db + + In theory the 3PIDs could be stored hashed with a static salt to protect + a stolen DB. This has been descoped from this MSC, and is largely an + orthogonal problem. + + 1. A compromised or malicious identity server, who may be trying to + determine the contents of a user's addressbook (including non-Matrix users) + +Our approaches for protecting against a malicious identity server are: + + * We resign ourselves to the IS knowing the 3PIDs at point of bind, as + otherwise it can't validate them. + + * To protect the 3PIDs of non-Matrix users: + + 1. We could hash the uploaded 3PIDs with a static pepper; however, a + malicious IS could pre-generate a rainbow table to reverse these hashes. + + 1. We could hash the uploaded 3PIDs with a slowly rotating pepper; a + malicious IS could generate a rainbow table in retrospect to reverse these + hashes (but wouldn't be able to reuse the table) + + 1. We could send partial hashes of the uploaded 3PIDs (with full salted + hashes to disambiguate the 3PIDs), have the IS respond with anonymised + partial results, to allow the IS to avoid reversing the 3PIDs (a + k-anonymity approach). However, the IS could still claim to have mappings + for all 3PIDs, and so receive all the salted hashes, and be able to + reverse them via rainbow tables for that salt. + +So, in terms of computational complexity for the attacker, respectively: + + 1. The attacker has to generate a rainbow table over all possible IDs once, + which can then be reused for subsequent attacks. + + 1. The attacker has to generate a rainbow table over all possible IDs for a + given lookup timeframe, which cannot be reused for subsequent attacks. + + 1. The attacker has to generate multiple but partial rainbow tables, one + per group of 3PIDs that share similar hash prefixes, which cannot then be + reused for any other attack. + +For making life hardest for an attacker, option 3 (k-anon) wins. However, it +also makes things harder for the client and server: + + * The client has to calculate new salted hashes for all 3PIDs every time it + uploads. + + * The server has to calculate new salted hashes for all partially-matching + 3PIDs hashes as it looks them up. + +It's worth noting that one could always just go and load up a malicious IS DB +with a huge pre-image set of mappings and thus see what uploaded 3PIDs match, +no matter what algorithm is used. + +For k-anon this would put the most computational onus on the server (as it +would effectively be creating a partial rainbow table for every lookup), but +this is probably not infeasible - so we've gone and added a lot of complexity +and computational cost for not much benefit, given the system can still be +trivially attacked. + +Finally, as more and more users come onto Matrix, their contact lists will +get more and more exposed anyway given the IS server has to be able to +identity Matrix-enabled 3PIDs to perform the lookup. + +Thus the conclusion is that while k-anon is harder to attack, it's unclear +that this is actually enough of an obstacle to meaningfully stop a malicious +IS. Therefore we should KISS and go for a simple hash lookup with a rotating +pepper (which is not much harder than a static pepper, especially if our +initial implementation doesn't bother rotating the pepper). Rather than trying +to make the k-anon approach work, we'd be better off spending that time +figuring out how to store 3pids as hashes in the DB (and in 3pid bindings +etc), or how to decentralise ISes in general. + A radical model was also considered where the first portion of the k-anonyminity scheme was done with an identity server, and the second would be done with various homeservers who originally reported the 3PID to the -identity server. While interesting and a more decentralised model, some -attacks are still possible if the identity server is running an evil -homeserver which it can direct the client to send its hashes to. Discussion -on this matter has taken place in the MSC-specific room [starting at this +identity server. While interesting and more decentralised, some attacks are +still possible if the identity server is running an evil homeserver which it +can direct the client to send its hashes to. Discussion on this matter has +taken place in the MSC-specific room [starting at this message](https://matrix.to/#/!LlraCeVuFgMaxvRySN:amorgan.xyz/$4wzTSsspbLVa6Lx5cBq6toh6P3TY3YnoxALZuO8n9gk?via=amorgan.xyz&via=matrix.org&via=matrix.vgorcum.com). -Ideally identity servers would never receive plain-text addresses, just -storing and receiving hash values instead. However, it is necessary for the -identity server to have plain-text addresses during a +Tangentially, identity servers would ideally just never receive plain-text +addresses, just storing and receiving hash values instead. However, it is +necessary for the identity server to have plain-text addresses during a [bind](https://matrix.org/docs/spec/identity_service/r0.2.1#post-matrix-identity-api-v1-3pid-bind) call, in order to send a verification email or sms message. It is not feasible to defer this job to a homeserver, as the identity server cannot trust that the homeserver has actually performed verification. Thus it may not be possible to prevent plain-text 3PIDs of registered Matrix users from -being sent to the identity server at least once. Yet, we can still do our -best by coming up with creative ways to prevent non-matrix user 3PIDs from -leaking to the identity server, when they're sent in a lookup. +being sent to the identity server at least once. Yet, it is possible that with +a few changes to other Identity Service endpoints, as described in [this +review +comment](https://github.com/matrix-org/matrix-doc/pull/2134#discussion_r309617900), +identity servers could refrain from storing any plaintext 3PIDs at rest. This +however, is a topic for a future MSC. ## Conclusion From c401a4d47b7f1edf63ed3aa5c2341f8554b824b1 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 1 Aug 2019 14:53:41 +0100 Subject: [PATCH 0701/1250] punctuation --- proposals/2134-identity-hash-lookup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index f4a5e36c..fd17475b 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -310,7 +310,7 @@ reversal. Mediums and peppers are appended to the address as to prevent a common prefix for each plain-text string, which prevents attackers from pre-computing the -internal state of the hash function +internal state of the hash function. ## Other considered solutions From 387772477497362f6b2714ee8ce1a6c2a6a9132b Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 1 Aug 2019 15:01:05 +0100 Subject: [PATCH 0702/1250] fix speeling --- proposals/2134-identity-hash-lookup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index fd17475b..11ea3258 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -331,7 +331,7 @@ interaction would look like are documented [in this Github comment](https://github.com/matrix-org/matrix-doc/pull/2134#discussion_r298691748). While this solution seems like a win for privacy, its actual benefits are a -lot more naunced. Let's explore them by performing threat-model analysis: +lot more nuanced. Let's explore them by performing a threat-model analysis: We consider three attackers: From 96e06b6f5f94c6d2f13ec1c50bca4e16469ed797 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 1 Aug 2019 15:04:38 +0100 Subject: [PATCH 0703/1250] Add line, britishise --- proposals/2134-identity-hash-lookup.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 11ea3258..6c3bbe63 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -322,7 +322,7 @@ Further considered solutions are explored in https://signal.org/blog/contact-discovery/. Signal's eventual solution of using Software Guard Extensions (detailed in https://signal.org/blog/private-contact-discovery/) is considered impractical -for a federated network, as it requires specialized hardware. +for a federated network, as it requires specialised hardware. k-anonymity was considered as an alternative approach, in which the identity server would never receive a full hash of a 3PID that it did not already know @@ -410,10 +410,12 @@ Thus the conclusion is that while k-anon is harder to attack, it's unclear that this is actually enough of an obstacle to meaningfully stop a malicious IS. Therefore we should KISS and go for a simple hash lookup with a rotating pepper (which is not much harder than a static pepper, especially if our -initial implementation doesn't bother rotating the pepper). Rather than trying -to make the k-anon approach work, we'd be better off spending that time -figuring out how to store 3pids as hashes in the DB (and in 3pid bindings -etc), or how to decentralise ISes in general. +initial implementation doesn't bother rotating the pepper). Rather than +trying to make the k-anon approach work, we'd be better off spending that +time figuring out how to store 3pids as hashes in the DB (and in 3pid +bindings etc), or how to decentralise ISes in general. It's also worth noting +that a malicious server may fail to rotate the pepper, making the rotation +logic of questionable benefit. A radical model was also considered where the first portion of the k-anonyminity scheme was done with an identity server, and the second would From ec37fe44270b6dfaa6ad6e143a26bf428d99f3d6 Mon Sep 17 00:00:00 2001 From: Luca Becker Date: Thu, 1 Aug 2019 15:13:04 +0200 Subject: [PATCH 0704/1250] first draft of MSC2209 --- ...rules-other-keys-in-m.room.power.levels.md | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 proposals/2209-auth-rules-other-keys-in-m.room.power.levels.md diff --git a/proposals/2209-auth-rules-other-keys-in-m.room.power.levels.md b/proposals/2209-auth-rules-other-keys-in-m.room.power.levels.md new file mode 100644 index 00000000..93d9158a --- /dev/null +++ b/proposals/2209-auth-rules-other-keys-in-m.room.power.levels.md @@ -0,0 +1,45 @@ +# Update auth rules to check notifications key in m.room.power_levels + +## Introduction + +The key `notifications` was added to the `m.room.power_levels` event after the finalisation of the auth rules specified in room version 1. This leads to the fact, that this dictionary is not subject to the same validation as other dictionaries in the event, such as `users` or `events`. This especially means that Alice is able to alter any entry within the dictionary including ones, that are above her own power level, which is inconsistent with the behaviour for the other two dictionaries. + +[m.room.power_levels](https://matrix.org/docs/spec/client_server/r0.5.0#m-room-power-levels) +[room version 1](https://matrix.org/docs/spec/rooms/v1) + +## Proposal + +The auth rules regarding `m.room.power_levels` have been established in room version 1. The general idea here was that creators of a new `m.room.power_levels` event are only able to make changes to something that is equal to or lower than their own power level. +So, assuming a room with Alice (50), Bob(100), `m.room.power_levels` at 50, `m.room.name` at 75 and `m.room.topic` at 25 would mean the following: + +* Alice CAN alter `m.room.topic` to any power level up to her own, in this case 50 +* Alice is NOT able to alter `m.room.name` since the current value is higher than her own (75 > 50) +* Alice is NOT able to alter the power level of Bob, since his current value is higher than her own (100 > 50) +* Alice is free to set the level for anything that has not been defined such as `org.alice.message` up to a maximum of 50 + +Later on the key `notifications` was added to the `m.room.power_levels` event. It contains a mapping of notification keys to a power level, that is required for a user to trigger the specific notification. The most famous notification type is the `@room` notification. + +Going back to the original example because this key was added later on, the auth rules make no mention of it, which enables the following behaviour. *It is assumed that `@room` is at 75* + +* Alice can add any key to the dictionary and set the value to any value she wants, including ones higher than her own. +* Alice can alter the value for `@room` to any value she wants, including ones that are higher than her own, even though her own value is lower. + +The proposed solution is to alter the auth rules and add the `notification` dictionary to the same rules that handle `events` and `users`. + +So the rule [10.d](https://matrix.org/docs/spec/rooms/v1.html) of the auth rules in room version 1 would be altered to: + + +For each entry being added, changed or removed in events, users __and notifications__ keys: + + +## Tradeoffs + +The proposed solution would be a breaking change with current room versions and the alternative would be to leave the `notifications` key without any checks. + +## Security considerations + +This is likely to improve security because it prevents malicious users that were only given the right to emit `m.room.power_levels` so that they could alter a very specific key, such as, `invite` from altering the rules established for triggering notifications. + +## Conclusion + +The current spec conform behaviour regarding `notifications` is inconsistent with behaviour shown by the other dictionaries and room administrators are very likely expecting the `notifications` to work the same as them. The required change is minimal is and also in line with the general spirit of the auth rules regarding the `m.room.power_levels` event. From 42dbeee7d356e96f22c4b64bda4a3c0594dfd76f Mon Sep 17 00:00:00 2001 From: Luca Becker Date: Thu, 1 Aug 2019 18:32:11 +0200 Subject: [PATCH 0705/1250] MSC2209: 2nd draft @uhoregs changes --- ...rules-other-keys-in-m.room.power.levels.md | 64 ++++++++++++++----- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/proposals/2209-auth-rules-other-keys-in-m.room.power.levels.md b/proposals/2209-auth-rules-other-keys-in-m.room.power.levels.md index 93d9158a..db4d9bee 100644 --- a/proposals/2209-auth-rules-other-keys-in-m.room.power.levels.md +++ b/proposals/2209-auth-rules-other-keys-in-m.room.power.levels.md @@ -2,44 +2,76 @@ ## Introduction -The key `notifications` was added to the `m.room.power_levels` event after the finalisation of the auth rules specified in room version 1. This leads to the fact, that this dictionary is not subject to the same validation as other dictionaries in the event, such as `users` or `events`. This especially means that Alice is able to alter any entry within the dictionary including ones, that are above her own power level, which is inconsistent with the behaviour for the other two dictionaries. +The key `notifications` was added to the `m.room.power_levels` event after the +finalisation of the auth rules specified in room version 1. This leads to the +fact, that this dictionary is not subject to the same validation as other +dictionaries in the event, such as `users` or `events`. This especially means +that Alice is able to alter any entry within the dictionary including ones, +that are above her own power level, which is inconsistent with the behaviour +for the other two dictionaries. [m.room.power_levels](https://matrix.org/docs/spec/client_server/r0.5.0#m-room-power-levels) [room version 1](https://matrix.org/docs/spec/rooms/v1) ## Proposal -The auth rules regarding `m.room.power_levels` have been established in room version 1. The general idea here was that creators of a new `m.room.power_levels` event are only able to make changes to something that is equal to or lower than their own power level. -So, assuming a room with Alice (50), Bob(100), `m.room.power_levels` at 50, `m.room.name` at 75 and `m.room.topic` at 25 would mean the following: +The auth rules regarding `m.room.power_levels` have been established in room +version 1. The general idea here was that creators of a new `m.room.power_levels` +event are only able to make changes to something that is equal to or lower than +their own power level. +So, assuming a room with Alice (50), Bob(100), `m.room.power_levels` at 50, +`m.room.name` at 75 and `m.room.topic` at 25 would mean the following: * Alice CAN alter `m.room.topic` to any power level up to her own, in this case 50 -* Alice is NOT able to alter `m.room.name` since the current value is higher than her own (75 > 50) -* Alice is NOT able to alter the power level of Bob, since his current value is higher than her own (100 > 50) -* Alice is free to set the level for anything that has not been defined such as `org.alice.message` up to a maximum of 50 +* Alice is NOT able to alter `m.room.name` since the current value is higher than +her own (75 > 50) +* Alice is NOT able to alter the power level of Bob, since his current value is +higher than her own (100 > 50) +* Alice is free to set the level for anything that has not been defined such as +`org.alice.message` up to a maximum of 50 -Later on the key `notifications` was added to the `m.room.power_levels` event. It contains a mapping of notification keys to a power level, that is required for a user to trigger the specific notification. The most famous notification type is the `@room` notification. +Later on the key `notifications` was added to the `m.room.power_levels` event. +It contains a mapping of notification keys to a power level, that is required +for a user to trigger the specific notification. The most famous notification +type is the `@room` notification. -Going back to the original example because this key was added later on, the auth rules make no mention of it, which enables the following behaviour. *It is assumed that `@room` is at 75* +Going back to the original example because this key was added later on, the auth +rules make no mention of it, which enables the following behaviour. *It is assumed +that `@room` is at 75* -* Alice can add any key to the dictionary and set the value to any value she wants, including ones higher than her own. -* Alice can alter the value for `@room` to any value she wants, including ones that are higher than her own, even though her own value is lower. +* Alice can add any key to the dictionary and set the value to any value she wants, +including ones higher than her own. +* Alice can alter the value for `@room` to any value she wants, including ones that +are higher than her own, even though her own value is lower. -The proposed solution is to alter the auth rules and add the `notification` dictionary to the same rules that handle `events` and `users`. +The proposed solution is to alter the auth rules and add the `notifications` dictionary +to the same rules that handle `events` and `users`. -So the rule [10.d](https://matrix.org/docs/spec/rooms/v1.html) of the auth rules in room version 1 would be altered to: +So the rule [10.d](https://matrix.org/docs/spec/rooms/v1.html) of the auth rules in +room version 1 would be updated in a new room version to: -For each entry being added, changed or removed in events, users __and notifications__ keys: +For each entry being added, changed or removed in events, users __and notifications__ +keys: ## Tradeoffs -The proposed solution would be a breaking change with current room versions and the alternative would be to leave the `notifications` key without any checks. +The proposed solution would be a breaking change with current room versions and +the alternative would be to leave the `notifications` key without any checks. ## Security considerations -This is likely to improve security because it prevents malicious users that were only given the right to emit `m.room.power_levels` so that they could alter a very specific key, such as, `invite` from altering the rules established for triggering notifications. +This is likely to improve security because it prevents malicious users that were +only given the right to emit `m.room.power_levels` so that they could alter a very +specific key, such as `invite`, from altering the rules established for triggering +notifications. ## Conclusion -The current spec conform behaviour regarding `notifications` is inconsistent with behaviour shown by the other dictionaries and room administrators are very likely expecting the `notifications` to work the same as them. The required change is minimal is and also in line with the general spirit of the auth rules regarding the `m.room.power_levels` event. +The current spec conform behaviour regarding `notifications` is inconsistent with +behaviour shown by the other dictionaries and room administrators are very likely +expecting the `notifications` to work the same as them. The required change is minimal +is and also in line with the general spirit of the auth rules regarding the +`m.room.power_levels` event. A new room version is, however, required. This can be +done with other pending changes. From 3edf5e3c16989a603d9f9e7996acdac5f6596ab3 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 2 Aug 2019 11:25:28 +0100 Subject: [PATCH 0706/1250] Make hashes real values --- proposals/2134-identity-hash-lookup.md | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/proposals/2134-identity-hash-lookup.md b/proposals/2134-identity-hash-lookup.md index 6c3bbe63..2fdda034 100644 --- a/proposals/2134-identity-hash-lookup.md +++ b/proposals/2134-identity-hash-lookup.md @@ -180,23 +180,21 @@ IDs](https://matrix.org/docs/spec/rooms/v4#event-ids)). Once hashing has been performed, the client sends each hash in an array. ``` -NOTE: Hashes are not real values - -"alice@example.com email matrixrocks" -> "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs" -"bob@example.com email matrixrocks" -> "r0-6x3rp9zIWS2suIque-wXTnlv9sc41fatbRMEOwQE" -"carl@example.com email matrixrocks" -> "ryr10d1K8fcFVxALb3egiSquqvFAxQEwegXtlHoQFBw" -"12345678910 msisdn matrixrocks" -> "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens" -"denny@example.com email matrixrocks" -> "bxt8rtRaOzMkSk49zIKE_NfqTndHvGbWHchZskW3xmY" +"alice@example.com email matrixrocks" -> "4kenr7N9drpCJ4AfalmlGQVsOn3o2RHjkADUpXJWZUc" +"bob@example.com email matrixrocks" -> "LJwSazmv46n0hlMlsb_iYxI0_HXEqy_yj6Jm636cdT8" +"carl@example.com email matrixrocks" -> "jDh2YLwYJg3vg9pEn3kaaXAP9jx-LlcotoH51Zgb9MA" +"12345678910 msisdn matrixrocks" -> "S11EvvwnUWBDZtI4MTRKgVuiRx76Z9HnkbyRlWkBqJs" +"denny@example.com email matrixrocks" -> "2tZto1arl2fUYtF6tQPJND69il3xke9OBlgFgnUt2ww" POST /_matrix/identity/v2/lookup { "addresses": [ - "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs", - "r0-6x3rp9zIWS2suIque-wXTnlv9sc41fatbRMEOwQE", - "ryr10d1K8fcFVxALb3egiSquqvFAxQEwegXtlHoQFBw", - "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens", - "bxt8rtRaOzMkSk49zIKE_NfqTndHvGbWHchZskW3xmY" + "4kenr7N9drpCJ4AfalmlGQVsOn3o2RHjkADUpXJWZUc", + "LJwSazmv46n0hlMlsb_iYxI0_HXEqy_yj6Jm636cdT8", + "jDh2YLwYJg3vg9pEn3kaaXAP9jx-LlcotoH51Zgb9MA", + "S11EvvwnUWBDZtI4MTRKgVuiRx76Z9HnkbyRlWkBqJs", + "2tZto1arl2fUYtF6tQPJND69il3xke9OBlgFgnUt2ww" ], "algorithm": "sha256", "pepper": "matrixrocks" @@ -210,8 +208,8 @@ IDs of those that match: ``` { "mappings": { - "y_TvXLKxFT9CURPXI1wvfjvfvsXe8FPgYj-mkQrnszs": "@alice:example.com", - "c_30UaSZhl5tyanIjFoE1IXTmuU3vmptEwVOc3P2Ens": "@fred:example.com" + "4kenr7N9drpCJ4AfalmlGQVsOn3o2RHjkADUpXJWZUc": "@alice:example.com", + "S11EvvwnUWBDZtI4MTRKgVuiRx76Z9HnkbyRlWkBqJs": "@fred:example.com" } } ``` From 25e3602bbe0f76285f75abd4277959ee8add4948 Mon Sep 17 00:00:00 2001 From: Luca Becker Date: Sat, 3 Aug 2019 09:15:32 +0200 Subject: [PATCH 0707/1250] 3rd draft of MSC2209 --- .../2209-auth-rules-other-keys-in-m.room.power.levels.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/2209-auth-rules-other-keys-in-m.room.power.levels.md b/proposals/2209-auth-rules-other-keys-in-m.room.power.levels.md index db4d9bee..594c0b99 100644 --- a/proposals/2209-auth-rules-other-keys-in-m.room.power.levels.md +++ b/proposals/2209-auth-rules-other-keys-in-m.room.power.levels.md @@ -19,7 +19,7 @@ The auth rules regarding `m.room.power_levels` have been established in room version 1. The general idea here was that creators of a new `m.room.power_levels` event are only able to make changes to something that is equal to or lower than their own power level. -So, assuming a room with Alice (50), Bob(100), `m.room.power_levels` at 50, +So, assuming a room with Alice (50), Bob (100), `m.room.power_levels` at 50, `m.room.name` at 75 and `m.room.topic` at 25 would mean the following: * Alice CAN alter `m.room.topic` to any power level up to her own, in this case 50 @@ -51,8 +51,8 @@ So the rule [10.d](https://matrix.org/docs/spec/rooms/v1.html) of the auth rules room version 1 would be updated in a new room version to: -For each entry being added, changed or removed in events, users __and notifications__ -keys: +> For each entry being added, changed or removed in events, users __and notifications__ +>keys: ## Tradeoffs From a63fab20ee136e4b58eae94ed567e4faeda605cb Mon Sep 17 00:00:00 2001 From: Dominic Fischer Date: Sat, 3 Aug 2019 17:25:54 +0100 Subject: [PATCH 0708/1250] Fix some typos Signed-off-by: Dominic Fischer --- api/client-server/definitions/sync_filter.yaml | 4 ++-- changelogs/client_server/newsfragments/2215.clarification | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2215.clarification diff --git a/api/client-server/definitions/sync_filter.yaml b/api/client-server/definitions/sync_filter.yaml index 45a269c7..fc37fb48 100644 --- a/api/client-server/definitions/sync_filter.yaml +++ b/api/client-server/definitions/sync_filter.yaml @@ -16,7 +16,7 @@ title: Filter 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. + fields are included. The entries may include '.' characters 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. @@ -25,7 +25,7 @@ properties: 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 + a format suitable for clients. 'federation' will return the raw event as received over federation. The default is 'client'. enum: - client diff --git a/changelogs/client_server/newsfragments/2215.clarification b/changelogs/client_server/newsfragments/2215.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/client_server/newsfragments/2215.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. From 493bb062afb1eef49c9282cc1162e72a022f2ff1 Mon Sep 17 00:00:00 2001 From: "Olivier Wilkinson (reivilibre)" Date: Mon, 5 Aug 2019 09:50:24 +0100 Subject: [PATCH 0709/1250] MSC2197: update with privacy perspective Includes recommendations for client developers. Signed-off-by: Olivier Wilkinson (reivilibre) --- ...search_filter_in_federation_publicrooms.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/proposals/2197-search_filter_in_federation_publicrooms.md b/proposals/2197-search_filter_in_federation_publicrooms.md index 04413c86..bc1a74a9 100644 --- a/proposals/2197-search_filter_in_federation_publicrooms.md +++ b/proposals/2197-search_filter_in_federation_publicrooms.md @@ -119,8 +119,23 @@ up sharing the client's search terms with a remote homeserver, which may not be operated by the same party or even trusted. For example, users' search terms could be logged. -It is uncertain, to the author of this MSC, what implications this has with -regards to legislation, such as GDPR. +The privacy implications of this proposal are not overly major, as the data +that's being shared is [\[1\]][1]: + +- only covered by GDPR if: + - the search terms contain personal data, or + - the user's homeserver IP address is uniquely identifying (because it's a + single-person homeserver, perhaps) +- likely to be *expected* to be shared with the remote homeserver + +[1]: https://github.com/matrix-org/matrix-doc/pull/2197#issuecomment-517641751 + +For the sake of clarity, clients SHOULD display a warning that a remote search +will take the user's data outside the jurisdiction of their own homeserver, +before using the `server` parameter of the Client-Server API `/publicRooms`, as +it can be assumed that this will lead to the server invoking the Federation +API's `/publicRooms` – on the specified remote server – with the user's search +terms. ## Conclusion From a171d5f6fdc90057020d416af1b4bf79524e091f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 8 Aug 2019 09:29:52 -0600 Subject: [PATCH 0710/1250] Check for a state_key on the tombstone push rule This is an oversight from the proposal. --- changelogs/client_server/newsfragments/2223.clarification | 1 + proposals/1930-tombstone-notifications.md | 5 +++++ specification/modules/push.rst | 7 ++++++- 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/2223.clarification diff --git a/changelogs/client_server/newsfragments/2223.clarification b/changelogs/client_server/newsfragments/2223.clarification new file mode 100644 index 00000000..165b7e13 --- /dev/null +++ b/changelogs/client_server/newsfragments/2223.clarification @@ -0,0 +1 @@ +Add a missing ``state_key`` check on ``.m.rule.tombstone``. diff --git a/proposals/1930-tombstone-notifications.md b/proposals/1930-tombstone-notifications.md index 715921aa..253bf826 100644 --- a/proposals/1930-tombstone-notifications.md +++ b/proposals/1930-tombstone-notifications.md @@ -19,6 +19,11 @@ A new default override rule is to be added which is similar to `@room` notificat "kind": "event_match", "key": "type", "pattern": "m.room.tombstone" + }, + { + "kind": "event_match", + "key": "state_key", + "pattern": "" } ], "actions": [ diff --git a/specification/modules/push.rst b/specification/modules/push.rst index b16ed8a6..c9489987 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -382,7 +382,7 @@ Definition: ``.m.rule.tombstone`` ````````````````````` -Matches any event whose type is ``m.room.tombstone``. This is intended +Matches any state event whose type is ``m.room.tombstone``. This is intended to notify users of a room when it is upgraded, similar to what an ``@room`` notification would accomplish. @@ -399,6 +399,11 @@ Definition: "kind": "event_match", "key": "type", "pattern": "m.room.tombstone" + }, + { + "kind": "event_match", + "key": "state_key", + "pattern": "" } ], "actions": [ From 60cbc4567b62a50f2c10b84525be0efb0452aa3e Mon Sep 17 00:00:00 2001 From: "Olivier Wilkinson (reivilibre)" Date: Fri, 9 Aug 2019 11:21:39 +0100 Subject: [PATCH 0711/1250] Addresses some of Andrew's comments Signed-off-by: Olivier Wilkinson (reivilibre) --- ...search_filter_in_federation_publicrooms.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/proposals/2197-search_filter_in_federation_publicrooms.md b/proposals/2197-search_filter_in_federation_publicrooms.md index bc1a74a9..3ac9f3c4 100644 --- a/proposals/2197-search_filter_in_federation_publicrooms.md +++ b/proposals/2197-search_filter_in_federation_publicrooms.md @@ -22,17 +22,15 @@ Having a filtered `/publicRooms` API endpoint means that irrelevant or uninteresting rooms can be excluded from a room directory query response. In turn, this means that these room directory query responses can be generated more quickly and then, due to their smaller size, transmitted over the network -more quickly, owing to their smaller size. +more quickly. These benefits have been exploited in the Client-Server API, which implements search filtering using the `filter` JSON body parameter in the `POST` method on the `/publicRooms` endpoint. -It should be noted that the Client-Server and Federation APIs both currently -possess `/publicRooms` endpoints which, whilst similar, are not equivalent. - Ignoring the `server` parameter in the Client-Server API, the following specific -differences are noticed: +differences are noticed between the Client-Server and Federation API's +`/publicRooms` endpoints: * the Federation API endpoint only accepts the `GET` method whereas the Client-Server API accepts the `POST` method as well. @@ -42,7 +40,13 @@ differences are noticed: This MSC proposes to introduce support for the `POST` method in the Federation API's `/publicRooms` endpoint, with all but one of the parameters from that of -the Client-Server API. The copied parameters shall have the same semantics as +the Client-Server API. + +The parameter that is intentionally omitted is the `server` query parameter, as +it does not make sense to include it – the requesting homeserver could make a +direct request instead of requesting that a request be relayed. + +The parameters which are copied, however, shall have the same semantics as they do in the Client-Server API. In the interest of clarity, the proposed parameter set is listed below, along @@ -103,7 +107,8 @@ would be quick to upgrade to support this feature once it is available. In addition, as the `POST` method was not previously accepted on the `/publicRooms` endpoint over federation, then it is not a difficult task to use -a `405 Method Not Allowed` HTTP response as a signal that fallback is required. +an `M_UNRECOGNIZED` standard error response `errcode` as a signal that fallback +is required. ## Security considerations From 7ed536751650b2762e370d1fcdbc7ad6aa0410d9 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Sat, 10 Aug 2019 14:14:30 -0700 Subject: [PATCH 0712/1250] clarifications, fix formatting --- .../1219-storing-megolm-keys-serverside.md | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 7e074a0d..dbcf3091 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -195,10 +195,10 @@ On success, returns a JSON object with keys: - `auth_data` (object): Required. Same as in the body parameters for `POST /room_keys/version`. - `version` (string): Required. The backup version. -- `hash` (string): Required. The hash value which is an opaque string - representing stored keys in the backup. Client can compare it with the `hash` - value they received in the response of their last key storage request. - If not equal, another matrix client pushed new keys to the backup. +- `hash` (string): Required. The hash value which is an opaque string + representing stored keys in the backup. Client can compare it with the `hash` + value they received in the response of their last key storage request. + If not equal, another matrix client pushed new keys to the backup. - `count` (number): Required. The number of keys stored in the backup. Error codes: @@ -212,7 +212,7 @@ Update information about the given version. Only `auth_data` can be updated. Body parameters: - `algorithm` (string): Required. Must be the same as in the body parameters for `GET - /room_keys/version`. + /room_keys/version`. - `auth_data` (object): Required. algorithm-dependent data. For `m.megolm_backup.v1.curve25519-aes-sha2`, see below for the definition of this property. @@ -270,7 +270,7 @@ Body parameters: On success, returns a JSON object with keys: - `hash` (string): Required. The new hash value representing stored keys. See -`GET /room_keys/version/{version}` for more details. + `GET /room_keys/version/{version}` for more details. - `count` (number): Required. The new count of keys stored in the backup. Error codes: @@ -470,11 +470,18 @@ On success, returns the empty JSON object. ##### `auth_data` for backup versions The `auth_data` property for the backup versions endpoints for -`m.megolm_backup.v1.curve25519-aes-sha2` is a signedjson object with the +`m.megolm_backup.v1.curve25519-aes-sha2` is a [signed +json](https://matrix.org/docs/spec/appendices#signing-json) object with the following keys: - `public_key` (string): the curve25519 public key used to encrypt the backups -- `signatures` (object): signatures of the public key +- `signatures` (object): signatures of the `auth_data`. + +The `auth_data` should be signed by the user's [master cross-signing +key](https://github.com/matrix-org/matrix-doc/pull/1756), and may also be +signed by the user's device key. The allows clients to ensure that the public +key is valid, and prevents an attacker from being able to change the backup to +use a public key that have the private key for. ##### `session_data` for key backups @@ -516,10 +523,10 @@ key backup. This proposal does not attempt to protect against that. An attacker who gains access to a user's account can create a new backup version using a key that they control. For this reason, clients SHOULD confirm with users before sending keys to a new backup version or verify that it was -created by a trusted device by checking the signature. One way to confirm the -new backup version if the signature cannot be checked is by asking the user to -enter the recovery key, and confirming that the backup's public key matches -what is expected. +created by a trusted device by checking the signature. Alternatively, if the +signature cannot be verified, the backup can be validated by prompting the user +to enter the recovery key, and confirming that the backup's public key +corresponds to the recovery key. Other Issues ------------ From 353b6cd198aa4f1cb13fd7d3dcfceba323151f3f Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 12 Aug 2019 13:10:22 +0100 Subject: [PATCH 0713/1250] clarification --- proposals/2176-update-redaction-rules.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/2176-update-redaction-rules.md b/proposals/2176-update-redaction-rules.md index 75bfc971..574028f2 100644 --- a/proposals/2176-update-redaction-rules.md +++ b/proposals/2176-update-redaction-rules.md @@ -40,7 +40,8 @@ which are preserved: result before or after it is redacted (and therefore may or may not redact the original event). - * `m.room.power_levels` should allow: + * `m.room.power_levels` should allow (in addition to the keys already listed + in the spec): * the `invite` key. Rationale: this is required to authenticate `m.room.member` events with the `invite` membership. Currently, redacting From 783fd78a6f740b5dffc76184f1103f2d36a523ae Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 12 Aug 2019 17:13:37 +0100 Subject: [PATCH 0714/1250] wip --- proposals/xxxx-existing-3pid-allowed.md | 108 ++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 proposals/xxxx-existing-3pid-allowed.md diff --git a/proposals/xxxx-existing-3pid-allowed.md b/proposals/xxxx-existing-3pid-allowed.md new file mode 100644 index 00000000..f3daa533 --- /dev/null +++ b/proposals/xxxx-existing-3pid-allowed.md @@ -0,0 +1,108 @@ +# Allowing 3PID Owners to Rebind + +This is a proposal to allow 3PID owners to rebind their 3PIDs using the `POST +/_matrix/client/r0/account/3pid/email/requestToken` endpoint. The spec +currently states that if a user tries to call this endpoint with an email +address they already own, then the request should be rejected. + +This MSC calls for those requests to be accepted iff the requesting user +currently has the 3PID bound to their Matrix ID, marking them as the user in +control of this 3PID. + +This would allow users to bind their 3PIDs to different servers, even if the +homeserver has already been made aware of it. + +--- TODO, below --- + +## Proposal + +*Here is where you'll reinforce your position from the introduction in more detail, as well as cover +the technical points of your proposal. Including rationale for your proposed solution and detailing +why parts are important helps reviewers understand the problem at hand. Not including enough detail +can result in people guessing, leading to confusing arguments in the comments section. The example +here covers why templates are important again, giving a stronger argument as to why we should have +a template. Afterwards, it goes on to cover the specifics of what the template could look like.* + +Having a default template that everyone can use is important. Without a template, proposals would be +all over the place and the minimum amount of detail may be left out. Introducing a template to the +proposal process helps ensure that some amount of consistency is present across multiple proposals, +even if each author decides to abandon the template. + +The default template should be a markdown document because the MSC process requires authors to write +a proposal in markdown. Using other formats wouldn't make much sense because that would prevent authors +from copy/pasting the template. + +The template should have the following sections: + +* **Introduction** - This should cover the primary problem and broad description of the solution. +* **Proposal** - The gory details of the proposal. +* **Tradeoffs** - Any items of the proposal that are less desirable should be listed here. Alternative + solutions to the same problem could also be listed here. +* **Potential issues** - This is where problems with the proposal would be listed, such as changes + that are not backwards compatible. +* **Security considerations** - Discussion of what steps were taken to avoid security issues in the + future and any potential risks in the proposal. +* **Conclusion** - A repeat of the problem and solution. + +Furthermore, the template should not be required to be followed. However it is strongly recommended to +maintain some sense of consistency between proposals. + + +## Tradeoffs + +*This is where alternative solutions could be listed. There's almost always another way to do things +and this section gives you the opportunity to highlight why those ways are not as desirable. The +argument made in this example is that all of the text provided by the template could be integrated +into the proposals introduction, although with some risk of losing clarity.* + +Instead of adding a template to the repository, the assistance it provides could be integrated into +the proposal process itself. There is an argument to be had that the proposal process should be as +descriptive as possible, although having even more detail in the proposals introduction could lead to +some confusion or lack of understanding. Not to mention if the document is too large then potential +authors could be scared off as the process suddenly looks a lot more complicated than it is. For those +reasons, this proposal does not consider integrating the template in the proposals introduction a good +idea. + + +## Potential issues + +*Not all proposals are perfect. Sometimes there's a known disadvantage to implementing the proposal, +and they should be documented here. There should be some explanation for why the disadvantage is +acceptable, however - just like in this example.* + +Someone is going to have to spend the time to figure out what the template should actually have in it. +It could be a document with just a few headers or a supplementary document to the process explanation, +however more detail should be included. A template that actually proposes something should be considered +because it not only gives an opportunity to show what a basic proposal looks like, it also means that +explanations for each section can be described. Spending the time to work out the content of the template +is beneficial and not considered a significant problem because it will lead to a document that everyone +can follow. + + +## Security considerations + +*Some proposals may have some security aspect to them that was addressed in the proposed solution. This +section is a great place to outline some of the security-sensitive components of your proposal, such as +why a particular approach was (or wasn't) taken. The example here is a bit of a stretch and unlikely to +actually be worthwhile of including in a proposal, but it is generally a good idea to list these kinds +of concerns where possible.* + +By having a template available, people would know what the desired detail for a proposal is. This is not +considered a risk because it is important that people understand the proposal process from start to end. + + +## Conclusion + +*Repeating the problem and solution in different words helps reviewers understand the problem a bit more. +This section should wrap up any loose ends left in the document, as well as cover a brief overview of the +content in each section. Note that the example here doesn't touch on the specific implementation details +described in the "Proposal" section - just the high-level points made there.* + +Not having a template for people to follow when making their proposals could lead to large differences +between each MSC. This would make it difficult for reviewers, and there's a potential that some information +could be left out by accident. A template written in the same format the proposal process requires would +give authors the ability to understand how to better explain their own proposal. + +A descriptive template would help potential authors comprehend what the proposal process requires by +demonstrating what is expected of a proposal. Although this is more effort up front, it would lead to more +time saved in the future due to questions about the process. From 6330fff5a4bdb1691898ccd7bfb435cbfda98b11 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 12 Aug 2019 18:13:58 +0100 Subject: [PATCH 0715/1250] Draft for IS URL in account data --- .../xxxx-identity-server-account-data.md | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 proposals/xxxx-identity-server-account-data.md diff --git a/proposals/xxxx-identity-server-account-data.md b/proposals/xxxx-identity-server-account-data.md new file mode 100644 index 00000000..da539f2a --- /dev/null +++ b/proposals/xxxx-identity-server-account-data.md @@ -0,0 +1,74 @@ +# Store Identity Server in Account Data + +The URL of the Identity Sever to use is currently specified at registration and +login time and then used for the lifetime of a login session. If users wish to +specify a custom one, they must do so each time they log in on every client. +Once they have chosen an Identity Server to advertise their 3PIDs on, it would +be normal that they would wish to continue using this Identity Server for all +Identity requests in their account accross all clients. This proposal aims to +make this easier. + +## Proposal + +The base URL of the Identity Server is to be stored in user account data. It +shall be stored in the same format as in a .well-known file under the key, +`m.identity_server` and shall comprise a single key, `base_url` which is the +base URL of the ID Server to use (that is, the part before `/_matrix`). + +Upon registration or login, a client MUST refrain from performing any requests +to the Identity Server until the account data has been fetched from the server. +Once it has the account data, it MUST check for the presence of the +`m.identity_server` key. If present, the `base_url` in this key MUST be used +as the Identity Server base URL for the duration of the login session. If this +key is not present, the client SHOULD populate it with the ID Server URL +that was or would have been used in the login/registration process. This may +be either from user input, a .well-known lookup, or a default in the client. + +Client MUST listen for changes in the `m.identity_server` account data value +and update the URL that they use for ID Server requests accordingly UNLESS +the login session and choice of ID Server base URL predates this change, in +which case they SHOULD continue to use the value they are currently using. + +Clients MAY offer a way for users to change the ID server being used. If they +do, the client MUST update the value of `m.identity_server` accordingly. + +The `m.identity_server` may be present with a value of `null`. In this case, +clients MUST treat this as no ID Server URL being set and not perform ID +Server requests, disabling any functionality that requires such requests. + +Conversely, if a user wishes to disable ID Server functionality, the client +shall action this by setting the `base_url` of the `m.identity_server` +account data entry to `null`. + +### Transition Period + +Clients currently logged in with a value configured for the ID Server base +URL SHOULD use the value from `m.identity_server` if it exists or is created, +but otherwise continue to use the URL they had previously. They MUST NOT +populate the `m.identity_server` with their current ID Server base URL. + +## Tradeoffs + +There are a number of ways to transition to this new scheme. Clients could +populate the account data with their current ID Server URL as soon as +possible, and immediately use any new value seen on account data. This +would a much faster migration but any users with clients using different +ID Servers would suddenly find all their clients using the ID Server of +whichever client they updated first. + +## Potential issues + +Users will no longer be able to have different clients configured with +different ID Servers. + +## Security considerations + +An attacker would be able to force all a user clients to use a given ID Server +if they gained control of any of a user's logins. + +## Conclusion + +This makes the ID server an account setting which means it persists between +logins. The intention would be to phase out clients ever asking for an ID +Server URL at registration or login: this will be much easier for users to +understand whilst still retaining the flexibilty for those who want it. From ed4d805d2f087ba242969d3b561e7c5e2cb234e5 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 13 Aug 2019 11:11:22 +0100 Subject: [PATCH 0716/1250] flesh out --- proposals/xxxx-existing-3pid-allowed.md | 146 +++++++++--------------- 1 file changed, 57 insertions(+), 89 deletions(-) diff --git a/proposals/xxxx-existing-3pid-allowed.md b/proposals/xxxx-existing-3pid-allowed.md index f3daa533..c10eec27 100644 --- a/proposals/xxxx-existing-3pid-allowed.md +++ b/proposals/xxxx-existing-3pid-allowed.md @@ -1,108 +1,76 @@ # Allowing 3PID Owners to Rebind -This is a proposal to allow 3PID owners to rebind their 3PIDs using the `POST -/_matrix/client/r0/account/3pid/email/requestToken` endpoint. The spec -currently states that if a user tries to call this endpoint with an email -address they already own, then the request should be rejected. - -This MSC calls for those requests to be accepted iff the requesting user -currently has the 3PID bound to their Matrix ID, marking them as the user in -control of this 3PID. - -This would allow users to bind their 3PIDs to different servers, even if the -homeserver has already been made aware of it. - ---- TODO, below --- +3PID + noun + A third-party identifier such as an email address or phone number, that + can be tied to your Matrix ID in order for your contacts outside of + Matrix to find you, typically with the help of an [identity + server](https://matrix.org/docs/spec/identity_service/r0.2.1.html). + +As part of the on-going privacy work, Matrix client applications are +attempting to make the concept of an identity server more clear to the user, +as well as allowing a user to interact with multiple identity servers while +they're logged in. + +As part of facilitating this work, Matrix clients should be able to allow +users, while logged in, the ability to pick an identity server, see what +3PIDs they currently have bound to their Matrix ID, and bind/unbind as they +desire. + +When implementating this functionality, a technicality in the spec was found +to prevent the ability to bind the same 3PID to multiple identity servers. +The line "The homeserver must check that the given email address is **not** +already associated with an account on this homeserver." appears under the +[POST +/_matrix/client/r0/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-email-requesttoken) +line. The same goes for the [equivalent msisdn +endpoint](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken). + +If a user binds their email address, through the homeserver to identity +server A, then switches to identity server B to try and do the same, the +homeserver will reject the second request as this email address has already +been bound. This is due to the homeserver attaching the email address user's +accounts whenever a bind is performed through them. ## Proposal -*Here is where you'll reinforce your position from the introduction in more detail, as well as cover -the technical points of your proposal. Including rationale for your proposed solution and detailing -why parts are important helps reviewers understand the problem at hand. Not including enough detail -can result in people guessing, leading to confusing arguments in the comments section. The example -here covers why templates are important again, giving a stronger argument as to why we should have -a template. Afterwards, it goes on to cover the specifics of what the template could look like.* - -Having a default template that everyone can use is important. Without a template, proposals would be -all over the place and the minimum amount of detail may be left out. Introducing a template to the -proposal process helps ensure that some amount of consistency is present across multiple proposals, -even if each author decides to abandon the template. +This proposal calls for allowing 3PID owners to rebind their 3PIDs using the +[POST +/_matrix/client/r0/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-email-requesttoken) and [POST +/_matrix/client/r0/account/3pid/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken) +endpoints by extending the definition of what homeservers should check before rejecting a bind. -The default template should be a markdown document because the MSC process requires authors to write -a proposal in markdown. Using other formats wouldn't make much sense because that would prevent authors -from copy/pasting the template. - -The template should have the following sections: - -* **Introduction** - This should cover the primary problem and broad description of the solution. -* **Proposal** - The gory details of the proposal. -* **Tradeoffs** - Any items of the proposal that are less desirable should be listed here. Alternative - solutions to the same problem could also be listed here. -* **Potential issues** - This is where problems with the proposal would be listed, such as changes - that are not backwards compatible. -* **Security considerations** - Discussion of what steps were taken to avoid security issues in the - future and any potential risks in the proposal. -* **Conclusion** - A repeat of the problem and solution. - -Furthermore, the template should not be required to be followed. However it is strongly recommended to -maintain some sense of consistency between proposals. +Homeservers should reject the binding of a 3PID if it already been bound, +**unless** the requesting user is the one who originally bound that 3PID. If +so, then they should be able to bind it again if they choose. +In doing so, it would allow users to bind their 3PIDs to multiple identity +servers, even if the homeserver has already been made aware of it. ## Tradeoffs -*This is where alternative solutions could be listed. There's almost always another way to do things -and this section gives you the opportunity to highlight why those ways are not as desirable. The -argument made in this example is that all of the text provided by the template could be integrated -into the proposals introduction, although with some risk of losing clarity.* - -Instead of adding a template to the repository, the assistance it provides could be integrated into -the proposal process itself. There is an argument to be had that the proposal process should be as -descriptive as possible, although having even more detail in the proposals introduction could lead to -some confusion or lack of understanding. Not to mention if the document is too large then potential -authors could be scared off as the process suddenly looks a lot more complicated than it is. For those -reasons, this proposal does not consider integrating the template in the proposals introduction a good -idea. - +Identity servers will still let 3PIDs be rebound to another Matrix ID, while +a single homeserver won't let a 3PID transition between two users. If one +thinks about typical internet services however, you aren't allowed to simply +take an email address from another account even if you have control of it. ## Potential issues -*Not all proposals are perfect. Sometimes there's a known disadvantage to implementing the proposal, -and they should be documented here. There should be some explanation for why the disadvantage is -acceptable, however - just like in this example.* - -Someone is going to have to spend the time to figure out what the template should actually have in it. -It could be a document with just a few headers or a supplementary document to the process explanation, -however more detail should be included. A template that actually proposes something should be considered -because it not only gives an opportunity to show what a basic proposal looks like, it also means that -explanations for each section can be described. Spending the time to work out the content of the template -is beneficial and not considered a significant problem because it will lead to a document that everyone -can follow. - +Newer clients will expect homeservers to allow them to switch between +identity servers and bind/rebind emails as they please. If dealing with an +older homeserver, clients will receive an `HTTP 400 M_THREEPID_IN_USE`. +Clients should be prepared to understand that this may just mean they are +dealing with an old homeserver, versus the 3PID already being bound on this +homeserver by another user. ## Security considerations -*Some proposals may have some security aspect to them that was addressed in the proposed solution. This -section is a great place to outline some of the security-sensitive components of your proposal, such as -why a particular approach was (or wasn't) taken. The example here is a bit of a stretch and unlikely to -actually be worthwhile of including in a proposal, but it is generally a good idea to list these kinds -of concerns where possible.* - -By having a template available, people would know what the desired detail for a proposal is. This is not -considered a risk because it is important that people understand the proposal process from start to end. - +None. ## Conclusion -*Repeating the problem and solution in different words helps reviewers understand the problem a bit more. -This section should wrap up any loose ends left in the document, as well as cover a brief overview of the -content in each section. Note that the example here doesn't touch on the specific implementation details -described in the "Proposal" section - just the high-level points made there.* - -Not having a template for people to follow when making their proposals could lead to large differences -between each MSC. This would make it difficult for reviewers, and there's a potential that some information -could be left out by accident. A template written in the same format the proposal process requires would -give authors the ability to understand how to better explain their own proposal. - -A descriptive template would help potential authors comprehend what the proposal process requires by -demonstrating what is expected of a proposal. Although this is more effort up front, it would lead to more -time saved in the future due to questions about the process. +By lifting the restriction of not allowing a user to bind a 3PID multiple +times, we unlock the ability to interact with multiple identity servers on +the same account. This not only allows the user to play around and gain a +better understanding of the purpose of an identity server, but it is also one +step towards further decentralisation in the identity server space. From 6ed0ae36badb5e978c6a8898d8bb058d1aa17263 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 13 Aug 2019 11:12:04 +0100 Subject: [PATCH 0717/1250] rename msc # --- ...xxxx-existing-3pid-allowed.md => 2229-rebind-existing-3pid.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/{xxxx-existing-3pid-allowed.md => 2229-rebind-existing-3pid.md} (100%) diff --git a/proposals/xxxx-existing-3pid-allowed.md b/proposals/2229-rebind-existing-3pid.md similarity index 100% rename from proposals/xxxx-existing-3pid-allowed.md rename to proposals/2229-rebind-existing-3pid.md From be77b5823c50808dd4545804fd66caaa29052460 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 13 Aug 2019 11:24:37 +0100 Subject: [PATCH 0718/1250] fix up --- proposals/2229-rebind-existing-3pid.md | 48 ++++++++++++++++---------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/proposals/2229-rebind-existing-3pid.md b/proposals/2229-rebind-existing-3pid.md index c10eec27..ce2547e2 100644 --- a/proposals/2229-rebind-existing-3pid.md +++ b/proposals/2229-rebind-existing-3pid.md @@ -1,20 +1,25 @@ # Allowing 3PID Owners to Rebind +``` 3PID noun - A third-party identifier such as an email address or phone number, that + + A "third-party identifier" such as an email address or phone number, that can be tied to your Matrix ID in order for your contacts outside of - Matrix to find you, typically with the help of an [identity - server](https://matrix.org/docs/spec/identity_service/r0.2.1.html). + Matrix to find you, typically with the help of an identity server. -As part of the on-going privacy work, Matrix client applications are -attempting to make the concept of an identity server more clear to the user, -as well as allowing a user to interact with multiple identity servers while -they're logged in. +Identity server + noun -As part of facilitating this work, Matrix clients should be able to allow -users, while logged in, the ability to pick an identity server, see what -3PIDs they currently have bound to their Matrix ID, and bind/unbind as they + A queryable server that holds mappings between 3PIDs and Matrix IDs. +``` + +As part of the on-going privacy work, Matrix client applications are +attempting to make the concept of an identity server clearer to the user, as +well as allowing a user to interact with multiple identity servers while +logged in. In facilitating this, Matrix clients should be able to allow +logged-in users the ability to pick an identity server, see what 3PIDs they +currently have bound to their Matrix ID, and bind/unbind addresses as they desire. When implementating this functionality, a technicality in the spec was found @@ -23,14 +28,14 @@ The line "The homeserver must check that the given email address is **not** already associated with an account on this homeserver." appears under the [POST /_matrix/client/r0/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-email-requesttoken) -line. The same goes for the [equivalent msisdn +endpoint description. The same goes for the [equivalent msisdn (phone) endpoint](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken). -If a user binds their email address, through the homeserver to identity -server A, then switches to identity server B to try and do the same, the -homeserver will reject the second request as this email address has already -been bound. This is due to the homeserver attaching the email address user's -accounts whenever a bind is performed through them. +When a user binds their 3PID through a homeserver to identity server A, the +homeserver keeps a record and attaches the address to the local account. +Then, if the user switches to identity server B to try and do the same, the +homeserver will reject the second request as this address has already been +bound. ## Proposal @@ -38,13 +43,14 @@ This proposal calls for allowing 3PID owners to rebind their 3PIDs using the [POST /_matrix/client/r0/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-email-requesttoken) and [POST /_matrix/client/r0/account/3pid/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken) -endpoints by extending the definition of what homeservers should check before rejecting a bind. +endpoints by extending the definition of what homeservers should check before +rejecting a bind. Homeservers should reject the binding of a 3PID if it already been bound, **unless** the requesting user is the one who originally bound that 3PID. If -so, then they should be able to bind it again if they choose. +so, then they should be able to bind it again and again if they so choose. -In doing so, it would allow users to bind their 3PIDs to multiple identity +In doing so, users would be able to bind their 3PIDs to multiple identity servers, even if the homeserver has already been made aware of it. ## Tradeoffs @@ -63,6 +69,10 @@ Clients should be prepared to understand that this may just mean they are dealing with an old homeserver, versus the 3PID already being bound on this homeserver by another user. +Homeservers will need to keep track of each identity server that an address +has been bound with, and upon user account deactivation, should attempt to +unbind all of them. + ## Security considerations None. From f313b49c2652f3ad13cab6d51098db5e5f4a83b3 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 13 Aug 2019 11:40:34 +0100 Subject: [PATCH 0719/1250] Add bind def. --- proposals/2229-rebind-existing-3pid.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/proposals/2229-rebind-existing-3pid.md b/proposals/2229-rebind-existing-3pid.md index ce2547e2..11b2e370 100644 --- a/proposals/2229-rebind-existing-3pid.md +++ b/proposals/2229-rebind-existing-3pid.md @@ -12,6 +12,12 @@ Identity server noun A queryable server that holds mappings between 3PIDs and Matrix IDs. + +Bind + verb + + Create a mapping between a 3PID and a Matrix ID. Useful for people to + find a user based on their existing third-party contact information. ``` As part of the on-going privacy work, Matrix client applications are From cb1e3b8373d04d2b2e9ca659d2517299027335af Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 13 Aug 2019 13:29:35 +0100 Subject: [PATCH 0720/1250] Take into account the 1 is case --- proposals/2229-rebind-existing-3pid.md | 44 ++++++++++++++++---------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/proposals/2229-rebind-existing-3pid.md b/proposals/2229-rebind-existing-3pid.md index 11b2e370..ce658121 100644 --- a/proposals/2229-rebind-existing-3pid.md +++ b/proposals/2229-rebind-existing-3pid.md @@ -29,19 +29,28 @@ currently have bound to their Matrix ID, and bind/unbind addresses as they desire. When implementating this functionality, a technicality in the spec was found -to prevent the ability to bind the same 3PID to multiple identity servers. -The line "The homeserver must check that the given email address is **not** -already associated with an account on this homeserver." appears under the -[POST +to prevent certain abilities for a user. A user could not add a 3PID to their +homeserver before binding it to an identity server. It also prevents users +from binding the same 3PID to multiple identity servers. The line "The +homeserver must check that the given email address is **not** already +associated with an account on this homeserver." appears under the [POST /_matrix/client/r0/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-email-requesttoken) endpoint description. The same goes for the [equivalent msisdn (phone) endpoint](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken). -When a user binds their 3PID through a homeserver to identity server A, the -homeserver keeps a record and attaches the address to the local account. -Then, if the user switches to identity server B to try and do the same, the -homeserver will reject the second request as this address has already been -bound. +When a user adds an email to their account on their homeserver, they can +choose to bind that email to an identity server at the same time. This is +specified through a `bind` boolean. If the user first adds the 3PID with +`bind: false`, then decides they want to bind that 3PID to an identity server +to make themselves discoverable by it, by making another request with `bind: +true`. The homeserver will reject the second request, because this 3PID is +already tied to the user's account. + +Similarly, when a user initially sends their 3PID with `bind: true` through a +homeserver to identity server A, the homeserver keeps a record and attaches +the address to the local account. If the user then switches to identity +server B to try and do the same, the homeserver will reject the second +request as this address has already been bound. ## Proposal @@ -56,15 +65,16 @@ Homeservers should reject the binding of a 3PID if it already been bound, **unless** the requesting user is the one who originally bound that 3PID. If so, then they should be able to bind it again and again if they so choose. -In doing so, users would be able to bind their 3PIDs to multiple identity -servers, even if the homeserver has already been made aware of it. +In doing so, users would be able to rebind their 3PIDs, even if the +homeserver has already been made aware of it. ## Tradeoffs Identity servers will still let 3PIDs be rebound to another Matrix ID, while a single homeserver won't let a 3PID transition between two users. If one thinks about typical internet services however, you aren't allowed to simply -take an email address from another account even if you have control of it. +take an email address from another account even if you have control of it, so +this shouldn't be too unintuitive. ## Potential issues @@ -86,7 +96,9 @@ None. ## Conclusion By lifting the restriction of not allowing a user to bind a 3PID multiple -times, we unlock the ability to interact with multiple identity servers on -the same account. This not only allows the user to play around and gain a -better understanding of the purpose of an identity server, but it is also one -step towards further decentralisation in the identity server space. +times, we allow the basic ability of publishing a 3PID after associating it +with an account, as well as allow users to interact with multiple identity +servers on the same account with the same 3PIDs. This not only allows the +user to play around and gain a better understanding of the purpose of an +identity server, but it is also one step towards further decentralisation in +the identity server space. From 5b1ea4ffcb9db8e721c630d3740d6103fee6de15 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Tue, 13 Aug 2019 17:13:48 +0100 Subject: [PATCH 0721/1250] Update proposals/2229-rebind-existing-3pid.md Co-Authored-By: J. Ryan Stinnett --- proposals/2229-rebind-existing-3pid.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2229-rebind-existing-3pid.md b/proposals/2229-rebind-existing-3pid.md index ce658121..dd89ecc3 100644 --- a/proposals/2229-rebind-existing-3pid.md +++ b/proposals/2229-rebind-existing-3pid.md @@ -43,7 +43,7 @@ choose to bind that email to an identity server at the same time. This is specified through a `bind` boolean. If the user first adds the 3PID with `bind: false`, then decides they want to bind that 3PID to an identity server to make themselves discoverable by it, by making another request with `bind: -true`. The homeserver will reject the second request, because this 3PID is +true`, the homeserver will reject the second request, because this 3PID is already tied to the user's account. Similarly, when a user initially sends their 3PID with `bind: true` through a From 01fc54faaeb353f5b0084d9f0d4ddb1e28fe60ae Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Tue, 13 Aug 2019 17:15:48 +0100 Subject: [PATCH 0722/1250] Update proposals/2229-rebind-existing-3pid.md Co-Authored-By: Travis Ralston --- proposals/2229-rebind-existing-3pid.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2229-rebind-existing-3pid.md b/proposals/2229-rebind-existing-3pid.md index dd89ecc3..276e45c5 100644 --- a/proposals/2229-rebind-existing-3pid.md +++ b/proposals/2229-rebind-existing-3pid.md @@ -61,7 +61,7 @@ This proposal calls for allowing 3PID owners to rebind their 3PIDs using the endpoints by extending the definition of what homeservers should check before rejecting a bind. -Homeservers should reject the binding of a 3PID if it already been bound, +Homeservers should reject the binding of a 3PID if it has already been bound, **unless** the requesting user is the one who originally bound that 3PID. If so, then they should be able to bind it again and again if they so choose. From 2547cc443c9b3de68fee289139f95884a645c005 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 13 Aug 2019 17:17:06 +0100 Subject: [PATCH 0723/1250] backticks --- proposals/2229-rebind-existing-3pid.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/proposals/2229-rebind-existing-3pid.md b/proposals/2229-rebind-existing-3pid.md index ce658121..9854d7d9 100644 --- a/proposals/2229-rebind-existing-3pid.md +++ b/proposals/2229-rebind-existing-3pid.md @@ -55,9 +55,10 @@ request as this address has already been bound. ## Proposal This proposal calls for allowing 3PID owners to rebind their 3PIDs using the -[POST -/_matrix/client/r0/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-email-requesttoken) and [POST -/_matrix/client/r0/account/3pid/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken) +[`POST +/_matrix/client/r0/account/3pid/email/requestToken`](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-email-requesttoken) +and [`POST +/_matrix/client/r0/account/3pid/msisdn/requestToken`](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken) endpoints by extending the definition of what homeservers should check before rejecting a bind. From 2c8d112089e9ab1290118d72c40b93a28b29e014 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 13 Aug 2019 18:03:43 +0100 Subject: [PATCH 0724/1250] assign number --- ...ver-account-data.md => 2230-identity-server-account-data.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename proposals/{xxxx-identity-server-account-data.md => 2230-identity-server-account-data.md} (98%) diff --git a/proposals/xxxx-identity-server-account-data.md b/proposals/2230-identity-server-account-data.md similarity index 98% rename from proposals/xxxx-identity-server-account-data.md rename to proposals/2230-identity-server-account-data.md index da539f2a..b863cc59 100644 --- a/proposals/xxxx-identity-server-account-data.md +++ b/proposals/2230-identity-server-account-data.md @@ -1,4 +1,4 @@ -# Store Identity Server in Account Data +# MSC2230: Store Identity Server in Account Data The URL of the Identity Sever to use is currently specified at registration and login time and then used for the lifetime of a login session. If users wish to From 7758e0701cb4535af50586fb0b8c31608ce03c03 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 13 Aug 2019 18:22:06 +0100 Subject: [PATCH 0725/1250] Remove homeserver warning --- proposals/2229-rebind-existing-3pid.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/proposals/2229-rebind-existing-3pid.md b/proposals/2229-rebind-existing-3pid.md index 6cd1d155..bd765a5e 100644 --- a/proposals/2229-rebind-existing-3pid.md +++ b/proposals/2229-rebind-existing-3pid.md @@ -86,10 +86,6 @@ Clients should be prepared to understand that this may just mean they are dealing with an old homeserver, versus the 3PID already being bound on this homeserver by another user. -Homeservers will need to keep track of each identity server that an address -has been bound with, and upon user account deactivation, should attempt to -unbind all of them. - ## Security considerations None. From 229cb67b01c92925dcc5a00c7660189b82fa318e Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 14 Aug 2019 09:51:27 +0100 Subject: [PATCH 0726/1250] Apply suggestions from code review Use fewer formal MUST etc in proposal Co-Authored-By: Travis Ralston --- proposals/2230-identity-server-account-data.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proposals/2230-identity-server-account-data.md b/proposals/2230-identity-server-account-data.md index b863cc59..3a81fa8e 100644 --- a/proposals/2230-identity-server-account-data.md +++ b/proposals/2230-identity-server-account-data.md @@ -15,21 +15,21 @@ shall be stored in the same format as in a .well-known file under the key, `m.identity_server` and shall comprise a single key, `base_url` which is the base URL of the ID Server to use (that is, the part before `/_matrix`). -Upon registration or login, a client MUST refrain from performing any requests +Upon registration or login, a client SHOULD refrain from performing any requests to the Identity Server until the account data has been fetched from the server. -Once it has the account data, it MUST check for the presence of the -`m.identity_server` key. If present, the `base_url` in this key MUST be used +Once it has the account data, it SHOULD check for the presence of the +`m.identity_server` key. If present, the `base_url` in this key SHOULD be used as the Identity Server base URL for the duration of the login session. If this key is not present, the client SHOULD populate it with the ID Server URL -that was or would have been used in the login/registration process. This may +that was or would have been used in the login/registration process. This could be either from user input, a .well-known lookup, or a default in the client. -Client MUST listen for changes in the `m.identity_server` account data value -and update the URL that they use for ID Server requests accordingly UNLESS +Client SHOULD listen for changes in the `m.identity_server` account data value +and update the URL that they use for ID Server requests accordingly unless the login session and choice of ID Server base URL predates this change, in which case they SHOULD continue to use the value they are currently using. -Clients MAY offer a way for users to change the ID server being used. If they +Clients can offer a way for users to change the ID server being used. If they do, the client MUST update the value of `m.identity_server` accordingly. The `m.identity_server` may be present with a value of `null`. In this case, From b9b984ae60172892c13efc5702d68c438ceac0e5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 14 Aug 2019 09:52:13 +0100 Subject: [PATCH 0727/1250] clarify --- proposals/2230-identity-server-account-data.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/2230-identity-server-account-data.md b/proposals/2230-identity-server-account-data.md index 3a81fa8e..d26de3e2 100644 --- a/proposals/2230-identity-server-account-data.md +++ b/proposals/2230-identity-server-account-data.md @@ -13,7 +13,8 @@ make this easier. The base URL of the Identity Server is to be stored in user account data. It shall be stored in the same format as in a .well-known file under the key, `m.identity_server` and shall comprise a single key, `base_url` which is the -base URL of the ID Server to use (that is, the part before `/_matrix`). +base URL of the ID Server to use (that is, the part before `/_matrix`, including +`https://`). Upon registration or login, a client SHOULD refrain from performing any requests to the Identity Server until the account data has been fetched from the server. From 97f856d70650afdd3e3934e7c4b9780396a40b9b Mon Sep 17 00:00:00 2001 From: "Olivier Wilkinson (reivilibre)" Date: Wed, 14 Aug 2019 11:00:03 +0100 Subject: [PATCH 0728/1250] Domain name is potentially personally-identifying Thanks to @turt2live Signed-off-by: Olivier Wilkinson (reivilibre) --- proposals/2197-search_filter_in_federation_publicrooms.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/2197-search_filter_in_federation_publicrooms.md b/proposals/2197-search_filter_in_federation_publicrooms.md index 3ac9f3c4..37e3fe7d 100644 --- a/proposals/2197-search_filter_in_federation_publicrooms.md +++ b/proposals/2197-search_filter_in_federation_publicrooms.md @@ -129,8 +129,8 @@ that's being shared is [\[1\]][1]: - only covered by GDPR if: - the search terms contain personal data, or - - the user's homeserver IP address is uniquely identifying (because it's a - single-person homeserver, perhaps) + - the user's homeserver IP address or domain name is uniquely identifying + (because it's a single-person homeserver, perhaps) - likely to be *expected* to be shared with the remote homeserver [1]: https://github.com/matrix-org/matrix-doc/pull/2197#issuecomment-517641751 From 7e85b9d56afb78b8cfd867db30db7d6b70f007d6 Mon Sep 17 00:00:00 2001 From: "Olivier Wilkinson (reivilibre)" Date: Wed, 14 Aug 2019 11:03:55 +0100 Subject: [PATCH 0729/1250] Acknowledge other potential error responses for fallback Signed-off-by: Olivier Wilkinson (reivilibre) --- .../2197-search_filter_in_federation_publicrooms.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/proposals/2197-search_filter_in_federation_publicrooms.md b/proposals/2197-search_filter_in_federation_publicrooms.md index 37e3fe7d..5d1ae7c1 100644 --- a/proposals/2197-search_filter_in_federation_publicrooms.md +++ b/proposals/2197-search_filter_in_federation_publicrooms.md @@ -106,9 +106,14 @@ any worse than the current one, and it is expected that large homeservers would be quick to upgrade to support this feature once it is available. In addition, as the `POST` method was not previously accepted on the -`/publicRooms` endpoint over federation, then it is not a difficult task to use -an `M_UNRECOGNIZED` standard error response `errcode` as a signal that fallback -is required. +`/publicRooms` endpoint over federation, then it is possible to fall back to the +old behaviour, if one of the following errors is encountered: + +- an `M_UNRECOGNIZED` standard error response `errcode` (this is what would be + typically expected in this situation) +- an `M_NOT_FOUND` standard error response +- a `404 Not Found` HTTP error response +- a `405 Method Not Allowed` HTTP error response ## Security considerations From 4219e272ec5382a7ac0992bc43b9717a72f25ddb Mon Sep 17 00:00:00 2001 From: "Olivier Wilkinson (reivilibre)" Date: Wed, 14 Aug 2019 11:06:45 +0100 Subject: [PATCH 0730/1250] Drop the hard SHOULD Adopts @turt2live's phrasing Signed-off-by: Olivier Wilkinson (reivilibre) --- .../2197-search_filter_in_federation_publicrooms.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/proposals/2197-search_filter_in_federation_publicrooms.md b/proposals/2197-search_filter_in_federation_publicrooms.md index 5d1ae7c1..b3ce3dc3 100644 --- a/proposals/2197-search_filter_in_federation_publicrooms.md +++ b/proposals/2197-search_filter_in_federation_publicrooms.md @@ -140,12 +140,12 @@ that's being shared is [\[1\]][1]: [1]: https://github.com/matrix-org/matrix-doc/pull/2197#issuecomment-517641751 -For the sake of clarity, clients SHOULD display a warning that a remote search -will take the user's data outside the jurisdiction of their own homeserver, -before using the `server` parameter of the Client-Server API `/publicRooms`, as -it can be assumed that this will lead to the server invoking the Federation -API's `/publicRooms` – on the specified remote server – with the user's search -terms. +For the sake of clarity, clients are strongly encouraged to display a warning +that a remote search will take the user's data outside the jurisdiction of their +own homeserver, before using the `server` parameter of the Client-Server API +`/publicRooms`, as it can be assumed that this will lead to the server invoking +the Federation API's `/publicRooms` – on the specified remote server – with the +user's search terms. ## Conclusion From 4059661c29b15c6bc04cdebcdb6c5deb477910ac Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Wed, 14 Aug 2019 11:38:53 +0100 Subject: [PATCH 0731/1250] Update proposals/2229-rebind-existing-3pid.md Co-Authored-By: Kitsune Ral --- proposals/2229-rebind-existing-3pid.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2229-rebind-existing-3pid.md b/proposals/2229-rebind-existing-3pid.md index bd765a5e..83883c78 100644 --- a/proposals/2229-rebind-existing-3pid.md +++ b/proposals/2229-rebind-existing-3pid.md @@ -28,7 +28,7 @@ logged-in users the ability to pick an identity server, see what 3PIDs they currently have bound to their Matrix ID, and bind/unbind addresses as they desire. -When implementating this functionality, a technicality in the spec was found +When implementing this functionality, a technicality in the spec was found to prevent certain abilities for a user. A user could not add a 3PID to their homeserver before binding it to an identity server. It also prevents users from binding the same 3PID to multiple identity servers. The line "The From 92c6f4c38e9cad7c42b813d2a4c89e9cc4f88105 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Thu, 15 Aug 2019 18:10:38 +0100 Subject: [PATCH 0732/1250] Add M_USER_DEACTIVATED to list of error codes (#2234) Spec PR for [MSC 2181](https://github.com/matrix-org/matrix-doc/pull/2181). Adds the `M_USER_DEACTIVATED` error code and a short description to the client-server API. --- api/client-server/login.yaml | 7 +++++-- changelogs/client_server/newsfragments/2234.feature | 1 + specification/client_server_api.rst | 4 ++++ 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2234.feature diff --git a/api/client-server/login.yaml b/api/client-server/login.yaml index 98914a06..f6c92638 100644 --- a/api/client-server/login.yaml +++ b/api/client-server/login.yaml @@ -194,10 +194,13 @@ paths: "$ref": "definitions/errors/error.yaml" 403: description: |- - The login attempt failed. For example, the password may have been incorrect. + The login attempt failed. This can include one of the following error codes: + * ``M_FORBIDDEN``: The provided authentication data was incorrect. + * ``M_USER_DEACTIVATED``: The user has been deactivated. examples: application/json: { - "errcode": "M_FORBIDDEN"} + "errcode": "M_FORBIDDEN" + } schema: "$ref": "definitions/errors/error.yaml" 429: diff --git a/changelogs/client_server/newsfragments/2234.feature b/changelogs/client_server/newsfragments/2234.feature new file mode 100644 index 00000000..bb1883b3 --- /dev/null +++ b/changelogs/client_server/newsfragments/2234.feature @@ -0,0 +1 @@ +Add ``M_USER_DEACTIVATED`` error code. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 39a2fd3d..916604a3 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -150,6 +150,10 @@ Other error codes the client might encounter are: :``M_UNAUTHORIZED``: The request was not correctly authorized. Usually due to login failures. +:``M_USER_DEACTIVATED``: + The user ID associated with the request has been deactivated. Typically for + endpoints that prove authentication, such as ``/login``. + :``M_USER_IN_USE``: Encountered when trying to register a user ID which has been taken. From 475c64de8c2827b772372ba0b6c53051b9d94e27 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 16 Aug 2019 19:52:35 -0600 Subject: [PATCH 0733/1250] Disclose origin story --- proposals/1961-integrations-auth.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/1961-integrations-auth.md b/proposals/1961-integrations-auth.md index 7f735607..1f868e4c 100644 --- a/proposals/1961-integrations-auth.md +++ b/proposals/1961-integrations-auth.md @@ -3,6 +3,9 @@ A set of common APIs needs to be defined for clients to be able to interact with an integration manager. This proposal covers the authentication portion of that API. +**Note**: this proposal is part of a larger "Integrations API" which has not yet been defined. +See [MSC1956](https://github.com/matrix-org/matrix-doc/pull/1956) for details. + ## Proposal From 22c96926848fae3089673c761c0284637bc763d8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 16 Aug 2019 19:53:28 -0600 Subject: [PATCH 0734/1250] Disclose origin story better --- proposals/1957-integrations-discovery.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/1957-integrations-discovery.md b/proposals/1957-integrations-discovery.md index cef17098..feac7451 100644 --- a/proposals/1957-integrations-discovery.md +++ b/proposals/1957-integrations-discovery.md @@ -1,6 +1,7 @@ # MSC1957: Integration manager discovery -*Note*: This is a required component of [MSC1956 - Integrations API](https://github.com/matrix-org/matrix-doc/pull/1956) +**Note**: this proposal is part of a larger "Integrations API" which has not yet been defined. +See [MSC1956](https://github.com/matrix-org/matrix-doc/pull/1956) for details. Users should have the freedom to choose which integration manager they want to use in their client, while also accepting suggestions from their homeserver and client. Clients need to know where to find the different From 865d3da0f866cb8afa126df1c56558e6dc353616 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 16 Aug 2019 19:59:32 -0600 Subject: [PATCH 0735/1250] General clarity improvements --- proposals/1957-integrations-discovery.md | 26 ++++++++++++++---------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/proposals/1957-integrations-discovery.md b/proposals/1957-integrations-discovery.md index feac7451..b305c18f 100644 --- a/proposals/1957-integrations-discovery.md +++ b/proposals/1957-integrations-discovery.md @@ -79,15 +79,16 @@ The user is able to have multiple integration managers through use of multiple w #### Display order of integration managers -Clients which have support for integration managers should display at least 1 manager, but may decide -to display multiple via something like tabs. Clients must prefer to display the user's configured +Clients which have support for integration managers should display at least 1 manager, but should +display multiple via something like tabs. Clients must prefer to display the user's configured integration managers over any defaults, and if only displaying one manager must pick the first -manager after sorting the `state_key`s in lexicographical order. Clients may additionally display -default managers if they so wish, and should preserve the order defined in the various defaults. -If the user has no configured integration managers, the client must prefer to display one or more -of the managers suggested by the homeserver over the managers recommended by the client. +manager after sorting the `state_key`s of the applicable widgets in lexicographical order. Clients +can additionally display default managers if they so wish, and should preserve the order defined in +the various defaults. If the user has no configured integration managers, the client must prefer +to display one or more of the managers suggested by the homeserver over the managers recommended +by the client. -The client may optionally support a way to entirely disable integration manager support, even if the +The client can optionally support a way to entirely disable integration manager support, even if the user and homeserver have managers defined. The rationale for having the client prefer to use the user's integration managers first is so that @@ -157,7 +158,10 @@ Some things which may be desirable in the future are: ## Security considerations -When displaying integration managers, clients should not trust that the input is sanitary. Integration -managers may only be at HTTP(S) endpoints and may still have malicious intent. Ensure any sandboxing -on the manager is appropriate such that it can communicate with the client, but cannot perform unauthorized -actions. +When displaying integration managers, clients should not trust that the input is sanitary. Per the +proposal above, an intergration manager is only permitted to be served from HTTP(S) URIs. A given +integration manager can still have malicious intent however, and clients should ensure any sandboxing +on the manager is appropriate such that it can communicate with the client, but cannot perform +unauthorized actions. Other URI schemes are just as dangerous and could potentially be allowed by +this proposal - use cases are less defined and desirable for schemes like `file://` and are excluded +by this proposal. They can be added in a future proposal if a use case arises. From 76f9196ff39a00c25423582a215c7017f3c9dc8a Mon Sep 17 00:00:00 2001 From: "Olivier Wilkinson (reivilibre)" Date: Mon, 19 Aug 2019 07:44:37 +0100 Subject: [PATCH 0736/1250] Address @richvdh's comments --- ...search_filter_in_federation_publicrooms.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/proposals/2197-search_filter_in_federation_publicrooms.md b/proposals/2197-search_filter_in_federation_publicrooms.md index b3ce3dc3..ef1521d1 100644 --- a/proposals/2197-search_filter_in_federation_publicrooms.md +++ b/proposals/2197-search_filter_in_federation_publicrooms.md @@ -24,7 +24,7 @@ In turn, this means that these room directory query responses can be generated more quickly and then, due to their smaller size, transmitted over the network more quickly. -These benefits have been exploited in the Client-Server API, which implements +These benefits have been utilised in the Client-Server API, which implements search filtering using the `filter` JSON body parameter in the `POST` method on the `/publicRooms` endpoint. @@ -105,15 +105,14 @@ any worse than the current one, and it is expected that large homeservers – which cause the most work with the current search implementations – would be quick to upgrade to support this feature once it is available. -In addition, as the `POST` method was not previously accepted on the -`/publicRooms` endpoint over federation, then it is possible to fall back to the -old behaviour, if one of the following errors is encountered: +As the `POST` method was not previously accepted on the `/publicRooms` endpoint +over federation, then requesting servers should fall back to the old behaviour, +if one of the following errors is encountered: -- an `M_UNRECOGNIZED` standard error response `errcode` (this is what would be - typically expected in this situation) -- an `M_NOT_FOUND` standard error response -- a `404 Not Found` HTTP error response -- a `405 Method Not Allowed` HTTP error response +- an HTTP `400` response with an `M_UNRECOGNIZED` standard error response + `errcode` (this is what would be typically expected in this situation) +- a `404` (Not Found) HTTP error response +- a `405` (Method Not Allowed) HTTP error response ## Security considerations @@ -121,7 +120,7 @@ There are no known security considerations. ## Privacy considerations -At current, remote homeservers do not learn about what a user has searched for. +At present, remote homeservers do not learn about what a user has searched for. However, under this proposal, in the context of using the Federation API to forward on queries from the Client-Server API, a client's homeserver would end From e4bdc283fd6cdeb2bf90b5a79a180fb19a8e9c63 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 19 Aug 2019 11:45:46 +0100 Subject: [PATCH 0737/1250] Apply suggestions from code review Typos / spelling Co-Authored-By: Hubert Chathi --- proposals/2140-terms-of-service-2.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 557376cc..78a682d7 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -7,7 +7,7 @@ corresponding method that can be used with Identity Servers and Integration Managers. Requirements for this proposal are: - * ISs and IMs should be able to give multiple documents a user must agree to + * ISes and IMs should be able to give multiple documents a user must agree to abide by * Each document shoud be versioned * ISes and IMs must, for each request that they handle, know that the user @@ -15,7 +15,7 @@ Requirements for this proposal are: absolute proof (we will always have to trust that the client actually showed the document to the user) but it must be reasonably demonstrable that the user has given informed consent for the client to use that service. - * ISs and IMs must be able to prevent users from using the service if they + * ISes and IMs must be able to prevent users from using the service if they have not provided agreement. * A user should only have to agree to each version of each document once for their Matrix ID, ie. having agreed to a set of terms in one client, they @@ -265,7 +265,7 @@ in the current login sessions is: A client uses this client/server API endpoint to request that the Homeserver removes the given 3PID from the given Identity Server, or all Identity Servers. -Takes parameters the same parameters as +Takes the same parameters as `POST /_matrix/client/r0/account/3pid/delete`, ie. `id_server`, `medium`, `address` and the newly added `is_token`. From 12377fbf50515989004bc133071ca56c34ae300f Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 19 Aug 2019 11:53:41 +0100 Subject: [PATCH 0738/1250] /account/logout not /logout Co-Authored-By: Hubert Chathi --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 78a682d7..c19a1ea9 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -71,7 +71,7 @@ of: * `/_matrix/identity/v2/pubkey/*` * The new `$prefix/account/register` endpoint * The new `GET /_matrix/identity/v2/terms` - * `$prefix/logout` + * `$prefix/account/logout` ...may return an error with `M_UNAUTHORIZED` errcode with HTTP status code 401. This indicates that the user must authenticate with OpenID and supply a valid From 6d0067320c5703d3408c19952d68fb5b41c588f0 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 19 Aug 2019 13:31:20 +0100 Subject: [PATCH 0739/1250] clarify error proxying --- proposals/2140-terms-of-service-2.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index c19a1ea9..ed8e740e 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -94,7 +94,8 @@ Homeserver to make calls to the IS on its behalf, it must also supply its access token for the Identity Server alongside in the `is_token` key of the same JSON object. That is, in the main request object for a `requestToken` request and in the `threepidCreds` object when supplying 3PID credentials (eg. -in the `m.email.identity` UI auth stage). Exceptions to this are any requests +in the `m.email.identity` UI auth stage). The server must also relay +`M_TERMS_NOT_SIGNED` errors back to the client. Exceptions to this are any requests where the only IS operation the Homeserver may perform is unbinding, ie. `/_matrix/client/r0/account/deactivate` and `/_matrix/client/r0/account/3pid/delete`, in which case the unbind will be From 9e073e9647eef1bfff0dad0a7f0fc46013b66ddc Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 19 Aug 2019 10:42:30 -0600 Subject: [PATCH 0740/1250] Speeeeeeling Co-Authored-By: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- proposals/1957-integrations-discovery.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1957-integrations-discovery.md b/proposals/1957-integrations-discovery.md index b305c18f..f6ac5aa4 100644 --- a/proposals/1957-integrations-discovery.md +++ b/proposals/1957-integrations-discovery.md @@ -100,7 +100,7 @@ user so they don't get left out. #### Displaying integration managers Clients simply open the `ui_url` (or equivalent) in an `iframe` or similar. In the current ecosystem, -integration managers would receive a `scalar_token` to idenitify the user - this is no longer the case +integration managers would receive a `scalar_token` to identify the user - this is no longer the case and instead integration managers must seek other avenues for determining the user ID. Other proposals cover how to do this in the context of the integrations API. @@ -159,7 +159,7 @@ Some things which may be desirable in the future are: ## Security considerations When displaying integration managers, clients should not trust that the input is sanitary. Per the -proposal above, an intergration manager is only permitted to be served from HTTP(S) URIs. A given +proposal above, an integration manager is only permitted to be served from HTTP(S) URIs. A given integration manager can still have malicious intent however, and clients should ensure any sandboxing on the manager is appropriate such that it can communicate with the client, but cannot perform unauthorized actions. Other URI schemes are just as dangerous and could potentially be allowed by From 9b2ca3cdfe99414e4cf2047c13a20991e32d6aae Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 20 Aug 2019 16:19:15 +0100 Subject: [PATCH 0741/1250] typoes / clarifications Co-Authored-By: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/2230-identity-server-account-data.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/2230-identity-server-account-data.md b/proposals/2230-identity-server-account-data.md index d26de3e2..98fcfbf1 100644 --- a/proposals/2230-identity-server-account-data.md +++ b/proposals/2230-identity-server-account-data.md @@ -1,6 +1,6 @@ # MSC2230: Store Identity Server in Account Data -The URL of the Identity Sever to use is currently specified at registration and +The URL of the Identity Server to use is currently specified at registration and login time and then used for the lifetime of a login session. If users wish to specify a custom one, they must do so each time they log in on every client. Once they have chosen an Identity Server to advertise their 3PIDs on, it would @@ -11,7 +11,7 @@ make this easier. ## Proposal The base URL of the Identity Server is to be stored in user account data. It -shall be stored in the same format as in a .well-known file under the key, +shall be stored in the same format as in a .well-known file under the event type `m.identity_server` and shall comprise a single key, `base_url` which is the base URL of the ID Server to use (that is, the part before `/_matrix`, including `https://`). @@ -33,7 +33,7 @@ which case they SHOULD continue to use the value they are currently using. Clients can offer a way for users to change the ID server being used. If they do, the client MUST update the value of `m.identity_server` accordingly. -The `m.identity_server` may be present with a value of `null`. In this case, +The `m.identity_server` may be present with a `base_url` of `null`. In this case, clients MUST treat this as no ID Server URL being set and not perform ID Server requests, disabling any functionality that requires such requests. From 788796e1c6b1f8b57a10530d633a50004f6b27d3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 20 Aug 2019 09:20:07 -0600 Subject: [PATCH 0742/1250] Multiple clarifications --- proposals/1957-integrations-discovery.md | 35 ++++++++++++++++-------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/proposals/1957-integrations-discovery.md b/proposals/1957-integrations-discovery.md index f6ac5aa4..201f28c8 100644 --- a/proposals/1957-integrations-discovery.md +++ b/proposals/1957-integrations-discovery.md @@ -45,10 +45,10 @@ As shown, the homeserver is able to suggest multiple integration managers throug must have an `api_url` which must be an `http` or `https` URL. The `ui_url` is optional and if not provided is the same as the `api_url`. Like the `api_url`, the `ui_url` must be `http` or `https` if supplied. -The `ui_url` is ultimately treated the same as a widget, except that the custom `data` is not present and -must not be templated here. Variables like `$matrix_display_name` are able to function, however. Integration -managers should never use the `$matrix_user_id` as authoritative and instead seek other ways to determine the -user ID. This is covered by other proposals. +The `ui_url` is ultimately treated the same as a widget, except that the `data` object from the widget is not +present and must not be templated here. Variables like `$matrix_display_name` are able to function, however. +Integration managers should never use the `$matrix_user_id` as authoritative and instead seek other ways to +determine the user ID. This is covered by other proposals. The `api_url` is the URL clients will use when *not* embedding the integration manager, and instead showing its own purpose-built interface. @@ -56,7 +56,8 @@ its own purpose-built interface. Clients should query the `.well-known` information for the homeserver periodically to update the integration manager settings for that homeserver. The client is not expected to validate or use any other information contained in the response. Current recommendations are to query the configuration when the client starts up -and every 8 hours after that. +and every 8 hours after that. Clients can additionally refresh the configuration whenever they feel is +necessary (such as every time the user opens the integration manager). #### User-configured integration managers @@ -111,10 +112,15 @@ as an account widget rather than a room widget. #### Discovering a manager by only the domain name Clients may wish to ask users for a single canonical domain name so they can find the manager to add -to the user's account transparently. Similar to the .well-known discovery done by servers (and clients -during login), clients which have an integrations domain (eg: "example.org") make a regular HTTPS -request to `https://example.org/.well-known/matrix/integrations` which returns an object which looks -like the following: +to the user's account transparently. This differs from the .well-known discovery which allows homeservers +to recommend their own integration manager: the homeserver is not recommending a default here. The +user has instead opted to pick an integration manager (identified only by domain name) and the client +is expected to resolve that to a set of URLs it can use for the manager. + +Similar to the .well-known discovery done by servers (and clients during login), clients which have an +integrations domain (eg: "example.org") make a regular HTTPS request to +`https://example.org/.well-known/matrix/integrations` which returns an object which looks like the +following: ```json { "m.integrations_widget": { @@ -132,6 +138,13 @@ property, the client should assume there is no integrations manager running on t an integration manager, described above. The client should wrap the object verbatim into the appropriate account data location. +Because the .well-known file would be accessed by web browsers, among other platforms, the server +should be using appropriate CORS headers for the request. The recommended headers are the same as those +which are already recommended for homeserver discovery in the Client-Server API. + +*Note*: this could reuse the client-server mechanic for discovery and just omit the homeserver information +however that conflates many concerns together on the one endpoint. A new endpoint is instead proposed +to keep the concerns isolated. ## Tradeoffs @@ -144,8 +157,8 @@ support this use case, even if it is moderately rare. We could also define the integration managers in a custom account data event rather than defining them as a widget. Doing so just adds clutter to the account data and risks duplicating code in clients as -using widgets gets us URL templating for free (see the section later on in this proposal about account -widgets for more information). +using widgets gets us URL templating for free (see the section earlier on in this proposal about account +widgets for more information: "User-configured integration managers"). ## Future extensions From 1f8cfd57298f68837a315008f8e280eac23e75b4 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 21 Aug 2019 14:19:20 +0100 Subject: [PATCH 0743/1250] Update migration mechanism --- proposals/2230-identity-server-account-data.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/proposals/2230-identity-server-account-data.md b/proposals/2230-identity-server-account-data.md index 98fcfbf1..19fb3062 100644 --- a/proposals/2230-identity-server-account-data.md +++ b/proposals/2230-identity-server-account-data.md @@ -21,14 +21,11 @@ to the Identity Server until the account data has been fetched from the server. Once it has the account data, it SHOULD check for the presence of the `m.identity_server` key. If present, the `base_url` in this key SHOULD be used as the Identity Server base URL for the duration of the login session. If this -key is not present, the client SHOULD populate it with the ID Server URL -that was or would have been used in the login/registration process. This could -be either from user input, a .well-known lookup, or a default in the client. +key is not present, the client SHOULD use whatever value it would have used prior +to this MSC. It should not update the account data in this situation. Client SHOULD listen for changes in the `m.identity_server` account data value -and update the URL that they use for ID Server requests accordingly unless -the login session and choice of ID Server base URL predates this change, in -which case they SHOULD continue to use the value they are currently using. +and update the URL that they use for ID Server requests accordingly. Clients can offer a way for users to change the ID server being used. If they do, the client MUST update the value of `m.identity_server` accordingly. @@ -43,10 +40,9 @@ account data entry to `null`. ### Transition Period -Clients currently logged in with a value configured for the ID Server base -URL SHOULD use the value from `m.identity_server` if it exists or is created, -but otherwise continue to use the URL they had previously. They MUST NOT -populate the `m.identity_server` with their current ID Server base URL. +Clients will continue to use whatever IS URLs they currently use until the +user sets one explicitly, at which point it will be written to account data +and all clients will start using this value. ## Tradeoffs From 4073d940da7d0a3ed25dd30f820dd83692389a47 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 21 Aug 2019 15:11:10 +0100 Subject: [PATCH 0744/1250] Typo Co-Authored-By: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index ed8e740e..3e2456bd 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -148,7 +148,7 @@ to use the service. Its response is similar to the structure used in the "version": "1.2", "en": { "name": "Privacy Policy", - "url": "https://example.org/somewhere/privaacy-1.2-en.html" + "url": "https://example.org/somewhere/privacy-1.2-en.html" }, "fr": { "name": "Politique de confidentialité", From 69315417b5c576e4e7966fda4f40503f2c2d3ad4 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 21 Aug 2019 15:12:25 +0100 Subject: [PATCH 0745/1250] Typo Co-Authored-By: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 3e2456bd..d256fa88 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -248,7 +248,7 @@ The `/_matrix/identity/v2/3pid/unbind` endpoint must not return either of these errors if the request has a valid signature from a Homeserver, and is being authenticated as such. In summary, the process for using a service that has not previously been used -in the current login sessions is: +in the current login session is: * `GET $prefix/terms` * Compare result with `m.accepted_terms` account data, get set of documents From 8bd9d7caeb2b5185878482eda0c81f50bc873468 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 21 Aug 2019 15:12:45 +0100 Subject: [PATCH 0746/1250] Add full stop Co-Authored-By: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- proposals/2140-terms-of-service-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index d256fa88..49042aaf 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -255,7 +255,7 @@ in the current login session is: pending agreement. * If non-empty, show this set of documents to the user and wait for the user to indicate their agreement. - * Add the newly agreed documents to `m.accepted_terms` + * Add the newly agreed documents to `m.accepted_terms`. * On success, or if there were no documents pending agreement, get an OpenID token from the Homeserver and submit this token to the `register` endpoint. Store the resulting access token. From 4ea8f645d6a6f134a137f86e81c4599e1cd057f7 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 21 Aug 2019 18:13:50 +0100 Subject: [PATCH 0747/1250] is_token -> id_access_token and add invite to proxy list --- proposals/2140-terms-of-service-2.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 49042aaf..9f96a00b 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -91,13 +91,14 @@ API, as specified in [MSC1961](https://github.com/matrix-org/matrix-doc/issues/1 When clients supply an identity server to the Homeserver in order for the Homeserver to make calls to the IS on its behalf, it must also supply its -access token for the Identity Server alongside in the `is_token` key of the -same JSON object. That is, in the main request object for a `requestToken` -request and in the `threepidCreds` object when supplying 3PID credentials (eg. -in the `m.email.identity` UI auth stage). The server must also relay -`M_TERMS_NOT_SIGNED` errors back to the client. Exceptions to this are any requests -where the only IS operation the Homeserver may perform is unbinding, ie. -`/_matrix/client/r0/account/deactivate` and +access token for the Identity Server alongside in the `id_access_token` key of +the same JSON object. That is, in the main request object for `requestToken` +and `/_matrix/client/r0/rooms/{roomId}/invite` requests and in the +`threepidCreds` object when supplying 3PID credentials (eg. in the +`m.email.identity` UI auth stage). The server must also relay +`M_TERMS_NOT_SIGNED` errors back to the client. Exceptions to this are any +requests where the only IS operation the Homeserver may perform is unbinding, +ie. `/_matrix/client/r0/account/deactivate` and `/_matrix/client/r0/account/3pid/delete`, in which case the unbind will be authenticated by a signed request from the Homeserver. From 8b85fda52cc27db4c424d1552a1c3a84fd176e10 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 21 Aug 2019 17:47:55 -0600 Subject: [PATCH 0748/1250] Add a link to the widget MSC to try and stem questions --- proposals/1957-integrations-discovery.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/1957-integrations-discovery.md b/proposals/1957-integrations-discovery.md index 201f28c8..bb5ada55 100644 --- a/proposals/1957-integrations-discovery.md +++ b/proposals/1957-integrations-discovery.md @@ -3,6 +3,9 @@ **Note**: this proposal is part of a larger "Integrations API" which has not yet been defined. See [MSC1956](https://github.com/matrix-org/matrix-doc/pull/1956) for details. +**Note**: this proposal makes use of the existing Widget API proposed by +[MSC1236](https://github.com/matrix-org/matrix-doc/issues/1236). + Users should have the freedom to choose which integration manager they want to use in their client, while also accepting suggestions from their homeserver and client. Clients need to know where to find the different integration managers and how to contact them. From b6f0e8e8ed663ad018baf233cada68782a426799 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 21 Aug 2019 17:50:18 -0600 Subject: [PATCH 0749/1250] Clarify that the query string is because they are widgets --- proposals/1957-integrations-discovery.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/proposals/1957-integrations-discovery.md b/proposals/1957-integrations-discovery.md index bb5ada55..85939726 100644 --- a/proposals/1957-integrations-discovery.md +++ b/proposals/1957-integrations-discovery.md @@ -81,6 +81,9 @@ widget rules apply here. The user is able to have multiple integration managers through use of multiple widgets. +The query string shown in the example is to demonstrate that integration managers are widgets and can +make use of the template options provided to widgets. + #### Display order of integration managers Clients which have support for integration managers should display at least 1 manager, but should @@ -149,6 +152,9 @@ which are already recommended for homeserver discovery in the Client-Server API. however that conflates many concerns together on the one endpoint. A new endpoint is instead proposed to keep the concerns isolated. +The query string shown in the example is to demonstrate that integration managers are widgets and can +make use of the template options provided to widgets. + ## Tradeoffs We could limit the user (and by extension, the homeserver and client) to exactly 1 integration manager From b0f873785d338922876990d30e542079888b11d8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 21 Aug 2019 18:03:17 -0600 Subject: [PATCH 0750/1250] Proposal for room version 6 --- proposals/2240-rooms-v6.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 proposals/2240-rooms-v6.md diff --git a/proposals/2240-rooms-v6.md b/proposals/2240-rooms-v6.md new file mode 100644 index 00000000..a67a1ad7 --- /dev/null +++ b/proposals/2240-rooms-v6.md @@ -0,0 +1,21 @@ +# MSC2240: Room Version 6 + +A new room version, `6`, is proposed using [room version 5](https://matrix.org/docs/spec/rooms/v5.html) +as a starting point and incorporating the following MSCs: + +* [MSC2174](https://github.com/matrix-org/matrix-doc/pull/2174) - Moving the `redacts` key. +* [MSC2175](https://github.com/matrix-org/matrix-doc/pull/2175) - Removing the `creator` from create events. +* [MSC2176](https://github.com/matrix-org/matrix-doc/pull/2176) - Modern redaction rules. +* [MSC2209](https://github.com/matrix-org/matrix-doc/pull/2209) - Including notifications in power level auth rules. +* [MSC2212](https://github.com/matrix-org/matrix-doc/pull/2212) - Third party user power levels. +* [MSC2213](https://github.com/matrix-org/matrix-doc/pull/2213) - Rejoinability of invite-only rooms. +* [MSC1849](https://github.com/matrix-org/matrix-doc/pull/1849) - Event aggregations/relationships. + +MSCs which require a new room version and are excluded from v6 are: +* [MSC2214](https://github.com/matrix-org/matrix-doc/pull/2214) - Joining upgraded private rooms. + This MSC is excluded due to the solution not being fully worked out. As this v6 proposal progresses, + it is possible for it to be included in the future. + + +Room version 6 upon being added to the specification shall be considered stable. No other room versions +are affected by this MSC. From ec38013daaa0887f12664523730bfb4036d55291 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 23 Aug 2019 23:07:57 +0300 Subject: [PATCH 0751/1250] Proposal to allow multiple targets for one redaction event Signed-off-by: Tulir Asokan --- proposals/2244-mass-redactions.md | 66 +++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 proposals/2244-mass-redactions.md diff --git a/proposals/2244-mass-redactions.md b/proposals/2244-mass-redactions.md new file mode 100644 index 00000000..296ffeee --- /dev/null +++ b/proposals/2244-mass-redactions.md @@ -0,0 +1,66 @@ +# Mass redactions +Matrix, like any platform with public chat rooms, has spammers. Currently, +redacting spam essentially requires spamming redaction events in a 1:1 ratio, +which is not optimal[1]. Most clients do not even have any mass +redaction tools, likely in part due to the lack of a mass redaction API. A mass +redaction API on the other hand has not been implemented as it would require +sending lots of events at once. However, this problem could be solved by +allowing a single redaction event to redact many events instead of sending many +redaction events. + +## Proposal +This proposal builds upon [MSC2174] and suggests making the `redacts` field +in the content of `m.room.redaction` events an array of event ID strings +instead of a single event ID string. + +It would be easiest to do this before MSC2174 is written into the spec, as then +only one migration would be needed: from an event-level redacts string to a +content-level redacts array. + +### Number of redactions +Room v4+ event IDs are 44 bytes long, which means the federation event size +limit would cap a single redaction event at a bit less than 1500 targets. +Redactions are not intrinsically heavy, so a separate limit should not be +necessary. + +### Auth rules +The redaction auth rules should change to iterate the array and check if the +sender has the privileges to redact each event. + +There are at least two potential ways to handle targets that are not found or +rejected: soft failing until all targets are found and handling each target +separately. + +#### Soft fail +Soft fail the event until all targets are found, then accept only if the sender +has the privileges to redact every listed event. This is how redactions +currently work. + +This has the downside of requiring servers to fetch all the target events (and +possibly forward them to clients) before being able to process and forward the +redaction event. + +#### Handle each target separately +Handle each target separately: if some targets are not found, remember the +redaction and check auth rules when the target is received. This option brings +some complexities, but might be more optimal in situations such as a spam +attack. + +When receiving a redaction event: +* Ignore illegal targets +* "Remember" targets that can't be found +* Send legal target event IDs to clients in the redaction event. + +When receiving an event that is "remembered" to be possibly redacted by an +earlier redaction, check if the redaction was legal, and if it was, do not +send the event to clients. + +## Tradeoffs + +## Potential issues + +## Security considerations + + +[1]: https://img.mau.lu/hEqqt.png +[MSC2174]: https://github.com/matrix-org/matrix-doc/pull/2174 From 65cd10249cb88a81c4caef4bb2164df183b32661 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sat, 24 Aug 2019 21:56:48 +0900 Subject: [PATCH 0752/1250] Render enums inside additionalProps as one more table Closes #2242. --- api/client-server/capabilities.yaml | 1 + scripts/templating/matrix_templates/units.py | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/api/client-server/capabilities.yaml b/api/client-server/capabilities.yaml index a50908f7..0d6b0677 100644 --- a/api/client-server/capabilities.yaml +++ b/api/client-server/capabilities.yaml @@ -96,6 +96,7 @@ paths: example: "1" available: type: object + title: AvailableRoomVersions description: |- A detailed description of the room versions the server supports. additionalProperties: diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index 04e6f8a9..f0d21ed0 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -211,9 +211,17 @@ def get_json_schema_object_fields(obj, enforce_title=False): key_type = additionalProps.get("x-pattern", "string") res = process_data_type(additionalProps) + tables = res["tables"] + val_title = res["title"] + if res.get("enum_desc") and val_title != "enum": + # A map to enum needs another table with enum description + tables.append(TypeTable( + title=val_title, + rows=[TypeTableRow(key="(mapped value)", title="enum", desc=res["desc"])] + )) return { - "title": "{%s: %s}" % (key_type, res["title"]), - "tables": res["tables"], + "title": "{%s: %s}" % (key_type, val_title), + "tables": tables, } if not props: @@ -338,8 +346,8 @@ def process_data_type(prop, required=False, enforce_title=True): prop_title = prop_type if prop.get("enum"): + prop_title = prop.get("title", "enum") if len(prop["enum"]) > 1: - prop_title = "enum" enum_desc = ( "One of: %s" % json.dumps(prop["enum"]) ) From 31c132ec823f8a7f4420c375693716b0e8141996 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sun, 25 Aug 2019 17:39:36 +0900 Subject: [PATCH 0753/1250] Add changelog --- changelogs/client_server/2245.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/2245.clarification diff --git a/changelogs/client_server/2245.clarification b/changelogs/client_server/2245.clarification new file mode 100644 index 00000000..67533d15 --- /dev/null +++ b/changelogs/client_server/2245.clarification @@ -0,0 +1 @@ +List available enum values for the room versions capability From 4e2fe124d21a8290b7b2fa01c0200cbc9514dc4f Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Sun, 25 Aug 2019 18:22:23 -0700 Subject: [PATCH 0754/1250] wording fixes/clarifications --- proposals/1946-secure_server-side_storage.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index 2f269f23..0e6fccb7 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -11,8 +11,8 @@ way of storing such data. Secrets are data that clients need to use and that are sent through or stored on the server, but should not be visible to server operators. Secrets are -plain strings -- if clients need to use more complicated data, it must be -encoded as a string. +plain strings -- if clients need to use more complicated data, they must be +encoded as a string, such as by encoding as JSON. ### Storage @@ -29,10 +29,11 @@ property, which is a human-readable name. The contents will be signed as signed JSON using the user's master cross-signing key. Other properties depend on the encryption algorithm, and are described below. -If a key has the `name` property set to `m.default`, then this key is marked as +If a key has the `name` property set to `m.default`, then this key is treated as the default key for the account. The default key is the one that all secrets -will be encrypted with, and the clients will try to use to decrypt data with, -unless the user specifies otherwise. Only one key can be marked as the default. +will be encrypted with, and that clients will try to use to decrypt data with, +unless the user specifies otherwise. Only one key can be marked as the default +at a time. Encrypted data can be stored using the `account_data` API. The `type` for the `account_data` is defined by the feature that uses the data. For example, @@ -85,7 +86,8 @@ The data is encrypted and MACed as follows: (The key HKDF, AES, and HMAC steps are the same as what are used for encryption in olm and megolm.) -For example, a key using this algorithm could look like: +For example, the `m.secret_storage.key.[key ID]` for a key using this algorithm +could look like: ```json { @@ -159,7 +161,8 @@ that it wishes to retrieve. A device that wishes to share the secret will reply with a `m.secret.send` event, encrypted using olm. When the original client obtains the secret, it sends a `m.secret.request` event with `action` set to `cancel_request` to all devices other than the one that it received the -secret from. +secret from. Clients should ignore `m.secret.send` events received from +devices that it did not send an `m.secret.request` event to. Clients SHOULD ensure that they only share secrets with other devices that are allowed to see them. For example, clients SHOULD only share secrets with devices @@ -213,7 +216,8 @@ to read the information if they manage to get hold of the decryption keys. In particular, if the key is based on a passphrase and the passphrase can be guessed, then the secrets could be compromised. In order to help protect the secrets, clients should provide feedback to the user when their chosen -passphrase is considered weak. +passphrase is considered weak, and may also wish to prevent the user from +reusing their login password. ## Conclusion From a96a2f3fcea9897817f44e4b5194d61e13becf9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 26 Aug 2019 12:11:11 +0200 Subject: [PATCH 0755/1250] Fix the action of a room key request cancellation. The spec states that the action of a room key request cancellation should be "cancel_request" but every known implementation uses "request_cancellation" instead. This patch fixes the spec to reflect the implementations. --- event-schemas/examples/m.room_key_request$cancel_request | 2 +- event-schemas/schema/m.room_key_request | 2 +- specification/modules/end_to_end_encryption.rst | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/event-schemas/examples/m.room_key_request$cancel_request b/event-schemas/examples/m.room_key_request$cancel_request index c6eb25de..afc1c350 100644 --- a/event-schemas/examples/m.room_key_request$cancel_request +++ b/event-schemas/examples/m.room_key_request$cancel_request @@ -1,6 +1,6 @@ { "content": { - "action": "cancel_request", + "action": "request_cancellation", "requesting_device_id": "RJYKSTBOIE", "request_id": "1495474790150.19" }, diff --git a/event-schemas/schema/m.room_key_request b/event-schemas/schema/m.room_key_request index 007d0086..c08ac0e3 100644 --- a/event-schemas/schema/m.room_key_request +++ b/event-schemas/schema/m.room_key_request @@ -38,7 +38,7 @@ properties: action: enum: - request - - cancel_request + - request_cancellation type: string requesting_device_id: description: ID of the device requesting the key. diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 329c0170..7758e2c1 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -756,8 +756,8 @@ sending `m.room_key_request`_ to-device messages to other devices with device, it can forward the keys to the first device by sending an encrypted `m.forwarded_room_key`_ to-device message. The first device should then send an `m.room_key_request`_ to-device message with ``action`` set to -``cancel_request`` to the other devices that it had originally sent the key -request to; a device that receives a ``cancel_request`` should disregard any +``request_cancellation`` to the other devices that it had originally sent the key +request to; a device that receives a ``request_cancellation`` should disregard any previously-received ``request`` message with the same ``request_id`` and ``requesting_device_id``. From 35eb1993d91d27c8abe350ffc4f756a4b866b23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 26 Aug 2019 17:40:32 +0200 Subject: [PATCH 0756/1250] Add a changelog fragment for the room key request action fix. --- changelogs/client_server/newsfragments/2247.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2247.clarification diff --git a/changelogs/client_server/newsfragments/2247.clarification b/changelogs/client_server/newsfragments/2247.clarification new file mode 100644 index 00000000..43553399 --- /dev/null +++ b/changelogs/client_server/newsfragments/2247.clarification @@ -0,0 +1 @@ +Fix the ``m.room_key_request`` ``action`` value, setting it from ``cancel_request`` to ``request_cancellation``. From cafe49d36d6152789ac23202af914267a48ca011 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 27 Aug 2019 16:13:18 -0700 Subject: [PATCH 0757/1250] some clarifications --- proposals/1946-secure_server-side_storage.md | 77 +++++++++++++------- 1 file changed, 51 insertions(+), 26 deletions(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index 0e6fccb7..05c20086 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -2,10 +2,11 @@ Some features may require clients to store encrypted data on the server so that it can be shared securely between clients. Clients may also wish to securely -send such data directly to each other. For example, key backups (MSC-1219) -can store the decryption key for the backups on the server, or cross-signing -(MSC-1756) can store the signing keys. This proposal presents a standardized -way of storing such data. +send such data directly to each other. For example, key backups +([MSC1219](https://github.com/matrix-org/matrix-doc/issues/1219)) can store the +decryption key for the backups on the server, or cross-signing +([MSC1756](https://github.com/matrix-org/matrix-doc/pull/1756)) can store the +signing keys. This proposal presents a standardized way of storing such data. ## Proposal @@ -21,13 +22,29 @@ prevent homeserver administrators from being able to read it. A user can have multiple keys used for encrypting data. This allows the user to selectively decrypt data on clients. For example, the user could have one key that can decrypt everything, and another key that can only decrypt their user-signing -key for cross-signing. Each key has an ID, and a description of the key is -stored in the user's `account_data` using the `type` `m.secret_storage.key.[key -ID]`. The contents of the account data for the key will include an `algorithm` -property, which indicates the encryption algorithm used, as well as a `name` -property, which is a human-readable name. The contents will be signed as -signed JSON using the user's master cross-signing key. Other properties depend -on the encryption algorithm, and are described below. +key for cross-signing. + +Key descriptions and secret data are both stored in the user's `account_data`. + +Each key has an ID, and the description of the key is stored in the +`account_data` using the `type` `m.secret_storage.key.[key ID]`. The contents +of the account data for the key will include an `algorithm` property, which +indicates the encryption algorithm used, as well as a `name` property, which is +a human-readable name. The contents will be signed as signed JSON using the +user's master cross-signing key. Other properties depend on the encryption +algorithm, and are described below. + +Example: + +A key with ID `abcdefg` is stored in `m.secret_storage.key.abcdefg` + +```json +{ + "name": "Some key", + "algorihm": "m.secret_storage.v1.curve25519-aes-sha2", + // ... other properties according to algorithm +} +``` If a key has the `name` property set to `m.default`, then this key is treated as the default key for the account. The default key is the one that all secrets @@ -35,31 +52,39 @@ will be encrypted with, and that clients will try to use to decrypt data with, unless the user specifies otherwise. Only one key can be marked as the default at a time. -Encrypted data can be stored using the `account_data` API. The `type` for the -`account_data` is defined by the feature that uses the data. For example, -decryption keys for key backups could be stored under the type -`m.megolm_backup.v1.recovery_key`, or the self-signing key for cross-signing -could be stored under the type `m.cross_signing.self_signing`. +Encrypted data is stored in the `account_data` using the `type` defined by the +feature that uses the data. For example, decryption keys for key backups could +be stored under the type `m.megolm_backup.v1.recovery_key`, or the self-signing +key for cross-signing could be stored under the type +`m.cross_signing.self_signing`. + +The `account_data` will have an `encrypted` property that is a map from key ID +to an object. The algorithm from the `m.secret_storage.key.[key ID]` data for +the given key defines how the other properties are interpreted, though it's +expected that most encryption schemes would have `ciphertext` and `mac` +properties, where the `ciphertext` property is the unpadded base64-encoded +ciphertext, and the `mac` is used to ensure the integrity of the data. + +Example: -Data will be stored using the following format: +Some secret is encrypted using keys with ID `key_id_1` and `key_id_2`: ```json { "encrypted": { - "key_id": { + "key_id_1": { "ciphertext": "base64+encoded+encrypted+data", - "mac": "base64+encoded+mac" + "mac": "base64+encoded+mac", + // ... other properties according to algorithm property in + // m.secret_storage.key.key_id_1 + }, + "key_id_2": { + // ... } } } ``` -The `encrypted` property is map from key ID to an object. The algorithm for -the given key defines how the other properties are interpreted, though it's -expected that most encryption schemes would have `ciphertext` and `mac` -properties, where the `ciphertext` property is the unpadded base64-encoded -ciphertext, and the `mac` is used to ensure the integrity of the data. - #### Encryption algorithms ##### `m.secret_storage.v1.curve25519-aes-sha2` @@ -181,7 +206,7 @@ unencrypted to-device event. - `name`: (string) Required if `action` is `request`. The name of the secret that is being requested. -- `action`: (enum) Required. One of ["request", "cancel_request"]. +- `action`: (enum) Required. One of ["request", "request_cancellation"]. - `requesting_device_id`: (string) Required. ID of the device requesting the secret. - `request_id`: (string) Required. A random string uniquely identifying the From 9aade7291a79f90f4a4d2fad8d214a5350b57381 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 27 Aug 2019 16:21:00 -0700 Subject: [PATCH 0758/1250] make it agree with what we actually did with key requests --- proposals/1946-secure_server-side_storage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index 05c20086..0ccde311 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -185,7 +185,7 @@ set to `request` to other devices, and `name` set to the name of the secret that it wishes to retrieve. A device that wishes to share the secret will reply with a `m.secret.send` event, encrypted using olm. When the original client obtains the secret, it sends a `m.secret.request` event with `action` -set to `cancel_request` to all devices other than the one that it received the +set to `request_cancellation` to all devices other than the one that it received the secret from. Clients should ignore `m.secret.send` events received from devices that it did not send an `m.secret.request` event to. From e1b0042e7be20c43908c32845ab0ea513b70b115 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 27 Aug 2019 17:46:45 -0700 Subject: [PATCH 0759/1250] clarifications, minor fixes, formatting --- proposals/1756-cross-signing.md | 39 ++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index ec3edc33..34789fb8 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -27,8 +27,8 @@ Each user has three sets of key pairs: - a user-signing key pair that is used to sign other users' master keys. When one user (e.g. Alice) verifies another user's (Bob's) identity, Alice will -sign Bob's self-signing key with her user-signing key. (This will mean that -verification methods will need to be modified to pass along the self-signing +sign Bob's master key with her user-signing key. (This will mean that +verification methods will need to be modified to pass along the master identity key.) Alice's device will trust Bob's device if: - Alice's device is using a master key that has signed her user-signing key, @@ -66,14 +66,18 @@ keys, respectively. ### Signature distribution -Currently, users will only be allowed to see signatures made by their own -master, self-signing or user-signing keys, signatures of their own master key -made by their own devices, signatures made by other users' master or -self-signing keys about their own devices, or signatures made of other users' -master keys by their own devices. This is done in order to preserve the -privacy of social connections. Future proposals may define mechanisms for -distributing signatures to other users in order to allow for other web-of-trust -use cases. +Currently, users will only be allowed to see +* signatures made by their own master, self-signing or user-signing keys, +* signatures made by their own devices of their own master key, +* signatures made by other users' self-signing keys about the other users' own + devices, +* signatures made by other users' master keys about the other users' + self-signing key, or +* signatures made by other users' devices about the other users' master keys. + +This is done in order to preserve the privacy of social connections. Future +proposals may define mechanisms for distributing signatures to other users in +order to allow for other web-of-trust use cases. ### Migrating from device verifications @@ -134,8 +138,7 @@ Auth](https://matrix.org/docs/spec/client_server/r0.4.0.html#user-interactive-au } ``` -Cross-signing keys are JSON objects with the following -properties: +Cross-signing keys are JSON objects with the following properties: * `user_id` (string): The user who owns the key * `usage` ([string]): Allowed uses for the key. Must contain `"master"` for @@ -149,10 +152,10 @@ properties: key MAY be signed by a device. In order to ensure that there will be no collisions in the `signatures` -property, the server must respond with an error (FIXME: what error?) if any of +property, the server must respond with an `M_FORBIDDEN` error if any of the uploaded public keys match an existing device ID for the user. Similarly, if a user attempts to log in specifying a device ID matching one of the signing -keys, the server must respond with an error (FIXME: what error?). +keys, the server must respond with an `M_FORBIDDEN` error. If a self-signing or user-signing key is uploaded, it must be signed by the master key that is included in the request, or the current master key if no @@ -211,10 +214,10 @@ response: } ``` -Similarly, the federation endpoints `GET /user/keys/query` and -`POST /user/devices/{userId}` will include the master and self-signing keys. -(It will not include the user-signing key because it is not intended to be -visible to other users.) +Similarly, the federation endpoints `GET /user/keys/query` and `POST +/user/devices/{userId}` will include the master and self-signing keys. (It +will not include the user-signing key because it is not intended to be visible +to other users.) `POST /keys/query` From 03ae5614b0daf45e02f87b92f99753bfae85b3c8 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 27 Aug 2019 17:56:52 -0700 Subject: [PATCH 0760/1250] remove unnecessary space --- proposals/1756-cross-signing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 34789fb8..1dbef83c 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -58,7 +58,7 @@ the usability of signing users and devices when performing key verification. The private halves of a user's cross-signing keys be stored encrypted on the server so that they may be retrieved by new devices, or shared between devices -using [MSC 1946](https://github.com/matrix-org/matrix-doc/pull/1946). When +using [MSC1946](https://github.com/matrix-org/matrix-doc/pull/1946). When handled in this way, the keys must be base64-encoded, and use the names `m.cross_signing.master`, `m.cross_signing.self_signing`, and `m.cross_signing.user_signing` for the master, self-signing, and user-signing From de3802cd5c3d33c62bbbd50d50e82275011a7711 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 27 Aug 2019 19:24:13 -0600 Subject: [PATCH 0761/1250] List deprecated endpoints as deprecated Affects the title and the table of contents. We can't realistically alter just the table of contents, but the table of contents is generated from this header. Fixes https://github.com/matrix-org/matrix-doc/issues/1800 --- .../templating/matrix_templates/templates/http-api.tmpl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/templating/matrix_templates/templates/http-api.tmpl b/scripts/templating/matrix_templates/templates/http-api.tmpl index 74836045..d2ee3ff7 100644 --- a/scripts/templating/matrix_templates/templates/http-api.tmpl +++ b/scripts/templating/matrix_templates/templates/http-api.tmpl @@ -1,11 +1,15 @@ {% import 'tables.tmpl' as tables -%} -``{{endpoint.method}} {{endpoint.path}}`` -{{(5 + (endpoint.path | length) + (endpoint.method | length)) * title_kind}} {% if "deprecated" in endpoint and endpoint.deprecated -%} +Deprecated: ``{{endpoint.method}} {{endpoint.path}}`` +{{(17 + (endpoint.path | length) + (endpoint.method | length)) * title_kind}} + .. WARNING:: This API is deprecated and will be removed from a future release. +{% else %} +``{{endpoint.method}} {{endpoint.path}}`` +{{(5 + (endpoint.path | length) + (endpoint.method | length)) * title_kind}} {% endif -%} {{endpoint.desc}} From b8a3f970eebfe6d321587adaced8c75656986e68 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Aug 2019 13:39:42 -0600 Subject: [PATCH 0762/1250] Add security definition for access token --- api/identity/definitions/security.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 api/identity/definitions/security.yaml diff --git a/api/identity/definitions/security.yaml b/api/identity/definitions/security.yaml new file mode 100644 index 00000000..ef49ff5c --- /dev/null +++ b/api/identity/definitions/security.yaml @@ -0,0 +1,18 @@ +# Copyright 2019 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. +accessToken: + type: apiKey + description: The access_token returned by a call to ``/register``. + name: access_token + in: query From 984e0af7b221b480f3bc1bd0c9795a1a6411d515 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 24 Aug 2019 11:58:33 +0300 Subject: [PATCH 0763/1250] Re-word auth rule section on handling each target separately Co-authored-by: Jason Volk Signed-off-by: Tulir Asokan Signed-off-by: Jason Volk --- proposals/2244-mass-redactions.md | 43 ++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/proposals/2244-mass-redactions.md b/proposals/2244-mass-redactions.md index 296ffeee..68802221 100644 --- a/proposals/2244-mass-redactions.md +++ b/proposals/2244-mass-redactions.md @@ -23,17 +23,21 @@ limit would cap a single redaction event at a bit less than 1500 targets. Redactions are not intrinsically heavy, so a separate limit should not be necessary. -### Auth rules +### Client behavior +Clients shall apply existing `m.room.redaction` target behavior over an array +of event ID strings. + +### Server behavior The redaction auth rules should change to iterate the array and check if the sender has the privileges to redact each event. There are at least two potential ways to handle targets that are not found or -rejected: soft failing until all targets are found and handling each target +rejected: soft failing until all targets are found or handling each target separately. #### Soft fail -Soft fail the event until all targets are found, then accept only if the sender -has the privileges to redact every listed event. This is how redactions +[Soft fail] the event until all targets are found, then accept only if the +sender has the privileges to redact every listed event. This is how redactions currently work. This has the downside of requiring servers to fetch all the target events (and @@ -41,19 +45,27 @@ possibly forward them to clients) before being able to process and forward the redaction event. #### Handle each target separately -Handle each target separately: if some targets are not found, remember the -redaction and check auth rules when the target is received. This option brings -some complexities, but might be more optimal in situations such as a spam -attack. +The target events of an `m.room.redaction` shall no longer be considered when +deciding the authenticity of an `m.room.redaction` event. Any other existing +rules remain unchanged. + +When a server accepts an `m.room.redaction` using the modified auth rules, it +evaluates targets individually for authenticity under the existing auth rules. +Servers MUST NOT include failing and unknown entries to clients. + +> Servers do not know whether redaction targets are authorized at the time they + receive the `m.room.redaction` unless they are in possession of the target + event. Implementations retain entries in the original list which were not + shared with clients to later evaluate the target's redaction status. -When receiving a redaction event: -* Ignore illegal targets -* "Remember" targets that can't be found -* Send legal target event IDs to clients in the redaction event. +When the implementation receives a belated target from an earlier +`m.room.redaction`, it evaluates at that point whether the redaction is +authorized. -When receiving an event that is "remembered" to be possibly redacted by an -earlier redaction, check if the redaction was legal, and if it was, do not -send the event to clients. +> Servers should not send belated target events to clients if their redaction + was found to be authentic, as clients were not made aware of the redaction. + That fact is also used to simply ignore unauthorized targets and send the + events to clients normally. ## Tradeoffs @@ -64,3 +76,4 @@ send the event to clients. [1]: https://img.mau.lu/hEqqt.png [MSC2174]: https://github.com/matrix-org/matrix-doc/pull/2174 +[Soft fail]: https://matrix.org/docs/spec/server_server/r0.1.3#soft-failure From 5b53b3d0b82dcc6c7b140f4e091892cb70b3f4de Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Aug 2019 13:47:06 -0600 Subject: [PATCH 0764/1250] Clone v1 APIs verbatim --- api/identity/v2_associations.yaml | 300 ++++++++++++++++++++++++ api/identity/v2_email_associations.yaml | 175 ++++++++++++++ api/identity/v2_invitation_signing.yaml | 97 ++++++++ api/identity/v2_phone_associations.yaml | 177 ++++++++++++++ api/identity/v2_ping.yaml | 46 ++++ api/identity/v2_pubkey.yaml | 127 ++++++++++ api/identity/v2_store_invite.yaml | 161 +++++++++++++ 7 files changed, 1083 insertions(+) create mode 100644 api/identity/v2_associations.yaml create mode 100644 api/identity/v2_email_associations.yaml create mode 100644 api/identity/v2_invitation_signing.yaml create mode 100644 api/identity/v2_phone_associations.yaml create mode 100644 api/identity/v2_ping.yaml create mode 100644 api/identity/v2_pubkey.yaml create mode 100644 api/identity/v2_store_invite.yaml diff --git a/api/identity/v2_associations.yaml b/api/identity/v2_associations.yaml new file mode 100644 index 00000000..247e1b4c --- /dev/null +++ b/api/identity/v2_associations.yaml @@ -0,0 +1,300 @@ +# Copyright 2018 New Vector Ltd +# Copyright 2019 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. +swagger: '2.0' +info: + title: "Matrix Identity Service Establishing Associations API" + version: "1.0.0" +host: localhost:8090 +schemes: + - https +basePath: /_matrix/identity/api/v1 +consumes: + - application/json +produces: + - application/json +paths: + "/3pid/getValidated3pid": + get: + summary: Check whether ownership of a 3pid was validated. + description: |- + Determines if a given 3pid has been validated by a user. + operationId: getValidated3pid + parameters: + - in: query + type: string + name: sid + description: The Session ID generated by the ``requestToken`` call. + required: true + x-example: 1234 + - in: query + type: string + name: client_secret + description: The client secret passed to the ``requestToken`` call. + required: true + x-example: monkeys_are_GREAT + responses: + 200: + description: Validation information for the session. + examples: + application/json: { + "medium": "email", + "validated_at": 1457622739026, + "address": "louise@bobs.burgers" + } + schema: + type: object + properties: + medium: + type: string + description: The medium type of the 3pid. + address: + type: string + description: The address of the 3pid being looked up. + validated_at: + type: integer + description: |- + Timestamp, in milliseconds, indicating the time that the 3pid + was validated. + required: ['medium', 'address', 'validated_at'] + 400: + description: |- + The session has not been validated. + + If the session has not been validated, then ``errcode`` will be + ``M_SESSION_NOT_VALIDATED``. If the session has timed out, then + ``errcode`` will be ``M_SESSION_EXPIRED``. + examples: + application/json: { + "errcode": "M_SESSION_NOT_VALIDATED", + "error": "This validation session has not yet been completed" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" + 404: + description: The Session ID or client secret were not found. + examples: + application/json: { + "errcode": "M_NO_VALID_SESSION", + "error": "No valid session was found matching that sid and client secret" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" + "/3pid/bind": + post: + summary: Publish an association between a session and a Matrix user ID. + description: |- + Publish an association between a session and a Matrix user ID. + + Future calls to ``/lookup`` for any of the session\'s 3pids will return + this association. + + Note: for backwards compatibility with previous drafts of this + specification, the parameters may also be specified as + ``application/x-form-www-urlencoded`` data. However, this usage is + deprecated. + operationId: bind + parameters: + - in: body + name: body + schema: + type: object + example: { + "sid": "1234", + "client_secret": "monkeys_are_GREAT", + "mxid": "@ears:matrix.org" + } + properties: + sid: + type: string + description: The Session ID generated by the ``requestToken`` call. + client_secret: + type: string + description: The client secret passed to the ``requestToken`` call. + mxid: + type: string + description: The Matrix user ID to associate with the 3pids. + required: ["sid", "client_secret", "mxid"] + responses: + 200: + description: The association was published. + examples: + application/json: { + "address": "louise@bobs.burgers", + "medium": "email", + "mxid": "@ears:matrix.org", + "not_before": 1428825849161, + "not_after": 4582425849161, + "ts": 1428825849161, + "signatures": { + "matrix.org": { + "ed25519:0": "ENiU2YORYUJgE6WBMitU0mppbQjidDLanAusj8XS2nVRHPu+0t42OKA/r6zV6i2MzUbNQ3c3MiLScJuSsOiVDQ" + } + } + } + schema: + type: object + properties: + address: + type: string + description: The 3pid address of the user being looked up. + medium: + type: string + description: The medium type of the 3pid. + mxid: + type: string + description: The Matrix user ID associated with the 3pid. + not_before: + type: integer + description: A unix timestamp before which the association is not known to be valid. + not_after: + type: integer + description: A unix timestamp after which the association is not known to be valid. + ts: + type: integer + description: The unix timestamp at which the association was verified. + signatures: + type: object + description: |- + The signatures of the verifying identity servers which show that the + association should be trusted, if you trust the verifying identity + services. + $ref: "../../schemas/server-signatures.yaml" + required: + - address + - medium + - mxid + - not_before + - not_after + - ts + - signatures + 400: + description: |- + The association was not published. + + If the session has not been validated, then ``errcode`` will be + ``M_SESSION_NOT_VALIDATED``. If the session has timed out, then + ``errcode`` will be ``M_SESSION_EXPIRED``. + examples: + application/json: { + "errcode": "M_SESSION_NOT_VALIDATED", + "error": "This validation session has not yet been completed" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" + 404: + description: The Session ID or client secret were not found + examples: + application/json: { + "errcode": "M_NO_VALID_SESSION", + "error": "No valid session was found matching that sid and client secret" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" + "/3pid/unbind": + post: + summary: Remove an association between a session and a Matrix user ID. + description: |- + Remove an association between a session and a Matrix user ID. + + Future calls to ``/lookup`` for any of the session's 3pids will not + return the removed association. + + 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`` parameters, + as per ``/3pid/bind``, which proves ownership of the 3PID. + + If this endpoint returns a JSON Matrix error, that error should be passed + through to the client requesting an unbind through a homeserver, if the + homeserver is acting on behalf of a client. + operationId: unbind + parameters: + - in: body + name: body + schema: + type: object + example: { + "sid": "1234", + "client_secret": "monkeys_are_GREAT", + "mxid": "@ears:example.org", + "threepid": { + "medium": "email", + "address": "monkeys_have_ears@example.org" + } + } + properties: + sid: + type: string + description: The Session ID generated by the ``requestToken`` call. + client_secret: + type: string + description: The client secret passed to the ``requestToken`` call. + mxid: + type: string + description: The Matrix user ID to remove from the 3pids. + threepid: + type: object + title: 3PID + description: |- + The 3PID to remove. Must match the 3PID used to generate the session + if using ``sid`` and ``client_secret`` to authenticate this request. + properties: + medium: + type: string + description: |- + A medium from the `3PID Types`_ Appendix, matching the medium + of the identifier to unbind. + address: + type: string + description: The 3PID address to remove. + required: ['medium', 'address'] + required: ["threepid", "mxid"] + responses: + 200: + description: The association was successfully removed. + examples: + application/json: {} + schema: + type: object + 400: + description: |- + If the response body is not a JSON Matrix error, the identity server + does not support unbinds. If a JSON Matrix error is in the response + body, the requesting party should respect the error. + 404: + description: |- + If the response body is not a JSON Matrix error, the identity server + does not support unbinds. If a JSON Matrix error is in the response + body, the requesting party should respect the error. + 403: + description: |- + The credentials supplied to authenticate the request were invalid. + This may also be returned if the identity server does not support + the chosen authentication method (such as blocking homeservers from + unbinding identifiers). + examples: + application/json: { + "errcode": "M_FORBIDDEN", + "error": "Invalid homeserver signature" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" + 501: + description: |- + If the response body is not a JSON Matrix error, the identity server + does not support unbinds. If a JSON Matrix error is in the response + body, the requesting party should respect the error. diff --git a/api/identity/v2_email_associations.yaml b/api/identity/v2_email_associations.yaml new file mode 100644 index 00000000..9911bc5d --- /dev/null +++ b/api/identity/v2_email_associations.yaml @@ -0,0 +1,175 @@ +# Copyright 2018 New Vector Ltd +# Copyright 2019 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. +swagger: '2.0' +info: + title: "Matrix Identity Service Email Associations API" + version: "1.0.0" +host: localhost:8090 +schemes: + - https +basePath: /_matrix/identity/api/v1 +consumes: + - application/json +produces: + - application/json +paths: + "/validate/email/requestToken": + post: + summary: Request a token for validating an email address. + description: |- + Create a session for validating an email address. + + The identity server will send an email containing a token. If that + token is presented to the identity server in the future, it indicates + that that user was able to read the email for that email address, and + so we validate ownership of the email address. + + Note that homeservers offer APIs that proxy this API, adding + additional behaviour on top, for example, + ``/register/email/requestToken`` is designed specifically for use when + registering an account and therefore will inform the user if the email + address given is already registered on the server. + + Note: for backwards compatibility with previous drafts of this + specification, the parameters may also be specified as + ``application/x-form-www-urlencoded`` data. However, this usage is + deprecated. + operationId: emailRequestToken + parameters: + - in: body + name: body + schema: + $ref: "definitions/request_email_validation.yaml" + responses: + 200: + description: Session created. + schema: + $ref: "definitions/sid.yaml" + 400: + description: | + An error ocurred. Some possible errors are: + + - ``M_INVALID_EMAIL``: The email address provided was invalid. + - ``M_EMAIL_SEND_ERROR``: The validation email could not be sent. + examples: + application/json: { + "errcode": "M_INVALID_EMAIL", + "error": "The email address is not valid" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" + "/validate/email/submitToken": + post: + summary: Validate ownership of an email address. + description: |- + Validate ownership of an email address. + + If the three parameters are consistent with a set generated by a + ``requestToken`` call, ownership of the email address is considered to + have been validated. This does not publish any information publicly, or + associate the email address with any Matrix user ID. Specifically, + calls to ``/lookup`` will not show a binding. + + The identity server is free to match the token case-insensitively, or + carry out other mapping operations such as unicode + normalisation. Whether to do so is an implementation detail for the + identity server. Clients must always pass on the token without + modification. + + Note: for backwards compatibility with previous drafts of this + specification, the parameters may also be specified as + ``application/x-form-www-urlencoded`` data. However, this usage is + deprecated. + operationId: emailSubmitTokenPost + parameters: + - in: body + name: body + schema: + type: object + example: { + "sid": "1234", + "client_secret": "monkeys_are_GREAT", + "token": "atoken" + } + properties: + sid: + type: string + description: The session ID, generated by the ``requestToken`` call. + client_secret: + type: string + description: The client secret that was supplied to the ``requestToken`` call. + token: + type: string + description: The token generated by the ``requestToken`` call and emailed to the user. + required: ["sid", "client_secret", "token"] + responses: + 200: + description: + The success of the validation. + examples: + application/json: { + "success": true + } + schema: + type: object + properties: + success: + type: boolean + description: Whether the validation was successful or not. + required: ['success'] + get: + summary: Validate ownership of an email address. + description: |- + Validate ownership of an email address. + + If the three parameters are consistent with a set generated by a + ``requestToken`` call, ownership of the email address is considered to + have been validated. This does not publish any information publicly, or + associate the email address with any Matrix user ID. Specifically, + calls to ``/lookup`` will not show a binding. + + Note that, in contrast with the POST version, this endpoint will be + used by end-users, and so the response should be human-readable. + operationId: emailSubmitTokenGet + parameters: + - in: query + type: string + name: sid + required: true + description: The session ID, generated by the ``requestToken`` call. + x-example: 1234 + - in: query + type: string + name: client_secret + required: true + description: The client secret that was supplied to the ``requestToken`` call. + x-example: monkeys_are_GREAT + - in: query + type: string + name: token + required: true + description: The token generated by the ``requestToken`` call and emailed to the user. + x-example: atoken + responses: + "200": + description: Email address is validated. + "3xx": + description: |- + Email address is validated, and the ``next_link`` parameter was + provided to the ``requestToken`` call. The user must be redirected + to the URL provided by the ``next_link`` parameter. + "4xx": + description: + Validation failed. diff --git a/api/identity/v2_invitation_signing.yaml b/api/identity/v2_invitation_signing.yaml new file mode 100644 index 00000000..f2d2933d --- /dev/null +++ b/api/identity/v2_invitation_signing.yaml @@ -0,0 +1,97 @@ +# Copyright 2018 New Vector Ltd +# Copyright 2019 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. +swagger: '2.0' +info: + title: "Matrix Identity Service Ephemeral Invitation Signing API" + version: "1.0.0" +host: localhost:8090 +schemes: + - https +basePath: /_matrix/identity/api/v1 +consumes: + - application/json +produces: + - application/json +paths: + "/sign-ed25519": + post: + summary: Sign invitation details + description: |- + Sign invitation details. + + The identity server will look up ``token`` which was stored in a call + to ``store-invite``, and fetch the sender of the invite. + operationId: blindlySignStuff + parameters: + - in: body + name: body + schema: + type: object + example: { + "mxid": "@foo:bar.com", + "token": "sometoken", + "private_key": "base64encodedkey" + } + properties: + mxid: + type: string + description: The Matrix user ID of the user accepting the invitation. + token: + type: string + description: The token from the call to ``store-invite``. + private_key: + type: string + description: The private key, encoded as `Unpadded base64`_. + required: ["mxid", "token", "private_key"] + responses: + 200: + description: The signed JSON of the mxid, sender, and token. + schema: + type: object + properties: + mxid: + type: string + description: The Matrix user ID of the user accepting the invitation. + sender: + type: string + description: The Matrix user ID of the user who sent the invitation. + signatures: + type: object + description: The signature of the mxid, sender, and token. + $ref: "../../schemas/server-signatures.yaml" + token: + type: string + description: The token for the invitation. + required: ['mxid', 'sender', 'signatures', 'token'] + examples: + application/json: { + "mxid": "@foo:bar.com", + "sender": "@baz:bar.com", + "signatures": { + "my.id.server": { + "ed25519:0": "def987" + } + }, + "token": "abc123" + } + 404: + description: The token was not found. + examples: + application/json: { + "errcode": "M_UNRECOGNIZED", + "error": "Didn't recognize token" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" diff --git a/api/identity/v2_phone_associations.yaml b/api/identity/v2_phone_associations.yaml new file mode 100644 index 00000000..8d0da628 --- /dev/null +++ b/api/identity/v2_phone_associations.yaml @@ -0,0 +1,177 @@ +# Copyright 2018 New Vector Ltd +# Copyright 2019 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. +swagger: '2.0' +info: + title: "Matrix Identity Service Phone Number Associations API" + version: "1.0.0" +host: localhost:8090 +schemes: + - https +basePath: /_matrix/identity/api/v1 +consumes: + - application/json +produces: + - application/json +paths: + "/validate/msisdn/requestToken": + post: + summary: Request a token for validating a phone number. + description: |- + Create a session for validating a phone number. + + The identity server will send an SMS message containing a token. If + that token is presented to the identity server in the future, it + indicates that that user was able to read the SMS for that phone + number, and so we validate ownership of the phone number. + + Note that homeservers offer APIs that proxy this API, adding + additional behaviour on top, for example, + ``/register/msisdn/requestToken`` is designed specifically for use when + registering an account and therefore will inform the user if the phone + number given is already registered on the server. + + Note: for backwards compatibility with previous drafts of this + specification, the parameters may also be specified as + ``application/x-form-www-urlencoded`` data. However, this usage is + deprecated. + operationId: msisdnRequestToken + parameters: + - in: body + name: body + schema: + $ref: "definitions/request_msisdn_validation.yaml" + responses: + 200: + description: Session created. + schema: + $ref: "definitions/sid.yaml" + 400: + description: | + An error ocurred. Some possible errors are: + + - ``M_INVALID_ADDRESS``: The phone number provided was invalid. + - ``M_SEND_ERROR``: The validation SMS could not be sent. + - ``M_DESTINATION_REJECTED``: The identity server cannot deliver an + SMS to the provided country or region. + examples: + application/json: { + "errcode": "M_INVALID_ADDRESS", + "error": "The phone number is not valid" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" + "/validate/msisdn/submitToken": + post: + summary: Validate ownership of a phone number. + description: |- + Validate ownership of a phone number. + + If the three parameters are consistent with a set generated by a + ``requestToken`` call, ownership of the phone number is considered to + have been validated. This does not publish any information publicly, or + associate the phone number address with any Matrix user + ID. Specifically, calls to ``/lookup`` will not show a binding. + + The identity server is free to match the token case-insensitively, or + carry out other mapping operations such as unicode + normalisation. Whether to do so is an implementation detail for the + identity server. Clients must always pass on the token without + modification. + + Note: for backwards compatibility with previous drafts of this + specification, the parameters may also be specified as + ``application/x-form-www-urlencoded`` data. However, this usage is + deprecated. + operationId: msisdnSubmitTokenPost + parameters: + - in: body + name: body + schema: + type: object + example: { + "sid": "1234", + "client_secret": "monkeys_are_GREAT", + "token": "atoken" + } + properties: + sid: + type: string + description: The session ID, generated by the ``requestToken`` call. + client_secret: + type: string + description: The client secret that was supplied to the ``requestToken`` call. + token: + type: string + description: The token generated by the ``requestToken`` call and sent to the user. + required: ["sid", "client_secret", "token"] + responses: + 200: + description: + The success of the validation. + examples: + application/json: { + "success": true + } + schema: + type: object + properties: + success: + type: boolean + description: Whether the validation was successful or not. + required: ['success'] + get: + summary: Validate ownership of a phone number. + description: |- + Validate ownership of a phone number. + + If the three parameters are consistent with a set generated by a + ``requestToken`` call, ownership of the phone number address is + considered to have been validated. This does not publish any + information publicly, or associate the phone number with any Matrix + user ID. Specifically, calls to ``/lookup`` will not show a binding. + + Note that, in contrast with the POST version, this endpoint will be + used by end-users, and so the response should be human-readable. + operationId: msisdnSubmitTokenGet + parameters: + - in: query + type: string + name: sid + required: true + description: The session ID, generated by the ``requestToken`` call. + x-example: 1234 + - in: query + type: string + name: client_secret + required: true + description: The client secret that was supplied to the ``requestToken`` call. + x-example: monkeys_are_GREAT + - in: query + type: string + name: token + required: true + description: The token generated by the ``requestToken`` call and sent to the user. + x-example: atoken + responses: + "200": + description: Phone number is validated. + "3xx": + description: |- + Phone number address is validated, and the ``next_link`` parameter + was provided to the ``requestToken`` call. The user must be + redirected to the URL provided by the ``next_link`` parameter. + "4xx": + description: + Validation failed. diff --git a/api/identity/v2_ping.yaml b/api/identity/v2_ping.yaml new file mode 100644 index 00000000..fd81c7c3 --- /dev/null +++ b/api/identity/v2_ping.yaml @@ -0,0 +1,46 @@ +# Copyright 2018 Kamax Sàrl +# Copyright 2018 New Vector Ltd +# Copyright 2019 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. + +swagger: "2.0" +info: + title: "Matrix Identity Service Ping API" + version: "1.0.0" +host: localhost:8090 +schemes: + - https +basePath: /_matrix/identity +produces: + - application/json +paths: + "/api/v1": + get: + summary: Checks that an identity server is available at this API endpoint. + description: |- + Checks that an identity server is available at this API endpoint. + + To discover that an identity server is available at a specific URL, + this endpoint can be queried and will return an empty object. + + This is primarly used for auto-discovery and health check purposes + by entities acting as a client for the identity server. + operationId: ping + responses: + 200: + description: An identity server is ready to serve requests. + examples: + application/json: {} + schema: + type: object diff --git a/api/identity/v2_pubkey.yaml b/api/identity/v2_pubkey.yaml new file mode 100644 index 00000000..48446ace --- /dev/null +++ b/api/identity/v2_pubkey.yaml @@ -0,0 +1,127 @@ +# Copyright 2016 OpenMarket Ltd +# Copyright 2019 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. +swagger: '2.0' +info: + title: "Matrix Identity Service Public Key API" + version: "1.0.0" +host: localhost:8090 +schemes: + - https +basePath: /_matrix/identity/api/v1 +consumes: + - application/json +produces: + - application/json +paths: + "/pubkey/{keyId}": + get: + summary: Get a public key. + description: |- + Get the public key for the passed key ID. + operationId: getPubKey + parameters: + - in: path + type: string + name: keyId + required: true + description: |- + The ID of the key. This should take the form algorithm:identifier + where algorithm identifies the signing algorithm, and the identifier + is an opaque string. + x-example: "ed25519:0" + responses: + 200: + description: + The public key exists. + examples: + application/json: { + "public_key": "VXuGitF39UH5iRfvbIknlvlAVKgD1BsLDMvBf0pmp7c" + } + schema: + type: object + properties: + public_key: + type: string + description: Unpadded Base64 encoded public key. + required: ['public_key'] + 404: + description: + The public key was not found. + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "The public key was not found" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" + "/pubkey/isvalid": + get: + summary: Check whether a long-term public key is valid. + description: |- + Check whether a long-term public key is valid. The response should always + be the same, provided the key exists. + operationId: isPubKeyValid + parameters: + - in: query + type: string + name: public_key + required: true + description: |- + The unpadded base64-encoded public key to check. + x-example: "VXuGitF39UH5iRfvbIknlvlAVKgD1BsLDMvBf0pmp7c" + responses: + 200: + description: + The validity of the public key. + examples: + application/json: { + "valid": true + } + schema: + type: object + properties: + valid: + type: boolean + description: Whether the public key is recognised and is currently valid. + required: ['valid'] + "/pubkey/ephemeral/isvalid": + get: + summary: Check whether a short-term public key is valid. + description: |- + Check whether a short-term public key is valid. + operationId: isEphemeralPubKeyValid + parameters: + - in: query + type: string + name: public_key + required: true + description: |- + The unpadded base64-encoded public key to check. + x-example: "VXuGitF39UH5iRfvbIknlvlAVKgD1BsLDMvBf0pmp7c" + responses: + 200: + description: + The validity of the public key. + examples: + application/json: { + "valid": true + } + schema: + type: object + properties: + valid: + type: boolean + description: Whether the public key is recognised and is currently valid. + required: ['valid'] diff --git a/api/identity/v2_store_invite.yaml b/api/identity/v2_store_invite.yaml new file mode 100644 index 00000000..802478dc --- /dev/null +++ b/api/identity/v2_store_invite.yaml @@ -0,0 +1,161 @@ +# Copyright 2018 New Vector Ltd +# Copyright 2019 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. +swagger: '2.0' +info: + title: "Matrix Identity Service Store Invitations API" + version: "1.0.0" +host: localhost:8090 +schemes: + - https +basePath: /_matrix/identity/api/v1 +consumes: + - application/json +produces: + - application/json +paths: + "/store-invite": + post: + summary: Store pending invitations to a user's 3pid. + description: |- + Store pending invitations to a user's 3pid. + + In addition to the request parameters specified below, an arbitrary + number of other parameters may also be specified. These may be used in + the invite message generation described below. + + The service will generate a random token and an ephemeral key used for + accepting the invite. + + The service also generates a ``display_name`` for the inviter, which is + a redacted version of ``address`` which does not leak the full contents + of the ``address``. + + The service records persistently all of the above information. + + It also generates an email containing all of this data, sent to the + ``address`` parameter, notifying them of the invitation. + + Also, the generated ephemeral public key will be listed as valid on + requests to ``/_matrix/identity/api/v1/pubkey/ephemeral/isvalid``. + + Currently, invites may only be issued for 3pids of the ``email`` medium. + + Optional fields in the request should be populated to the best of the + server's ability. Identity servers may use these variables when notifying + the ``address`` of the pending invite for display purposes. + operationId: storeInvite + parameters: + - in: body + name: body + schema: + type: object + properties: + medium: + type: string + description: The literal string ``email``. + example: "email" + address: + type: string + description: The email address of the invited user. + example: "foo@example.com" + room_id: + type: string + description: The Matrix room ID to which the user is invited + example: "!something:example.org" + sender: + type: string + description: The Matrix user ID of the inviting user + example: "@bob:example.com" + room_alias: + type: string + description: |- + The Matrix room alias for the room to which the user is + invited. This should be retrieved from the ``m.room.canonical_alias`` + state event. + example: "#somewhere:exmaple.org" + room_avatar_url: + type: string + description: |- + The Content URI for the room to which the user is invited. This should + be retrieved from the ``m.room.avatar`` state event. + example: "mxc://example.org/s0meM3dia" + room_join_rules: + type: string + description: |- + The ``join_rule`` for the room to which the user is invited. This should + be retrieved from the ``m.room.join_rules`` state event. + example: "public" + room_name: + type: string + description: |- + The name of the room to which the user is invited. This should be retrieved + from the ``m.room.name`` state event. + example: "Bob's Emporium of Messages" + sender_display_name: + type: string + description: The display name of the user ID initiating the invite. + example: "Bob Smith" + sender_avatar_url: + type: string + description: The Content URI for the avatar of the user ID initiating the invite. + example: "mxc://example.org/an0th3rM3dia" + required: ["medium", "address", "room_id", "sender"] + responses: + 200: + description: The invitation was stored. + schema: + type: object + properties: + token: + type: string + description: | + The generated token. Must be a string consisting of the + characters ``[0-9a-zA-Z.=_-]``. Its length must not exceed + 255 characters and it must not be empty. + public_keys: + type: array + description: | + A list of [server's long-term public key, generated ephemeral + public key]. + items: + type: string + display_name: + type: string + description: The generated (redacted) display_name. + required: ['token', 'public_keys', 'display_name'] + example: + application/json: { + "token": "sometoken", + "public_keys": [ + "serverpublickey", + "ephemeralpublickey" + ], + "display_name": "f...@b..." + } + 400: + description: | + An error has occured. + + If the 3pid is already bound to a Matrix user ID, the error code + will be ``M_THREEPID_IN_USE``. If the medium is unsupported, the + error code will be ``M_UNRECOGNIZED``. + examples: + application/json: { + "errcode": "M_THREEPID_IN_USE", + "error": "Binding already known", + "mxid": "@alice:example.com" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" From cd75d0f220e8fa2d64d19e04a21a6e4b4bb35854 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 25 Aug 2019 11:29:12 +0300 Subject: [PATCH 0765/1250] Fix authenticity/authorization terminology Co-authored-by: Kitsune Ral Signed-off-by: Tulir Asokan --- proposals/2244-mass-redactions.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/2244-mass-redactions.md b/proposals/2244-mass-redactions.md index 68802221..1b012cf8 100644 --- a/proposals/2244-mass-redactions.md +++ b/proposals/2244-mass-redactions.md @@ -46,12 +46,12 @@ redaction event. #### Handle each target separately The target events of an `m.room.redaction` shall no longer be considered when -deciding the authenticity of an `m.room.redaction` event. Any other existing -rules remain unchanged. +authorizing of an `m.room.redaction` event. Any other existing rules remain +unchanged. When a server accepts an `m.room.redaction` using the modified auth rules, it -evaluates targets individually for authenticity under the existing auth rules. -Servers MUST NOT include failing and unknown entries to clients. +evaluates individually whether each target can be redacted under the existing +auth rules. Servers MUST NOT include failing and unknown entries to clients. > Servers do not know whether redaction targets are authorized at the time they receive the `m.room.redaction` unless they are in possession of the target @@ -63,7 +63,7 @@ When the implementation receives a belated target from an earlier authorized. > Servers should not send belated target events to clients if their redaction - was found to be authentic, as clients were not made aware of the redaction. + was found to be in effect, as clients were not made aware of the redaction. That fact is also used to simply ignore unauthorized targets and send the events to clients normally. From 238b78bbaf4c6c6b3019be9fc0f93e3021a8c3f2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 25 Aug 2019 20:41:39 +0300 Subject: [PATCH 0766/1250] Add potential issue with redacted_because field Signed-off-by: Tulir Asokan --- proposals/2244-mass-redactions.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/2244-mass-redactions.md b/proposals/2244-mass-redactions.md index 1b012cf8..ea0874c3 100644 --- a/proposals/2244-mass-redactions.md +++ b/proposals/2244-mass-redactions.md @@ -70,6 +70,10 @@ authorized. ## Tradeoffs ## Potential issues +A redaction with a thousand targets could mean a thousand events get `unsiged` +-> `redacted_because` containing that redaction event. One potential solution +to this is omitting the list of redacted event IDs from the data in the +`redacted_because` field. ## Security considerations From 79a5663ec3b69c0d26c4cbb56562152778075b37 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 25 Aug 2019 20:50:20 +0300 Subject: [PATCH 0767/1250] Fix typos, inline links and move image into tree Signed-off-by: Tulir Asokan --- proposals/2244-mass-redactions.md | 31 ++++++++++------------- proposals/images/2244-redaction-spam.png | Bin 0 -> 164158 bytes 2 files changed, 13 insertions(+), 18 deletions(-) create mode 100644 proposals/images/2244-redaction-spam.png diff --git a/proposals/2244-mass-redactions.md b/proposals/2244-mass-redactions.md index ea0874c3..2a24a41e 100644 --- a/proposals/2244-mass-redactions.md +++ b/proposals/2244-mass-redactions.md @@ -1,17 +1,17 @@ # Mass redactions Matrix, like any platform with public chat rooms, has spammers. Currently, redacting spam essentially requires spamming redaction events in a 1:1 ratio, -which is not optimal[1]. Most clients do not even have any mass -redaction tools, likely in part due to the lack of a mass redaction API. A mass -redaction API on the other hand has not been implemented as it would require -sending lots of events at once. However, this problem could be solved by -allowing a single redaction event to redact many events instead of sending many -redaction events. +which is not optimal[1](images/2244-redaction-spam.png). Most +clients do not even have any mass redaction tools, likely in part due to the +lack of a mass redaction API. A mass redaction API on the other hand has not +been implemented as it would require sending lots of events at once. However, +this problem could be solved by allowing a single redaction event to redact +many events instead of sending many redaction events. ## Proposal -This proposal builds upon [MSC2174] and suggests making the `redacts` field -in the content of `m.room.redaction` events an array of event ID strings -instead of a single event ID string. +This proposal builds upon [MSC2174](https://github.com/matrix-org/matrix-doc/pull/2174) +and suggests making the `redacts` field in the content of `m.room.redaction` +events an array of event ID strings instead of a single event ID string. It would be easiest to do this before MSC2174 is written into the spec, as then only one migration would be needed: from an event-level redacts string to a @@ -36,9 +36,9 @@ rejected: soft failing until all targets are found or handling each target separately. #### Soft fail -[Soft fail] the event until all targets are found, then accept only if the -sender has the privileges to redact every listed event. This is how redactions -currently work. +[Soft fail](https://matrix.org/docs/spec/server_server/r0.1.3#soft-failure) the +event until all targets are found, then accept only if the sender has the +privileges to redact every listed event. This is how redactions currently work. This has the downside of requiring servers to fetch all the target events (and possibly forward them to clients) before being able to process and forward the @@ -46,7 +46,7 @@ redaction event. #### Handle each target separately The target events of an `m.room.redaction` shall no longer be considered when -authorizing of an `m.room.redaction` event. Any other existing rules remain +authorizing an `m.room.redaction` event. Any other existing rules remain unchanged. When a server accepts an `m.room.redaction` using the modified auth rules, it @@ -76,8 +76,3 @@ to this is omitting the list of redacted event IDs from the data in the `redacted_because` field. ## Security considerations - - -[1]: https://img.mau.lu/hEqqt.png -[MSC2174]: https://github.com/matrix-org/matrix-doc/pull/2174 -[Soft fail]: https://matrix.org/docs/spec/server_server/r0.1.3#soft-failure diff --git a/proposals/images/2244-redaction-spam.png b/proposals/images/2244-redaction-spam.png new file mode 100644 index 0000000000000000000000000000000000000000..386d95767bd02f2a1e852977b4e479f930887bf9 GIT binary patch literal 164158 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 P>fS3kW!VyGqrm?H8`(gv literal 0 HcmV?d00001 From a47c5aeb426eb5c5be7c50dbdd7c82418e839484 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Aug 2019 14:17:51 -0600 Subject: [PATCH 0768/1250] v2-ify the v2 api Note that ping and pubkey doesn't require auth - see MSC2140 for more information. --- api/identity/v2_associations.yaml | 18 +++++++++++++----- api/identity/v2_email_associations.yaml | 18 +++++++++++++----- api/identity/v2_invitation_signing.yaml | 10 +++++++--- api/identity/v2_phone_associations.yaml | 18 +++++++++++++----- api/identity/v2_ping.yaml | 6 +++--- api/identity/v2_pubkey.yaml | 10 +++++----- api/identity/v2_store_invite.yaml | 12 ++++++++---- 7 files changed, 62 insertions(+), 30 deletions(-) diff --git a/api/identity/v2_associations.yaml b/api/identity/v2_associations.yaml index 247e1b4c..d1b29a8f 100644 --- a/api/identity/v2_associations.yaml +++ b/api/identity/v2_associations.yaml @@ -15,22 +15,26 @@ swagger: '2.0' info: title: "Matrix Identity Service Establishing Associations API" - version: "1.0.0" + version: "2.0.0" host: localhost:8090 schemes: - https -basePath: /_matrix/identity/api/v1 +basePath: /_matrix/identity/v2 consumes: - application/json produces: - application/json +securityDefinitions: + $ref: definitions/security.yaml paths: "/3pid/getValidated3pid": get: summary: Check whether ownership of a 3pid was validated. description: |- Determines if a given 3pid has been validated by a user. - operationId: getValidated3pid + operationId: getValidated3pidV2 + security: + - accessToken: [] parameters: - in: query type: string @@ -104,7 +108,9 @@ paths: specification, the parameters may also be specified as ``application/x-form-www-urlencoded`` data. However, this usage is deprecated. - operationId: bind + operationId: bindV2 + security: + - accessToken: [] parameters: - in: body name: body @@ -221,7 +227,9 @@ paths: If this endpoint returns a JSON Matrix error, that error should be passed through to the client requesting an unbind through a homeserver, if the homeserver is acting on behalf of a client. - operationId: unbind + operationId: unbindV2 + security: + - accessToken: [] parameters: - in: body name: body diff --git a/api/identity/v2_email_associations.yaml b/api/identity/v2_email_associations.yaml index 9911bc5d..eff18eaf 100644 --- a/api/identity/v2_email_associations.yaml +++ b/api/identity/v2_email_associations.yaml @@ -15,15 +15,17 @@ swagger: '2.0' info: title: "Matrix Identity Service Email Associations API" - version: "1.0.0" + version: "2.0.0" host: localhost:8090 schemes: - https -basePath: /_matrix/identity/api/v1 +basePath: /_matrix/identity/v2 consumes: - application/json produces: - application/json +securityDefinitions: + $ref: definitions/security.yaml paths: "/validate/email/requestToken": post: @@ -46,7 +48,9 @@ paths: specification, the parameters may also be specified as ``application/x-form-www-urlencoded`` data. However, this usage is deprecated. - operationId: emailRequestToken + operationId: emailRequestTokenV2 + security: + - accessToken: [] parameters: - in: body name: body @@ -92,7 +96,9 @@ paths: specification, the parameters may also be specified as ``application/x-form-www-urlencoded`` data. However, this usage is deprecated. - operationId: emailSubmitTokenPost + operationId: emailSubmitTokenPostV2 + security: + - accessToken: [] parameters: - in: body name: body @@ -142,7 +148,9 @@ paths: Note that, in contrast with the POST version, this endpoint will be used by end-users, and so the response should be human-readable. - operationId: emailSubmitTokenGet + operationId: emailSubmitTokenGetV2 + security: + - accessToken: [] parameters: - in: query type: string diff --git a/api/identity/v2_invitation_signing.yaml b/api/identity/v2_invitation_signing.yaml index f2d2933d..c1267bdc 100644 --- a/api/identity/v2_invitation_signing.yaml +++ b/api/identity/v2_invitation_signing.yaml @@ -15,15 +15,17 @@ swagger: '2.0' info: title: "Matrix Identity Service Ephemeral Invitation Signing API" - version: "1.0.0" + version: "2.0.0" host: localhost:8090 schemes: - https -basePath: /_matrix/identity/api/v1 +basePath: /_matrix/identity/v2 consumes: - application/json produces: - application/json +securityDefinitions: + $ref: definitions/security.yaml paths: "/sign-ed25519": post: @@ -33,7 +35,9 @@ paths: The identity server will look up ``token`` which was stored in a call to ``store-invite``, and fetch the sender of the invite. - operationId: blindlySignStuff + operationId: blindlySignStuffV2 + security: + - accessToken: [] parameters: - in: body name: body diff --git a/api/identity/v2_phone_associations.yaml b/api/identity/v2_phone_associations.yaml index 8d0da628..cfaea410 100644 --- a/api/identity/v2_phone_associations.yaml +++ b/api/identity/v2_phone_associations.yaml @@ -15,15 +15,17 @@ swagger: '2.0' info: title: "Matrix Identity Service Phone Number Associations API" - version: "1.0.0" + version: "2.0.0" host: localhost:8090 schemes: - https -basePath: /_matrix/identity/api/v1 +basePath: /_matrix/identity/v2 consumes: - application/json produces: - application/json +securityDefinitions: + $ref: definitions/security.yaml paths: "/validate/msisdn/requestToken": post: @@ -46,7 +48,9 @@ paths: specification, the parameters may also be specified as ``application/x-form-www-urlencoded`` data. However, this usage is deprecated. - operationId: msisdnRequestToken + operationId: msisdnRequestTokenV2 + security: + - accessToken: [] parameters: - in: body name: body @@ -94,7 +98,9 @@ paths: specification, the parameters may also be specified as ``application/x-form-www-urlencoded`` data. However, this usage is deprecated. - operationId: msisdnSubmitTokenPost + operationId: msisdnSubmitTokenPostV2 + security: + - accessToken: [] parameters: - in: body name: body @@ -144,7 +150,9 @@ paths: Note that, in contrast with the POST version, this endpoint will be used by end-users, and so the response should be human-readable. - operationId: msisdnSubmitTokenGet + operationId: msisdnSubmitTokenGetV2 + security: + - accessToken: [] parameters: - in: query type: string diff --git a/api/identity/v2_ping.yaml b/api/identity/v2_ping.yaml index fd81c7c3..61f5d35b 100644 --- a/api/identity/v2_ping.yaml +++ b/api/identity/v2_ping.yaml @@ -17,7 +17,7 @@ swagger: "2.0" info: title: "Matrix Identity Service Ping API" - version: "1.0.0" + version: "2.0.0" host: localhost:8090 schemes: - https @@ -25,7 +25,7 @@ basePath: /_matrix/identity produces: - application/json paths: - "/api/v1": + "/v2": get: summary: Checks that an identity server is available at this API endpoint. description: |- @@ -36,7 +36,7 @@ paths: This is primarly used for auto-discovery and health check purposes by entities acting as a client for the identity server. - operationId: ping + operationId: pingV2 responses: 200: description: An identity server is ready to serve requests. diff --git a/api/identity/v2_pubkey.yaml b/api/identity/v2_pubkey.yaml index 48446ace..68facd68 100644 --- a/api/identity/v2_pubkey.yaml +++ b/api/identity/v2_pubkey.yaml @@ -15,11 +15,11 @@ swagger: '2.0' info: title: "Matrix Identity Service Public Key API" - version: "1.0.0" + version: "2.0.0" host: localhost:8090 schemes: - https -basePath: /_matrix/identity/api/v1 +basePath: /_matrix/identity/v2 consumes: - application/json produces: @@ -30,7 +30,7 @@ paths: summary: Get a public key. description: |- Get the public key for the passed key ID. - operationId: getPubKey + operationId: getPubKeyV2 parameters: - in: path type: string @@ -72,7 +72,7 @@ paths: description: |- Check whether a long-term public key is valid. The response should always be the same, provided the key exists. - operationId: isPubKeyValid + operationId: isPubKeyValidV2 parameters: - in: query type: string @@ -101,7 +101,7 @@ paths: summary: Check whether a short-term public key is valid. description: |- Check whether a short-term public key is valid. - operationId: isEphemeralPubKeyValid + operationId: isEphemeralPubKeyValidV2 parameters: - in: query type: string diff --git a/api/identity/v2_store_invite.yaml b/api/identity/v2_store_invite.yaml index 802478dc..afc41a1c 100644 --- a/api/identity/v2_store_invite.yaml +++ b/api/identity/v2_store_invite.yaml @@ -15,15 +15,17 @@ swagger: '2.0' info: title: "Matrix Identity Service Store Invitations API" - version: "1.0.0" + version: "2.0.0" host: localhost:8090 schemes: - https -basePath: /_matrix/identity/api/v1 +basePath: /_matrix/identity/v2 consumes: - application/json produces: - application/json +securityDefinitions: + $ref: definitions/security.yaml paths: "/store-invite": post: @@ -48,14 +50,16 @@ paths: ``address`` parameter, notifying them of the invitation. Also, the generated ephemeral public key will be listed as valid on - requests to ``/_matrix/identity/api/v1/pubkey/ephemeral/isvalid``. + requests to ``/_matrix/identity/v2/pubkey/ephemeral/isvalid``. Currently, invites may only be issued for 3pids of the ``email`` medium. Optional fields in the request should be populated to the best of the server's ability. Identity servers may use these variables when notifying the ``address`` of the pending invite for display purposes. - operationId: storeInvite + operationId: storeInviteV2 + security: + - accessToken: [] parameters: - in: body name: body From b0acaeddfadb5e7753201e9e0f79dab581b7a3f6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Aug 2019 14:18:11 -0600 Subject: [PATCH 0769/1250] Reference the v2 API where possible --- specification/identity_service_api.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/specification/identity_service_api.rst b/specification/identity_service_api.rst index 89604644..f8211f70 100644 --- a/specification/identity_service_api.rst +++ b/specification/identity_service_api.rst @@ -57,6 +57,8 @@ The following other versions are also available, in reverse chronological order: General principles ------------------ +.. TODO: TravisR - Define auth for IS v2 API in a future PR + The purpose of an identity server is to validate, store, and answer questions about the identities of users. In particular, it stores associations of the form "identifier X represents the same user as identifier Y", where identities may @@ -176,6 +178,8 @@ Status check {{ping_is_http_api}} +{{v2_ping_is_http_api}} + Key management -------------- @@ -195,11 +199,15 @@ service's long-term keys. {{pubkey_is_http_api}} +{{v2_pubkey_is_http_api}} + Association lookup ------------------ {{lookup_is_http_api}} +.. TODO: TravisR - Add v2 lookup API in future PR + Establishing associations ------------------------- @@ -243,16 +251,22 @@ Email associations {{email_associations_is_http_api}} +{{v2_email_associations_is_http_api}} + Phone number associations ~~~~~~~~~~~~~~~~~~~~~~~~~ {{phone_associations_is_http_api}} +{{v2_phone_associations_is_http_api}} + General ~~~~~~~ {{associations_is_http_api}} +{{v2_associations_is_http_api}} + Invitation storage ------------------ @@ -267,6 +281,8 @@ long-term private key for the identity server. {{store_invite_is_http_api}} +{{v2_store_invite_is_http_api}} + Ephemeral invitation signing ---------------------------- @@ -277,6 +293,8 @@ this isn't possible. {{invitation_signing_is_http_api}} +{{v2_invitation_signing_is_http_api}} + .. _`Unpadded Base64`: ../appendices.html#unpadded-base64 .. _`3PID Types`: ../appendices.html#pid-types .. _`Signing JSON`: ../appendices.html#signing-json From ca4d9d8636a883cfdf122e3df41562786ff823ef Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Aug 2019 14:19:13 -0600 Subject: [PATCH 0770/1250] Deprecate the v1 IS API --- api/identity/associations.yaml | 3 +++ api/identity/email_associations.yaml | 3 +++ api/identity/invitation_signing.yaml | 1 + api/identity/lookup.yaml | 2 ++ api/identity/phone_associations.yaml | 3 +++ api/identity/ping.yaml | 1 + api/identity/pubkey.yaml | 3 +++ api/identity/store_invite.yaml | 1 + 8 files changed, 17 insertions(+) diff --git a/api/identity/associations.yaml b/api/identity/associations.yaml index 8ff4a9ed..82c70fb8 100644 --- a/api/identity/associations.yaml +++ b/api/identity/associations.yaml @@ -30,6 +30,7 @@ paths: description: |- Determines if a given 3pid has been validated by a user. operationId: getValidated3pid + deprecated: true parameters: - in: query type: string @@ -104,6 +105,7 @@ paths: ``application/x-form-www-urlencoded`` data. However, this usage is deprecated. operationId: bind + deprecated: true parameters: - in: body name: body @@ -221,6 +223,7 @@ paths: through to the client requesting an unbind through a homeserver, if the homeserver is acting on behalf of a client. operationId: unbind + deprecated: true parameters: - in: body name: body diff --git a/api/identity/email_associations.yaml b/api/identity/email_associations.yaml index 38186432..6ac28cd0 100644 --- a/api/identity/email_associations.yaml +++ b/api/identity/email_associations.yaml @@ -46,6 +46,7 @@ paths: ``application/x-form-www-urlencoded`` data. However, this usage is deprecated. operationId: emailRequestToken + deprecated: true parameters: - in: body name: body @@ -92,6 +93,7 @@ paths: ``application/x-form-www-urlencoded`` data. However, this usage is deprecated. operationId: emailSubmitTokenPost + deprecated: true parameters: - in: body name: body @@ -142,6 +144,7 @@ paths: Note that, in contrast with the POST version, this endpoint will be used by end-users, and so the response should be human-readable. operationId: emailSubmitTokenGet + deprecated: true parameters: - in: query type: string diff --git a/api/identity/invitation_signing.yaml b/api/identity/invitation_signing.yaml index 4e10e2b5..e2ac28b0 100644 --- a/api/identity/invitation_signing.yaml +++ b/api/identity/invitation_signing.yaml @@ -33,6 +33,7 @@ paths: The identity server will look up ``token`` which was stored in a call to ``store-invite``, and fetch the sender of the invite. operationId: blindlySignStuff + deprecated: true parameters: - in: body name: body diff --git a/api/identity/lookup.yaml b/api/identity/lookup.yaml index fd50f94b..166b0962 100644 --- a/api/identity/lookup.yaml +++ b/api/identity/lookup.yaml @@ -32,6 +32,7 @@ paths: summary: Look up the Matrix user ID for a 3pid. description: Look up the Matrix user ID for a 3pid. operationId: lookupUser + deprecated: true parameters: - in: query type: string @@ -101,6 +102,7 @@ paths: summary: Lookup Matrix user IDs for a list of 3pids. description: Lookup Matrix user IDs for a list of 3pids. operationId: lookupUsers + deprecated: true parameters: - in: body name: body diff --git a/api/identity/phone_associations.yaml b/api/identity/phone_associations.yaml index b9933f1a..28312a4d 100644 --- a/api/identity/phone_associations.yaml +++ b/api/identity/phone_associations.yaml @@ -46,6 +46,7 @@ paths: ``application/x-form-www-urlencoded`` data. However, this usage is deprecated. operationId: msisdnRequestToken + deprecated: true parameters: - in: body name: body @@ -94,6 +95,7 @@ paths: ``application/x-form-www-urlencoded`` data. However, this usage is deprecated. operationId: msisdnSubmitTokenPost + deprecated: true parameters: - in: body name: body @@ -144,6 +146,7 @@ paths: Note that, in contrast with the POST version, this endpoint will be used by end-users, and so the response should be human-readable. operationId: msisdnSubmitTokenGet + deprecated: true parameters: - in: query type: string diff --git a/api/identity/ping.yaml b/api/identity/ping.yaml index 05e12a87..d7249a77 100644 --- a/api/identity/ping.yaml +++ b/api/identity/ping.yaml @@ -36,6 +36,7 @@ paths: This is primarly used for auto-discovery and health check purposes by entities acting as a client for the identity server. operationId: ping + deprecated: true responses: 200: description: An identity server is ready to serve requests. diff --git a/api/identity/pubkey.yaml b/api/identity/pubkey.yaml index e657c61c..a585e7ec 100644 --- a/api/identity/pubkey.yaml +++ b/api/identity/pubkey.yaml @@ -30,6 +30,7 @@ paths: description: |- Get the public key for the passed key ID. operationId: getPubKey + deprecated: true parameters: - in: path type: string @@ -72,6 +73,7 @@ paths: Check whether a long-term public key is valid. The response should always be the same, provided the key exists. operationId: isPubKeyValid + deprecated: true parameters: - in: query type: string @@ -101,6 +103,7 @@ paths: description: |- Check whether a short-term public key is valid. operationId: isEphemeralPubKeyValid + deprecated: true parameters: - in: query type: string diff --git a/api/identity/store_invite.yaml b/api/identity/store_invite.yaml index bca78d7e..4a5d525d 100644 --- a/api/identity/store_invite.yaml +++ b/api/identity/store_invite.yaml @@ -55,6 +55,7 @@ paths: server's ability. Identity servers may use these variables when notifying the ``address`` of the pending invite for display purposes. operationId: storeInvite + deprecated: true parameters: - in: body name: body From ef5d3b9f302982f04f1decad72c0cdaefbc398e4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Aug 2019 15:12:24 -0600 Subject: [PATCH 0771/1250] Correct token reference in MSC2140 --- proposals/2140-terms-of-service-2.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 9f96a00b..e5bcd0ac 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -170,7 +170,7 @@ This endpoint does *not* require authentication. #### `POST $prefix/terms`: Requests to this endpoint have a single key, `user_accepts` whose value is -a list of URLs (given by the `url` field in the GET response) of documents that +a list of URLs (given by the `url` field in the GET response) of documents that the user has agreed to: ```json @@ -269,7 +269,7 @@ A client uses this client/server API endpoint to request that the Homeserver removes the given 3PID from the given Identity Server, or all Identity Servers. Takes the same parameters as `POST /_matrix/client/r0/account/3pid/delete`, ie. `id_server`, `medium`, -`address` and the newly added `is_token`. +`address` and the newly added `id_access_token`. Returns the same as `POST /_matrix/client/r0/account/3pid/delete`. From e40d9e296d098a5a476efaa5e0f845418c017333 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Aug 2019 15:12:47 -0600 Subject: [PATCH 0772/1250] Split OpenID token info out verbatim --- .../definitions/openid_token.yaml | 36 +++++++++++++++++++ api/client-server/openid.yaml | 23 +----------- 2 files changed, 37 insertions(+), 22 deletions(-) create mode 100644 api/client-server/definitions/openid_token.yaml diff --git a/api/client-server/definitions/openid_token.yaml b/api/client-server/definitions/openid_token.yaml new file mode 100644 index 00000000..8c84c26f --- /dev/null +++ b/api/client-server/definitions/openid_token.yaml @@ -0,0 +1,36 @@ +# Copyright 2018 New Vector Ltd +# Copyright 2019 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 +properties: + access_token: + type: string + description: |- + An access token the consumer may use to verify the identity of + the person who generated the token. This is given to the federation + API ``GET /openid/userinfo``. + token_type: + type: string + description: The string ``Bearer``. + matrix_server_name: + type: string + description: |- + The homeserver domain the consumer should use when attempting to + verify the user's identity. + expires_in: + type: integer + description: |- + The number of seconds before this token expires and a new one must + be generated. +required: ['access_token', 'token_type', 'matrix_server_name', 'expires_in'] diff --git a/api/client-server/openid.yaml b/api/client-server/openid.yaml index cb982fb3..01fdf68f 100644 --- a/api/client-server/openid.yaml +++ b/api/client-server/openid.yaml @@ -73,28 +73,7 @@ paths: "expires_in": 3600, } schema: - type: object - properties: - access_token: - type: string - description: |- - An access token the consumer may use to verify the identity of - the person who generated the token. This is given to the federation - API ``GET /openid/userinfo``. - token_type: - type: string - description: The string ``Bearer``. - matrix_server_name: - type: string - description: |- - The homeserver domain the consumer should use when attempting to - verify the user's identity. - expires_in: - type: integer - description: |- - The number of seconds before this token expires and a new one must - be generated. - required: ['access_token', 'token_type', 'matrix_server_name', 'expires_in'] + $ref: "definitions/openid_token.yaml" 429: description: This request was rate-limited. schema: From 4d0ea641211e2ea0292a1bc12392b955c903f285 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Aug 2019 15:39:49 -0600 Subject: [PATCH 0773/1250] Define authentication, ripping off the client-server API description --- .../definitions/openid_token.yaml | 2 +- api/identity/v2_auth.yaml | 109 ++++++++++++++++++ specification/identity_service_api.rst | 29 ++++- 3 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 api/identity/v2_auth.yaml diff --git a/api/client-server/definitions/openid_token.yaml b/api/client-server/definitions/openid_token.yaml index 8c84c26f..b50fcd54 100644 --- a/api/client-server/definitions/openid_token.yaml +++ b/api/client-server/definitions/openid_token.yaml @@ -19,7 +19,7 @@ properties: description: |- An access token the consumer may use to verify the identity of the person who generated the token. This is given to the federation - API ``GET /openid/userinfo``. + API ``GET /openid/userinfo`` to verify the user's identity. token_type: type: string description: The string ``Bearer``. diff --git a/api/identity/v2_auth.yaml b/api/identity/v2_auth.yaml new file mode 100644 index 00000000..16864b8e --- /dev/null +++ b/api/identity/v2_auth.yaml @@ -0,0 +1,109 @@ +# Copyright 2019 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. +swagger: '2.0' +info: + title: "Matrix Identity Service Authentication API" + version: "2.0.0" +host: localhost:8090 +schemes: + - https +basePath: /_matrix/identity/v2 +consumes: + - application/json +produces: + - application/json +securityDefinitions: + $ref: definitions/security.yaml +paths: + "/account/register": + post: + summary: Exchanges an OpenID token for an access token. + description: |- + Exchanges an OpenID token from the homeserver for an access token to + access the identity server. The request body is the same as the values + returned by ``/openid/request_token`` in the Client-Server API. + operationId: registerAccount + parameters: + - in: body + name: body + schema: + $ref: "../client-server/definitions/openid_token.yaml" + responses: + 200: + description: |- + A token which can be used to authenticate future requests to the + identity server. + examples: + application/json: { + "token": "abc123_OpaqueString" + } + schema: + type: object + properties: + token: + type: string + description: |- + An opaque string representing the token to authenticate future + requests to the identity server with. + required: ['token'] + "/account": + get: + summary: Gets account holder information for a given token. + description: |- + Gets information about what user owns the access token used in the request. + operationId: getAccount + security: + - accessToken: [] + parameters: [] + responses: + 200: + description: The token holder's information. + examples: + application/json: { + "user_id": "@alice:example.org" + } + schema: + type: object + properties: + user_id: + type: string + description: The user ID which registered the token. + required: ['user_id'] + "/account/logout": + post: + summary: Logs out an access token, rendering it unusable. + description: |- + Logs out the access token, preventing it from being used to authenticate + future requests to the server. + operationId: logout + security: + - accessToken: [] + parameters: [] + responses: + 200: + description: The token was successfully logged out. + examples: + application/json: {} + schema: + type: object + 401: + description: |- + The token is not registered or is otherwise unknown to the server. + examples: + application/json: { + "errcode": "M_UNKNOWN_TOKEN", + "error": "Unrecognised access token" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" diff --git a/specification/identity_service_api.rst b/specification/identity_service_api.rst index f8211f70..455e10b4 100644 --- a/specification/identity_service_api.rst +++ b/specification/identity_service_api.rst @@ -57,8 +57,6 @@ The following other versions are also available, in reverse chronological order: General principles ------------------ -.. TODO: TravisR - Define auth for IS v2 API in a future PR - The purpose of an identity server is to validate, store, and answer questions about the identities of users. In particular, it stores associations of the form "identifier X represents the same user as identifier Y", where identities may @@ -173,6 +171,33 @@ to be returned by servers on all requests are:: Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization +Authentication +-------------- + +Most ``v2`` endpoints in the Identity Service API require authentication in order +to ensure that the requesting user has accepted all relevant policies and is otherwise +permitted to make the request. The ``v1`` API (currently deprecated) does not require +this authentication, however using ``v1`` is strongly discouraged as it will be removed +in a future release. + +Identity Servers use a scheme similar to the Client-Server API's concept of access +tokens to authenticate users. The access tokens provided by an Identity Server cannot +be used to authenticate Client-Server API requests. + +An access token is provided to an endpoint in one of two ways: + +1. Via a query string parameter, ``access_token=TheTokenHere``. +2. Via a request header, ``Authorization: Bearer TheTokenHere``. + +Clients are encouraged to the use the ``Authorization`` header where possible to prevent +the access token being leaked in access/HTTP logs. The query string should only be used +in cases where the ``Authorization`` header is inaccessible for the client. + +When credentials are required but missing or invalid, the HTTP call will return with a +status of 401 and the error code ``M_MISSING_TOKEN`` or ``M_UNKNOWN_TOKEN`` respectively. + +{{v2_auth_is_http_api}} + Status check ------------ From 0408373cf93bed99ab8422b84467da539b258b31 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Aug 2019 15:43:47 -0600 Subject: [PATCH 0774/1250] Litter the client-server API with id_access_token --- api/client-server/administrative_contact.yaml | 11 ++++++++++- api/client-server/create_room.yaml | 5 ++++- .../definitions/request_email_validation.yaml | 5 ++++- .../definitions/request_msisdn_validation.yaml | 5 ++++- api/client-server/registration.yaml | 5 +++++ api/client-server/third_party_membership.yaml | 6 +++++- specification/client_server_api.rst | 6 ++++-- 7 files changed, 36 insertions(+), 7 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 0e93e4cd..30153bb0 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -110,10 +110,13 @@ paths: id_server: type: string description: The identity server to use. + id_access_token: + type: string + description: An access token previously registered with the identity server. sid: type: string description: The session identifier given by the identity server. - required: ["client_secret", "id_server", "sid"] + required: ["client_secret", "id_server", "id_access_token", "sid"] bind: type: boolean description: |- @@ -125,6 +128,7 @@ paths: example: { "three_pid_creds": { "id_server": "matrix.org", + "id_access_token": "abc123_OpaqueString", "sid": "abc123987", "client_secret": "d0n'tT3ll" }, @@ -189,6 +193,11 @@ paths: homeserver does not know the original ``id_server``, it MUST return a ``id_server_unbind_result`` of ``no-support``. example: "example.org" + id_access_token: + type: string + description: |- + An access token previously registered with the identity server. Required + if an ``id_server`` is specified. medium: type: string description: The medium of the third party identifier being removed. diff --git a/api/client-server/create_room.yaml b/api/client-server/create_room.yaml index bce61aad..d7a29d99 100644 --- a/api/client-server/create_room.yaml +++ b/api/client-server/create_room.yaml @@ -139,6 +139,9 @@ paths: id_server: type: string description: The hostname+port of the identity server which should be used for third party identifier lookups. + id_access_token: + type: string + description: An access token previously registered with the identity server. medium: type: string # TODO: Link to Identity Service spec when it eixsts @@ -146,7 +149,7 @@ paths: address: type: string description: The invitee's third party identifier. - required: ["id_server", "medium", "address"] + required: ["id_server", "id_access_token", "medium", "address"] room_version: type: string description: |- diff --git a/api/client-server/definitions/request_email_validation.yaml b/api/client-server/definitions/request_email_validation.yaml index 15bc5b3a..63e3ee21 100644 --- a/api/client-server/definitions/request_email_validation.yaml +++ b/api/client-server/definitions/request_email_validation.yaml @@ -23,4 +23,7 @@ allOf: include a port. This parameter is ignored when the homeserver handles 3PID verification. example: "id.example.com" - required: ["id_server"] + id_access_token: + type: string + description: An access token previously registered with the identity server. + required: ["id_server", "id_access_token"] diff --git a/api/client-server/definitions/request_msisdn_validation.yaml b/api/client-server/definitions/request_msisdn_validation.yaml index 370a10cc..43513628 100644 --- a/api/client-server/definitions/request_msisdn_validation.yaml +++ b/api/client-server/definitions/request_msisdn_validation.yaml @@ -23,4 +23,7 @@ allOf: include a port. This parameter is ignored when the homeserver handles 3PID verification. example: "id.example.com" - required: ["id_server"] + id_access_token: + type: string + description: An access token previously registered with the identity server. + required: ["id_server", "id_access_token"] diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 71177d0c..a747e38b 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -542,6 +542,11 @@ paths: it must return an ``id_server_unbind_result`` of ``no-support``. example: "example.org" + id_access_token: + type: string + description: |- + An access token previously registered with the identity server. Required if an + ``id_server`` is supplied. responses: 200: description: The account has been deactivated. diff --git a/api/client-server/third_party_membership.yaml b/api/client-server/third_party_membership.yaml index 077e1f6a..075cd34b 100644 --- a/api/client-server/third_party_membership.yaml +++ b/api/client-server/third_party_membership.yaml @@ -92,6 +92,7 @@ paths: type: object example: { "id_server": "matrix.org", + "id_access_token": "abc123_OpaqueString", "medium": "email", "address": "cheeky@monkey.com" } @@ -99,6 +100,9 @@ paths: id_server: type: string description: The hostname+port of the identity server which should be used for third party identifier lookups. + id_access_token: + type: string + description: An access token previously registered with the identity server. medium: type: string # TODO: Link to Identity Service spec when it eixsts @@ -106,7 +110,7 @@ paths: address: type: string description: The invitee's third party identifier. - required: ["id_server", "medium", "address"] + required: ["id_server", "id_access_token", "medium", "address"] responses: 200: description: The user has been invited to join the room. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 916604a3..5ff710d1 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -802,7 +802,8 @@ To use this authentication type, clients should submit an auth dict as follows: { "sid": "", "client_secret": "", - "id_server": "" + "id_server": "", + "id_access_token": "" } ], "session": "" @@ -830,7 +831,8 @@ To use this authentication type, clients should submit an auth dict as follows: { "sid": "", "client_secret": "", - "id_server": "" + "id_server": "", + "id_access_token": "" } ], "session": "" From aa98137514f121c55a1e4282bb50835fb85b8e82 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Aug 2019 15:45:28 -0600 Subject: [PATCH 0775/1250] Add changelog --- changelogs/client_server/newsfragments/2255.breaking | 1 + changelogs/identity_service/newsfragments/2255.new | 1 + 2 files changed, 2 insertions(+) create mode 100644 changelogs/client_server/newsfragments/2255.breaking create mode 100644 changelogs/identity_service/newsfragments/2255.new diff --git a/changelogs/client_server/newsfragments/2255.breaking b/changelogs/client_server/newsfragments/2255.breaking new file mode 100644 index 00000000..f9c8c6e1 --- /dev/null +++ b/changelogs/client_server/newsfragments/2255.breaking @@ -0,0 +1 @@ +Add a required ``id_access_token`` to many places which require an ``id_server`` parameter. diff --git a/changelogs/identity_service/newsfragments/2255.new b/changelogs/identity_service/newsfragments/2255.new new file mode 100644 index 00000000..fcb6ba88 --- /dev/null +++ b/changelogs/identity_service/newsfragments/2255.new @@ -0,0 +1 @@ +Add ``/account``, ``/account/register``, and ``/account/logout`` to authenticate with the identity server. From fad99743836862d6651816de0a23d3437fd0987b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Aug 2019 15:40:02 -0600 Subject: [PATCH 0776/1250] Add missed changelog from prior PR --- changelogs/identity_service/newsfragments/2254.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/identity_service/newsfragments/2254.feature diff --git a/changelogs/identity_service/newsfragments/2254.feature b/changelogs/identity_service/newsfragments/2254.feature new file mode 100644 index 00000000..089d01fe --- /dev/null +++ b/changelogs/identity_service/newsfragments/2254.feature @@ -0,0 +1 @@ +Deprecate the v1 API in favour of an authenticated v2 API. From 91f862d9e8c34ec2b85be955975ae44b41351249 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Aug 2019 20:57:07 -0600 Subject: [PATCH 0777/1250] Use the right error code for 401 errors --- specification/identity_service_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/identity_service_api.rst b/specification/identity_service_api.rst index 455e10b4..4afac6ef 100644 --- a/specification/identity_service_api.rst +++ b/specification/identity_service_api.rst @@ -194,7 +194,7 @@ the access token being leaked in access/HTTP logs. The query string should only in cases where the ``Authorization`` header is inaccessible for the client. When credentials are required but missing or invalid, the HTTP call will return with a -status of 401 and the error code ``M_MISSING_TOKEN`` or ``M_UNKNOWN_TOKEN`` respectively. +status of 401 and the error code ``M_UNAUTHORIZED``. {{v2_auth_is_http_api}} From c909a7c423aea546a5d31ea7d424bdda2473f1eb Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 29 Aug 2019 21:18:02 +0300 Subject: [PATCH 0778/1250] Move omitting redacted_because into proposal and add security consideration Signed-off-by: Tulir Asokan --- proposals/2244-mass-redactions.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/proposals/2244-mass-redactions.md b/proposals/2244-mass-redactions.md index 2a24a41e..38d699e1 100644 --- a/proposals/2244-mass-redactions.md +++ b/proposals/2244-mass-redactions.md @@ -23,11 +23,18 @@ limit would cap a single redaction event at a bit less than 1500 targets. Redactions are not intrinsically heavy, so a separate limit should not be necessary. +Due to the possible large number of redaction targets per redaction event, +servers should omit the list of redaction targets from the `unsigned` -> +`redacted_because` field of redacted events. If clients want to get the list +of targets of a redaction event in `redacted_because`, they should read the +`event_id` field of the `redacted_because` event and use the +`/rooms/{roomId}/event/{eventId}` endpoint to fetch the content. + ### Client behavior Clients shall apply existing `m.room.redaction` target behavior over an array of event ID strings. -### Server behavior +### Server behavior (auth rules) The redaction auth rules should change to iterate the array and check if the sender has the privileges to redact each event. @@ -70,9 +77,7 @@ authorized. ## Tradeoffs ## Potential issues -A redaction with a thousand targets could mean a thousand events get `unsiged` --> `redacted_because` containing that redaction event. One potential solution -to this is omitting the list of redacted event IDs from the data in the -`redacted_because` field. ## Security considerations +Server implementations should ensure that large redaction events do not become +a DoS vector, e.g. by processing redactions in the background. From 1d6501b6ecae194e5b105c513bb412548f1d0ab6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 29 Aug 2019 13:51:38 -0600 Subject: [PATCH 0779/1250] What if we allowed homeservers to deal with their own business? --- proposals/0000-id_server-now-optional.md | 57 ++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 proposals/0000-id_server-now-optional.md diff --git a/proposals/0000-id_server-now-optional.md b/proposals/0000-id_server-now-optional.md new file mode 100644 index 00000000..a066cf6b --- /dev/null +++ b/proposals/0000-id_server-now-optional.md @@ -0,0 +1,57 @@ +# Proposal to make the `id_server` parameter on client-server APIs optional + +In order to better protect the privacy of of a user, Matrix is wanting to shift to +a model where identity servers have less control over the affairs of the homeserver. +Identity servers are currently used to reset the passwords of users on a given homeserver +as an identity verification technique, however there is no reason why the homeserver +itself can't handle the verification. This proposal allows for a homeserver to verify +the identity of users itself, without the use of an identity server. + +## Proposal + +The `id_server` parameter is to become optional on the following endpoints: + +* `/_matrix/client/:version/account/3pid/:medium/requestToken` +* `/_matrix/client/:version/register/:medium/requestToken` +* `/_matrix/client/:version/account/password/:medium/requestToken` + +The `id_server` parameter is additionally deprecated with intentions of being removed +in a future specification release on the `/register/:medium` and `/account/password/:medium` +endpoints. Once appropriate adoption has been achieved, the specification can safely +remove the parameter as supported. The reason for this deprecation is to completely +remove the identity server's ability to be involved in password resets/registration. +Users wishing to bind their 3rd party identifiers can do so after registration, and +clients can automate this if they so desire. + +Similarly, `bind_email` and `bind_msisdn` are deprecated with intentions to be removed +in a future specification version on `/register`. The flags have no effect if no `id_server` +is being used. + +As per [MSC2140](https://github.com/matrix-org/matrix-doc/pull/2140), an `id_access_token` +is required only if an `id_server` is supplied. + +Although not specified as required in the specification currently, the `id_server` +as part of User-Interactive Authentication is also optional if this proposal is accepted. +When the client requests a token without an `id_server`, it should not specify an +`id_server` in UIA. + +Homeservers can reuse HTTP 400 `M_SERVER_NOT_TRUSTED` as an error code on the `/requestToken` +endpoints listed above if they do not trust the identity server the user is supplying. + +In order to allow client implementations to determine if the homeserver they are developed +against supports `id_server` being optional, an unstable feature flag of `m.require_identity_server` +is to be added to `/versions`. When the flag is `false` or not present, clients must assume +that the homeserver requires an `id_server` (ie: it has not yet considered it optional). +If this proposal is accepted, clients are expected to use the supported specification versions +the homeserver advertises instead of the feature flag's presence. + +## Tradeoffs + +Homeservers may have to set up MSISDN/email support to their implementations. This is believed +to be of minimal risk compared to allowing the identity server to continue being involved +with password reset/registration. + +## Security considerations + +The identity server was previously involved with affairs only the homeserver cares about. +This is no longer the case. From 4e43024039e10ade0ec4e40b2396dcfa69b743b6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 29 Aug 2019 13:54:53 -0600 Subject: [PATCH 0780/1250] Assign number --- ...0-id_server-now-optional.md => 2263-homeserver-pw-resets.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename proposals/{0000-id_server-now-optional.md => 2263-homeserver-pw-resets.md} (96%) diff --git a/proposals/0000-id_server-now-optional.md b/proposals/2263-homeserver-pw-resets.md similarity index 96% rename from proposals/0000-id_server-now-optional.md rename to proposals/2263-homeserver-pw-resets.md index a066cf6b..8db52572 100644 --- a/proposals/0000-id_server-now-optional.md +++ b/proposals/2263-homeserver-pw-resets.md @@ -1,4 +1,4 @@ -# Proposal to make the `id_server` parameter on client-server APIs optional +# MSC2263: Give homeservers the ability to handle their own 3PID registrations/password resets In order to better protect the privacy of of a user, Matrix is wanting to shift to a model where identity servers have less control over the affairs of the homeserver. From 16bb3bd8b522e506501f3bfbcf5dd91046a40a25 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 29 Aug 2019 13:59:48 -0600 Subject: [PATCH 0781/1250] Add an unstable feature flag to MSC2140 for clients to detect support --- proposals/2140-terms-of-service-2.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 9f96a00b..93259143 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -170,7 +170,7 @@ This endpoint does *not* require authentication. #### `POST $prefix/terms`: Requests to this endpoint have a single key, `user_accepts` whose value is -a list of URLs (given by the `url` field in the GET response) of documents that +a list of URLs (given by the `url` field in the GET response) of documents that the user has agreed to: ```json @@ -277,6 +277,16 @@ Clients may add IS bindings for 3PIDs that already exist on the user's Homeserver account by using the `POST /_matrix/client/r0/account/3pid` to re-add the 3PID. +### Unstable feature flag for transition + +In order to allow client implementations to determine if the homeserver they are developed +against supports `id_access_token`, an unstable feature flag of `m.id_access_token` +is to be added to `/versions`. When the flag is `false` or not present, clients must assume +that the homeserver does not support being given `id_access_token` and may receive an error +for doing so. Clients are expected to use the supported specification versions the homeserver +advertises instead of the feature flag's presence once this proposal is included in a release +of the specification. + ## Tradeoffs The Identity Service API previously did not require authentication, and OpenID From 6d5e90b1d6d01aef3afa2e630222007b4e281bb4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 29 Aug 2019 14:51:32 -0600 Subject: [PATCH 0782/1250] Apply suggestions from code review Co-Authored-By: Matthew Hodgson --- proposals/2263-homeserver-pw-resets.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/2263-homeserver-pw-resets.md b/proposals/2263-homeserver-pw-resets.md index 8db52572..1bb55da0 100644 --- a/proposals/2263-homeserver-pw-resets.md +++ b/proposals/2263-homeserver-pw-resets.md @@ -1,6 +1,6 @@ # MSC2263: Give homeservers the ability to handle their own 3PID registrations/password resets -In order to better protect the privacy of of a user, Matrix is wanting to shift to +In order to better protect the privacy of a user, Matrix is wanting to shift to a model where identity servers have less control over the affairs of the homeserver. Identity servers are currently used to reset the passwords of users on a given homeserver as an identity verification technique, however there is no reason why the homeserver @@ -15,7 +15,7 @@ The `id_server` parameter is to become optional on the following endpoints: * `/_matrix/client/:version/register/:medium/requestToken` * `/_matrix/client/:version/account/password/:medium/requestToken` -The `id_server` parameter is additionally deprecated with intentions of being removed +The `id_server` parameter is additionally deprecated with intention of being removed in a future specification release on the `/register/:medium` and `/account/password/:medium` endpoints. Once appropriate adoption has been achieved, the specification can safely remove the parameter as supported. The reason for this deprecation is to completely @@ -23,7 +23,7 @@ remove the identity server's ability to be involved in password resets/registrat Users wishing to bind their 3rd party identifiers can do so after registration, and clients can automate this if they so desire. -Similarly, `bind_email` and `bind_msisdn` are deprecated with intentions to be removed +Similarly, `bind_email` and `bind_msisdn` are deprecated with intention to be removed in a future specification version on `/register`. The flags have no effect if no `id_server` is being used. From 1a6eb9a4131a0683f095c142934bc45b8a2a71ad Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 29 Aug 2019 15:19:12 -0600 Subject: [PATCH 0783/1250] Update proposals/2263-homeserver-pw-resets.md Co-Authored-By: J. Ryan Stinnett --- proposals/2263-homeserver-pw-resets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2263-homeserver-pw-resets.md b/proposals/2263-homeserver-pw-resets.md index 1bb55da0..564d1e45 100644 --- a/proposals/2263-homeserver-pw-resets.md +++ b/proposals/2263-homeserver-pw-resets.md @@ -40,7 +40,7 @@ endpoints listed above if they do not trust the identity server the user is supp In order to allow client implementations to determine if the homeserver they are developed against supports `id_server` being optional, an unstable feature flag of `m.require_identity_server` -is to be added to `/versions`. When the flag is `false` or not present, clients must assume +is to be added to `/versions`. When the flag is `true` or not present, clients must assume that the homeserver requires an `id_server` (ie: it has not yet considered it optional). If this proposal is accepted, clients are expected to use the supported specification versions the homeserver advertises instead of the feature flag's presence. From f8780e23955e5f8a70b108daa0e6428f5ab9e7a6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 30 Aug 2019 04:44:39 -0600 Subject: [PATCH 0784/1250] add note about edit --- proposals/2140-terms-of-service-2.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 93259143..177da4d6 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -1,5 +1,7 @@ # MSC2140: Terms of Service API for Identity Servers and Integration Managers +*Note*: This MSC was added to in [MSC2264](https://github.com/matrix-org/matrix-doc/pull/2264) + [MSC1692](https://github.com/matrix-org/matrix-doc/issues/1692) introduces a method for homeservers to require that users read and agree to certain documents before being permitted to use the service. This proposal introduces a From 62cc11eee658ead69eb18cad153193a4082daa1f Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 30 Aug 2019 13:49:54 +0100 Subject: [PATCH 0786/1250] add missing github-labels file --- README.rst | 2 +- meta/github-labels.rst | 91 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 meta/github-labels.rst diff --git a/README.rst b/README.rst index b8847bfb..ace8ebdd 100644 --- a/README.rst +++ b/README.rst @@ -138,4 +138,4 @@ Issue tracking Issues with the Matrix specification are tracked in `GitHub `_. -See `meta/labels.rst `_ for notes on what the labels mean. +See `meta/github-labels.rst `_ for notes on what the labels mean. diff --git a/meta/github-labels.rst b/meta/github-labels.rst new file mode 100644 index 00000000..f674b81b --- /dev/null +++ b/meta/github-labels.rst @@ -0,0 +1,91 @@ +The following labels are used to help categorize issues: + +`spec-omission `_ +-------------------------------------------------------------------------------- + +Things which have been implemented but not currently specified. These may range +from entire API endpoints, to particular options or return parameters. + +Issues with this label will have been implemented in `Synapse +`_. Normally there will be a design +document in Google Docs or similar which describes the feature. + +Examples: + +* `Spec PUT /directory/list `_ +* `Unspec'd server_name request param for /join/{roomIdOrAlias} + `_ + +`clarification `_ +-------------------------------------------------------------------------------- + +An area where the spec could do with being more explicit. + +Examples: + +* `Spec the implicit limit on /syncs + `_ + +* `Clarify the meaning of the currently_active flags in presence events + `_ + +`spec-bug `_ +---------------------------------------------------------------------- + +Something which is in the spec, but is wrong. + +Note: this is *not* for things that are badly designed or don't work well +(for which see 'improvement' or 'feature') - it is for places where the +spec doesn't match reality. + +Examples: + +* `swagger is wrong for directory PUT + `_ + +* `receipts section still refers to initialSync + `_ + +`improvement `_ +---------------------------------------------------------------------------- + +A suggestion for a relatively simple improvement to the protocol. + +Examples: + +* `We need a 'remove 3PID' API so that users can remove mappings + `_ +* `We should mandate that /publicRooms requires an access_token + `_ + +`feature `_ +-------------------------------------------------------------------- + +A suggestion for a significant extension to the matrix protocol which +needs considerable consideration before implementation. + +Examples: + +* `Peer-to-peer Matrix `_ +* `Specify a means for clients to "edit" previous messages + `_ + + +`wart `_ +-------------------------------------------------------------- + +A point where the protocol is inconsistent or inelegant, but which isn't really +causing anybody any problems right now. Might be nice to consider fixing one +day. + + +`question `_ +---------------------------------------------------------------------- + +A thought or idea about the protocol which we aren't really sure whether to +pursue or not. + +Examples: + +* `Should we prepend anti-eval code to our json responses? + `_ From d1efd488b7c3d62472db063a86b7084403cc4ab8 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Fri, 30 Aug 2019 14:43:17 +0100 Subject: [PATCH 0787/1250] Proposal for mandating lowercasing when processing e-mail address localparts --- proposals/xxxx-email-lowercase.md | 65 +++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 proposals/xxxx-email-lowercase.md diff --git a/proposals/xxxx-email-lowercase.md b/proposals/xxxx-email-lowercase.md new file mode 100644 index 00000000..cef94fa8 --- /dev/null +++ b/proposals/xxxx-email-lowercase.md @@ -0,0 +1,65 @@ +# Proposal for mandating lowercasing when processing e-mail address localparts + +[RFC822](https://tools.ietf.org/html/rfc822#section-3.4.7) mandates that +localparts in e-mail addresses must be processed with the original case +preserved. [The Matrix spec](https://matrix.org/docs/spec/appendices#pid-types) +doesn't mandate anything about processing e-mail addresses, other than the fact +that the domain part must be converted to lowercase, as domain names are case +insensitive. + +On the other hand, most major e-mail providers nowadays process the localparts +of e-mail addresses as case insensitive. Therefore, most users expect localparts +to be treated case insensitively, and get confused when it's not. Some users, +for example, get confused over the fact that registering a 3PID association for +`john.doe@example.com` doesn't mean that the association is valid for +`John.Doe@example.com`, and don't expect to be expected to remember the exact +case they used to initially register the association (and sometimes get locked +out of their account because of that). So far we've seen that confusion occur +and lead to troubles of various degrees over several deployments of Synapse and +Sydent. + +## Proposal + +This proposal suggests changing the specification of the e-mail 3PID type in +[the Matrix spec appendices](https://matrix.org/docs/spec/appendices#pid-types) +to mandate that any e-mail address must be entirely converted to lowercase +before any processing, instead of only its domain. + +## Other considered solutions + +A first look at this issue concluded that there was no need to add such a +mention to the spec, and that it can be considered as an implementation detail. +However, [MSC2134](https://github.com/matrix-org/matrix-doc/pull/2134) changes +this: because hashing functions are case sensitive, we need both clients and +identity servers to follow the same policy regarding case sensitivity. + +## Tradeoffs + +Implementing this MSC in identity servers would require the databases of +existing identity servers to be updated in a large part to convert the email +addresses of existing associations to lowercase, in order to avoid conflicts. +However, most of this update can usually be done by a single database query (or +a background job running at startup), so the UX improvement outweights this +trouble. + +## Potential issues + +Some users might already have two different accounts associated with the same +e-mail address but with different cases. This appears to happen in a small +number of cases, however, and can be dealt by the identity server's maintainer. + +For example, with Sydent, the process of dealing with such cases could look +like: + +1. list all MXIDs associated with a variant of the email address, and the + timestamp of that association +2. delete all associations except for the most recent one [0] +3. inform the user of the deletion by sending them an email notice to the email + address + +## Footnotes + +[0]: This is specific to Sydent because of a bug it has where v1 lookups are +already processed case insensitively, which means it will return the most recent +association for any case of the given email address, therefore keeping only this +association won't change the result of v1 lookups. From 60354f8cf90753667d797dd97a348550b5c121db Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Fri, 30 Aug 2019 14:47:02 +0100 Subject: [PATCH 0788/1250] MSC number --- proposals/{xxxx-email-lowercase.md => 2265-email-lowercase.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/{xxxx-email-lowercase.md => 2265-email-lowercase.md} (100%) diff --git a/proposals/xxxx-email-lowercase.md b/proposals/2265-email-lowercase.md similarity index 100% rename from proposals/xxxx-email-lowercase.md rename to proposals/2265-email-lowercase.md From b36fe24f1b719d8650de39187f112ebe0fada041 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 30 Aug 2019 08:27:44 -0600 Subject: [PATCH 0789/1250] Let's not doubly remove things --- proposals/2263-homeserver-pw-resets.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/proposals/2263-homeserver-pw-resets.md b/proposals/2263-homeserver-pw-resets.md index 564d1e45..3b58af17 100644 --- a/proposals/2263-homeserver-pw-resets.md +++ b/proposals/2263-homeserver-pw-resets.md @@ -23,9 +23,8 @@ remove the identity server's ability to be involved in password resets/registrat Users wishing to bind their 3rd party identifiers can do so after registration, and clients can automate this if they so desire. -Similarly, `bind_email` and `bind_msisdn` are deprecated with intention to be removed -in a future specification version on `/register`. The flags have no effect if no `id_server` -is being used. +Note that `bind_email` and `bind_msisdn` on `/register` have already been removed +by [MSC2140](https://github.com/matrix-org/matrix-doc/pull/2140). As per [MSC2140](https://github.com/matrix-org/matrix-doc/pull/2140), an `id_access_token` is required only if an `id_server` is supplied. From 5acac5a44e0d4fb04010ed166069e96fc369c3e9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 30 Aug 2019 09:12:02 -0600 Subject: [PATCH 0790/1250] Try bumping golang version --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 659380b0..b37478bf 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -97,7 +97,7 @@ jobs: command: DOCS_URL="${CIRCLE_BUILD_URL}/artifacts/${CIRCLE_NODE_INDEX}/${CIRCLE_WORKING_DIRECTORY/#\~/$HOME}/api/client-server/index.html"; echo $DOCS_URL build-dev-scripts: docker: - - image: golang:1.8 + - image: golang:1.10 steps: - checkout - run: From e6f85cacff43640ca3499b637b581f7973cb9a8d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 31 Aug 2019 00:53:08 +0300 Subject: [PATCH 0791/1250] Specify that "existing auth rules" means room v5 --- proposals/2244-mass-redactions.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/2244-mass-redactions.md b/proposals/2244-mass-redactions.md index 38d699e1..6999b268 100644 --- a/proposals/2244-mass-redactions.md +++ b/proposals/2244-mass-redactions.md @@ -58,7 +58,8 @@ unchanged. When a server accepts an `m.room.redaction` using the modified auth rules, it evaluates individually whether each target can be redacted under the existing -auth rules. Servers MUST NOT include failing and unknown entries to clients. +room v5 auth rules. Servers MUST NOT include failing and unknown entries to +clients. > Servers do not know whether redaction targets are authorized at the time they receive the `m.room.redaction` unless they are in possession of the target From 6d71a41e225f1f0cc227e3528c917f6042d4f148 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 31 Aug 2019 16:01:04 +0100 Subject: [PATCH 0792/1250] Proposal for ignoring invites --- proposals/2270-ignore-invites.md | 47 ++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 proposals/2270-ignore-invites.md diff --git a/proposals/2270-ignore-invites.md b/proposals/2270-ignore-invites.md new file mode 100644 index 00000000..c6e51e70 --- /dev/null +++ b/proposals/2270-ignore-invites.md @@ -0,0 +1,47 @@ +# Proposal for ignoring invites + +## Problem + +There is currently no way to ignore an invite in Matrix without explicitly +rejecting it and informing the inviter of the rejection. There are many social +situations where a user may want to silently ignore the invite instead. + +The closest you can currently get is to ignore the user who sent the invite - +but this will then ignore all activity from that user, which may not be +desirable. + +## Solution + +Currently we support ignoring users by maintaining an `m.ignored_user_list` event in +account_data, as per https://matrix.org/docs/spec/client_server/r0.5.0#id189. + +We could do also silently ignore rooms (including invites) with an equivalent +`m.ignored_room_list` event, with precisely the same semantics but listing +room IDs rather than user IDs. + +## Tradeoffs + + * We're limited to ~65KB worth of room IDs (although we could change the + limits for account_data 'events', given they're more freeform JSON than + events) + * We waste initial sync bandwidth with account_data info for ignored rooms + which we may never care about ever again. + * The list will grow unbounded over time (unless the user occasionally + unignores and explicitly rejects the invites), especially if invite spam + accelerates. + * We could instead have a dedicated API for this: + * `PUT /user/{userId}/ignore/{txnId}` + * `PUT /rooms/{roomId}/ignore/{txnId}` + * `GET /user/{userId}/ignore` + * `GET /rooms/{roomId}/ignore` + * `GET /ignore` (for querying the current lists) + * ...and a custom block in `/sync` responses to synchronise ignore changes + * ...except it feels that yet another custom API & custom response block + is even more complicated and clunky than making account_data a bit more + flexible. + * Alternatively, we could extend `/leave` with a `silent` parameter of some kind, + and rely on the invitee's HS to track these 'silent' leaves and ignore the + room on behalf of the invitee. However, it may be nice to let the user track + ignored invites cross-client so they can undo if necessary, which account_data + gives us for free. Plus semantically it seems a bit wrong to use `/leave` + to describe the act of ignoring an invite, when you're not actually leaving it. \ No newline at end of file From a805d2b77961816f6f15ce0a44ee3dfde838fb37 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 31 Aug 2019 16:04:55 +0100 Subject: [PATCH 0793/1250] oops, premature merge --- proposals/2270-ignore-invites.md | 47 -------------------------------- 1 file changed, 47 deletions(-) delete mode 100644 proposals/2270-ignore-invites.md diff --git a/proposals/2270-ignore-invites.md b/proposals/2270-ignore-invites.md deleted file mode 100644 index c6e51e70..00000000 --- a/proposals/2270-ignore-invites.md +++ /dev/null @@ -1,47 +0,0 @@ -# Proposal for ignoring invites - -## Problem - -There is currently no way to ignore an invite in Matrix without explicitly -rejecting it and informing the inviter of the rejection. There are many social -situations where a user may want to silently ignore the invite instead. - -The closest you can currently get is to ignore the user who sent the invite - -but this will then ignore all activity from that user, which may not be -desirable. - -## Solution - -Currently we support ignoring users by maintaining an `m.ignored_user_list` event in -account_data, as per https://matrix.org/docs/spec/client_server/r0.5.0#id189. - -We could do also silently ignore rooms (including invites) with an equivalent -`m.ignored_room_list` event, with precisely the same semantics but listing -room IDs rather than user IDs. - -## Tradeoffs - - * We're limited to ~65KB worth of room IDs (although we could change the - limits for account_data 'events', given they're more freeform JSON than - events) - * We waste initial sync bandwidth with account_data info for ignored rooms - which we may never care about ever again. - * The list will grow unbounded over time (unless the user occasionally - unignores and explicitly rejects the invites), especially if invite spam - accelerates. - * We could instead have a dedicated API for this: - * `PUT /user/{userId}/ignore/{txnId}` - * `PUT /rooms/{roomId}/ignore/{txnId}` - * `GET /user/{userId}/ignore` - * `GET /rooms/{roomId}/ignore` - * `GET /ignore` (for querying the current lists) - * ...and a custom block in `/sync` responses to synchronise ignore changes - * ...except it feels that yet another custom API & custom response block - is even more complicated and clunky than making account_data a bit more - flexible. - * Alternatively, we could extend `/leave` with a `silent` parameter of some kind, - and rely on the invitee's HS to track these 'silent' leaves and ignore the - room on behalf of the invitee. However, it may be nice to let the user track - ignored invites cross-client so they can undo if necessary, which account_data - gives us for free. Plus semantically it seems a bit wrong to use `/leave` - to describe the act of ignoring an invite, when you're not actually leaving it. \ No newline at end of file From 1f2acbcf29ecfe4495cf53a7d9f749e9ec0f37c3 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 31 Aug 2019 16:45:53 +0100 Subject: [PATCH 0794/1250] RST is not MD --- specification/proposals_intro.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 20cfd48d..de65ba27 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -79,7 +79,7 @@ their proposed changes to the Matrix protocol: * Pragmatism rather than perfection * Proof rather than conjecture -Please see [MSC1779](https://github.com/matrix-org/matrix-doc/blob/matthew/msc1779/proposals/1779-open-governance.md) +Please see `MSC1779 `_ for full details of the project's Guiding Principles. Technical notes From 7ba4564ac3145bae862069a16cb2c5a1308fbfb4 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 31 Aug 2019 21:04:15 +0300 Subject: [PATCH 0795/1250] Remove soft fail auth rule option Signed-off-by: Tulir Asokan --- proposals/2244-mass-redactions.md | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/proposals/2244-mass-redactions.md b/proposals/2244-mass-redactions.md index 6999b268..b2d35dff 100644 --- a/proposals/2244-mass-redactions.md +++ b/proposals/2244-mass-redactions.md @@ -35,28 +35,11 @@ Clients shall apply existing `m.room.redaction` target behavior over an array of event ID strings. ### Server behavior (auth rules) -The redaction auth rules should change to iterate the array and check if the -sender has the privileges to redact each event. - -There are at least two potential ways to handle targets that are not found or -rejected: soft failing until all targets are found or handling each target -separately. - -#### Soft fail -[Soft fail](https://matrix.org/docs/spec/server_server/r0.1.3#soft-failure) the -event until all targets are found, then accept only if the sender has the -privileges to redact every listed event. This is how redactions currently work. - -This has the downside of requiring servers to fetch all the target events (and -possibly forward them to clients) before being able to process and forward the -redaction event. - -#### Handle each target separately The target events of an `m.room.redaction` shall no longer be considered when authorizing an `m.room.redaction` event. Any other existing rules remain unchanged. -When a server accepts an `m.room.redaction` using the modified auth rules, it +After a server accepts an `m.room.redaction` using the modified auth rules, it evaluates individually whether each target can be redacted under the existing room v5 auth rules. Servers MUST NOT include failing and unknown entries to clients. From 524ec52f73fded7b43a0ae44b1c9b2e4175319c2 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Mon, 2 Sep 2019 13:41:07 +0100 Subject: [PATCH 0796/1250] Wording Co-Authored-By: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- proposals/2265-email-lowercase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2265-email-lowercase.md b/proposals/2265-email-lowercase.md index cef94fa8..0e862272 100644 --- a/proposals/2265-email-lowercase.md +++ b/proposals/2265-email-lowercase.md @@ -12,7 +12,7 @@ of e-mail addresses as case insensitive. Therefore, most users expect localparts to be treated case insensitively, and get confused when it's not. Some users, for example, get confused over the fact that registering a 3PID association for `john.doe@example.com` doesn't mean that the association is valid for -`John.Doe@example.com`, and don't expect to be expected to remember the exact +`John.Doe@example.com`, and don't expect to have to remember the exact case they used to initially register the association (and sometimes get locked out of their account because of that). So far we've seen that confusion occur and lead to troubles of various degrees over several deployments of Synapse and From 552f71a9f9cb088f501c0b899704908e71ba0dd9 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Mon, 2 Sep 2019 13:41:23 +0100 Subject: [PATCH 0797/1250] Wording Co-Authored-By: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- proposals/2265-email-lowercase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2265-email-lowercase.md b/proposals/2265-email-lowercase.md index 0e862272..50bad406 100644 --- a/proposals/2265-email-lowercase.md +++ b/proposals/2265-email-lowercase.md @@ -28,7 +28,7 @@ before any processing, instead of only its domain. ## Other considered solutions A first look at this issue concluded that there was no need to add such a -mention to the spec, and that it can be considered as an implementation detail. +mention to the spec, and that it can be considered an implementation detail. However, [MSC2134](https://github.com/matrix-org/matrix-doc/pull/2134) changes this: because hashing functions are case sensitive, we need both clients and identity servers to follow the same policy regarding case sensitivity. From bddadfeb184b6546a2e74782d2786bfc168075ee Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Mon, 2 Sep 2019 13:41:33 +0100 Subject: [PATCH 0798/1250] Typo Co-Authored-By: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- proposals/2265-email-lowercase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2265-email-lowercase.md b/proposals/2265-email-lowercase.md index 50bad406..166de458 100644 --- a/proposals/2265-email-lowercase.md +++ b/proposals/2265-email-lowercase.md @@ -39,7 +39,7 @@ Implementing this MSC in identity servers would require the databases of existing identity servers to be updated in a large part to convert the email addresses of existing associations to lowercase, in order to avoid conflicts. However, most of this update can usually be done by a single database query (or -a background job running at startup), so the UX improvement outweights this +a background job running at startup), so the UX improvement outweighs this trouble. ## Potential issues From 997360995ccc5d3d46b2d8983601afc10a0d47ac Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Mon, 2 Sep 2019 13:41:49 +0100 Subject: [PATCH 0799/1250] Wording Co-Authored-By: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- proposals/2265-email-lowercase.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2265-email-lowercase.md b/proposals/2265-email-lowercase.md index 166de458..3bc3c445 100644 --- a/proposals/2265-email-lowercase.md +++ b/proposals/2265-email-lowercase.md @@ -46,7 +46,7 @@ trouble. Some users might already have two different accounts associated with the same e-mail address but with different cases. This appears to happen in a small -number of cases, however, and can be dealt by the identity server's maintainer. +number of cases, however, and can be dealt with by the identity server's maintainer. For example, with Sydent, the process of dealing with such cases could look like: From 520c76a1cb8e8669ac624be3c36cc606aeb4cba6 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Mon, 2 Sep 2019 13:56:01 +0100 Subject: [PATCH 0800/1250] Spell out that the proposal also concerns homeservers --- proposals/2265-email-lowercase.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/proposals/2265-email-lowercase.md b/proposals/2265-email-lowercase.md index 3bc3c445..5698a8c2 100644 --- a/proposals/2265-email-lowercase.md +++ b/proposals/2265-email-lowercase.md @@ -35,18 +35,19 @@ identity servers to follow the same policy regarding case sensitivity. ## Tradeoffs -Implementing this MSC in identity servers would require the databases of -existing identity servers to be updated in a large part to convert the email -addresses of existing associations to lowercase, in order to avoid conflicts. -However, most of this update can usually be done by a single database query (or -a background job running at startup), so the UX improvement outweighs this -trouble. +Implementing this MSC in identity servers and homeservers might require the +databases of existing instances to be updated in a large part to convert the +email addresses of existing associations to lowercase, in order to avoid +conflicts. However, most of this update can usually be done by a single database +query (or a background job running at startup), so the UX improvement outweighs +this trouble. ## Potential issues Some users might already have two different accounts associated with the same e-mail address but with different cases. This appears to happen in a small -number of cases, however, and can be dealt with by the identity server's maintainer. +number of cases, however, and can be dealt with by the identity server's or the +homeserver's maintainer. For example, with Sydent, the process of dealing with such cases could look like: From d346099cf70282c1db82ed7821b58c3e8a2bd915 Mon Sep 17 00:00:00 2001 From: Ben Parsons Date: Tue, 3 Sep 2019 18:30:05 +0100 Subject: [PATCH 0801/1250] deduplicate MSC1779 ref in proposals list --- specification/proposals_intro.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index de65ba27..06bd6dfd 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -79,7 +79,7 @@ their proposed changes to the Matrix protocol: * Pragmatism rather than perfection * Proof rather than conjecture -Please see `MSC1779 `_ +Please `see MSC1779 `_ for full details of the project's Guiding Principles. Technical notes From 2b8c8ad5126260ab7a3326f69a7fa881e62c4120 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 3 Sep 2019 13:49:25 -0600 Subject: [PATCH 0802/1250] MSC1779 is actually merged now --- specification/proposals_intro.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 06bd6dfd..82a4225b 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -79,7 +79,7 @@ their proposed changes to the Matrix protocol: * Pragmatism rather than perfection * Proof rather than conjecture -Please `see MSC1779 `_ +Please `see MSC1779 `_ for full details of the project's Guiding Principles. Technical notes From afd50184940a957b6b0023acd284be07e177147b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Aug 2019 21:56:09 -0600 Subject: [PATCH 0803/1250] Spec the terms of service handling for identity servers Part of MSC2140 Convert status codes to strings if there is a string status code. Fixes a build error when we mix 4xx and 403 in the same definition. We also have to correct stringified numbers to pass the build. --- api/identity/email_associations.yaml | 2 +- api/identity/phone_associations.yaml | 2 +- api/identity/v2_associations.yaml | 25 +++ api/identity/v2_auth.yaml | 22 +++ api/identity/v2_email_associations.yaml | 35 +++- api/identity/v2_invitation_signing.yaml | 11 ++ api/identity/v2_phone_associations.yaml | 35 +++- api/identity/v2_store_invite.yaml | 11 ++ api/identity/v2_terms.yaml | 149 ++++++++++++++++++ .../identity_service/newsfragments/2258.new | 1 + event-schemas/examples/m.accepted_terms | 10 ++ event-schemas/schema/m.accepted_terms | 23 +++ scripts/templating/matrix_templates/units.py | 16 +- specification/identity_service_api.rst | 27 ++++ 14 files changed, 364 insertions(+), 5 deletions(-) create mode 100644 api/identity/v2_terms.yaml create mode 100644 changelogs/identity_service/newsfragments/2258.new create mode 100644 event-schemas/examples/m.accepted_terms create mode 100644 event-schemas/schema/m.accepted_terms diff --git a/api/identity/email_associations.yaml b/api/identity/email_associations.yaml index 6ac28cd0..69ec7c58 100644 --- a/api/identity/email_associations.yaml +++ b/api/identity/email_associations.yaml @@ -165,7 +165,7 @@ paths: description: The token generated by the ``requestToken`` call and emailed to the user. x-example: atoken responses: - "200": + 200: description: Email address is validated. "3xx": description: |- diff --git a/api/identity/phone_associations.yaml b/api/identity/phone_associations.yaml index 28312a4d..65bbff0c 100644 --- a/api/identity/phone_associations.yaml +++ b/api/identity/phone_associations.yaml @@ -167,7 +167,7 @@ paths: description: The token generated by the ``requestToken`` call and sent to the user. x-example: atoken responses: - "200": + 200: description: Phone number is validated. "3xx": description: |- diff --git a/api/identity/v2_associations.yaml b/api/identity/v2_associations.yaml index d1b29a8f..b9039a18 100644 --- a/api/identity/v2_associations.yaml +++ b/api/identity/v2_associations.yaml @@ -95,6 +95,17 @@ paths: } schema: $ref: "../client-server/definitions/errors/error.yaml" + 403: + description: | + The user must do something in order to use this endpoint. One example + is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_. + examples: + application/json: { + "errcode": "M_TERMS_NOT_SIGNED", + "error": "Please accept our updated terms of service before continuing" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" "/3pid/bind": post: summary: Publish an association between a session and a Matrix user ID. @@ -208,6 +219,17 @@ paths: } schema: $ref: "../client-server/definitions/errors/error.yaml" + 403: + description: | + The user must do something in order to use this endpoint. One example + is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_. + examples: + application/json: { + "errcode": "M_TERMS_NOT_SIGNED", + "error": "Please accept our updated terms of service before continuing" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" "/3pid/unbind": post: summary: Remove an association between a session and a Matrix user ID. @@ -294,6 +316,9 @@ paths: This may also be returned if the identity server does not support the chosen authentication method (such as blocking homeservers from unbinding identifiers). + + Another common error code is ``M_TERMS_NOT_SIGNED`` where the user + needs to `agree to more terms`_ in order to continue. examples: application/json: { "errcode": "M_FORBIDDEN", diff --git a/api/identity/v2_auth.yaml b/api/identity/v2_auth.yaml index 16864b8e..a34f679c 100644 --- a/api/identity/v2_auth.yaml +++ b/api/identity/v2_auth.yaml @@ -80,6 +80,17 @@ paths: type: string description: The user ID which registered the token. required: ['user_id'] + 403: + description: | + The user must do something in order to use this endpoint. One example + is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_. + examples: + application/json: { + "errcode": "M_TERMS_NOT_SIGNED", + "error": "Please accept our updated terms of service before continuing" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" "/account/logout": post: summary: Logs out an access token, rendering it unusable. @@ -107,3 +118,14 @@ paths: } schema: $ref: "../client-server/definitions/errors/error.yaml" + 403: + description: | + The user must do something in order to use this endpoint. One example + is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_. + examples: + application/json: { + "errcode": "M_TERMS_NOT_SIGNED", + "error": "Please accept our updated terms of service before continuing" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" diff --git a/api/identity/v2_email_associations.yaml b/api/identity/v2_email_associations.yaml index eff18eaf..76c3747e 100644 --- a/api/identity/v2_email_associations.yaml +++ b/api/identity/v2_email_associations.yaml @@ -74,6 +74,17 @@ paths: } schema: $ref: "../client-server/definitions/errors/error.yaml" + 403: + description: | + The user must do something in order to use this endpoint. One example + is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_. + examples: + application/json: { + "errcode": "M_TERMS_NOT_SIGNED", + "error": "Please accept our updated terms of service before continuing" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" "/validate/email/submitToken": post: summary: Validate ownership of an email address. @@ -135,6 +146,17 @@ paths: type: boolean description: Whether the validation was successful or not. required: ['success'] + 403: + description: | + The user must do something in order to use this endpoint. One example + is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_. + examples: + application/json: { + "errcode": "M_TERMS_NOT_SIGNED", + "error": "Please accept our updated terms of service before continuing" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" get: summary: Validate ownership of an email address. description: |- @@ -171,7 +193,7 @@ paths: description: The token generated by the ``requestToken`` call and emailed to the user. x-example: atoken responses: - "200": + 200: description: Email address is validated. "3xx": description: |- @@ -181,3 +203,14 @@ paths: "4xx": description: Validation failed. + 403: + description: | + The user must do something in order to use this endpoint. One example + is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_. + examples: + application/json: { + "errcode": "M_TERMS_NOT_SIGNED", + "error": "Please accept our updated terms of service before continuing" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" diff --git a/api/identity/v2_invitation_signing.yaml b/api/identity/v2_invitation_signing.yaml index c1267bdc..0431233a 100644 --- a/api/identity/v2_invitation_signing.yaml +++ b/api/identity/v2_invitation_signing.yaml @@ -99,3 +99,14 @@ paths: } schema: $ref: "../client-server/definitions/errors/error.yaml" + 403: + description: | + The user must do something in order to use this endpoint. One example + is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_. + examples: + application/json: { + "errcode": "M_TERMS_NOT_SIGNED", + "error": "Please accept our updated terms of service before continuing" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" diff --git a/api/identity/v2_phone_associations.yaml b/api/identity/v2_phone_associations.yaml index cfaea410..6d4ad79b 100644 --- a/api/identity/v2_phone_associations.yaml +++ b/api/identity/v2_phone_associations.yaml @@ -76,6 +76,17 @@ paths: } schema: $ref: "../client-server/definitions/errors/error.yaml" + 403: + description: | + The user must do something in order to use this endpoint. One example + is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_. + examples: + application/json: { + "errcode": "M_TERMS_NOT_SIGNED", + "error": "Please accept our updated terms of service before continuing" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" "/validate/msisdn/submitToken": post: summary: Validate ownership of a phone number. @@ -137,6 +148,17 @@ paths: type: boolean description: Whether the validation was successful or not. required: ['success'] + 403: + description: | + The user must do something in order to use this endpoint. One example + is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_. + examples: + application/json: { + "errcode": "M_TERMS_NOT_SIGNED", + "error": "Please accept our updated terms of service before continuing" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" get: summary: Validate ownership of a phone number. description: |- @@ -173,7 +195,7 @@ paths: description: The token generated by the ``requestToken`` call and sent to the user. x-example: atoken responses: - "200": + 200: description: Phone number is validated. "3xx": description: |- @@ -183,3 +205,14 @@ paths: "4xx": description: Validation failed. + 403: + description: | + The user must do something in order to use this endpoint. One example + is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_. + examples: + application/json: { + "errcode": "M_TERMS_NOT_SIGNED", + "error": "Please accept our updated terms of service before continuing" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" diff --git a/api/identity/v2_store_invite.yaml b/api/identity/v2_store_invite.yaml index afc41a1c..9b7a653c 100644 --- a/api/identity/v2_store_invite.yaml +++ b/api/identity/v2_store_invite.yaml @@ -163,3 +163,14 @@ paths: } schema: $ref: "../client-server/definitions/errors/error.yaml" + 403: + description: | + The user must do something in order to use this endpoint. One example + is an ``M_TERMS_NOT_SIGNED`` error where the user must `agree to more terms`_. + examples: + application/json: { + "errcode": "M_TERMS_NOT_SIGNED", + "error": "Please accept our updated terms of service before continuing" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" diff --git a/api/identity/v2_terms.yaml b/api/identity/v2_terms.yaml new file mode 100644 index 00000000..9b831fba --- /dev/null +++ b/api/identity/v2_terms.yaml @@ -0,0 +1,149 @@ +# Copyright 2019 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. +swagger: '2.0' +info: + title: "Matrix Identity Service Terms of Service API" + version: "2.0.0" +host: localhost:8090 +schemes: + - https +basePath: /_matrix/identity/v2 +consumes: + - application/json +produces: + - application/json +securityDefinitions: + $ref: definitions/security.yaml +paths: + "/terms": + get: + summary: Gets the terms of service offered by the server. + description: |- + Gets all the terms of service offered by the server. The client is expected + to filter through the terms to determine which terms need acceptance from the + user. Note that this endpoint does not require authentication. + operationId: getTerms + parameters: [] + responses: + 200: + description: |- + The terms of service offered by the server. + examples: + application/json: { + "policies": { + "terms_of_service": { + "version": "2.0", + "en": { + "name": "Terms of Service", + "url": "https://example.org/somewhere/terms-2.0-en.html" + }, + "fr": { + "name": "Conditions d'utilisation", + "url": "https://example.org/somewhere/terms-2.0-fr.html" + } + }, + "privacy_policy": { + "version": "1.2", + "en": { + "name": "Privacy Policy", + "url": "https://example.org/somewhere/privacy-1.2-en.html" + }, + "fr": { + "name": "Politique de confidentialité", + "url": "https://example.org/somewhere/privacy-1.2-fr.html" + } + } + } + } + schema: + type: object + properties: + policies: + type: object + title: Policy Map + description: |- + The policies the server offers. Mapped from arbitrary ID (unused in + this version of the specification) to a Policy Object. + additionalProperties: + type: object + title: Policy Object + description: |- + The policy. Includes a map of language (ISO 639-2) to language-specific + policy information. + properties: + version: + type: string + description: |- + The version for the policy. There are no requirements on what this + might be and could be "alpha", semantically versioned, or arbitrary. + required: ['version'] + # TODO: TravisR - Make this render + additionalProperties: + type: object + title: Internationalised Policy + description: |- + The policy information for the specified language. + properties: + name: + type: string + description: The translated name of the policy. + url: + type: string + description: |- + The URL, which should include the policy ID, version, and language + in it, to be presented to the user as the policy. URLs should have + all three criteria to avoid conflicts when the policy is updated + in the future: for example, if this was "https://example.org/terms.html" + then the server would be unable to update it because the client would + have already added that URL to the ``m.accepted_terms`` collection. + required: ['name', 'url'] + required: ['policies'] + post: + summary: Indicates acceptance of terms to the server. + description: |- + Called by a client to indicate that the user has accepted/agreed to the included + set of URLs. Servers MUST NOT assume that the client will be sending all previously + accepted URLs and should therefore append the provided URLs to what the server + already knows has been accepted. + + Clients MUST provide the URL of the policy in the language that was presented + to the user. Servers SHOULD consider acceptance of any one language's URL as + acceptance for all other languages of that policy. + + The server should avoid returning ``M_TERMS_NOT_SIGNED`` because the client + may not be accepting all terms at once. + operationId: agreeToTerms + security: + - accessToken: [] + parameters: + - in: body + name: body + schema: + type: object + properties: + user_accepts: + type: array + items: + type: string + description: The URLs the user is accepting in this request. + example: "https://example.org/somewhere/terms-2.0-en.html" + required: ['user_accepts'] + responses: + 200: + description: |- + The server has considered the user as having accepted the provided URLs. + examples: + application/json: {} + schema: + type: object diff --git a/changelogs/identity_service/newsfragments/2258.new b/changelogs/identity_service/newsfragments/2258.new new file mode 100644 index 00000000..06b9efff --- /dev/null +++ b/changelogs/identity_service/newsfragments/2258.new @@ -0,0 +1 @@ +Add endpoints for accepting and handling terms of service. diff --git a/event-schemas/examples/m.accepted_terms b/event-schemas/examples/m.accepted_terms new file mode 100644 index 00000000..5e8dad16 --- /dev/null +++ b/event-schemas/examples/m.accepted_terms @@ -0,0 +1,10 @@ +{ + "$ref": "core/event.json", + "type": "m.accepted_terms", + "content": { + "accepted": [ + "https://example.org/somewhere/terms-1.2-en.html", + "https://example.org/somewhere/privacy-1.2-en.html" + ] + } +} diff --git a/event-schemas/schema/m.accepted_terms b/event-schemas/schema/m.accepted_terms new file mode 100644 index 00000000..510e741d --- /dev/null +++ b/event-schemas/schema/m.accepted_terms @@ -0,0 +1,23 @@ +--- +allOf: + - $ref: core-event-schema/event.yaml +description: |- + A list of terms URLs the user has previously accepted. Clients SHOULD use this + to avoid presenting the user with terms they have already agreed to. +properties: + content: + type: object + properties: + accepted: + type: array + items: + type: string + description: |- + The list of URLs the user has previously accepted. Should be appended to + when the user agrees to new terms. + type: + enum: + - m.accepted_terms + type: string +title: Accepted Terms of Service URLs +type: object diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index 04e6f8a9..0c835508 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -586,7 +586,21 @@ class MatrixUnits(Units): raise Exception("Error handling parameter %s" % param_name, e) # endfor[param] good_response = None - for code in sorted(endpoint_swagger.get("responses", {}).keys()): + endpoint_status_codes = endpoint_swagger.get("responses", {}).keys() + # Check to see if any of the status codes are strings ("4xx") and if + # so convert everything to a string to avoid comparing ints and strings. + has_string_status = False + for code in endpoint_status_codes: + if isinstance(code, str): + has_string_status = True + break + if has_string_status: + endpoint_status_codes = [str(i) for i in endpoint_status_codes] + for code in sorted(endpoint_status_codes): + # Convert numeric responses to ints, assuming they got converted + # above. + if isinstance(code, str) and code.isdigit(): + code = int(code) res = endpoint_swagger["responses"][code] if not good_response and code == 200: good_response = res diff --git a/specification/identity_service_api.rst b/specification/identity_service_api.rst index 4afac6ef..c92f737b 100644 --- a/specification/identity_service_api.rst +++ b/specification/identity_service_api.rst @@ -198,6 +198,33 @@ status of 401 and the error code ``M_UNAUTHORIZED``. {{v2_auth_is_http_api}} + +.. _`agree to more terms`: + +Terms of service +---------------- + +Identity Servers are encouraged to have terms of service (or similar policies) to +ensure that users have agreed to their data being processed by the server. To facilitate +this, an identity server can respond to almost any authenticated API endpoint with a +HTTP 403 and the error code ``M_TERMS_NOT_SIGNED``. The error code is used to indicate +that the user must accept new terms of service before being able to continue. + +All endpoints which support authentication can return the ``M_TERMS_NOT_SIGNED`` error. +When clients receive the error, they are expected to make a call to ``GET /terms`` to +find out what terms the server offers. The client compares this to the ``m.accepted_terms`` +account data for the user (described later) and presents the user with option to accept +the still-missing terms of service. After the user has made their selection, if applicable, +the client sends a request to ``POST /terms`` to indicate the user's acceptance. The +server cannot expect that the client will send acceptance for all pending terms, and the +client should not expect that the server will not respond with another ``M_TERMS_NOT_SIGNED`` +on their next request. The terms the user has just accepted are appended to ``m.accepted_terms``. + +{{m_accepted_terms_event}} + +{{v2_terms_is_http_api}} + + Status check ------------ From 52e6868f5095d16bd3c72f73d797b208ebe2d1fc Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 3 Sep 2019 15:03:41 -0600 Subject: [PATCH 0804/1250] Remove bind_* params on /register as per MSC2140 See https://github.com/matrix-org/matrix-doc/pull/2140 See https://github.com/matrix-org/matrix-doc/issues/2253 --- api/client-server/registration.yaml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 71177d0c..8bb9a027 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -95,18 +95,6 @@ paths: should be authenticated, but is instead used to authenticate the ``register`` call itself. "$ref": "definitions/auth_data.yaml" - bind_email: - type: boolean - description: |- - If true, the server binds the email used for authentication to - the Matrix ID with the identity server. - example: false - bind_msisdn: - type: boolean - description: |- - If true, the server binds the phone number used for authentication - to the Matrix ID with the identity server. - example: false username: type: string description: |- From caf46db6e797cddffd205b1d81d4b1eb3a3c79e9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 3 Sep 2019 15:04:58 -0600 Subject: [PATCH 0805/1250] Changelog --- changelogs/client_server/newsfragments/2279.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2279.feature diff --git a/changelogs/client_server/newsfragments/2279.feature b/changelogs/client_server/newsfragments/2279.feature new file mode 100644 index 00000000..a1fdf168 --- /dev/null +++ b/changelogs/client_server/newsfragments/2279.feature @@ -0,0 +1 @@ +Remove ``bind_msisdn`` and ``bind_email`` from ``/register`` now that the identity server's bind endpoint requires authentication. From 001c51a7401f646d765c07d92593913d90a2ba47 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 3 Sep 2019 15:09:59 -0600 Subject: [PATCH 0806/1250] /3pid/delete and /deactivate don't take an id_access_token --- api/client-server/administrative_contact.yaml | 9 ++++----- api/client-server/registration.yaml | 9 ++++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 30153bb0..4b8e1d63 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -176,6 +176,10 @@ paths: description: |- Removes a third party identifier from the user's account. This might not cause an unbind of the identifier from the identity server. + + Unlike other endpoints, this endpoint does not take an ``id_access_token`` + parameter because the homeserver is expected to sign the request to the + identity server instead. operationId: delete3pidFromAccount security: - accessToken: [] @@ -193,11 +197,6 @@ paths: homeserver does not know the original ``id_server``, it MUST return a ``id_server_unbind_result`` of ``no-support``. example: "example.org" - id_access_token: - type: string - description: |- - An access token previously registered with the identity server. Required - if an ``id_server`` is specified. medium: type: string description: The medium of the third party identifier being removed. diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index a747e38b..596dfe34 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -519,6 +519,10 @@ paths: The homeserver may change the flows available depending on whether a valid access token is provided. + + Unlike other endpoints, this endpoint does not take an ``id_access_token`` + parameter because the homeserver is expected to sign the request to the + identity server instead. security: - accessToken: [] operationId: deactivateAccount @@ -542,11 +546,6 @@ paths: it must return an ``id_server_unbind_result`` of ``no-support``. example: "example.org" - id_access_token: - type: string - description: |- - An access token previously registered with the identity server. Required if an - ``id_server`` is supplied. responses: 200: description: The account has been deactivated. From 9574f3c8d0efa062f1d077b7590e29ea073d02d9 Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Wed, 4 Sep 2019 14:12:00 +0100 Subject: [PATCH 0807/1250] update to the new deployment of Giles Signed-off-by: Stuart Mumford --- .circleci/config.yml | 2 +- pyproject.toml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b37478bf..bf4404ce 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -121,4 +121,4 @@ workflows: notify: webhooks: - - url: https://giles.cadair.com/circleci + - url: https://giles.cadair.dev/circleci diff --git a/pyproject.toml b/pyproject.toml index b53982b8..060a44fc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,9 +1,9 @@ -[ tool.giles ] +[ tool.gilesbot ] - [ tool.giles.circleci_artifacts.docs ] + [ tool.gilesbot.circleci_artifacts.docs ] url = "gen/index.html" message = "Click details to preview the HTML documentation." - [ tool.giles.circleci_artifacts.swagger ] + [ tool.gilesbot.circleci_artifacts.swagger ] url = "client-server/index.html" message = "Click to preview the swagger build." From 958cffd33085c44070bb400f0912192697fedb3c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 4 Sep 2019 16:17:41 -0600 Subject: [PATCH 0808/1250] Spec m.identity_server account data As per [MSC2230](https://github.com/matrix-org/matrix-doc/pull/2230) --- event-schemas/examples/m.identity_server | 7 +++++ event-schemas/schema/m.identity_server | 23 ++++++++++++++++ specification/client_server_api.rst | 35 ++++++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 event-schemas/examples/m.identity_server create mode 100644 event-schemas/schema/m.identity_server diff --git a/event-schemas/examples/m.identity_server b/event-schemas/examples/m.identity_server new file mode 100644 index 00000000..32855e9c --- /dev/null +++ b/event-schemas/examples/m.identity_server @@ -0,0 +1,7 @@ +{ + "$ref": "core/event.json", + "type": "m.identity_server", + "content": { + "base_url": "https://example.org" + } +} diff --git a/event-schemas/schema/m.identity_server b/event-schemas/schema/m.identity_server new file mode 100644 index 00000000..75d2409f --- /dev/null +++ b/event-schemas/schema/m.identity_server @@ -0,0 +1,23 @@ +--- +allOf: + - $ref: core-event-schema/event.yaml +description: |- + Persists the user's preferred identity server, or preference to not use + an identity server at all, in the user's account data. +properties: + content: + type: object + properties: + base_url: + type: string + description: |- + The URL of the identity server the user prefers to use, or ``null`` + if the user does not want to use an identity server. This value is + similar in structure to the ``base_url`` for identity servers in the + ``.well-known/matrix/client`` schema. + type: + enum: + - m.identity_server + type: string +title: Identity Server Preference +type: object diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 916604a3..1ea98fef 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1139,6 +1139,41 @@ Current account information {{whoami_cs_http_api}} +Notes on identity servers ++++++++++++++++++++++++++ + +Identity servers in Matrix store bindings (relationships) between a user's third +party identifier, typically email or phone number, and their user ID. Once a user +has chosen an identity server, that identity server should be used by all clients. + +Clients can see which identity server the user has chosen through the ``m.identity_server`` +account data event, as described below. Clients SHOULD refrain from making requests +to any identity server until the presence of ``m.identity_server`` is confirmed as +(not) present. If present, the client SHOULD check for the presence of the ``base_url`` +property in the event's content. If the ``base_url`` is present, the client SHOULD +use the identity server in that property as the identity server for the user. If the +``base_url`` is missing, or the account data event is not present, the client SHOULD +use whichever default value it normally would for an identity server, if applicable. +Clients SHOULD NOT update the account data with the default identity server when the +user is missing an identity server in their account data. + +Clients SHOULD listen for changes to the ``m.identity_server`` account data event +and update the identity server they are contacting as a result. + +If the client offers a way to set the identity server to use, it MUST update the +value of ``m.identity_server`` accordingly. A ``base_url`` of ``null`` MUST be +treated as though the user does not want to use an identity server, disabling all +related functionality as a result. + +Clients SHOULD refrain from populating the account data as a migration step for users +who are lacking the account data, unless the user sets the identity server within +the client to a value. For example, a user which has no ``m.identity_server`` account +data event should not end up with the client's default identity server in their +account data, unless the user first visits their account settings to set the identity +server. + +{{m_identity_server_event}} + Capabilities negotiation ------------------------ From 6ec7d4cd891e055294b883278c036af3dd6a993c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 4 Sep 2019 16:20:14 -0600 Subject: [PATCH 0809/1250] changelog --- changelogs/client_server/newsfragments/2281.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2281.feature diff --git a/changelogs/client_server/newsfragments/2281.feature b/changelogs/client_server/newsfragments/2281.feature new file mode 100644 index 00000000..7c235423 --- /dev/null +++ b/changelogs/client_server/newsfragments/2281.feature @@ -0,0 +1 @@ +Add ``m.identity_server`` account data for tracking the user's preferred identity server. From 185c564a13797f511fc42ae43154fac8f28fe552 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 4 Sep 2019 16:33:54 -0600 Subject: [PATCH 0810/1250] Spec client-server IS unbind API As per [MSC2140](https://github.com/matrix-org/matrix-doc/pull/2140) Note: this modifies the endpoint in MSC2140 to be more in line with the remainder of the proposal. --- api/client-server/administrative_contact.yaml | 64 +++++++++++++++++++ .../client_server/newsfragments/2282.new | 1 + proposals/2140-terms-of-service-2.md | 3 +- 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/2282.new diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 4b8e1d63..2c9a7da7 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -234,6 +234,70 @@ paths: - id_server_unbind_result tags: - User data + "/account/3pid/unbind": + post: + summary: Removes a user's third party identifier from an identity server. + description: |- + Removes a user's third party identifier from the provided identity server. + This should not cause an unbind from the homeserver (as ``/3pid/delete`` + would) and should only affect the identity server. + + Unlike other endpoints, this endpoint does not take an ``id_access_token`` + parameter because the homeserver is expected to sign the request to the + identity server instead. + operationId: unbind3pidFromAccount + security: + - accessToken: [] + parameters: + - in: body + name: body + schema: + type: object + properties: + id_server: + type: string + description: |- + The identity server to unbind from. If not provided, the homeserver + MUST use the ``id_server`` the identifier was added through. If the + homeserver does not know the original ``id_server``, it MUST return + a ``id_server_unbind_result`` of ``no-support``. + example: "example.org" + medium: + type: string + description: The medium of the third party identifier being removed. + enum: ["email", "msisdn"] + example: "email" + address: + type: string + description: The third party address being removed. + example: "example@example.org" + required: ['medium', 'address'] + responses: + 200: + description: |- + The identity server has disassociated the third party identifier from the + user. + schema: + type: object + properties: + id_server_unbind_result: + type: string + enum: + # XXX: I don't know why, but the order matters here so that "no-support" + # doesn't become "no- support" by the renderer. + - "no-support" + - "success" + description: |- + An indicator as to whether or not the identity server was able to unbind + the 3PID. ``success`` indicates that the identity server has unbound the + identifier whereas ``no-support`` indicates that the identity server + refuses to support the request or the homeserver was not able to determine + an identity server to unbind from. + example: "success" + required: + - id_server_unbind_result + tags: + - User data "/account/3pid/email/requestToken": post: summary: Begins the validation process for an email address for association with the user's account. diff --git a/changelogs/client_server/newsfragments/2282.new b/changelogs/client_server/newsfragments/2282.new new file mode 100644 index 00000000..3395758d --- /dev/null +++ b/changelogs/client_server/newsfragments/2282.new @@ -0,0 +1 @@ +Add ``POST /account/3pid/unbind`` for removing a 3PID from an identity server. diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 3767c9b4..6bff8ebb 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -271,7 +271,8 @@ A client uses this client/server API endpoint to request that the Homeserver removes the given 3PID from the given Identity Server, or all Identity Servers. Takes the same parameters as `POST /_matrix/client/r0/account/3pid/delete`, ie. `id_server`, `medium`, -`address` and the newly added `id_access_token`. +`address`. Similar to the other unbind endpoints, this endpoint does not +require an `id_access_token` because the homeserver can only unbind. Returns the same as `POST /_matrix/client/r0/account/3pid/delete`. From 4d835c1753b695d9f77b84415c34a08344f4ccd3 Mon Sep 17 00:00:00 2001 From: Charlie Varley Date: Thu, 5 Sep 2019 10:31:44 +0100 Subject: [PATCH 0811/1250] Update index.rst --- specification/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/index.rst b/specification/index.rst index bf554e4a..c337d417 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -106,7 +106,7 @@ The principles that Matrix attempts to follow are: - Empowering the end-user + The user should be able to choose the server and clients they use - + The user should be control how private their communication is + + The user should be able to control how private their communication is + The user should know precisely where their data is stored - Fully decentralised - no single points of control over conversations or the From fc262300070aedbc8a948fc20518eeaa07c6f8e7 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Thu, 5 Sep 2019 14:41:53 +0100 Subject: [PATCH 0812/1250] Update proposals/1802-standardised-federation-response-format.md Co-Authored-By: Matthew Hodgson --- proposals/1802-standardised-federation-response-format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1802-standardised-federation-response-format.md b/proposals/1802-standardised-federation-response-format.md index bd8b1189..abb39361 100644 --- a/proposals/1802-standardised-federation-response-format.md +++ b/proposals/1802-standardised-federation-response-format.md @@ -47,5 +47,5 @@ code), then the sending server should retry the request with the `v1` API. ## Alternative solutions -An alternative solution would be to make the change in the `v1` fedration API, +An alternative solution would be to make the change in the `v1` federation API, but would break backward compatibility, thus would be harder to manage. From cb2b71c0be27346e8cd8c431b57031c692446ee7 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Thu, 5 Sep 2019 14:54:31 +0100 Subject: [PATCH 0813/1250] Remove /send + rename --- proposals/1802-standardised-federation-response-format.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/1802-standardised-federation-response-format.md b/proposals/1802-standardised-federation-response-format.md index bd8b1189..e874524e 100644 --- a/proposals/1802-standardised-federation-response-format.md +++ b/proposals/1802-standardised-federation-response-format.md @@ -1,4 +1,4 @@ -# Standardised federation response formats +# Remove the '200' value from some federation responses Some responses formats in the federation API specifications use the form `[200, res]` in which `res` is the JSON object containing the actual response for the @@ -13,7 +13,6 @@ This proposal proposes a backward compatible alternative Add a new version of the following endpoints under the prefix `/_matrix/federation/v2`: -* `PUT /_matrix/federation/v2/send/{txnId}` * `PUT /_matrix/federation/v2/send_join/{roomId}/{eventId}` * `PUT /_matrix/federation/v2/send_leave/{roomId}/{eventId}` From 1881a255c2e44b5c7e00bd4ac80555a5fe7502c8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 5 Sep 2019 13:53:58 -0600 Subject: [PATCH 0814/1250] Clarify that id_access_token is optional for r0.5 --- api/client-server/administrative_contact.yaml | 5 ++++- api/client-server/create_room.yaml | 5 ++++- api/client-server/definitions/request_email_validation.yaml | 5 ++++- api/client-server/definitions/request_msisdn_validation.yaml | 5 ++++- api/client-server/third_party_membership.yaml | 5 ++++- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 4b8e1d63..cce0b261 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -112,7 +112,10 @@ paths: description: The identity server to use. id_access_token: type: string - description: An access token previously registered with the identity server. + description: |- + An access token previously registered with the identity server. Servers + can treat this as optional to distinguish between r0.5-compatible clients + and this specification version. sid: type: string description: The session identifier given by the identity server. diff --git a/api/client-server/create_room.yaml b/api/client-server/create_room.yaml index d7a29d99..2487707e 100644 --- a/api/client-server/create_room.yaml +++ b/api/client-server/create_room.yaml @@ -141,7 +141,10 @@ paths: description: The hostname+port of the identity server which should be used for third party identifier lookups. id_access_token: type: string - description: An access token previously registered with the identity server. + description: |- + An access token previously registered with the identity server. Servers + can treat this as optional to distinguish between r0.5-compatible clients + and this specification version. medium: type: string # TODO: Link to Identity Service spec when it eixsts diff --git a/api/client-server/definitions/request_email_validation.yaml b/api/client-server/definitions/request_email_validation.yaml index 63e3ee21..2b270514 100644 --- a/api/client-server/definitions/request_email_validation.yaml +++ b/api/client-server/definitions/request_email_validation.yaml @@ -25,5 +25,8 @@ allOf: example: "id.example.com" id_access_token: type: string - description: An access token previously registered with the identity server. + description: |- + An access token previously registered with the identity server. Servers + can treat this as optional to distinguish between r0.5-compatible clients + and this specification version. required: ["id_server", "id_access_token"] diff --git a/api/client-server/definitions/request_msisdn_validation.yaml b/api/client-server/definitions/request_msisdn_validation.yaml index 43513628..b013a561 100644 --- a/api/client-server/definitions/request_msisdn_validation.yaml +++ b/api/client-server/definitions/request_msisdn_validation.yaml @@ -25,5 +25,8 @@ allOf: example: "id.example.com" id_access_token: type: string - description: An access token previously registered with the identity server. + description: |- + An access token previously registered with the identity server. Servers + can treat this as optional to distinguish between r0.5-compatible clients + and this specification version. required: ["id_server", "id_access_token"] diff --git a/api/client-server/third_party_membership.yaml b/api/client-server/third_party_membership.yaml index 075cd34b..4c5890d1 100644 --- a/api/client-server/third_party_membership.yaml +++ b/api/client-server/third_party_membership.yaml @@ -102,7 +102,10 @@ paths: description: The hostname+port of the identity server which should be used for third party identifier lookups. id_access_token: type: string - description: An access token previously registered with the identity server. + description: |- + An access token previously registered with the identity server. Servers + can treat this as optional to distinguish between r0.5-compatible clients + and this specification version. medium: type: string # TODO: Link to Identity Service spec when it eixsts From 738fa6833e033bbf5e6a58c7003d1dc1904dc404 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 5 Sep 2019 20:24:17 -0600 Subject: [PATCH 0815/1250] Proposal to make the identity server optional during discovery --- ...0000-optional-identity-server-discovery.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 proposals/0000-optional-identity-server-discovery.md diff --git a/proposals/0000-optional-identity-server-discovery.md b/proposals/0000-optional-identity-server-discovery.md new file mode 100644 index 00000000..013a3e77 --- /dev/null +++ b/proposals/0000-optional-identity-server-discovery.md @@ -0,0 +1,22 @@ +# Proposal to make the identity server optional during discovery + +Currently the specification requires that clients `FAIL_ERROR` (hard failure - do not continue) +when the `.well-known` file for `m.identity_server` points to somewhere invalid or is invalid +itself. + +This proposal aims to change that by allowing clients to make a conscious decision to continue +with the invalid identity server configuration, provided the homeserver configuration is valid. + +## Proposal + +Instead of `FAIL_ERROR` for an invalid `m.identity_server` schema/server, clients are to move +to the `FAIL_PROMPT` (inform the user, ask for input if applicable) state. Clients can decide +to show a warning that the identity server is unavailable and allow the user to continue with +the invalid (or client's default) configuration. + +## Tradeoffs + +Clients can end up being configured with an invalid or inoperable identity server. This is +considered a feature by this proposal to allow for less intelligent clients to have their +identity server disabled. Intelligent clients could interpret the lack of identity server +as the homeserver/user asking that identity server functionality be disabled in the client. From 6baeb6c21875f2440f220561af2d069e85749bd9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 5 Sep 2019 20:25:31 -0600 Subject: [PATCH 0816/1250] Assign number --- ...-discovery.md => 2284-optional-identity-server-discovery.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename proposals/{0000-optional-identity-server-discovery.md => 2284-optional-identity-server-discovery.md} (94%) diff --git a/proposals/0000-optional-identity-server-discovery.md b/proposals/2284-optional-identity-server-discovery.md similarity index 94% rename from proposals/0000-optional-identity-server-discovery.md rename to proposals/2284-optional-identity-server-discovery.md index 013a3e77..2da7018f 100644 --- a/proposals/0000-optional-identity-server-discovery.md +++ b/proposals/2284-optional-identity-server-discovery.md @@ -1,4 +1,4 @@ -# Proposal to make the identity server optional during discovery +# MSC2284: Making the identity server optional during discovery Currently the specification requires that clients `FAIL_ERROR` (hard failure - do not continue) when the `.well-known` file for `m.identity_server` points to somewhere invalid or is invalid From 642be6c6773bf269e95ba2c268230046e2748913 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 6 Sep 2019 13:06:16 -0600 Subject: [PATCH 0817/1250] Fix unbind wording --- api/client-server/administrative_contact.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index dfb9520e..3581edf7 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -241,9 +241,8 @@ paths: post: summary: Removes a user's third party identifier from an identity server. description: |- - Removes a user's third party identifier from the provided identity server. - This should not cause an unbind from the homeserver (as ``/3pid/delete`` - would) and should only affect the identity server. + Removes a user's third party identifier from the provided identity server + without removing it from the homeserver. Unlike other endpoints, this endpoint does not take an ``id_access_token`` parameter because the homeserver is expected to sign the request to the From 7644085274e1837b4e5f5701ebcfa8edfb95b425 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Sat, 7 Sep 2019 16:03:11 -0400 Subject: [PATCH 0818/1250] wording fixes and clarifications --- proposals/1756-cross-signing.md | 50 ++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 1dbef83c..53690b5f 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -2,9 +2,9 @@ ## Background -A user with multiple devices will have a different key for end-to-end -encryption for each device. Other users who want to communicate securely with -this user must then verify each key on each of their devices. If Alice has *n* +If a user has multiple devices, each device will have a different key for +end-to-end encryption. Other users who want to communicate securely with this +user must then verify each key on each of their own devices. If Alice has *n* devices, and Bob has *m* devices, then for Alice to be able to communicate with Bob on any of their devices, this involves *n×m* key verifications. @@ -21,15 +21,15 @@ MSC1680 is presented below. Each user has three sets of key pairs: -- a master cross-signing key pair that is used to identify themselves and to +- a *master* cross-signing key pair that is used to identify themselves and to sign their other cross-signing keys, -- a self-signing key pair that is used to sign their own devices, and -- a user-signing key pair that is used to sign other users' master keys. +- a *self-signing* key pair that is used to sign their own devices, and +- a *user-signing* key pair that is used to sign other users' master keys. When one user (e.g. Alice) verifies another user's (Bob's) identity, Alice will sign Bob's master key with her user-signing key. (This will mean that -verification methods will need to be modified to pass along the master -identity key.) Alice's device will trust Bob's device if: +verification methods will need to be modified to pass along the public part of +the master key.) Alice's device will trust Bob's device if: - Alice's device is using a master key that has signed her user-signing key, - Alice's user-signing key has signed Bob's master key, @@ -41,7 +41,7 @@ identity key.) Alice's device will trust Bob's device if: A user's master key could allow an attacker to impersonate that user to other users, or other users to that user. Thus clients must ensure that the private part of the master key is treated securely. If clients do not have a secure -means of storing the master key (such as an secret storage system provided by +means of storing the master key (such as a secret storage system provided by the operating system), then clients must not store the private part. If a user changes their master key, clients of users that they communicate with must notify their users about the change. @@ -68,7 +68,7 @@ keys, respectively. Currently, users will only be allowed to see * signatures made by their own master, self-signing or user-signing keys, -* signatures made by their own devices of their own master key, +* signatures made by their own devices about their own master key, * signatures made by other users' self-signing keys about the other users' own devices, * signatures made by other users' master keys about the other users' @@ -85,8 +85,8 @@ Users who have verified individual devices may wish to migrate these verifications to use cross-signing instead. In order to aid with this, signatures of a user's master key, made by their own devices, may be uploaded to the server. If another client sees that the user's master key has a valid -signature from a device that was previously verified, then the client MAY -choose to trust and sign the master key. The client SHOULD take precautions to +signature from a device that was previously verified, then the client may +choose to trust and sign the master key. The client should take precautions to ensure that a stolen device cannot be used to cause it to trust a malicious master key. For example, a client could prompt the user before signing the master key, or it could only do this migration on the first master key that it @@ -379,13 +379,15 @@ response: The response contains a `failures` property, which is a map of user ID to device ID to failure reason, if any of the uploaded keys failed. The -homeserver should verify that the signature is correct. If it is not, the -homeserver should set the corresponding entry in `failures` to a JSON object -with the `errcode` property set to `M_INVALID_SIGNATURE`. +homeserver should verify that the signatures on the uploaded keys are valid. +If a signature is not valid, the homeserver should set the corresponding entry +in `failures` to a JSON object with the `errcode` property set to +`M_INVALID_SIGNATURE`. After Alice uploads a signature for her own devices or master key, her signature will be included in the results of the `/keys/query` request when -*anyone* requests her keys: +*anyone* requests her keys. However, signatures made for other users' keys, +made by her user-signing key, will not be included. `POST /keys/query` @@ -455,12 +457,16 @@ response: } ``` -Similarly, the federation endpoints `GET /user/keys/query` and -`POST /user/devices/{userId}` will include the new signature. - -In addition, Alice's server will send an `m.device_list_update` EDU to servers -that have users who share encrypted rooms with Alice, updating her device to -include her new signature. +Similarly, the federation endpoints `GET /user/keys/query` and `POST +/user/devices/{userId}` will include the new signatures for her own devices or +master key, but not signatures made by her user-signing key. + +In addition, when Alice uploads signatures for her own device, Alice's server +will send an `m.device_list_update` EDU to servers that have users who share +encrypted rooms with Alice, updating her device to include her new signature. +And when a signature of a master key is uploaded, Alice's server will send an +`m.signing_key_update` EDU, updating her master key to include her new +signature. After Alice uploads a signature for Bob's user-signing key, her signature will be included in the results of the `/keys/query` request when Alice requests From 60f0ad5b24b8928dff7c246083339c1332b9873e Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Sat, 7 Sep 2019 16:05:46 -0400 Subject: [PATCH 0819/1250] lowercase --- proposals/1756-cross-signing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 53690b5f..2e4f1b43 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -148,8 +148,8 @@ Cross-signing keys are JSON objects with the following properties: "`ed25519:`" followed by the unpadded base64 encoding of the public key, and whose value is the unpadded base64 encoding of the public key. * `signatures` ({string: {string: string}}): signatures of the key. A - self-signing or user-signing key MUST be signed by the master key. A master - key MAY be signed by a device. + self-signing or user-signing key must be signed by the master key. A master + key may be signed by a device. In order to ensure that there will be no collisions in the `signatures` property, the server must respond with an `M_FORBIDDEN` error if any of From cf953c47fd799af7573bc257fce6fd6db47c5d02 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 9 Sep 2019 17:29:32 -0400 Subject: [PATCH 0820/1250] clarifications, change "hash" to "etag" --- .../1219-storing-megolm-keys-serverside.md | 112 ++++++++++-------- 1 file changed, 63 insertions(+), 49 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index dbcf3091..f51ed5f9 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -38,20 +38,26 @@ Proposal -------- This proposal creates new APIs to allow clients to back up room decryption keys -on the server. Decryption keys are encrypted (using public key crypto) before -being sent to the server along with some unencrypted metadata to allow the -server to manage the backups, overwriting backups with "better" versions of the -keys. The user is given a private recovery key to save for recovering the keys -from the backup. - -Clients can create new versions of backups. Aside from the initial backup -creation, a client might start a new version of a backup when, for example, a -user loses a device, and wants to ensure that that device does not get any new -decryption keys. - -Once one client has created a backup version, other clients can fetch the -public key for the backup from the server and add keys to the backup, if they -trust that the backup was not created by a malicious device. +on the server. Room decryption keys are encrypted (using public key crypto) +before being sent to the server along with some unencrypted metadata to allow +the server to manage the backups. If a key for a new megolm session is +uploaded, it is added to the current backup. If a key is uploaded for a megolm +session is that is already present in the backup, the server will use the +metadata to determine which version of the key is "better". The way in which +the server determines which key is "better" is described in the [Storing +Keys](#storing-keys) section. The user is given a private recovery key in +order to recover the keys from the backup in the future. + +Clients can create new key backups (sometimes also referred to in the API as +backup versions) to replace the current backup. Aside from the initial backup +creation, a client might start a new a backup when, for example, a user loses a +device and wants to ensure that that device does not get any new decryption +keys. In this case, the client will then create a new backup using a new key +that the device does not have access to. + +Once one client has created a backup, other clients can fetch the public part +of the recovery key from the server and add keys to the backup, if they trust +that the backup was not created by a malicious device. ### Possible UX for interactive clients @@ -63,31 +69,30 @@ On receipt of encryption keys (1st time): 1. client checks if there is an existing backup: `GET /room_keys/version` 1. if not, ask if the user wants to back up keys 1. if yes: - 1. generate new curve25519 key pair - 2. create new backup version: `POST /room_keys/version` - 3. display private key for user to save (see below for the format) + 1. generate new curve25519 key pair, which will be the recovery key + 2. create new backup: `POST /room_keys/version` + 3. display private key for user to save (see below for the + [format of the recovery key](#recovery-key)) 2. if no, exit and remember decision (user can change their mind later) 3. while prompting, continue to poll `GET /room_keys/versions`, as another device may have created a backup. If so, go to 1.2. - 2. if yes, get public key, prompt user to verify a device that signed the - key¹, or enter recovery key (which can derive the backup key). + 2. if yes, either get the public part of the recovery key and check that it + is signed by the master cross-signing key, or prompt user to enter the + private part of the recovery key (which can derive the public part). 1. User can also decide to create a new backup, in which case, go to 1.1. 2. send key to backup: `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v` 3. continue backing up keys as we receive them (may receive a - `M_WRONG_ROOM_KEYS_VERSION` error if a new backup version has been created: + `M_WRONG_ROOM_KEYS_VERSION` error if a new backup has been created: see below) On `M_WRONG_ROOM_KEYS_VERSION` error when trying to `PUT` keys: 1. get the current version -2. notify the user that there is a new backup version, and display relevant - information +2. notify the user that there is a new backup, and display relevant information 3. confirm with user that they want to use the backup (user may want use the backup, to stop backing up keys, or to create a new backup) -4. verify the device that signed the backup key¹, or enter recovery key - -¹: cross-signing (when that is completed) can be used to verify the device -that signed the key. +4. ensure the backup key is signed by the user's master key, or prompt the user + to enter the recovery key On receipt of undecryptable message: @@ -125,7 +130,7 @@ is 35 bytes. Clients must then remove the first two bytes and the last byte, and use the resulting string as the private key to decrypt backups. If MSC1946 is used to store the key on the server, it must be stored using the -`account_data` `type` `m.megolm_backup.v1`. +`account_data` type `m.megolm_backup.v1`. As a special case, if the recovery key is the same as the curve25519 key used for storing the key, then the contents of the `m.megolm_backup.v1` @@ -160,8 +165,8 @@ Body parameters: - `algorithm` (string): Required. The algorithm used for storing backups. Currently, only `m.megolm_backup.v1.curve25519-aes-sha2` is defined. - `auth_data` (object): Required. algorithm-dependent data. For - `m.megolm_backup.v1.curve25519-aes-sha2`, see below for the definition of - this property. + `m.megolm_backup.v1.curve25519-aes-sha2`, see below for the [definition of + this property](#auth_data-backup-versions). Example: @@ -195,10 +200,10 @@ On success, returns a JSON object with keys: - `auth_data` (object): Required. Same as in the body parameters for `POST /room_keys/version`. - `version` (string): Required. The backup version. -- `hash` (string): Required. The hash value which is an opaque string - representing stored keys in the backup. Client can compare it with the `hash` - value they received in the response of their last key storage request. - If not equal, another matrix client pushed new keys to the backup. +- `etag` (string): Required. The etag value which is an opaque string + representing stored keys in the backup. Clients can compare it with the + `etag` value they received in the response of their last key storage request. + If not equal, another client has pushed new keys to the backup. - `count` (number): Required. The number of keys stored in the backup. Error codes: @@ -214,8 +219,8 @@ Body parameters: - `algorithm` (string): Required. Must be the same as in the body parameters for `GET /room_keys/version`. - `auth_data` (object): Required. algorithm-dependent data. For - `m.megolm_backup.v1.curve25519-aes-sha2`, see below for the definition of - this property. + `m.megolm_backup.v1.curve25519-aes-sha2`, see below for the [definition of + this property](#auth_data-backup-versions). - `version` (string): Required. The backup version. Must be the same as the query parameter or must be the current version. Example: @@ -251,9 +256,15 @@ version. If the server already has a backup in the backup version for the given session and room, then it will keep the "better" one. To determine which one is -"better", key backups are compared first by the `is_verified` flag (`true` is -better than `false`), then by the `first_message_index` (a lower number is better), -and finally by `forwarded_count` (a lower number is better). +"better", keys are compared: + +- first by the `is_verified` flag (`true` is better than `false`), +- then, if `is_verified` is equal, by the `first_message_index` (a lower number is better), +- and finally, is `is_verified` and `first_message_index` are equal, by + `forwarded_count` (a lower number is better). + +If neither key is better than the other (that is, if all three fields are +equal), then the server should keep the existing key. Body parameters: @@ -264,12 +275,12 @@ Body parameters: - `is_verified` (boolean): Required. Whether the device backing up the key has verified the device that the key is from. - `session_data` (object): Required. Algorithm-dependent data. For - `m.megolm_backup.v1.curve25519-aes-sha2`, see below for the definition of - this property. + `m.megolm_backup.v1.curve25519-aes-sha2`, see below for the [definition of + this property](#auth_data-backup-versions). On success, returns a JSON object with keys: -- `hash` (string): Required. The new hash value representing stored keys. See +- `etag` (string): Required. The new etag value representing stored keys. See `GET /room_keys/version/{version}` for more details. - `count` (number): Required. The new count of keys stored in the backup. @@ -299,7 +310,7 @@ Result: ```javascript { - "hash": "abcdefghi", + "etag": "abcdefghi", "count": 10 } ``` @@ -344,7 +355,7 @@ Result: ```javascript { - "hash": "abcdefghi", + "etag": "abcdefghi", "count": 10 } ``` @@ -393,7 +404,7 @@ Result: ```javascript { - "hash": "abcdefghi", + "etag": "abcdefghi", "count": 10 } ``` @@ -401,7 +412,7 @@ Result: #### Retrieving keys When retrieving keys, the `version` parameter is optional, and defaults to -retrieving the latest backup version. +retrieving keys from the latest backup version. ##### `GET /room_keys/keys/${roomId}/${sessionId}?version=$v` @@ -463,7 +474,8 @@ Error codes: Deletes keys from the backup. -On success, returns the empty JSON object. +Returns the same as `PUT +/room_keys/keys/${roomId}/${sessionId}?version=$v`. #### `m.megolm_backup.v1.curve25519-aes-sha2` definitions @@ -479,9 +491,9 @@ following keys: The `auth_data` should be signed by the user's [master cross-signing key](https://github.com/matrix-org/matrix-doc/pull/1756), and may also be -signed by the user's device key. The allows clients to ensure that the public +signed by the user's device key. This allows clients to ensure that the public key is valid, and prevents an attacker from being able to change the backup to -use a public key that have the private key for. +use a public key that they have the private key for. ##### `session_data` for key backups @@ -489,7 +501,9 @@ 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: - `algorithm` (string): `m.megolm.v1.aes-sha2` - - `sender_key` (string): base64-encoded device curve25519 key + - `sender_key` (string): base64-encoded device curve25519 key in + [session-sharing + format](https://gitlab.matrix.org/matrix-org/olm/blob/master/docs/megolm.md#session-sharing-format) - `sender_claimed_keys` (object): object containing the identity keys for the sending device - `forwarding_curve25519_key_chain` (array): zero or more curve25519 keys From 6cfd761204b3fe36c76c290afa8463c8256ae951 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 9 Sep 2019 19:49:49 -0600 Subject: [PATCH 0821/1250] Spec the v2 lookup API Spec for [MSC2134](https://github.com/matrix-org/matrix-doc/pull/2134) --- api/identity/lookup.yaml | 2 +- api/identity/v2_lookup.yaml | 145 ++++++++++++++++++++++++ specification/identity_service_api.rst | 146 ++++++++++++++++++++++++- 3 files changed, 291 insertions(+), 2 deletions(-) create mode 100644 api/identity/v2_lookup.yaml diff --git a/api/identity/lookup.yaml b/api/identity/lookup.yaml index 166b0962..78fa3e3e 100644 --- a/api/identity/lookup.yaml +++ b/api/identity/lookup.yaml @@ -16,7 +16,7 @@ # limitations under the License. swagger: '2.0' info: - title: "Matrix Identity Service Lookup API" + title: "Matrix Identity Service Lookup API" version: "1.0.0" host: localhost:8090 schemes: diff --git a/api/identity/v2_lookup.yaml b/api/identity/v2_lookup.yaml new file mode 100644 index 00000000..561700f4 --- /dev/null +++ b/api/identity/v2_lookup.yaml @@ -0,0 +1,145 @@ +# Copyright 2016 OpenMarket Ltd +# Copyright 2017 Kamax.io +# Copyright 2017 New Vector Ltd +# Copyright 2018 New Vector Ltd +# Copyright 2019 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. +swagger: '2.0' +info: + title: "Matrix Identity Service Lookup API" + version: "2.0.0" +host: localhost:8090 +schemes: + - https +basePath: /_matrix/identity/v2 +consumes: + - application/json +produces: + - application/json +securityDefinitions: + $ref: definitions/security.yaml +paths: + "/hash_details": + get: + summary: Gets hash function information from the server. + description: |- + Gets parameters for hashing identifiers from the server. This can include + any of the algorithms defined in this specification. + operationId: getHashDetails + security: + - accessToken: [] + parameters: [] + responses: + 200: + description: The hash function information. + examples: + application/json: { + "lookup_pepper": "matrixrocks", + "algorithms": ["none", "sha256"] + } + schema: + type: object + properties: + lookup_pepper: + type: string + description: |- + The pepper the client MUST use in hashing identifiers, and MUST + supply to the ``/lookup`` endpoint when performing lookups. + + Servers SHOULD rotate this string often. + algorithms: + type: array + items: + type: string + description: |- + The algorithms the server supports. Must contain at least ``sha256``. + required: ['lookup_pepper', 'algorithms'] + "/lookup": + post: + summary: Look up Matrix User IDs for a set of 3PIDs. + description: |- + Looks up the set of Matrix User IDs which have bound the 3PIDs given, if + bindings are available. Note that the format of the addresses is defined + later in this specification. + operationId: lookupUsersV2 + security: + - accessToken: [] + parameters: + - in: body + name: body + schema: + type: object + properties: + algorithm: + type: string + description: |- + The algorithm the client is using to encode the ``addresses``. This + should be one of the available options from ``/hash_details``. + example: "sha256" + pepper: + type: string + description: |- + The pepper from ``/hash_details``. This is required even when the + ``algorithm`` does not make use of it. + example: "matrixrocks" + addresses: + type: array + items: + type: string + description: |- + The addresses to look up. The format of the entries here depend on + the ``algorithm`` used. Note that queries which have been incorrectly + hashed or formatted will lead to no matches. + example: [ + "4kenr7N9drpCJ4AfalmlGQVsOn3o2RHjkADUpXJWZUc", + "nlo35_T5fzSGZzJApqu8lgIudJvmOQtDaHtr-I4rU7I" + ] + required: ['algorithm', 'pepper', 'addresses'] + responses: + 200: + description: + The associations for any matched ``addresses``. + examples: + application/json: { + "mappings": { + "4kenr7N9drpCJ4AfalmlGQVsOn3o2RHjkADUpXJWZUc": "@alice:example.org" + } + } + schema: + type: object + properties: + mappings: + type: object + description: |- + Any applicable mappings of ``addresses`` to Matrix User IDs. Addresses + which do not have associations will not be included, which can make + this property be an empty object. + title: AssociatedMappings + additionalProperties: + type: string + required: ['mappings'] + 400: + description: + The client's request was invalid in some way. One possible problem could + be the ``pepper`` being invalid after the server has rotated it - this is + presented with the ``M_INVALID_PEPPER`` error code. Clients SHOULD make + a call to ``/hash_details`` to get a new pepper in this scenario, being + careful to avoid retry loops. + examples: + application/json: { + "errcode": "M_INVALID_PEPPER", + "error": "Unknown or invalid pepper - has it been rotated?" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" diff --git a/specification/identity_service_api.rst b/specification/identity_service_api.rst index c92f737b..f389cbc7 100644 --- a/specification/identity_service_api.rst +++ b/specification/identity_service_api.rst @@ -155,6 +155,23 @@ should allow a 3PID to be mapped to a Matrix user identity, but not in the other direction (i.e. one should not be able to get all 3PIDs associated with a Matrix user ID, or get all 3PIDs associated with a 3PID). +Version 1 API deprecation +------------------------- + +.. TODO: Remove this section when the v1 API is removed. + +As described on each of the version 1 endpoints, the v1 API is deprecated in +favour of the v2 API described here. The major difference, with the exception +of a few isolated cases, is that the v2 API requires authentication to ensure +the user has given permission for the identity server to operate on their data. + +The v1 API is planned to be removed from the specification in a future version. + +Clients SHOULD attempt the v2 endpoints first, and if they receive a ``404``, +``400``, or similar error they should try the v1 endpoint or fail the operation. +Clients are strongly encouraged to warn the user of the risks in using the v1 API, +if they are planning on using it. + Web browser clients ------------------- @@ -258,7 +275,134 @@ Association lookup {{lookup_is_http_api}} -.. TODO: TravisR - Add v2 lookup API in future PR +{{v2_lookup_is_http_api}} + +Client behaviour +~~~~~~~~~~~~~~~~ + +.. TODO: Remove this note when v1 is removed completely +.. Note:: + This section only covers the v2 lookup endpoint. The v1 endpoint is described + in isolation above. + +Prior to performing a lookup clients SHOULD make a request to the ``/hash_details`` +endpoint to determine what algorithms the server supports (described in more detail +below). The client then uses this information to form a ``/lookup`` request and +receive known bindings from the server. + +Clients MUST support at least the ``sha256`` algorithm. + +Server behaviour +~~~~~~~~~~~~~~~~ + +.. TODO: Remove this note when v1 is removed completely +.. Note:: + This section only covers the v2 lookup endpoint. The v1 endpoint is described + in isolation above. + +Servers, upon receipt of a ``/lookup`` request, will compare the query against +known bindings it has, hashing the identifiers it knows about as needed to +verify exact matches to the request. + +Servers MUST support at least the ``sha256`` algorithm. + +Algorithms +~~~~~~~~~~ + +Some algorithms are defined as part of the specification, however other formats +can be negotiated between the client and server using ``/hash_details``. + +``sha256`` +++++++++++ + +This algorithm MUST be supported by clients and servers at a minimum. It is +additionally the preferred algorithm for lookups. + +When using this algorithm, the client converts the query first into strings +separated by spaces in the format ``

``. The ```` +is retrieved from ``/hash_details``, the ```` is typically ``email`` or +``msisdn`` (both lowercase), and the ``
`` is the 3PID to search for. +For example, if the client wanted to know about ``alice@example.org``'s bindings, +it would first format the query as ``alice@example.org email ThePepperGoesHere``. + +.. admonition:: Rationale + + Mediums and peppers are appended to the address to prevent a common prefix + for each 3PID, helping prevent attackers from pre-computing the internal state + of the hash function. + +After formatting each query, the string is run through SHA-256 as defined by +`RFC 4634 `_. The resulting bytes are then +encoded using URL-Safe `Unpadded Base64`_ (similar to `room version 4's +event ID format <../../rooms/v4.html#event-ids>`_). + +An example set of queries when using the pepper ``matrixrocks`` would be:: + + "alice@example.com email matrixrocks" -> "4kenr7N9drpCJ4AfalmlGQVsOn3o2RHjkADUpXJWZUc" + "bob@example.com email matrixrocks" -> "LJwSazmv46n0hlMlsb_iYxI0_HXEqy_yj6Jm636cdT8" + "18005552067 msisdn matrixrocks" -> "nlo35_T5fzSGZzJApqu8lgIudJvmOQtDaHtr-I4rU7I" + + +The set of hashes is then given as the ``addresses`` array in ``/lookup``. Note +that the pepper used MUST be supplied as ``pepper`` in the ``/lookup`` request. + +``none`` +++++++++ + +This algorithm performs plaintext lookups on the identity server. Typically this +algorithm should not be used due to the security concerns of unhashed identifiers, +however some scenarios (such as LDAP-backed identity servers) prevent the use of +hashed identifiers. Identity servers (and optionally clients) can use this algorithm +to perform those kinds of lookups. + +Similar to the ``sha256`` algorithm, the client converts the queries into strings +separated by spaces in the format ``
`` - note the lack of ````. +For example, if the client wanted to know about ``alice@example.org``'s bindings, +it would format the query as ``alice@example.org email``. + +The formatted strings are then given as the ``addresses`` in ``/lookup``. Note that +the ``pepper`` is still required, and must be provided to ensure the client has made +an appropriate request to ``/hash_details`` first. + +Security considerations +~~~~~~~~~~~~~~~~~~~~~~~ + +.. Note:: + `MSC2134 `_ has much more + information about the security considerations made for this section of the + specification. This section covers the high-level details for why the specification + is the way it is. + +Typically the lookup endpoint is used when a client has an unknown 3PID it wants to +find a Matrix User ID for. Clients normally do this kind of lookup when inviting new +users to a room or searching a user's address book to find any Matrix users they may +not have discovered yet. Rogue or malicious identity servers could harvest this +unknown information and do nefarious things with it if it were sent in plain text. +In order to protect the privacy of users who might not have a Matrix identifier bound +to their 3PID addresses, the specification attempts to make it difficult to harvest +3PIDs. + +.. admonition:: Rationale + + Hashing identifiers, while not perfect, helps make the effort required to harvest + identifiers significantly higher. Phone numbers in particular are still difficult + to protect with hashing, however hashing is objectively better than not. + + An alternative to hashing would be using bcrypt or similar with many rounds, however + by nature of needing to serve mobile clients and clients on limited hardware the + solution needs be kept relatively lightweight. + +Clients should be cautious of servers not rotating their pepper very often, and +potentially of servers which use a weak pepper - these servers may be attempting to +brute force the identifiers or use rainbow tables to mine the addresses. Similarly, +clients which support the ``none`` algorithm should consider at least warning the user +of the risks in sending identifiers in plain text to the identity server. + +Addresses are still potentially reversable using a calculated rainbow table given +some identifiers, such as phone numbers, common email address domains, and leaked +addresses are easily calculated. For example, phone numbers can have roughly 12 +digits to them, making them an easier target for attack than email addresses. + Establishing associations ------------------------- From b3e2326d8b857fc5c5d944135995c7de5d3e6867 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 9 Sep 2019 19:59:18 -0600 Subject: [PATCH 0822/1250] changelog --- changelogs/identity_service/newsfragments/2287.new | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/identity_service/newsfragments/2287.new diff --git a/changelogs/identity_service/newsfragments/2287.new b/changelogs/identity_service/newsfragments/2287.new new file mode 100644 index 00000000..7d575bc9 --- /dev/null +++ b/changelogs/identity_service/newsfragments/2287.new @@ -0,0 +1 @@ +Add ``/hash_details`` and a new ``/lookup`` endpoint for performing hashed association lookups. From 8123c4ef0ff499eefbf7ca5becae11511d8835f7 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 9 Sep 2019 22:57:29 -0400 Subject: [PATCH 0823/1250] additional clarification --- proposals/1219-storing-megolm-keys-serverside.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index f51ed5f9..1103eecf 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -91,8 +91,8 @@ On `M_WRONG_ROOM_KEYS_VERSION` error when trying to `PUT` keys: 2. notify the user that there is a new backup, and display relevant information 3. confirm with user that they want to use the backup (user may want use the backup, to stop backing up keys, or to create a new backup) -4. ensure the backup key is signed by the user's master key, or prompt the user - to enter the recovery key +4. ensure the public part of the recovery key is signed by the user's master + key, or prompt the user to enter the private part of the recovery key On receipt of undecryptable message: From d813b8e12c6e8839d9496c65861ab7ab070bc322 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 10 Sep 2019 09:35:37 -0600 Subject: [PATCH 0824/1250] Mention M_INVALID_PARAM --- api/identity/v2_lookup.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/api/identity/v2_lookup.yaml b/api/identity/v2_lookup.yaml index 561700f4..8acafd75 100644 --- a/api/identity/v2_lookup.yaml +++ b/api/identity/v2_lookup.yaml @@ -136,6 +136,9 @@ paths: presented with the ``M_INVALID_PEPPER`` error code. Clients SHOULD make a call to ``/hash_details`` to get a new pepper in this scenario, being careful to avoid retry loops. + + ``M_INVALID_PARAM`` can also be returned to indicate the client supplied + an ``algorithm`` that is unknown to the server. examples: application/json: { "errcode": "M_INVALID_PEPPER", From fdea3e34a864aa55e5fe48f797741e64f6d19c52 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 12 Sep 2019 13:30:51 +0100 Subject: [PATCH 0825/1250] wip --- temp | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 temp diff --git a/temp b/temp new file mode 100644 index 00000000..e69de29b From 7096092da901a1e3feda3341c213727f1608a1cb Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 12 Sep 2019 13:52:52 +0100 Subject: [PATCH 0826/1250] init --- proposals/2290-separate-threepid-bind-hs.md | 190 ++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 proposals/2290-separate-threepid-bind-hs.md diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md new file mode 100644 index 00000000..a62e5b39 --- /dev/null +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -0,0 +1,190 @@ +# Separate Endpoints for Binding Threepids + +On the Client Server API there is currently a single API for binding a +threepid (an email or a phone number): [POST +/_matrix/client/r0/account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid). +Depending on whether the `bind` flag is `true` or `false`, the threepid will +be bound to either a user's account on the homeserver, or both the homeserver +and an identity server. + +A threepid can be bound to an identity server to allow other users to find +their Matrix ID using their email address or phone number. A threepid can +also be bound to a user's account on the homeserver. This allows that +threepid to be used for message notifications, login, password reset, and +other important functions. + +Typically, when using the `POST /_matrix/client/r0/account/3pid` endpoint, +the identity server handles the verification -- either by sending an email to +the email address, or a SMS message to the phone number. Once completed, the +homeserver would check with the identity server that verification had indeed +happened, and if so, the threepid would be bound (again, either to the +homeserver, or the homeserver and identity server simultaneously). + +Now, consider the fact that the identity server used in this process is +provided by the user, using the endpoint's `id_server` parameter. If the user were +to supply a malicious identity server that would immediately answer "yes" to +any threepid validation, then the user could add any threepid to their +account on the homeserver (which is likely not something homeserver admins want). + +To solve this problem, we propose adding a second endpoint that is only used +for binding to an identity server of the user's choice. This endpoint will +not bind the threepid to the user's account on the homeserver, only on the +identity server. + +In addition, the existing binding endpoint will lose the ability to bind +threepids to an identity server, by removing its `bind` flag. Instead, it +will solely be used to bind to the user's account on the homeserver. + +To be clear, the above issue is not a long-standing security issue. Indeed it +is not a problem in any released version of Synapse, as Synapse keeps a list +of "trusted identity servers" that acts a whitelist for what identity servers +a user can specify. + +Synapse is soon to lose this whitelist however, as part of lessening the +reliance of homeservers on identity servers. This cannot be done while the +homeserver is still trusting an identity server for validation of threepids. +If the endpoints are split, the homeserver will handle the validation of +threepids being added to user accounts, and identity servers will validate +threepids being added to their own database. + +One may question why clients don't just contact an identity server directly +to bind a threepid, bypassing the implications of binding through a +homeserver. While this will work, binds should still occur through a +homeserver such that the homeserver can keep track of which binds were made, +which is important when a user wishes to deactivate their account (and remove +all of their bindings made on different identity servers). + +A bind could be made on an identity server, which could then tell the +homeserver that a validation occured, but then there are security +considerations about how to authenticate an identity server in that instance +(and prevent people pretending to be identity servers and telling homeservers +about hundreds of fake binds to a user's account). + +This MSC obseletes +[MSC2229](https://github.com/matrix-org/matrix-doc/pull/2229), which dealt +with changing the rules of the `bind` flag. Since this flag is being removed, +the MSC is no longer relevant. + +## Proposal + +A new endpoint will be added to the Client Server API: `POST /_matrix/client/r0/account/3pid/identity/bind`, and requires authentication. + +The endpoint definition is the same as `POST +/_matrix/client/r0/account/3pid`, minus the `bind` flag. + +An example of binding a threepid to an identity server with this new endpoint: + +First the client must request the threepid be validated by its chosen identity server. + +``` +POST https://identity.server/_matrix/identity/v2/validate/email/requestToken + +{ + "client_secret": "don'tT3ll", + "email": "bob@example.com", + "send_attempt": 1 +} +``` + +Once an email has been sent, the user clicks the link in the email, which +notifies the identity server that the email has been verified. + +Next, the client completes the bind by calling the new endpoint on the homeserver: + +``` +POST https://home.server/_matrix/client/r0/account/3pid/identity/bind + +{ + "three_pid_creds": { + "id_server": "example.org", + "id_access_token": "abc123_OpaqueString", + "sid": "abc123987", + "client_secret": "don'tT3ll" + } +} +``` + +The homeserver will then make a bind request on behalf of the user to the +specified identity server. The homeserver will record if the bind was +successful and notify the user. + +And for completeness, here is an example of binding a threepid to the +homeserver only, using the old endpoint: + +The homeserver is validating the threepid in this instance, so the client +must use the `/requestToken` endpoint of the homeserver: + +``` +POST https://home.server/_matrix/client/r0/account/3pid/email/requestToken + +{ + "client_secret": "don'tT3ll", + "email": "bob@example.com", + "send_attempt": 1, +} +``` + +Once an email has been sent, the user clicks the link in the email, which +notifies the homeserver that the email has been verified. + +The client then sends a request to the old endpoint to bind the threepid to +user's account. + +``` +POST /_matrix/client/r0/account/3pid + +{ + "three_pid_creds": { + "sid": "abc123987", + "client_secret": "don'tT3ll" + } +} +``` + +The threepid will then be bound to the user's account. + +Users will be able to perform binds to an identity server for a threepid even if that threepid has not been bound to the user's account on the homeserver before. + +The achieve the above flow, some changes need to be made to existing +endpoints as well. This MSC requests that the `id_server` and +`id_access_token` parameters be removed from the Client-Server API's [POST +/_matrix/client/r0/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-email-requesttoken) +endpoint, as this endpoint is now only intended for the homeserver to send +emails from. Additionally, the same parameters will be removed from the [POST +/_matrix/client/r0/account/3pid](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid)endpoint's +`three_pid_creds` parameter as an identity server is no longer required to +perform verification. + +This MSC also requests that the text "It is imperative that the homeserver +keep a list of trusted Identity Servers and only proxies to those that it +trusts." be removed from all parts of the spec, as the homeserver should no +longer need to trust any identity servers. + +## Tradeoffs + +It may be possible to reduce the two calls per flow into a single endpoint, +but the current asynchronous approach makes it easy for a client to send a +request, go offline, have the threepid be validated, and then come online +again to finalize the validation afterwards. + +## Backwards compatibility + +TODO + +## Security considerations + +Reducing the homeserver's trust in identity servers should be a boost to security and improve decentralisation in the Matrix ecosystem to boot. + +Caution should be taken for homeserver developers to be sure not to continue +to use user-provided identity servers for any sensitive tasks once it removes +the concept of a trusted identity server. + +## Conclusion + +This MSC helps reduce the homeserver's trust in an identity server even +further to the point where it is only used for binding addresses for lookup - +which was the original intention of the Identity Service API. + +Additionally, by clearly separating the threepid bind endpoint into two +endpoints that each have a clear intention, the concept of threepid binding +becomes a lot easier to reason about. From f5b10c689fc0f83705f161dcae20ce4be9c79715 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 12 Sep 2019 15:55:50 +0100 Subject: [PATCH 0827/1250] cleanup --- proposals/2290-separate-threepid-bind-hs.md | 68 +++++++++++---------- temp | 0 2 files changed, 37 insertions(+), 31 deletions(-) delete mode 100644 temp diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index a62e5b39..95e90192 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -1,22 +1,22 @@ # Separate Endpoints for Binding Threepids -On the Client Server API there is currently a single API for binding a +On the Client Server API there is currently a single endpoint for binding a threepid (an email or a phone number): [POST /_matrix/client/r0/account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid). Depending on whether the `bind` flag is `true` or `false`, the threepid will be bound to either a user's account on the homeserver, or both the homeserver and an identity server. -A threepid can be bound to an identity server to allow other users to find +For context a threepid can be bound to an identity server to allow other users to find their Matrix ID using their email address or phone number. A threepid can -also be bound to a user's account on the homeserver. This allows that +also be bound to a user's account on the homeserver. This allows the threepid to be used for message notifications, login, password reset, and other important functions. Typically, when using the `POST /_matrix/client/r0/account/3pid` endpoint, the identity server handles the verification -- either by sending an email to -the email address, or a SMS message to the phone number. Once completed, the -homeserver would check with the identity server that verification had indeed +an email address, or a SMS message to a phone number. Once completed, the +homeserver will check with the identity server that verification had indeed happened, and if so, the threepid would be bound (again, either to the homeserver, or the homeserver and identity server simultaneously). @@ -28,7 +28,7 @@ account on the homeserver (which is likely not something homeserver admins want) To solve this problem, we propose adding a second endpoint that is only used for binding to an identity server of the user's choice. This endpoint will -not bind the threepid to the user's account on the homeserver, only on the +not bind the threepid to the user's account on the homeserver, only the identity server. In addition, the existing binding endpoint will lose the ability to bind @@ -67,12 +67,12 @@ the MSC is no longer relevant. ## Proposal -A new endpoint will be added to the Client Server API: `POST /_matrix/client/r0/account/3pid/identity/bind`, and requires authentication. - -The endpoint definition is the same as `POST +A new endpoint will be added to the Client Server API: `POST +/_matrix/client/r0/account/3pid/identity/bind`, and will require +authentication. The endpoint definition is the same as `POST /_matrix/client/r0/account/3pid`, minus the `bind` flag. -An example of binding a threepid to an identity server with this new endpoint: +An example of binding a threepid to **an identity server only** with this new endpoint is as follows: First the client must request the threepid be validated by its chosen identity server. @@ -104,11 +104,15 @@ POST https://home.server/_matrix/client/r0/account/3pid/identity/bind } ``` -The homeserver will then make a bind request on behalf of the user to the -specified identity server. The homeserver will record if the bind was -successful and notify the user. +The homeserver will then make a bind request to the specified identity server +on behalf of the user. The homeserver will record if the bind was successful +and notify the user. + +The threepid has now been binded on the user's identity server without +causing that threepid to be used for password resets or any other +homeserver-related functions. -And for completeness, here is an example of binding a threepid to the +For completeness, here is an example of binding a threepid to the homeserver only, using the old endpoint: The homeserver is validating the threepid in this instance, so the client @@ -125,10 +129,10 @@ POST https://home.server/_matrix/client/r0/account/3pid/email/requestToken ``` Once an email has been sent, the user clicks the link in the email, which -notifies the homeserver that the email has been verified. +notifies the homeserver that the threepid has been verified. -The client then sends a request to the old endpoint to bind the threepid to -user's account. +The client then sends a request to the old endpoint on the homeserver to bind +the threepid to user's account. ``` POST /_matrix/client/r0/account/3pid @@ -143,15 +147,16 @@ POST /_matrix/client/r0/account/3pid The threepid will then be bound to the user's account. -Users will be able to perform binds to an identity server for a threepid even if that threepid has not been bound to the user's account on the homeserver before. - -The achieve the above flow, some changes need to be made to existing -endpoints as well. This MSC requests that the `id_server` and -`id_access_token` parameters be removed from the Client-Server API's [POST +The achieve the above flows, some changes need to be made to existing +endpoints. This MSC requests that the `id_server` and `id_access_token` +parameters be removed from the Client-Server API's [POST /_matrix/client/r0/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-email-requesttoken) -endpoint, as this endpoint is now only intended for the homeserver to send -emails from. Additionally, the same parameters will be removed from the [POST -/_matrix/client/r0/account/3pid](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid)endpoint's +and [POST +/_matrix/client/r0/account/3pid/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken) +endpoints, as these endpoints are now only intended for the homeserver to +send validation requests from. Additionally, the same parameters will be +removed from the [POST +/_matrix/client/r0/account/3pid](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid) endpoint's `three_pid_creds` parameter as an identity server is no longer required to perform verification. @@ -173,18 +178,19 @@ TODO ## Security considerations -Reducing the homeserver's trust in identity servers should be a boost to security and improve decentralisation in the Matrix ecosystem to boot. +Reducing the homeserver's trust in identity servers should be a boost to +security and improve decentralisation in the Matrix ecosystem to boot. Caution should be taken for homeserver developers to be sure not to continue to use user-provided identity servers for any sensitive tasks once it removes -the concept of a trusted identity server. +the concept of a trusted identity server list. ## Conclusion -This MSC helps reduce the homeserver's trust in an identity server even +This MSC helps to minimize the homeserver's trust in an identity server even further to the point where it is only used for binding addresses for lookup - -which was the original intention of the Identity Service API. +which was the original intention of identity servers to begin with. Additionally, by clearly separating the threepid bind endpoint into two -endpoints that each have a clear intention, the concept of threepid binding -becomes a lot easier to reason about. +endpoints that each have a clear intention, the concept of attaching +threepids to a Matrix user becomes a lot easier to reason about. diff --git a/temp b/temp deleted file mode 100644 index e69de29b..00000000 From 5193c319e7b0250d5a6a74e66d04a9f4cfaa76f1 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 13 Sep 2019 11:49:31 +0100 Subject: [PATCH 0828/1250] Cleaner API endpoints --- proposals/2290-separate-threepid-bind-hs.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index 95e90192..69ed4827 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -2,7 +2,7 @@ On the Client Server API there is currently a single endpoint for binding a threepid (an email or a phone number): [POST -/_matrix/client/r0/account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid). +/account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid). Depending on whether the `bind` flag is `true` or `false`, the threepid will be bound to either a user's account on the homeserver, or both the homeserver and an identity server. @@ -13,7 +13,7 @@ also be bound to a user's account on the homeserver. This allows the threepid to be used for message notifications, login, password reset, and other important functions. -Typically, when using the `POST /_matrix/client/r0/account/3pid` endpoint, +Typically, when using the `/account/3pid` endpoint, the identity server handles the verification -- either by sending an email to an email address, or a SMS message to a phone number. Once completed, the homeserver will check with the identity server that verification had indeed @@ -68,9 +68,10 @@ the MSC is no longer relevant. ## Proposal A new endpoint will be added to the Client Server API: `POST -/_matrix/client/r0/account/3pid/identity/bind`, and will require -authentication. The endpoint definition is the same as `POST -/_matrix/client/r0/account/3pid`, minus the `bind` flag. +/account/3pid/identity/bind`, and will require authentication. The endpoint +definition is the same as [POST +/account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid), +minus the `bind` flag. An example of binding a threepid to **an identity server only** with this new endpoint is as follows: @@ -150,13 +151,13 @@ The threepid will then be bound to the user's account. The achieve the above flows, some changes need to be made to existing endpoints. This MSC requests that the `id_server` and `id_access_token` parameters be removed from the Client-Server API's [POST -/_matrix/client/r0/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-email-requesttoken) +/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-email-requesttoken) and [POST -/_matrix/client/r0/account/3pid/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken) +/account/3pid/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken) endpoints, as these endpoints are now only intended for the homeserver to send validation requests from. Additionally, the same parameters will be removed from the [POST -/_matrix/client/r0/account/3pid](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid) endpoint's +/account/3pid](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid) endpoint's `three_pid_creds` parameter as an identity server is no longer required to perform verification. From cb7c072edb042ce02046ad4fdaa1af112e85f066 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 16 Sep 2019 14:42:21 +0100 Subject: [PATCH 0829/1250] Two new endpoints instead of one --- proposals/2229-rebind-existing-3pid.md | 2 + proposals/2290-separate-threepid-bind-hs.md | 92 ++++++++++++--------- 2 files changed, 55 insertions(+), 39 deletions(-) diff --git a/proposals/2229-rebind-existing-3pid.md b/proposals/2229-rebind-existing-3pid.md index 83883c78..4c709326 100644 --- a/proposals/2229-rebind-existing-3pid.md +++ b/proposals/2229-rebind-existing-3pid.md @@ -1,5 +1,7 @@ # Allowing 3PID Owners to Rebind +## Note: This MSC has been made obselete by MSC2290. + ``` 3PID noun diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index 69ed4827..0d2b9f2d 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -2,7 +2,7 @@ On the Client Server API there is currently a single endpoint for binding a threepid (an email or a phone number): [POST -/account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid). +/account/3pid](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid). Depending on whether the `bind` flag is `true` or `false`, the threepid will be bound to either a user's account on the homeserver, or both the homeserver and an identity server. @@ -26,26 +26,23 @@ to supply a malicious identity server that would immediately answer "yes" to any threepid validation, then the user could add any threepid to their account on the homeserver (which is likely not something homeserver admins want). -To solve this problem, we propose adding a second endpoint that is only used -for binding to an identity server of the user's choice. This endpoint will -not bind the threepid to the user's account on the homeserver, only the -identity server. +To be clear, this is not a long-standing security issue. It is not a problem +in any released version of Synapse, as Synapse keeps a list of "trusted +identity servers" that acts a whitelist for what identity servers a user can +specify. -In addition, the existing binding endpoint will lose the ability to bind -threepids to an identity server, by removing its `bind` flag. Instead, it -will solely be used to bind to the user's account on the homeserver. +The requirement for homeservers to keep this whitelist is soon to be lost +however, as part of lessening the reliance of homeservers on identity +servers. This cannot be done while the homeserver is still trusting an +identity server for validation of threepids. If the endpoints are split, the +homeserver will handle the validation of threepids being added to user +accounts, and identity servers will validate threepids being added to their +own database. -To be clear, the above issue is not a long-standing security issue. Indeed it -is not a problem in any released version of Synapse, as Synapse keeps a list -of "trusted identity servers" that acts a whitelist for what identity servers -a user can specify. - -Synapse is soon to lose this whitelist however, as part of lessening the -reliance of homeservers on identity servers. This cannot be done while the -homeserver is still trusting an identity server for validation of threepids. -If the endpoints are split, the homeserver will handle the validation of -threepids being added to user accounts, and identity servers will validate -threepids being added to their own database. +To solve this problem, we propose adding two new endpoints. One that is only +used for binding to user's account, and another that is only for binding to +an identity server of the user's choice. The existing binding endpoint will +be deprecated. One may question why clients don't just contact an identity server directly to bind a threepid, bypassing the implications of binding through a @@ -62,18 +59,21 @@ about hundreds of fake binds to a user's account). This MSC obseletes [MSC2229](https://github.com/matrix-org/matrix-doc/pull/2229), which dealt -with changing the rules of the `bind` flag. Since this flag is being removed, -the MSC is no longer relevant. +with changing the rules of the `bind` flag on the original endpoint. Since +that endpoint is being deprecated, the MSC is no longer relevant. ## Proposal -A new endpoint will be added to the Client Server API: `POST -/account/3pid/identity/bind`, and will require authentication. The endpoint -definition is the same as [POST -/account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid), -minus the `bind` flag. +Two new endpoints will be added to the Client Server API: `POST +/account/3pid/bind` and `POST /account/3pid/add`. Both will require +authentication. The request parameters of `POST /account/3pid/bind` are the +same as [POST +/account/3pid](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid), +minus the `bind` flag. The request parameters of `POST /account/3pid/add` +will simply consist of a JSON body containing `client_secret` and `sid`. -An example of binding a threepid to **an identity server only** with this new endpoint is as follows: +An example of binding a threepid to **an identity server only** with this new +endpoint is as follows: First the client must request the threepid be validated by its chosen identity server. @@ -93,7 +93,7 @@ notifies the identity server that the email has been verified. Next, the client completes the bind by calling the new endpoint on the homeserver: ``` -POST https://home.server/_matrix/client/r0/account/3pid/identity/bind +POST https://home.server/_matrix/client/r0/account/3pid/bind { "three_pid_creds": { @@ -109,8 +109,8 @@ The homeserver will then make a bind request to the specified identity server on behalf of the user. The homeserver will record if the bind was successful and notify the user. -The threepid has now been binded on the user's identity server without -causing that threepid to be used for password resets or any other +The threepid has now been binded on the user's requested identity server +without causing that threepid to be used for password resets or any other homeserver-related functions. For completeness, here is an example of binding a threepid to the @@ -136,7 +136,7 @@ The client then sends a request to the old endpoint on the homeserver to bind the threepid to user's account. ``` -POST /_matrix/client/r0/account/3pid +POST /_matrix/client/r0/account/3pid/bind { "three_pid_creds": { @@ -151,15 +151,20 @@ The threepid will then be bound to the user's account. The achieve the above flows, some changes need to be made to existing endpoints. This MSC requests that the `id_server` and `id_access_token` parameters be removed from the Client-Server API's [POST -/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-email-requesttoken) +/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid-email-requesttoken) and [POST -/account/3pid/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken) +/account/3pid/msisdn/requestToken](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid-msisdn-requesttoken) endpoints, as these endpoints are now only intended for the homeserver to -send validation requests from. Additionally, the same parameters will be -removed from the [POST -/account/3pid](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid) endpoint's -`three_pid_creds` parameter as an identity server is no longer required to -perform verification. +send validation requests from. + +Additionally, the [POST +/account/3pid](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid) +endpoint is deprecated as the two new endpoints replace its functionality. +The `bind` endpoint will also be removed, with the endpoint functioning as if +`bind` was `false`. Allowing an endpoint to add a threepid to both the +identity server and homeserver at the same time requires one to trust the +other, which is the exact behaviour we're trying to eliminate. Doing this +also helps backward compatibility, as explained below. This MSC also requests that the text "It is imperative that the homeserver keep a list of trusted Identity Servers and only proxies to those that it @@ -175,7 +180,16 @@ again to finalize the validation afterwards. ## Backwards compatibility -TODO +Old matrix clients will continue to use the `/account/3pid` endpoint. As this +MSC removes the `bind` parameter and forces `/account/3pid` calls to act as +if `bind` was set to `false`, old clients will still be able to add 3pids, +but they will only be added to the homeserver, not the identity server. New +homeservers will ignore any `id_server` information passed to this endpoint. + +New matrix clients running with old homeservers should try their desired +endpoint (either `/account/3pid/add` or `/account/3pid/bind`) and on +receiving a HTTP `404` error code, should either attempt to use +`/account/3pid` with the `bind` parameter or give up, at their discretion. ## Security considerations From 5b259bfb52e38ecf849ab1ce064efc449a37281f Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 16 Sep 2019 14:47:38 +0100 Subject: [PATCH 0830/1250] Fix homeserver binding example --- proposals/2290-separate-threepid-bind-hs.md | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index 0d2b9f2d..17a04420 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -31,13 +31,12 @@ in any released version of Synapse, as Synapse keeps a list of "trusted identity servers" that acts a whitelist for what identity servers a user can specify. -The requirement for homeservers to keep this whitelist is soon to be lost -however, as part of lessening the reliance of homeservers on identity -servers. This cannot be done while the homeserver is still trusting an -identity server for validation of threepids. If the endpoints are split, the -homeserver will handle the validation of threepids being added to user -accounts, and identity servers will validate threepids being added to their -own database. +Synapse is soon to lose this whitelist however, as part of lessening the +reliance of homeservers on identity servers. This cannot be done while the +homeserver is still trusting an identity server for validation of threepids. +If the endpoints are split, the homeserver will handle the validation of +threepids being added to user accounts, and identity servers will validate +threepids being added to their own database. To solve this problem, we propose adding two new endpoints. One that is only used for binding to user's account, and another that is only for binding to @@ -139,10 +138,8 @@ the threepid to user's account. POST /_matrix/client/r0/account/3pid/bind { - "three_pid_creds": { - "sid": "abc123987", - "client_secret": "don'tT3ll" - } + "sid": "abc123987", + "client_secret": "don'tT3ll" } ``` From 1fc1e3c6cecf7c49753316958696ac5065f45fec Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 16 Sep 2019 14:49:30 +0100 Subject: [PATCH 0831/1250] run on sentence --- proposals/2290-separate-threepid-bind-hs.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index 17a04420..5bd5129b 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -135,7 +135,7 @@ The client then sends a request to the old endpoint on the homeserver to bind the threepid to user's account. ``` -POST /_matrix/client/r0/account/3pid/bind +POST https://home.server/_matrix/client/r0/account/3pid/add { "sid": "abc123987", @@ -177,11 +177,11 @@ again to finalize the validation afterwards. ## Backwards compatibility -Old matrix clients will continue to use the `/account/3pid` endpoint. As this +Old matrix clients will continue to use the `/account/3pid` endpoint. This MSC removes the `bind` parameter and forces `/account/3pid` calls to act as -if `bind` was set to `false`, old clients will still be able to add 3pids, -but they will only be added to the homeserver, not the identity server. New -homeservers will ignore any `id_server` information passed to this endpoint. +if `bind` was set to `false`. Old clients will still be able to add 3pids to +the homeserver, but not the identity server. New homeservers must ignore any +`id_server` information passed to this endpoint. New matrix clients running with old homeservers should try their desired endpoint (either `/account/3pid/add` or `/account/3pid/bind`) and on From 196f27efb2ebff9f64e3ebef5c3aa387edc49dfb Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Mon, 16 Sep 2019 15:22:05 +0100 Subject: [PATCH 0832/1250] Update proposals/2290-separate-threepid-bind-hs.md Co-Authored-By: Matthew Hodgson --- proposals/2290-separate-threepid-bind-hs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index 5bd5129b..d692207d 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -145,7 +145,7 @@ POST https://home.server/_matrix/client/r0/account/3pid/add The threepid will then be bound to the user's account. -The achieve the above flows, some changes need to be made to existing +To achieve the above flows, some changes need to be made to existing endpoints. This MSC requests that the `id_server` and `id_access_token` parameters be removed from the Client-Server API's [POST /account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid-email-requesttoken) From 7b656e9013adeefb4fd70d84b41aed93edc85d1b Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Mon, 16 Sep 2019 15:24:43 +0100 Subject: [PATCH 0833/1250] Update proposals/2290-separate-threepid-bind-hs.md Co-Authored-By: Matthew Hodgson --- proposals/2290-separate-threepid-bind-hs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index d692207d..6e34f954 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -108,7 +108,7 @@ The homeserver will then make a bind request to the specified identity server on behalf of the user. The homeserver will record if the bind was successful and notify the user. -The threepid has now been binded on the user's requested identity server +The threepid has now been bound on the user's requested identity server without causing that threepid to be used for password resets or any other homeserver-related functions. From f36ed9a27195233c12edb6271207f09935735e01 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 16 Sep 2019 15:26:07 +0100 Subject: [PATCH 0834/1250] typos --- proposals/2290-separate-threepid-bind-hs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index 6e34f954..6187efdd 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -131,8 +131,8 @@ POST https://home.server/_matrix/client/r0/account/3pid/email/requestToken Once an email has been sent, the user clicks the link in the email, which notifies the homeserver that the threepid has been verified. -The client then sends a request to the old endpoint on the homeserver to bind -the threepid to user's account. +The client then sends a request to the endpoint on the homeserver to bind +the threepid to a user's account. ``` POST https://home.server/_matrix/client/r0/account/3pid/add From f06ba491fefc9168a869d6ae09734afdded160ad Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 16 Sep 2019 15:49:31 +0100 Subject: [PATCH 0835/1250] Assign meaning to bind and add --- proposals/2290-separate-threepid-bind-hs.md | 61 +++++++++++---------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index 6187efdd..de844e47 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -7,18 +7,20 @@ Depending on whether the `bind` flag is `true` or `false`, the threepid will be bound to either a user's account on the homeserver, or both the homeserver and an identity server. -For context a threepid can be bound to an identity server to allow other users to find -their Matrix ID using their email address or phone number. A threepid can -also be bound to a user's account on the homeserver. This allows the -threepid to be used for message notifications, login, password reset, and -other important functions. - -Typically, when using the `/account/3pid` endpoint, -the identity server handles the verification -- either by sending an email to -an email address, or a SMS message to a phone number. Once completed, the -homeserver will check with the identity server that verification had indeed -happened, and if so, the threepid would be bound (again, either to the -homeserver, or the homeserver and identity server simultaneously). +For context a threepid can be bound to an identity server to allow other +users to find their Matrix ID using their email address or phone number. A +threepid can also be added to a user's account on the homeserver. This allows +the threepid to be used for message notifications, login, password reset, and +other important functions. We use the term `add` when talking about adding a +threepid to a homeserver, and `bind` when binding a threepid to an identity +server. This terminology will be used throughout the rest of this proposal. + +Typically, when using the `/account/3pid` endpoint, the identity server +handles the verification -- either by sending an email to an email address, +or a SMS message to a phone number. Once completed, the homeserver will check +with the identity server that verification had indeed happened, and if so, +the threepid would be either added to the homeserver, or added to the +homeserver and bound to the identity server simultaneously. Now, consider the fact that the identity server used in this process is provided by the user, using the endpoint's `id_server` parameter. If the user were @@ -36,12 +38,13 @@ reliance of homeservers on identity servers. This cannot be done while the homeserver is still trusting an identity server for validation of threepids. If the endpoints are split, the homeserver will handle the validation of threepids being added to user accounts, and identity servers will validate -threepids being added to their own database. +threepids being bound to themselves. -To solve this problem, we propose adding two new endpoints. One that is only -used for binding to user's account, and another that is only for binding to -an identity server of the user's choice. The existing binding endpoint will -be deprecated. +To solve this problem, we propose adding two new endpoints. `POST +/account/3pid/add` that is only used for adding to user's account on a +homeserver, and `POST /account/3pid/bind` that is only for binding to an +identity server of the user's choice. The existing binding endpoint (`POST +/account/3pid`) will be deprecated. One may question why clients don't just contact an identity server directly to bind a threepid, bypassing the implications of binding through a @@ -50,11 +53,11 @@ homeserver such that the homeserver can keep track of which binds were made, which is important when a user wishes to deactivate their account (and remove all of their bindings made on different identity servers). -A bind could be made on an identity server, which could then tell the -homeserver that a validation occured, but then there are security +A verification could occur on an identity server, which could then tell the +homeserver that a validation happened, but then there are security considerations about how to authenticate an identity server in that instance (and prevent people pretending to be identity servers and telling homeservers -about hundreds of fake binds to a user's account). +about hundreds of fake threepid additions to a user's account). This MSC obseletes [MSC2229](https://github.com/matrix-org/matrix-doc/pull/2229), which dealt @@ -71,8 +74,8 @@ same as [POST minus the `bind` flag. The request parameters of `POST /account/3pid/add` will simply consist of a JSON body containing `client_secret` and `sid`. -An example of binding a threepid to **an identity server only** with this new -endpoint is as follows: +An example of binding a threepid to an identity server with this new endpoint +is as follows: First the client must request the threepid be validated by its chosen identity server. @@ -112,8 +115,8 @@ The threepid has now been bound on the user's requested identity server without causing that threepid to be used for password resets or any other homeserver-related functions. -For completeness, here is an example of binding a threepid to the -homeserver only, using the old endpoint: +For completeness, here is an example of adding a threepid to the homeserver +only, using the `/account/3pid/add` endpoint: The homeserver is validating the threepid in this instance, so the client must use the `/requestToken` endpoint of the homeserver: @@ -131,7 +134,7 @@ POST https://home.server/_matrix/client/r0/account/3pid/email/requestToken Once an email has been sent, the user clicks the link in the email, which notifies the homeserver that the threepid has been verified. -The client then sends a request to the endpoint on the homeserver to bind +The client then sends a request to the endpoint on the homeserver to add the threepid to a user's account. ``` @@ -143,7 +146,7 @@ POST https://home.server/_matrix/client/r0/account/3pid/add } ``` -The threepid will then be bound to the user's account. +The threepid has now been added to the user's account. To achieve the above flows, some changes need to be made to existing endpoints. This MSC requests that the `id_server` and `id_access_token` @@ -180,8 +183,8 @@ again to finalize the validation afterwards. Old matrix clients will continue to use the `/account/3pid` endpoint. This MSC removes the `bind` parameter and forces `/account/3pid` calls to act as if `bind` was set to `false`. Old clients will still be able to add 3pids to -the homeserver, but not the identity server. New homeservers must ignore any -`id_server` information passed to this endpoint. +the homeserver, but not bind to the identity server. New homeservers must +ignore any `id_server` information passed to this endpoint. New matrix clients running with old homeservers should try their desired endpoint (either `/account/3pid/add` or `/account/3pid/bind`) and on @@ -203,6 +206,6 @@ This MSC helps to minimize the homeserver's trust in an identity server even further to the point where it is only used for binding addresses for lookup - which was the original intention of identity servers to begin with. -Additionally, by clearly separating the threepid bind endpoint into two +Additionally, by clearly separating the original threepid endpoint into two endpoints that each have a clear intention, the concept of attaching threepids to a Matrix user becomes a lot easier to reason about. From 4bc005ac84fa632d6ab933378445142206b6aa65 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 16 Sep 2019 16:27:16 +0100 Subject: [PATCH 0836/1250] Remove threepid explanation --- proposals/2290-separate-threepid-bind-hs.md | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index de844e47..0da60797 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -5,15 +5,10 @@ threepid (an email or a phone number): [POST /account/3pid](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid). Depending on whether the `bind` flag is `true` or `false`, the threepid will be bound to either a user's account on the homeserver, or both the homeserver -and an identity server. - -For context a threepid can be bound to an identity server to allow other -users to find their Matrix ID using their email address or phone number. A -threepid can also be added to a user's account on the homeserver. This allows -the threepid to be used for message notifications, login, password reset, and -other important functions. We use the term `add` when talking about adding a -threepid to a homeserver, and `bind` when binding a threepid to an identity -server. This terminology will be used throughout the rest of this proposal. +and an identity server. Note that we use the term `add` when talking about +adding a threepid to a homeserver, and `bind` when binding a threepid to an +identity server. This terminology will be used throughout the rest of this +proposal. Typically, when using the `/account/3pid` endpoint, the identity server handles the verification -- either by sending an email to an email address, From af2467606e6a67d418414794df4ecc7a9f9f80b2 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 16 Sep 2019 18:01:21 +0100 Subject: [PATCH 0837/1250] parameter, not endpoint --- proposals/2290-separate-threepid-bind-hs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index 0da60797..a28f6d93 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -155,7 +155,7 @@ send validation requests from. Additionally, the [POST /account/3pid](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid) endpoint is deprecated as the two new endpoints replace its functionality. -The `bind` endpoint will also be removed, with the endpoint functioning as if +The `bind` parameter will also be removed, with the endpoint functioning as if `bind` was `false`. Allowing an endpoint to add a threepid to both the identity server and homeserver at the same time requires one to trust the other, which is the exact behaviour we're trying to eliminate. Doing this From 2a5531075460547b02c6d5c9916f21d8a6d5137a Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 17 Sep 2019 11:43:56 +0100 Subject: [PATCH 0838/1250] Clarify why MSC2229 was made obselete --- proposals/2229-rebind-existing-3pid.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/proposals/2229-rebind-existing-3pid.md b/proposals/2229-rebind-existing-3pid.md index 4c709326..1bfb5106 100644 --- a/proposals/2229-rebind-existing-3pid.md +++ b/proposals/2229-rebind-existing-3pid.md @@ -2,6 +2,15 @@ ## Note: This MSC has been made obselete by MSC2290. +MSC2290 provides two separate API endpoints, one for adding a 3PID to the +homeserver, and another for binding to an identity server. These new +endpoints will allow the homeserver to enforce rules on emails that already +exist on the homeserver, only when modifying homeserver email, while only +needing to forward requests when binding to an identity server. This removes +the problem MSC2229 is trying to solve, and it is thus made obselete. + +--- + ``` 3PID noun From c57250b3935c675e3cb0d17c973be50bc32cbd5d Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Tue, 17 Sep 2019 11:48:50 +0100 Subject: [PATCH 0839/1250] Apply suggestions from code review Co-Authored-By: Travis Ralston --- proposals/2290-separate-threepid-bind-hs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index a28f6d93..8999d143 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -35,7 +35,7 @@ If the endpoints are split, the homeserver will handle the validation of threepids being added to user accounts, and identity servers will validate threepids being bound to themselves. -To solve this problem, we propose adding two new endpoints. `POST +To solve this problem, it is proposed to add two new endpoints. `POST /account/3pid/add` that is only used for adding to user's account on a homeserver, and `POST /account/3pid/bind` that is only for binding to an identity server of the user's choice. The existing binding endpoint (`POST @@ -155,7 +155,7 @@ send validation requests from. Additionally, the [POST /account/3pid](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid) endpoint is deprecated as the two new endpoints replace its functionality. -The `bind` parameter will also be removed, with the endpoint functioning as if +The `bind` parameter is to be removed, with the endpoint functioning as if `bind` was `false`. Allowing an endpoint to add a threepid to both the identity server and homeserver at the same time requires one to trust the other, which is the exact behaviour we're trying to eliminate. Doing this From 0b67f34578c29e016195dca487a1d949b8561545 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 17 Sep 2019 12:10:32 +0100 Subject: [PATCH 0840/1250] Address review comments --- proposals/2290-separate-threepid-bind-hs.md | 117 +++++++++----------- 1 file changed, 53 insertions(+), 64 deletions(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index a28f6d93..644be55b 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -1,8 +1,15 @@ # Separate Endpoints for Binding Threepids +*Note: This MSC obseletes +[MSC2229](https://github.com/matrix-org/matrix-doc/pull/2229), which dealt +with changing the rules of the `bind` flag on [POST +/account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid). +That endpoint is being deprecated as part of this MSC, thus MSC2229 is no +longer relevant.* + On the Client Server API there is currently a single endpoint for binding a threepid (an email or a phone number): [POST -/account/3pid](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid). +/account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid). Depending on whether the `bind` flag is `true` or `false`, the threepid will be bound to either a user's account on the homeserver, or both the homeserver and an identity server. Note that we use the term `add` when talking about @@ -28,46 +35,30 @@ in any released version of Synapse, as Synapse keeps a list of "trusted identity servers" that acts a whitelist for what identity servers a user can specify. -Synapse is soon to lose this whitelist however, as part of lessening the -reliance of homeservers on identity servers. This cannot be done while the -homeserver is still trusting an identity server for validation of threepids. -If the endpoints are split, the homeserver will handle the validation of -threepids being added to user accounts, and identity servers will validate -threepids being bound to themselves. - -To solve this problem, we propose adding two new endpoints. `POST -/account/3pid/add` that is only used for adding to user's account on a -homeserver, and `POST /account/3pid/bind` that is only for binding to an -identity server of the user's choice. The existing binding endpoint (`POST -/account/3pid`) will be deprecated. - -One may question why clients don't just contact an identity server directly -to bind a threepid, bypassing the implications of binding through a -homeserver. While this will work, binds should still occur through a -homeserver such that the homeserver can keep track of which binds were made, -which is important when a user wishes to deactivate their account (and remove -all of their bindings made on different identity servers). - -A verification could occur on an identity server, which could then tell the -homeserver that a validation happened, but then there are security -considerations about how to authenticate an identity server in that instance -(and prevent people pretending to be identity servers and telling homeservers -about hundreds of fake threepid additions to a user's account). - -This MSC obseletes -[MSC2229](https://github.com/matrix-org/matrix-doc/pull/2229), which dealt -with changing the rules of the `bind` flag on the original endpoint. Since -that endpoint is being deprecated, the MSC is no longer relevant. +The concept of this whitelist is being removed in this MSC however, as part +of lessening the reliance of homeservers on identity servers. This cannot be +done while the homeserver is still trusting an identity server for validation +of threepids. If the endpoints are split, the homeserver will handle the +validation of threepids being added to user accounts, and identity servers +will validate threepids being bound to themselves. ## Proposal -Two new endpoints will be added to the Client Server API: `POST -/account/3pid/bind` and `POST /account/3pid/add`. Both will require -authentication. The request parameters of `POST /account/3pid/bind` are the -same as [POST +To solve this problem, two new endpoints will be added to the Client Server +API: `POST /account/3pid/bind` and `POST /account/3pid/add`. Both will +require authentication and be rate-limited. The request parameters of `POST +/account/3pid/bind` are the same as [POST /account/3pid](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid), -minus the `bind` flag. The request parameters of `POST /account/3pid/add` -will simply consist of a JSON body containing `client_secret` and `sid`. +minus the `bind` flag, and the contents of `three_pid_creds` have been +brought to the top level of the request body. The request parameters of `POST +/account/3pid/add` will simply consist of a JSON body containing +`client_secret` and `sid`. + +The homeserver should prevent a threepid being added to a user's account if +it already part of another user's account. However, the homeserver should not +check for existing threepids when binding to an identity server. Identity +servers do not enforce this requirement and neither should the proxying +homeserver. An example of binding a threepid to an identity server with this new endpoint is as follows: @@ -93,12 +84,10 @@ Next, the client completes the bind by calling the new endpoint on the homeserve POST https://home.server/_matrix/client/r0/account/3pid/bind { - "three_pid_creds": { - "id_server": "example.org", - "id_access_token": "abc123_OpaqueString", - "sid": "abc123987", - "client_secret": "don'tT3ll" - } + "id_server": "example.org", + "id_access_token": "abc123_OpaqueString", + "sid": "abc123987", + "client_secret": "don'tT3ll" } ``` @@ -161,17 +150,25 @@ identity server and homeserver at the same time requires one to trust the other, which is the exact behaviour we're trying to eliminate. Doing this also helps backward compatibility, as explained below. -This MSC also requests that the text "It is imperative that the homeserver -keep a list of trusted Identity Servers and only proxies to those that it -trusts." be removed from all parts of the spec, as the homeserver should no -longer need to trust any identity servers. +The text "It is imperative that the homeserver keep a list of trusted +Identity Servers and only proxies to those that it trusts." is to be removed +from all parts of the spec, as the homeserver should no longer need to trust +any identity servers. ## Tradeoffs -It may be possible to reduce the two calls per flow into a single endpoint, -but the current asynchronous approach makes it easy for a client to send a -request, go offline, have the threepid be validated, and then come online -again to finalize the validation afterwards. +One may question why clients don't just contact an identity server directly +to bind a threepid, bypassing the implications of binding through a +homeserver. While this will work, binds should still occur through a +homeserver such that the homeserver can keep track of which binds were made, +which is important when a user wishes to deactivate their account (and remove +all of their bindings made on different identity servers). + +A verification could occur on an identity server, which could then tell the +homeserver that a validation happened, but then there are security +considerations about how to authenticate an identity server in that instance +(and prevent people pretending to be identity servers and telling homeservers +about hundreds of fake threepid additions to a user's account). ## Backwards compatibility @@ -191,16 +188,8 @@ receiving a HTTP `404` error code, should either attempt to use Reducing the homeserver's trust in identity servers should be a boost to security and improve decentralisation in the Matrix ecosystem to boot. -Caution should be taken for homeserver developers to be sure not to continue -to use user-provided identity servers for any sensitive tasks once it removes -the concept of a trusted identity server list. - -## Conclusion - -This MSC helps to minimize the homeserver's trust in an identity server even -further to the point where it is only used for binding addresses for lookup - -which was the original intention of identity servers to begin with. - -Additionally, by clearly separating the original threepid endpoint into two -endpoints that each have a clear intention, the concept of attaching -threepids to a Matrix user becomes a lot easier to reason about. +Some endpoints of the Client Server API allow a user to provide an +`id_server` parameter. Caution should be taken for homeserver developers to +stop using these user-provided identity servers for any sensitive tasks, such +as password reset or account registration, if it removes the concept of a +trusted identity server list. From 1e69a7f3f21e70877248d5168cdca5627b9ea69d Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 17 Sep 2019 15:02:41 +0100 Subject: [PATCH 0841/1250] be assertive --- proposals/2290-separate-threepid-bind-hs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index 75fce27a..df60bd83 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -133,8 +133,8 @@ POST https://home.server/_matrix/client/r0/account/3pid/add The threepid has now been added to the user's account. To achieve the above flows, some changes need to be made to existing -endpoints. This MSC requests that the `id_server` and `id_access_token` -parameters be removed from the Client-Server API's [POST +endpoints. The `id_server` and `id_access_token` parameters are to be removed +from the Client-Server API's [POST /account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid-email-requesttoken) and [POST /account/3pid/msisdn/requestToken](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid-msisdn-requesttoken) From 169174e00be3be405a79a2a7b62347c5ff0f0e13 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 17 Sep 2019 17:01:18 +0100 Subject: [PATCH 0842/1250] Suggest the use of a unstable flag --- proposals/2290-separate-threepid-bind-hs.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index df60bd83..26cbbeb7 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -172,17 +172,19 @@ about hundreds of fake threepid additions to a user's account). ## Backwards compatibility +A new flag will be added to `/versions`' unstable_features section, +`m.separate_add_and_bind`. If this flag is present and set to `true`, then +clients should use the new API endpoints to carry out threepid adds and +binds. If this flag is not present or set to `false`, clients should use +`/account/3pid`, being aware that they can only bind threepids to the +homeserver, not the identity server. + Old matrix clients will continue to use the `/account/3pid` endpoint. This MSC removes the `bind` parameter and forces `/account/3pid` calls to act as if `bind` was set to `false`. Old clients will still be able to add 3pids to the homeserver, but not bind to the identity server. New homeservers must ignore any `id_server` information passed to this endpoint. -New matrix clients running with old homeservers should try their desired -endpoint (either `/account/3pid/add` or `/account/3pid/bind`) and on -receiving a HTTP `404` error code, should either attempt to use -`/account/3pid` with the `bind` parameter or give up, at their discretion. - ## Security considerations Reducing the homeserver's trust in identity servers should be a boost to From 53519f98d0986371e99812f4e7acba89a552036c Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 17 Sep 2019 17:01:45 +0100 Subject: [PATCH 0843/1250] Pin a spec version when we link to it --- proposals/2290-separate-threepid-bind-hs.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index 26cbbeb7..3a15a52c 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -48,7 +48,7 @@ To solve this problem, two new endpoints will be added to the Client Server API: `POST /account/3pid/bind` and `POST /account/3pid/add`. Both will require authentication and be rate-limited. The request parameters of `POST /account/3pid/bind` are the same as [POST -/account/3pid](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid), +/account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid), minus the `bind` flag, and the contents of `three_pid_creds` have been brought to the top level of the request body. The request parameters of `POST /account/3pid/add` will simply consist of a JSON body containing @@ -135,14 +135,14 @@ The threepid has now been added to the user's account. To achieve the above flows, some changes need to be made to existing endpoints. The `id_server` and `id_access_token` parameters are to be removed from the Client-Server API's [POST -/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid-email-requesttoken) +/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-email-requesttoken) and [POST -/account/3pid/msisdn/requestToken](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid-msisdn-requesttoken) +/account/3pid/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken) endpoints, as these endpoints are now only intended for the homeserver to send validation requests from. Additionally, the [POST -/account/3pid](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-account-3pid) +/account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid) endpoint is deprecated as the two new endpoints replace its functionality. The `bind` parameter is to be removed, with the endpoint functioning as if `bind` was `false`. Allowing an endpoint to add a threepid to both the From e50bb3df25bedc3eb776888c2eb2ce393482e045 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 17 Sep 2019 17:04:40 +0100 Subject: [PATCH 0844/1250] Mention that homeserver's should remember binds done through them --- proposals/2290-separate-threepid-bind-hs.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index 3a15a52c..85803baf 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -93,7 +93,9 @@ POST https://home.server/_matrix/client/r0/account/3pid/bind The homeserver will then make a bind request to the specified identity server on behalf of the user. The homeserver will record if the bind was successful -and notify the user. +and notify the user. The homeserver will remember this bind and the identity +server it occurred on so that it can perform an unbind later if the user +requests it or their account is deactivated. The threepid has now been bound on the user's requested identity server without causing that threepid to be used for password resets or any other From 87d641c7c12c2cdd50a7e197cc438a5da409e05b Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Tue, 17 Sep 2019 17:20:57 +0100 Subject: [PATCH 0845/1250] Describe what the IS and HS are doing in the examples --- proposals/2290-separate-threepid-bind-hs.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index 85803baf..0e6004ab 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -75,6 +75,10 @@ POST https://identity.server/_matrix/identity/v2/validate/email/requestToken } ``` +The identity server must send an email to the specified address, including a +link to a URL on the identity server which will accept the validation session +ID, the given client_secret, and a randomly-generated token. + Once an email has been sent, the user clicks the link in the email, which notifies the identity server that the email has been verified. @@ -117,6 +121,10 @@ POST https://home.server/_matrix/client/r0/account/3pid/email/requestToken } ``` +Here the homeserver must send an email to the specified address, including a +link to a URL on the homeserver which will accept the validation session ID, +the given client_secret, and a randomly-generated token. + Once an email has been sent, the user clicks the link in the email, which notifies the homeserver that the threepid has been verified. @@ -132,7 +140,9 @@ POST https://home.server/_matrix/client/r0/account/3pid/add } ``` -The threepid has now been added to the user's account. +The homeserver checks the threepid validation session referred to by the +given ID and client_secret was validated, and if so adds the threepid to the +user's account. To achieve the above flows, some changes need to be made to existing endpoints. The `id_server` and `id_access_token` parameters are to be removed From 5d6113db1ec97052d74f271ceb7adb11a9f84787 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Wed, 18 Sep 2019 01:39:40 +0100 Subject: [PATCH 0846/1250] Update the MSC template (#2296) Tradeoffs->Alternatives, and kill the Conclusions section --- proposals/0000-proposal-template.md | 54 ++++++++++------------------- 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/proposals/0000-proposal-template.md b/proposals/0000-proposal-template.md index 8c8cdcea..cf79ed99 100644 --- a/proposals/0000-proposal-template.md +++ b/proposals/0000-proposal-template.md @@ -41,34 +41,17 @@ The template should have the following sections: * **Introduction** - This should cover the primary problem and broad description of the solution. * **Proposal** - The gory details of the proposal. -* **Tradeoffs** - Any items of the proposal that are less desirable should be listed here. Alternative - solutions to the same problem could also be listed here. * **Potential issues** - This is where problems with the proposal would be listed, such as changes that are not backwards compatible. +* **Alternatives** - This section lists alternative solutions to the same + problem which have been considered and dismsissed. * **Security considerations** - Discussion of what steps were taken to avoid security issues in the future and any potential risks in the proposal. -* **Conclusion** - A repeat of the problem and solution. Furthermore, the template should not be required to be followed. However it is strongly recommended to maintain some sense of consistency between proposals. -## Tradeoffs - -*This is where alternative solutions could be listed. There's almost always another way to do things -and this section gives you the opportunity to highlight why those ways are not as desirable. The -argument made in this example is that all of the text provided by the template could be integrated -into the proposals introduction, although with some risk of losing clarity.* - -Instead of adding a template to the repository, the assistance it provides could be integrated into -the proposal process itself. There is an argument to be had that the proposal process should be as -descriptive as possible, although having even more detail in the proposals introduction could lead to -some confusion or lack of understanding. Not to mention if the document is too large then potential -authors could be scared off as the process suddenly looks a lot more complicated than it is. For those -reasons, this proposal does not consider integrating the template in the proposals introduction a good -idea. - - ## Potential issues *Not all proposals are perfect. Sometimes there's a known disadvantage to implementing the proposal, @@ -84,6 +67,22 @@ is beneficial and not considered a significant problem because it will lead to a can follow. +## Alternatives + +*This is where alternative solutions could be listed. There's almost always another way to do things +and this section gives you the opportunity to highlight why those ways are not as desirable. The +argument made in this example is that all of the text provided by the template could be integrated +into the proposals introduction, although with some risk of losing clarity.* + +Instead of adding a template to the repository, the assistance it provides could be integrated into +the proposal process itself. There is an argument to be had that the proposal process should be as +descriptive as possible, although having even more detail in the proposals introduction could lead to +some confusion or lack of understanding. Not to mention if the document is too large then potential +authors could be scared off as the process suddenly looks a lot more complicated than it is. For those +reasons, this proposal does not consider integrating the template in the proposals introduction a good +idea. + + ## Security considerations *Some proposals may have some security aspect to them that was addressed in the proposed solution. This @@ -94,20 +93,3 @@ of concerns where possible.* By having a template available, people would know what the desired detail for a proposal is. This is not considered a risk because it is important that people understand the proposal process from start to end. - - -## Conclusion - -*Repeating the problem and solution in different words helps reviewers understand the problem a bit more. -This section should wrap up any loose ends left in the document, as well as cover a brief overview of the -content in each section. Note that the example here doesn't touch on the specific implementation details -described in the "Proposal" section - just the high-level points made there.* - -Not having a template for people to follow when making their proposals could lead to large differences -between each MSC. This would make it difficult for reviewers, and there's a potential that some information -could be left out by accident. A template written in the same format the proposal process requires would -give authors the ability to understand how to better explain their own proposal. - -A descriptive template would help potential authors comprehend what the proposal process requires by -demonstrating what is expected of a proposal. Although this is more effort up front, it would lead to more -time saved in the future due to questions about the process. From bd64ffc442127774a9f34631a3960be43dd975d8 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 18 Sep 2019 11:57:26 +0100 Subject: [PATCH 0847/1250] Homeservers shouldn't proxy to user-provided identity servers anymore --- proposals/2290-separate-threepid-bind-hs.md | 42 ++++++++++++--------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index 0e6004ab..34712d23 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -145,27 +145,33 @@ given ID and client_secret was validated, and if so adds the threepid to the user's account. To achieve the above flows, some changes need to be made to existing -endpoints. The `id_server` and `id_access_token` parameters are to be removed -from the Client-Server API's [POST -/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-email-requesttoken) -and [POST -/account/3pid/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken) -endpoints, as these endpoints are now only intended for the homeserver to -send validation requests from. - -Additionally, the [POST +endpoints. The [POST /account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid) endpoint is deprecated as the two new endpoints replace its functionality. The `bind` parameter is to be removed, with the endpoint functioning as if `bind` was `false`. Allowing an endpoint to add a threepid to both the identity server and homeserver at the same time requires one to trust the other, which is the exact behaviour we're trying to eliminate. Doing this -also helps backward compatibility, as explained below. - -The text "It is imperative that the homeserver keep a list of trusted -Identity Servers and only proxies to those that it trusts." is to be removed -from all parts of the spec, as the homeserver should no longer need to trust -any identity servers. +also helps backward compatibility, as explained in [Backwards +compatibility](#backwards-compatibility). + +The `id_server` and `id_access_token` parameters are to be removed +from all of the Client-Server API's `requestToken` endpoints. That is: + +* [POST /account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-email-requesttoken) +* [POST /account/3pid/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken) +* [POST /register/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-register-email-requesttoken) +* [POST /register/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-register-msisdn-requesttoken) +* [POST /account/password/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-password-email-requesttoken) +* [POST /account/password/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-password-msisdn-requesttoken) + +Either the homeserver itself or a service that the homeserver delegates to +should be handling the sending of validation messages, not a user-provided +server. Any mention of the homeserver being able to proxy to an identity +server in the above endpoint descriptions, as well as the text "It is +imperative that the homeserver keep a list of trusted Identity Servers and +only proxies to those that it trusts." is to be removed from all parts of the +spec, as the homeserver should no longer need to trust any identity servers. ## Tradeoffs @@ -204,6 +210,6 @@ security and improve decentralisation in the Matrix ecosystem to boot. Some endpoints of the Client Server API allow a user to provide an `id_server` parameter. Caution should be taken for homeserver developers to -stop using these user-provided identity servers for any sensitive tasks, such -as password reset or account registration, if it removes the concept of a -trusted identity server list. +stop using these user-provided identity servers for any sensitive tasks where +possible, such as password reset or account registration, if it removes the +concept of a trusted identity server list. From 40420d963387bfddf2f8efa6d8b0ad45584e74ec Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Thu, 19 Sep 2019 11:50:16 +0100 Subject: [PATCH 0848/1250] Update proposals/2290-separate-threepid-bind-hs.md Co-Authored-By: Kitsune Ral --- proposals/2290-separate-threepid-bind-hs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index 34712d23..b361d0e1 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -55,7 +55,7 @@ brought to the top level of the request body. The request parameters of `POST `client_secret` and `sid`. The homeserver should prevent a threepid being added to a user's account if -it already part of another user's account. However, the homeserver should not +it's already part of another user's account. However, the homeserver should not check for existing threepids when binding to an identity server. Identity servers do not enforce this requirement and neither should the proxying homeserver. From 6b0a8505ec4ef375d7b8dad0baeb01d12061bd09 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Thu, 19 Sep 2019 17:34:25 +0100 Subject: [PATCH 0849/1250] Propose case folding instead of lowercasing --- proposals/2265-email-lowercase.md | 51 ++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/proposals/2265-email-lowercase.md b/proposals/2265-email-lowercase.md index 5698a8c2..935e6f2c 100644 --- a/proposals/2265-email-lowercase.md +++ b/proposals/2265-email-lowercase.md @@ -1,4 +1,4 @@ -# Proposal for mandating lowercasing when processing e-mail address localparts +# Proposal for mandating case folding when processing e-mail address localparts [RFC822](https://tools.ietf.org/html/rfc822#section-3.4.7) mandates that localparts in e-mail addresses must be processed with the original case @@ -22,8 +22,13 @@ Sydent. This proposal suggests changing the specification of the e-mail 3PID type in [the Matrix spec appendices](https://matrix.org/docs/spec/appendices#pid-types) -to mandate that any e-mail address must be entirely converted to lowercase -before any processing, instead of only its domain. +to mandate that, before any processing, e-mail address localparts must go +through a full case folding based on [the unicode mapping +file](https://www.unicode.org/Public/8.0.0/ucd/CaseFolding.txt), on top of +having their domain lowercased. + +This means that `Strauß@Example.com` must be considered as being the same e-mail +address as `strauss@example.com`. ## Other considered solutions @@ -33,17 +38,24 @@ However, [MSC2134](https://github.com/matrix-org/matrix-doc/pull/2134) changes this: because hashing functions are case sensitive, we need both clients and identity servers to follow the same policy regarding case sensitivity. +An initial version of this proposal proposed to mandate lowercasing e-mail +addresses instead of case folding them, however it was pointed out that this +solution might not be the best and most future-proof one. + +Unicode normalisation was also looked at but judged unnecessary. + ## Tradeoffs Implementing this MSC in identity servers and homeservers might require the -databases of existing instances to be updated in a large part to convert the -email addresses of existing associations to lowercase, in order to avoid -conflicts. However, most of this update can usually be done by a single database -query (or a background job running at startup), so the UX improvement outweighs -this trouble. +databases of existing instances to be updated in a large part to case fold the +email addresses of existing associations, in order to avoid conflicts. However, +most of this update can usually be done by a background job running at startup, +so the UX improvement outweighs this trouble. ## Potential issues +### Conflicts with existing associations + Some users might already have two different accounts associated with the same e-mail address but with different cases. This appears to happen in a small number of cases, however, and can be dealt with by the identity server's or the @@ -58,6 +70,29 @@ like: 3. inform the user of the deletion by sending them an email notice to the email address +### Storing and querying + +Most database engines don't support case folding, therefore querying all +e-mail addresses matching a case folded e-mail address might not be trivial, +e.g. an identity server querying all associations for `strauss@example.com` when +processing a `/lookup` request would be expected to also get associations for +`Strauß@Example.com`. + +To address this issue, implementation maintainers are strongly encouraged to +make e-mail addresses go through a full case folding before storing them. + +### Implementing case folding + +The need for case folding in services on the Internet doesn't seem to be very +large currently (probably due to its young age), therefore there seem to be only +a few third-party implementation librairies out there. However, both +[Go](https://godoc.org/golang.org/x/text/cases#Fold), [Python +2](https://docs.python.org/2/library/stringprep.html#stringprep.map_table_b3) +and [Python 3](https://docs.python.org/3/library/stdtypes.html#str.casefold) +support it natively, and [a third-party JavaScript +implementation](https://github.com/ar-nelson/foldcase) exists which, although +young, seems to be working. + ## Footnotes [0]: This is specific to Sydent because of a bug it has where v1 lookups are From eebcaaef02c7c1e0b5e13bcf9a999d2083229d4c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 24 Sep 2019 13:30:24 -0600 Subject: [PATCH 0850/1250] Point to the new v2 identity endpoint --- specification/modules/third_party_invites.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/third_party_invites.rst b/specification/modules/third_party_invites.rst index 282b06f4..04c3b180 100644 --- a/specification/modules/third_party_invites.rst +++ b/specification/modules/third_party_invites.rst @@ -255,4 +255,4 @@ these is left to the implementer's discretion. -.. _`identity server /isvalid`: ../identity_service/%IDENTITY_RELEASE_LABEL%.html#get-matrix-identity-api-v1-pubkey-isvalid +.. _`identity server /isvalid`: ../identity_service/%IDENTITY_RELEASE_LABEL%.html#get-matrix-identity-v2-pubkey-isvalid From 8d865ca53aebce6a6aa8ac02d9a77c987eb13a05 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 24 Sep 2019 13:36:51 -0600 Subject: [PATCH 0851/1250] Add s2s POST /publicRooms per MSC2197 See https://github.com/matrix-org/matrix-doc/pull/2197 --- api/server-server/public_rooms.yaml | 160 ++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/api/server-server/public_rooms.yaml b/api/server-server/public_rooms.yaml index b7691023..0216f0c3 100644 --- a/api/server-server/public_rooms.yaml +++ b/api/server-server/public_rooms.yaml @@ -68,3 +68,163 @@ paths: description: The public room list for the homeserver. schema: $ref: "../client-server/definitions/public_rooms_response.yaml" + post: + summary: Gets the public rooms on the server with optional filter. + description: |- + Lists the public rooms on the server, with optional filter. + + This API returns paginated responses. The rooms are ordered by the number + of joined members, with the largest rooms first. + + Note that this endpoint receives and returns the same format that is seen + in the Client-Server API's ``POST /publicRooms`` endpoint. + operationId: queryPublicRooms + security: + - signedRequest: [] + parameters: + - in: body + name: body + required: true + description: |- + Options for which rooms to return. + schema: + type: object + properties: + limit: + type: integer + description: |- + Limit the number of results returned. + since: + type: string + description: |- + A pagination token from a previous request, allowing servers + to get the next (or previous) batch of rooms. The direction + of pagination is specified solely by which token is supplied, + rather than via an explicit flag. + filter: + type: object + title: "Filter" + description: |- + Filter to apply to the results. + properties: + generic_search_term: + type: string + description: |- + A string to search for in the room metadata, e.g. name, + topic, canonical alias etc. (Optional). + include_all_networks: + type: boolean + description: |- + Whether or not to include all known networks/protocols from + application services on the homeserver. Defaults to false. + example: false + third_party_instance_id: + type: string + description: |- + The specific third party network/protocol to request from the + homeserver. Can only be used if ``include_all_networks`` is false. + example: "irc" + example: { + "limit": 10, + "filter": { + "generic_search_term": "foo" + }, + "include_all_networks": false, + "third_party_instance_id": "irc" + } + responses: + 200: + description: A list of the rooms on the server. + schema: + type: object + description: A list of the rooms on the server. + required: ["chunk"] + properties: + chunk: + title: "PublicRoomsChunks" + type: array + description: |- + A paginated chunk of public rooms. + items: + type: object + title: "PublicRoomsChunk" + required: + - room_id + - num_joined_members + - world_readable + - guest_can_join + properties: + aliases: + type: array + description: |- + Aliases of the room. May be empty. + items: + type: string + canonical_alias: + type: string + description: |- + The canonical alias of the room, if any. + name: + type: string + description: |- + The name of the room, if any. + num_joined_members: + type: integer + description: |- + The number of members joined to the room. + room_id: + type: string + description: |- + The ID of the room. + topic: + type: string + description: |- + The topic of the room, if any. + world_readable: + type: boolean + description: |- + Whether the room may be viewed by guest users without joining. + guest_can_join: + type: boolean + description: |- + Whether guest users may join the room and participate in it. + If they can, they will be subject to ordinary power level + rules like any other user. + avatar_url: + type: string + description: The URL for the room's avatar, if one is set. + next_batch: + type: string + description: |- + A pagination token for the response. The absence of this token + means there are no more results to fetch and the client should + stop paginating. + prev_batch: + type: string + description: |- + A pagination token that allows fetching previous results. The + absence of this token means there are no results before this + batch, i.e. this is the first batch. + total_room_count_estimate: + type: integer + description: |- + An estimate on the total number of public rooms, if the + server has an estimate. + examples: + application/json: { + "chunk": [ + { + "aliases": ["#murrays:cheese.bar"], + "avatar_url": "mxc://bleeker.street/CHEDDARandBRIE", + "guest_can_join": false, + "name": "CHEESE", + "num_joined_members": 37, + "room_id": "!ol19s:bleecker.street", + "topic": "Tasty tasty cheese", + "world_readable": true + } + ], + "next_batch": "p190q", + "prev_batch": "p1902", + "total_room_count_estimate": 115 + } From 5cb7599196c4be0f01e41d530fdc85255abd7169 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 24 Sep 2019 13:39:33 -0600 Subject: [PATCH 0852/1250] Changelog --- changelogs/server_server/newsfragments/2035.new | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/server_server/newsfragments/2035.new diff --git a/changelogs/server_server/newsfragments/2035.new b/changelogs/server_server/newsfragments/2035.new new file mode 100644 index 00000000..6794c4ea --- /dev/null +++ b/changelogs/server_server/newsfragments/2035.new @@ -0,0 +1 @@ +Add new ``POST /publicRooms`` endpoint for filtering the room directory. From 9311e899414401121501b87b0e95bb031542e620 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Wed, 25 Sep 2019 01:32:35 +0200 Subject: [PATCH 0853/1250] Update proposals/2229-rebind-existing-3pid.md Co-Authored-By: Hubert Chathi --- proposals/2229-rebind-existing-3pid.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2229-rebind-existing-3pid.md b/proposals/2229-rebind-existing-3pid.md index 1bfb5106..398e6513 100644 --- a/proposals/2229-rebind-existing-3pid.md +++ b/proposals/2229-rebind-existing-3pid.md @@ -1,6 +1,6 @@ # Allowing 3PID Owners to Rebind -## Note: This MSC has been made obselete by MSC2290. +## Note: This MSC has been made obsolete by MSC2290. MSC2290 provides two separate API endpoints, one for adding a 3PID to the homeserver, and another for binding to an identity server. These new From 219ebff6d39837d3982982483f1e114d8f77f832 Mon Sep 17 00:00:00 2001 From: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Date: Thu, 26 Sep 2019 10:37:10 +0200 Subject: [PATCH 0854/1250] typo fix Co-Authored-By: Hubert Chathi --- proposals/2290-separate-threepid-bind-hs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index b361d0e1..fad547c4 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -1,6 +1,6 @@ # Separate Endpoints for Binding Threepids -*Note: This MSC obseletes +*Note: This MSC obsoletes [MSC2229](https://github.com/matrix-org/matrix-doc/pull/2229), which dealt with changing the rules of the `bind` flag on [POST /account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid). From 1a51a2476849cc7f08d5d880a6564e74fa10f181 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 26 Sep 2019 17:16:44 +0100 Subject: [PATCH 0855/1250] UIAA on /account/3pid/add --- proposals/2290-separate-threepid-bind-hs.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index b361d0e1..a1c7f09e 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -45,8 +45,15 @@ will validate threepids being bound to themselves. ## Proposal To solve this problem, two new endpoints will be added to the Client Server -API: `POST /account/3pid/bind` and `POST /account/3pid/add`. Both will -require authentication and be rate-limited. The request parameters of `POST +API: `POST /account/3pid/bind` and `POST /account/3pid/add`. Binding to an +identity server will require standard authentication, whereas adding a 3pid +to a user account will require [User-Interactive +Authentication](https://matrix.org/docs/spec/client_server/r0.5.0#user-interactive-authentication-api). +The latter is to prevent someone from adding a 3pid (which can be used to +reset passwords) to someone who's left their account open on a public +computer, without needing their password to do so. + +Both endpoints will be rate-limited. The request parameters of `POST /account/3pid/bind` are the same as [POST /account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid), minus the `bind` flag, and the contents of `three_pid_creds` have been From ec7e795112ddc5a4d6fb498be996784e9c0ee8b4 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 26 Sep 2019 17:20:40 +0100 Subject: [PATCH 0856/1250] reflow --- proposals/2290-separate-threepid-bind-hs.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index 95f810e9..aa71fb35 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -70,7 +70,8 @@ homeserver. An example of binding a threepid to an identity server with this new endpoint is as follows: -First the client must request the threepid be validated by its chosen identity server. +First the client must request the threepid be validated by its chosen +identity server. ``` POST https://identity.server/_matrix/identity/v2/validate/email/requestToken @@ -89,7 +90,8 @@ ID, the given client_secret, and a randomly-generated token. Once an email has been sent, the user clicks the link in the email, which notifies the identity server that the email has been verified. -Next, the client completes the bind by calling the new endpoint on the homeserver: +Next, the client completes the bind by calling the new endpoint on the +homeserver: ``` POST https://home.server/_matrix/client/r0/account/3pid/bind From 46e7137252088f7fe6b12d2ccd713d3b07f4e33b Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 26 Sep 2019 17:51:51 +0100 Subject: [PATCH 0857/1250] Don't remove id_server and id_access_token --- proposals/2290-separate-threepid-bind-hs.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/proposals/2290-separate-threepid-bind-hs.md b/proposals/2290-separate-threepid-bind-hs.md index aa71fb35..8c899699 100644 --- a/proposals/2290-separate-threepid-bind-hs.md +++ b/proposals/2290-separate-threepid-bind-hs.md @@ -164,8 +164,10 @@ other, which is the exact behaviour we're trying to eliminate. Doing this also helps backward compatibility, as explained in [Backwards compatibility](#backwards-compatibility). -The `id_server` and `id_access_token` parameters are to be removed -from all of the Client-Server API's `requestToken` endpoints. That is: +Either the homeserver itself or a service that the homeserver delegates to +should be handling the sending of validation messages, not a user-provided +server. Any mention of the homeserver being able to proxy to an identity +server in the below endpoint descriptions: * [POST /account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-email-requesttoken) * [POST /account/3pid/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken) @@ -174,13 +176,10 @@ from all of the Client-Server API's `requestToken` endpoints. That is: * [POST /account/password/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-password-email-requesttoken) * [POST /account/password/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-password-msisdn-requesttoken) -Either the homeserver itself or a service that the homeserver delegates to -should be handling the sending of validation messages, not a user-provided -server. Any mention of the homeserver being able to proxy to an identity -server in the above endpoint descriptions, as well as the text "It is -imperative that the homeserver keep a list of trusted Identity Servers and -only proxies to those that it trusts." is to be removed from all parts of the -spec, as the homeserver should no longer need to trust any identity servers. +As well as the text "It is imperative that the homeserver keep a list of +trusted Identity Servers and only proxies to those that it trusts." is to be +removed from all parts of the spec, as the homeserver should no longer need +to trust any identity servers. ## Tradeoffs From 79f16d40a9b40379a6a4bdd2b50500baf6799a47 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Thu, 3 Oct 2019 08:28:05 +0900 Subject: [PATCH 0858/1250] Add a full stop Co-Authored-By: Travis Ralston --- changelogs/client_server/2245.clarification | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/client_server/2245.clarification b/changelogs/client_server/2245.clarification index 67533d15..31e5c2df 100644 --- a/changelogs/client_server/2245.clarification +++ b/changelogs/client_server/2245.clarification @@ -1 +1 @@ -List available enum values for the room versions capability +List available enum values for the room versions capability. From 48b8a95df6b9f344d765bf6a856b8f0b21b75f7e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 3 Oct 2019 09:41:45 -0600 Subject: [PATCH 0859/1250] Deprecate id_server and make it optional As per [MSC2263](https://github.com/matrix-org/matrix-doc/pull/2263) --- api/client-server/administrative_contact.yaml | 8 ++++++-- .../definitions/request_email_validation.yaml | 6 +++++- .../definitions/request_msisdn_validation.yaml | 6 +++++- api/client-server/registration.yaml | 8 ++++++-- specification/client_server_api.rst | 6 ++++++ 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 3581edf7..41270535 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -343,7 +343,9 @@ paths: 400: description: |- The third party identifier is already in use on the homeserver, or - the request was invalid. + the request was invalid. The error code ``M_SERVER_NOT_TRUSTED`` + can be returned if the server does not trust/support the identity server + provided in the request. schema: $ref: "definitions/errors/error.yaml" examples: @@ -391,7 +393,9 @@ paths: 400: description: |- The third party identifier is already in use on the homeserver, or - the request was invalid. + the request was invalid. The error code ``M_SERVER_NOT_TRUSTED`` + can be returned if the server does not trust/support the identity server + provided in the request. schema: $ref: "definitions/errors/error.yaml" examples: diff --git a/api/client-server/definitions/request_email_validation.yaml b/api/client-server/definitions/request_email_validation.yaml index 2b270514..2d789d05 100644 --- a/api/client-server/definitions/request_email_validation.yaml +++ b/api/client-server/definitions/request_email_validation.yaml @@ -22,6 +22,9 @@ allOf: The hostname of the identity server to communicate with. May optionally include a port. This parameter is ignored when the homeserver handles 3PID verification. + + This parameter is deprected with a plan to be removed in a future specification + version for ``/account/password`` and ``/register`` requests. example: "id.example.com" id_access_token: type: string @@ -29,4 +32,5 @@ allOf: An access token previously registered with the identity server. Servers can treat this as optional to distinguish between r0.5-compatible clients and this specification version. - required: ["id_server", "id_access_token"] + + Required if an ``id_server`` is supplied. diff --git a/api/client-server/definitions/request_msisdn_validation.yaml b/api/client-server/definitions/request_msisdn_validation.yaml index b013a561..54988fd4 100644 --- a/api/client-server/definitions/request_msisdn_validation.yaml +++ b/api/client-server/definitions/request_msisdn_validation.yaml @@ -22,6 +22,9 @@ allOf: The hostname of the identity server to communicate with. May optionally include a port. This parameter is ignored when the homeserver handles 3PID verification. + + This parameter is deprected with a plan to be removed in a future specification + version for ``/account/password`` and ``/register`` requests. example: "id.example.com" id_access_token: type: string @@ -29,4 +32,5 @@ allOf: An access token previously registered with the identity server. Servers can treat this as optional to distinguish between r0.5-compatible clients and this specification version. - required: ["id_server", "id_access_token"] + + Required if an ``id_server`` is supplied. diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 733ebe47..a4c5bf71 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -425,7 +425,9 @@ paths: 400: description: |- The referenced third party identifier is not recognised by the - homeserver, or the request was invalid + homeserver, or the request was invalid. The error code ``M_SERVER_NOT_TRUSTED`` + can be returned if the server does not trust/support the identity server + provided in the request. schema: $ref: "definitions/errors/error.yaml" examples: @@ -485,7 +487,9 @@ paths: 400: description: |- The referenced third party identifier is not recognised by the - homeserver, or the request was invalid + homeserver, or the request was invalid. The error code ``M_SERVER_NOT_TRUSTED`` + can be returned if the server does not trust/support the identity server + provided in the request. schema: $ref: "definitions/errors/error.yaml" examples: diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 8df596be..81fb28a6 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -809,6 +809,9 @@ To use this authentication type, clients should submit an auth dict as follows: "session": "" } +Note that ``id_server`` (and therefore ``id_access_token``) is optional if the +``/requestToken`` request did not include them. + Phone number/MSISDN-based (identity / homeserver) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< :Type: @@ -838,6 +841,9 @@ To use this authentication type, clients should submit an auth dict as follows: "session": "" } +Note that ``id_server`` (and therefore ``id_access_token``) is optional if the +``/requestToken`` request did not include them. + Dummy Auth <<<<<<<<<< :Type: From 2e84465c13e4333f08c518db35d73c710188f6e9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 3 Oct 2019 09:42:59 -0600 Subject: [PATCH 0860/1250] Changelog --- changelogs/client_server/newsfragments/2310.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2310.feature diff --git a/changelogs/client_server/newsfragments/2310.feature b/changelogs/client_server/newsfragments/2310.feature new file mode 100644 index 00000000..0169d23b --- /dev/null +++ b/changelogs/client_server/newsfragments/2310.feature @@ -0,0 +1 @@ +Deprecate ``id_server`` and make it optional in several places. From b59998fd2ba3aa559f05b41441a8d90574e8358e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 3 Oct 2019 09:49:01 -0600 Subject: [PATCH 0861/1250] Fix client-server typos changelog Note: .misc is not a valid changelog entry. --- changelogs/client_server/newsfragments/2131.clarification | 2 +- changelogs/client_server/newsfragments/2148.clarification | 1 + changelogs/client_server/newsfragments/2148.misc | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2148.clarification delete mode 100644 changelogs/client_server/newsfragments/2148.misc diff --git a/changelogs/client_server/newsfragments/2131.clarification b/changelogs/client_server/newsfragments/2131.clarification index 3c41fb60..3ccb2333 100644 --- a/changelogs/client_server/newsfragments/2131.clarification +++ b/changelogs/client_server/newsfragments/2131.clarification @@ -1 +1 @@ -Fix typo in key verification framework section. +Fix various typos throughout the specification. diff --git a/changelogs/client_server/newsfragments/2148.clarification b/changelogs/client_server/newsfragments/2148.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/client_server/newsfragments/2148.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. diff --git a/changelogs/client_server/newsfragments/2148.misc b/changelogs/client_server/newsfragments/2148.misc deleted file mode 100644 index d5514131..00000000 --- a/changelogs/client_server/newsfragments/2148.misc +++ /dev/null @@ -1 +0,0 @@ -Fix a small duplicated "as". From 54e73e47291712ed250d8ed3482e789ac0c8b9e5 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 4 Oct 2019 10:41:28 -0400 Subject: [PATCH 0862/1250] Apply suggestions from code review Co-Authored-By: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/1219-storing-megolm-keys-serverside.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 1103eecf..23f1e0f5 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -113,7 +113,7 @@ the key is saved directly by the user, then the code is constructed as follows: 1. The 256-bit curve25519 private key is prepended by the bytes `0x8B` and `0x01` -2. All the bytes in the string are above are XORed together to form a parity +2. All the bytes in the string above, including the two header bytes, are XORed together to form a parity byte. This parity byte is appended to the byte string. 3. The byte string is encoded using base58, using the same mapping as is used for Bitcoin addresses. @@ -129,12 +129,14 @@ results in 0, and ensure that the total length of the decoded string is 35 bytes. Clients must then remove the first two bytes and the last byte, and use the resulting string as the private key to decrypt backups. +#### Enconding the recovery key for server-side storage via MSC1946 + If MSC1946 is used to store the key on the server, it must be stored using the `account_data` type `m.megolm_backup.v1`. As a special case, if the recovery key is the same as the curve25519 key used for storing the key, then the contents of the `m.megolm_backup.v1` -`account_data` for that key will be the an object with a `passthrough` property +`account_data` for that key will be an object with a `passthrough` property whose value is `true`. For example, if `m.megolm_backup.v1` is set to: ```json @@ -245,7 +247,7 @@ On success, returns the empty JSON object. Error codes: -- `M_NOT_FOUND`: No backup version found. +- `M_NOT_FOUND`: This backup version was not found. #### Storing keys From eddce003908691e66a312a520dd1e8c30055cef6 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Fri, 4 Oct 2019 21:56:02 -0400 Subject: [PATCH 0863/1250] MSC2313: Ban lists --- proposals/2313-ban-lists.md | 198 ++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 proposals/2313-ban-lists.md diff --git a/proposals/2313-ban-lists.md b/proposals/2313-ban-lists.md new file mode 100644 index 00000000..284ebf23 --- /dev/null +++ b/proposals/2313-ban-lists.md @@ -0,0 +1,198 @@ +# MSC2313: Ban lists + +Matrix is an open network and anyone can participate in it. As a result, a +very wide range of content exists, and it is important to empower users to be +able to select which content they wish to see, and wish they to block. By +extension, room moderators and server admins should also be able to select +which content they do not wish to host in their rooms and servers. + +The protocol's position in this solution should be one of neutrality: it +should not be deciding what content is undesirable for any particular entity and +should instead be empowering those entities to make their own decisions. This +proposal introduces ban lists as a basic mechanism to help users manage this +process, by providing a way of modelling sets of servers, rooms and users +which can then be used to make filtering decisions. This proposal makes no +attempt at interpreting the model and actually making those decisions however. + +To reaffirm: where this proposal says that some content is undesirable it does not intend to +bias the reader into what that could entail. Undesirability is purely in the hands of the +entity perceiving the content. For example, someone who believes birthday cake is undesirable +is perfectly valid in taking that position and is encouraged by this proposal to set up or +use a ban list which prevents birthday cake from coming across their field of view. + +## Proposal + +Ban lists are represented in rooms, allowing for structures and concepts to be reused without +defining a new room version. This proposal does not make any restrictions on how the rooms +are configured, just that the state events described here are represented in the room. For +example, a room which is invite only is just as valid as a room that is not: the important +details are specific state events and not the accessibility, retention, or other aspects +of the room. + +Ban lists are stored as `m.room.rule.` state events, with state keys being arbitrary IDs +assigned by the sender. The `` is currently one of `user`, `room`, and `server`. Three +fields are defined in `content`: + +* `entity` (`string`) - **Required.** The entity/entities affected. Simple globs are supported + for defining entities (`*` and `?` as wildcards, just like `m.room.server_acl`). +* `recommendation` (`enum`) - **Required.** The action subscribed entities should take against + the described entity. Currently only `m.ban` is defined (see below). +* `reason` (`string`) - **Required.** The human-readable description for the recommendation. + +Invalid or missing fields are to be treated as though the rule doesn't exist. This is to +allow for rules to be deleted while state events cannot be deleted in Matrix. + +An example set of minimal state events for banning `@alice:example.org`, `!matrix:example.org`, +`evil.example.org`, and `*.evil.example.org` would be: + +```json +[ + { + "type": "m.room.rule.user", + "state_key": "rule_1", + "content": { + "entity": "@alice:example.org", + "recommendation": "m.ban", + "reason": "undesirable behaviour" + } + }, + { + "type": "m.room.rule.room", + "state_key": "rule_2", + "content": { + "entity": "!matrix:example.org", + "recommendation": "m.ban", + "reason": "undesirable content" + } + }, + { + "type": "m.room.rule.server", + "state_key": "rule_3", + "content": { + "entity": "evil.example.org", + "recommendation": "m.ban", + "reason": "undesirable engagement" + } + }, + { + "type": "m.room.rule.server", + "state_key": "rule_4", + "content": { + "entity": "*.evil.example.org", + "recommendation": "m.ban", + "reason": "undesirable engagement" + } + } +] +``` + +When the entity is a room, it can be a room alias or ID - the subscriber is responsible for +resolving it to a room ID (if it wants to). + +Non-standard recommendations are permitted using the Java package naming convention for +namespacing. A `recommendation` is just a recommendation: how implementations apply the rules +is left as a concern for those implementations. The only standard `recommendation` currently +defined is `m.ban`: The `entity` should be banned from participation where possible. + +The enforcement mechanism of `m.ban` is deliberately left as an implementation detail to avoid the +protocol imposing its opinion on how the lists are interpreted. However, a suggestion for +a simple implementation is as follows: + +* Is a user... + * Applied to a user: The user should be added to the subscriber's ignore list. + * Applied to a room: The user should be banned from the room (either on sight or immediately). + * Applied to a server: The user should not be allowed to send invites to users on the server. +* Is a room... + * Applied to a user: The user should leave the room and not join it (MSC2270-style ignore). + * Applied to a room: No-op because a room cannot ban itself. + * Applied to a server: The server should prevent users from joining the room and from receiving + invites to it (similar to the `shutdown_room` API in Synapse). +* Is a server... + * Applied to a user: The user should not receive events or invites from the server. + * Applied to a room: The server is added as a denied server in the ACLs. + * Applied to a server: The subscriber should avoid federating with the server as much as + possible by blocking invites from the server and not sending traffic unless strictly + required (no outbound invites). + +Other entities could be represented by this recommendation as well, however as per the +introduction to this proposal they are strictly out of scope. An example would be an integration +manager which doesn't want to offer integrations to banned entities - this is an implementation +detail for the integration manager to solve. + +A new event type is introduced here instead of reusing existing events (membership, ACLs, etc) +because the implication of a recommendation/rule is less clear when using the more narrow-scoped +events. For example, a philosophical question arises over what a `membership` of `ban` means to a server +subscribed to the list. More questions get raised when the `membership` of a user isn't `ban`, +but is `join` or similar instead - if the subscriber was mirroring events, it would be inclined +to try and sync membership lists, which this proposal attempts to avoid by using a more generic +and neutral event type. + +How subscriptions to ban lists are handled is also left as an implementation +detail (to avoid unnecessarily blocking progress on this MSC). The subscriber +could be anything that speaks Matrix, therefore this proposal makes no attempt +to describe how this should work for everything. Some ideas for how this could +be implemented include joining the ban list room to watch for updates and +applying them automatically, however there is no requirement that the +subscriber needs to join the room: they could peek or poll at an interval +instead, which is just as valid. + +To ease sharing of these ban list rooms, a system very similar to [MSC1951's sharable URLs]( +https://github.com/matrix-org/matrix-doc/pull/1951/files#diff-4ee6ed0ee1f2df73efac5fa9a9835642R50-R70) +is defined. There are two ways to share the ban list: a link to the room as one would when +sharing any reference to any other room ("please add `#bans:example.org` to your block list"), +or by using plain `http` or `https` URLs. Just like in MSC1951, the URL when approached with +a `Accept: application/json` header or has `.json` appended to the end of the URL should return +a `room_uri` which is a reference to the ban list room. Currently, the reference would be a +`matrix.to` URI, however in the future this could be a `mx://` or similar URL. When not approached +with the intent of JSON, the service could return a user-friendly page describing what is included +in the ban list. + +## Future considerations + +This proposal notably does not define specific behaviour for AI or machine learning applications. +Implementations are currently able to apply AI/ML to their systems if they see fit (for example, +spam detection or undesirable content being uploaded), however no specification is proposed +here to make the interaction standardized. + +This proposal additionally does not describe how a server could subscribe to a ban list: this +is left for the server to figure out (possibly by using a utility user account?) potentially +with the support of other proposals, such as [MSC1777](https://github.com/matrix-org/matrix-doc/pull/1777). + +Further work on reputation systems could enhance ban lists by adding additional metrics to +assert their validity. This proposal assumes social trust ("don't use it if you +don't trust the creator") over verifiable/provable trust - a future proposal can easily add +such systems to these ban lists. + +This proposal intentionally does not handle how a server could assist the user in preventing +undesirable content or subscribing to ban lists. Users already have some tools at their disposal, +such as being able to ignore other users, and are encouraged to make use of those first. Other +proposals are encouraged to specify what additional tools might look like to better handle +ban lists. + +Media (uploaded content) is not handled by this proposal either. This is a concern left for +other proposals like [MSC2278](https://github.com/matrix-org/matrix-doc/pull/2278) and +[MSC701](https://github.com/matrix-org/matrix-doc/issues/701). + +## Security considerations + +Using this solution one can build a social system of shared blacklists, which +may create a divide within established communities if not carefully deployed. +This may well not be a suitable answer for all communities. + +Depending on how the implementations handle subscriptions, user IDs may be linked to ban +lists and therefore expose the views of that user. Using the example from the introduction, +if a user who does not like birthday cake were to join the ban list room for blocking +birthday cake, that user's preference would be exposed to any other observers of that ban +list. Proposals like [MSC1228](https://github.com/matrix-org/matrix-doc/issues/1228) and +[MSC1777](https://github.com/matrix-org/matrix-doc/pull/1777) could help solve this. + +## Implementation notes + +This proposal is partially implemented by [mjolnir](https://github.com/matrix-org/mjolnir) +using the `org.matrix.mjolnir.*` namespace until this becomes stable. This results in +the following mappings: + +* `m.room.rule.user` => `org.matrix.mjolnir.rule.user` +* `m.room.rule.room` => `org.matrix.mjolnir.rule.room` +* `m.room.rule.server` => `org.matrix.mjolnir.rule.server` +* `m.ban` => `org.matrix.mjolnir.ban` From 576177b579699ec7e07e114d338e60db56c2f1a7 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 9 Oct 2019 17:52:53 -0400 Subject: [PATCH 0864/1250] make version optional in versions update --- proposals/1219-storing-megolm-keys-serverside.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 23f1e0f5..13f16bc9 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -223,7 +223,7 @@ Body parameters: - `auth_data` (object): Required. algorithm-dependent data. For `m.megolm_backup.v1.curve25519-aes-sha2`, see below for the [definition of this property](#auth_data-backup-versions). -- `version` (string): Required. The backup version. Must be the same as the query parameter or must be the current version. +- `version` (string): Optional. The backup version. If present, must be the same as the path parameter. Example: From 5799c433fe992154f1e37921c41debd6f4313319 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 10 Oct 2019 15:03:10 -0400 Subject: [PATCH 0865/1250] add HTTP status codes for errors and move key format to the right spot --- .../1219-storing-megolm-keys-serverside.md | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index 13f16bc9..ff74eb16 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -210,7 +210,7 @@ On success, returns a JSON object with keys: Error codes: -- `M_NOT_FOUND`: No backup version has been created. +- `M_NOT_FOUND`: No backup version has been created. (with HTTP status code 404) ##### `PUT /room_keys/version/{version}` @@ -247,7 +247,7 @@ On success, returns the empty JSON object. Error codes: -- `M_NOT_FOUND`: This backup version was not found. +- `M_NOT_FOUND`: This backup version was not found. (with HTTP status code 404) #### Storing keys @@ -289,7 +289,8 @@ On success, returns a JSON object with keys: Error codes: - `M_WRONG_ROOM_KEYS_VERSION`: the version specified does not match the current - backup version + backup version (with HTTP status code 403). The current backup version will + be included in the `current_version` field of the HTTP result. Example: @@ -426,7 +427,7 @@ On success, returns a JSON object in the same form as the request body of `PUT Error codes: - M_NOT_FOUND: The session is not present in the backup, or the requested - backup version does not exist. + backup version does not exist. (with HTTP status code 404) ##### `GET /room_keys/keys/${roomId}?version=$v` @@ -446,7 +447,7 @@ a successful response with body: Error codes: -- `M_NOT_FOUND`: The requested backup version does not exist. +- `M_NOT_FOUND`: The requested backup version does not exist. (with HTTP status code 404) ##### `GET /room_keys/keys?version=$v` @@ -466,7 +467,7 @@ a successful response with body: Error codes: -- `M_NOT_FOUND`: The requested backup version does not exist. +- `M_NOT_FOUND`: The requested backup version does not exist. (with HTTP status code 404) #### Deleting keys @@ -503,14 +504,14 @@ 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: - `algorithm` (string): `m.megolm.v1.aes-sha2` - - `sender_key` (string): base64-encoded device curve25519 key in - [session-sharing - format](https://gitlab.matrix.org/matrix-org/olm/blob/master/docs/megolm.md#session-sharing-format) + - `sender_key` (string): base64-encoded device curve25519 key - `sender_claimed_keys` (object): object containing the identity keys for the sending device - `forwarding_curve25519_key_chain` (array): zero or more curve25519 keys for devices who forwarded the session key - - `session_key` (string): base64-encoded (unpadded) session key + - `session_key` (string): base64-encoded (unpadded) session key in + [session-sharing + format](https://gitlab.matrix.org/matrix-org/olm/blob/master/docs/megolm.md#session-sharing-format) 2. Generate an ephemeral curve25519 key, and perform an ECDH with the ephemeral key and the backup's public key to generate a shared secret. The public half of the ephemeral key, encoded using base64, becomes the `ephemeral` From 9dfca61ae790e15b7a924955cc93518b4655142f Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 23 Oct 2019 16:13:17 -0400 Subject: [PATCH 0866/1250] Apply suggestions from code review Co-Authored-By: David Baker Co-Authored-By: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> Co-Authored-By: Erik Johnston --- proposals/1946-secure_server-side_storage.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index 0ccde311..2f6460c6 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -41,7 +41,7 @@ A key with ID `abcdefg` is stored in `m.secret_storage.key.abcdefg` ```json { "name": "Some key", - "algorihm": "m.secret_storage.v1.curve25519-aes-sha2", + "algorithm": "m.secret_storage.v1.curve25519-aes-sha2", // ... other properties according to algorithm } ``` @@ -52,7 +52,7 @@ will be encrypted with, and that clients will try to use to decrypt data with, unless the user specifies otherwise. Only one key can be marked as the default at a time. -Encrypted data is stored in the `account_data` using the `type` defined by the +Encrypted data is stored in `account_data` using the `type` defined by the feature that uses the data. For example, decryption keys for key backups could be stored under the type `m.megolm_backup.v1.recovery_key`, or the self-signing key for cross-signing could be stored under the type @@ -180,7 +180,7 @@ and the number of iterations given in the `iterations` parameter. Rather than (or in addition to) storing secrets on the server encrypted by a shared key, devices can send secrets to each other, encrypted using olm. -To request a secret, a client sends a `m.secret.request` event with `action` +To request a secret, a client sends a `m.secret.request` device event with `action` set to `request` to other devices, and `name` set to the name of the secret that it wishes to retrieve. A device that wishes to share the secret will reply with a `m.secret.send` event, encrypted using olm. When the original @@ -229,8 +229,8 @@ also define a secret key mechanism. ## Potential issues -Keeping all the data and keys in account data means that it may clutter up the -`/sync`. However, clients can filter out the data that they are not interested +Keeping all the data and keys in account data means that it may clutter up +`/sync` requests. However, clients can filter out the data that they are not interested in. One possibility for addressing this would be to add a flag to the account data to indicate whether it should come down the `/sync` or not. From b27f6985b2850ceb93ea29112b445ccb821cc82e Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 23 Oct 2019 17:32:36 -0400 Subject: [PATCH 0867/1250] more clarifications --- proposals/1946-secure_server-side_storage.md | 55 +++++++++++--------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index 2f6460c6..49f115da 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -24,10 +24,12 @@ decrypt data on clients. For example, the user could have one key that can decrypt everything, and another key that can only decrypt their user-signing key for cross-signing. -Key descriptions and secret data are both stored in the user's `account_data`. +Key descriptions and secret data are both stored in the user's account_data. -Each key has an ID, and the description of the key is stored in the -`account_data` using the `type` `m.secret_storage.key.[key ID]`. The contents +#### Key storage + +Each key has an ID, and the description of the key is stored in the user's +account_data using the event type `m.secret_storage.key.[key ID]`. The contents of the account data for the key will include an `algorithm` property, which indicates the encryption algorithm used, as well as a `name` property, which is a human-readable name. The contents will be signed as signed JSON using the @@ -52,13 +54,15 @@ will be encrypted with, and that clients will try to use to decrypt data with, unless the user specifies otherwise. Only one key can be marked as the default at a time. -Encrypted data is stored in `account_data` using the `type` defined by the -feature that uses the data. For example, decryption keys for key backups could -be stored under the type `m.megolm_backup.v1.recovery_key`, or the self-signing -key for cross-signing could be stored under the type +#### Secret storage + +Encrypted data is stored in the user's account_data using the event type +defined by the feature that uses the data. For example, decryption keys for +key backups could be stored under the type `m.megolm_backup.v1.recovery_key`, +or the self-signing key for cross-signing could be stored under the type `m.cross_signing.self_signing`. -The `account_data` will have an `encrypted` property that is a map from key ID +The account_data will have an `encrypted` property that is a map from key ID to an object. The algorithm from the `m.secret_storage.key.[key ID]` data for the given key defines how the other properties are interpreted, though it's expected that most encryption schemes would have `ciphertext` and `mac` @@ -71,17 +75,17 @@ Some secret is encrypted using keys with ID `key_id_1` and `key_id_2`: ```json { - "encrypted": { - "key_id_1": { - "ciphertext": "base64+encoded+encrypted+data", - "mac": "base64+encoded+mac", - // ... other properties according to algorithm property in - // m.secret_storage.key.key_id_1 - }, - "key_id_2": { - // ... - } + "encrypted": { + "key_id_1": { + "ciphertext": "base64+encoded+encrypted+data", + "mac": "base64+encoded+mac", + // ... other properties according to algorithm property in + // m.secret_storage.key.key_id_1 + }, + "key_id_2": { + // ... } + } } ``` @@ -90,7 +94,7 @@ Some secret is encrypted using keys with ID `key_id_1` and `key_id_2`: ##### `m.secret_storage.v1.curve25519-aes-sha2` The public key is stored in the `pubkey` property of the `m.secret_storage.key.[key -ID]` `account_data` as a base64-encoded string. +ID]` account_data as a base64-encoded string. The data is encrypted and MACed as follows: @@ -189,12 +193,13 @@ set to `request_cancellation` to all devices other than the one that it received secret from. Clients should ignore `m.secret.send` events received from devices that it did not send an `m.secret.request` event to. -Clients SHOULD ensure that they only share secrets with other devices that are -allowed to see them. For example, clients SHOULD only share secrets with devices -that are verified and MAY prompt the user to confirm sharing the secret. +Clients MUST ensure that they only share secrets with other devices that are +allowed to see them. For example, clients SHOULD only share secrets with +devices that are verified and MAY prompt the user to confirm sharing the +secret. If a feature allows secrets to be stored or shared, then for consistency it -SHOULD use the same name for both the `account_data` `type` and the `name` in +SHOULD use the same name for both the account_data event type and the `name` in the `m.secret.request`. #### Event definitions @@ -216,8 +221,8 @@ unencrypted to-device event. ##### `m.secret.send` Sent by a client to share a secret with another device, in response to an -`m.secret.request` event. Typically it is encrypted as an `m.room.encrypted` -event, then sent as a to-device event. +`m.secret.request` event. It MUST be encrypted as an `m.room.encrypted` event, +then sent as a to-device event. - `request_id`: (string) Required. The ID of the request that this a response to. - `secret`: (string) Required. The contents of the secret. From f5f12a29e08a197cb183f0ae5b5a36b7f52d63a1 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 8 Oct 2019 15:31:06 +0100 Subject: [PATCH 0868/1250] Spec MSC2290: 3PID binding split --- api/client-server/administrative_contact.yaml | 149 +++++++++++++++--- api/client-server/registration.yaml | 30 +--- specification/client_server_api.rst | 10 +- 3 files changed, 144 insertions(+), 45 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 41270535..504e149d 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -1,4 +1,5 @@ # Copyright 2016 OpenMarket Ltd +# Copyright 2019 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. @@ -89,8 +90,19 @@ paths: - User data post: summary: Adds contact information to the user's account. - description: Adds contact information to the user's account. + description: |- + Adds contact information to the user's account. + + This endpoint is deprecated in favour of the more specific ``/3pid/add`` + and ``/3pid/bind`` endpoints. + + .. Note:: + Previously this endpoint supported a ``bind`` parameter. This parameter + has been removed, making this endpoint behave as though it was ``false``. + This results in this endpoint being an equivalent to ``/3pid/bind`` rather + than dual-purpose. operationId: post3PIDs + deprecated: true security: - accessToken: [] parameters: @@ -120,13 +132,6 @@ paths: type: string description: The session identifier given by the identity server. required: ["client_secret", "id_server", "id_access_token", "sid"] - bind: - type: boolean - description: |- - Whether the homeserver should also bind this third party - identifier to the account's Matrix ID with the passed identity - server. Default: ``false``. - x-example: true required: ["three_pid_creds"] example: { "three_pid_creds": { @@ -134,8 +139,7 @@ paths: "id_access_token": "abc123_OpaqueString", "sid": "abc123987", "client_secret": "d0n'tT3ll" - }, - "bind": false + } } responses: 200: @@ -173,6 +177,113 @@ paths: "$ref": "definitions/errors/error.yaml" tags: - User data + "/account/3pid/add": + post: + summary: Adds contact information to the user's account. + description: |- + This API endpoint uses the `User-Interactive Authentication API`_. + + Adds contact information to the user's account. Homeservers should use 3PIDs added + through this endpoint for password resets instead of relying on the identity server. + + Homeservers should prevent the caller from adding a 3PID to their account if it has + already been added to another user's account on the homeserver. + operationId: add3PID + security: + - accessToken: [] + parameters: + - in: body + name: body + schema: + type: object + properties: + auth: + description: |- + Additional authentication information for the + user-interactive authentication API. + $ref: "definitions/auth_data.yaml" + client_secret: + type: string + description: The client secret used in the session with the homeserver. + sid: + type: string + description: The session identifier given by the homeserver. + required: ["client_secret", "sid"] + example: { + "sid": "abc123987", + "client_secret": "d0n'tT3ll" + } + responses: + 200: + description: The addition was successful. + examples: + application/json: {} + schema: + type: object + 401: + description: |- + The homeserver requires additional authentication information. + schema: + "$ref": "definitions/auth_response.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" + "/account/3pid/bind": + post: + summary: Binds a 3PID to the user's account through an Identity Service. + description: |- + Binds a 3PID to the user's account through the specified identity server. + + Homeservers should not prevent this request from succeeding if another user + has bound the 3PID. Homeservers should simply proxy any errors received by + the identity server to the caller. + + Homeservers should track successful binds so they can be unbound later. + operationId: bind3PID + security: + - accessToken: [] + parameters: + - in: body + name: body + schema: + type: object + properties: + client_secret: + type: string + description: The client secret used in the session with the identity server. + id_server: + type: string + description: The identity server to use. + id_access_token: + type: string + description: |- + An access token previously registered with the identity server. Servers + can treat this as optional to distinguish between r0.5-compatible clients + and this specification version. + sid: + type: string + description: The session identifier given by the identity server. + required: ["client_secret", "id_server", "id_access_token", "sid"] + example: { + "id_server": "example.org", + "id_access_token": "abc123_OpaqueString", + "sid": "abc123987", + "client_secret": "d0n'tT3ll" + } + responses: + 200: + description: The addition was successful. + examples: + application/json: {} + schema: + type: object + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" + tags: + - User data "/account/3pid/delete": post: summary: Deletes a third party identifier from the user's account @@ -308,12 +419,9 @@ paths: already associated with an account on this homeserver. This API should be used to request validation tokens when adding an email address to an account. This API's parameters and response are identical to that of - the |/register/email/requestToken|_ endpoint. The homeserver has the - choice of validating the email address itself, or proxying the request - to the ``/validate/email/requestToken`` Identity Service API as - identified by ``id_server``. It is imperative that the - homeserver keep a list of trusted Identity Servers and only proxies to - those that it trusts. + the |/register/email/requestToken|_ endpoint. The homeserver should validate + the email itself, either by sending a validation email itself or by using + a service it has control over. operationId: requestTokenTo3PIDEmail parameters: - in: body @@ -361,12 +469,9 @@ paths: already associated with an account on this homeserver. This API should be used to request validation tokens when adding a phone number to an account. This API's parameters and response are identical to that of - the |/register/msisdn/requestToken|_ endpoint. The homeserver has the - choice of validating the phone number itself, or proxying the request - to the ``/validate/msisdn/requestToken`` Identity Service API as - identified by ``id_server``. It is imperative that the - homeserver keep a list of trusted Identity Servers and only proxies to - those that it trusts. + the |/register/msisdn/requestToken|_ endpoint. The homeserver should validate + the phone number itself, either by sending a validation message itself or by using + a service it has control over. operationId: requestTokenTo3PIDMSISDN parameters: - in: body diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index a4c5bf71..8114299e 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -219,11 +219,8 @@ paths: description: |- The homeserver must check that the given email address is **not** already associated with an account on this homeserver. The homeserver - has the choice of validating the email address itself, or proxying the - request to the ``/validate/email/requestToken`` Identity Service API. The - request should be proxied to the domain that is sent by the client in - the ``id_server``. It is imperative that the homeserver keep a list of - trusted Identity Servers and only proxies to those it trusts. + should validate the email itself, either by sending a validation email + itself or by using a service it has control over. operationId: requestTokenToRegisterEmail parameters: - in: body @@ -272,11 +269,8 @@ paths: description: |- The homeserver must check that the given phone number is **not** already associated with an account on this homeserver. The homeserver - has the choice of validating the phone number itself, or proxying the - request to the ``/validate/msisdn/requestToken`` Identity Service API. The - request should be proxied to the domain that is sent by the client in - the ``id_server``. It is imperative that the homeserver keep a list of - trusted Identity Servers and only proxies to those it trusts. + should validate the phone number itself, either by sending a validation + message itself or by using a service it has control over. operationId: requestTokenToRegisterMSISDN parameters: - in: body @@ -388,12 +382,8 @@ paths: email to the given address prompting the user to create an account. ``M_THREEPID_IN_USE`` may not be returned. - The homeserver has the choice of validating the email address itself, - or proxying the request to the ``/validate/email/requestToken`` - Identity Service API. The request should be proxied to the domain that - is sent by the client in the ``id_server``. It is imperative that the - homeserver keep a list of trusted Identity Servers and only proxies to - those that it trusts. + The homeserver should validate the email itself, either by sending a + validation email itself or by using a service it has control over. .. |/register/email/requestToken| replace:: ``/register/email/requestToken`` @@ -451,12 +441,8 @@ paths: to the given phone number prompting the user to create an account. ``M_THREEPID_IN_USE`` may not be returned. - The homeserver has the choice of validating the phone number itself, or - proxying the request to the ``/validate/msisdn/requestToken`` Identity - Service API. The request should be proxied to the domain that is sent - by the client in the ``id_server``. It is imperative that the - homeserver keep a list of trusted Identity Servers and only proxies to - those that it trusts. + The homeserver should validate the phone number itself, either by sending a + validation message itself or by using a service it has control over. .. |/register/msisdn/requestToken| replace:: ``/register/msisdn/requestToken`` diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 81fb28a6..d1d5dee4 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1138,7 +1138,15 @@ Adding Account Administrative Contact Information ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A homeserver may keep some contact information for administrative use. -This is independent of any information kept by any identity servers. +This is independent of any information kept by any identity servers, though +can be proxied (bound) to the identity server in many cases. + +.. Note:: + This section deals with two terms: "add" and "bind". Where "add" (or "remove") + is used, it is speaking about an identifier that was not bound to an identity + server. As a result, "bind" (or "unbind") references an identifier that is found + in an identity server. Note that an identifer can be added and bound at the same + time, depending on context. {{administrative_contact_cs_http_api}} From 86eccc3bc8d5c1748a607a2c79067c1dae1b6923 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 25 Oct 2019 15:00:23 -0400 Subject: [PATCH 0869/1250] change how we mark the default key, and make sure clients trust keys --- proposals/1946-secure_server-side_storage.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index 49f115da..a2dfb381 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -48,11 +48,17 @@ A key with ID `abcdefg` is stored in `m.secret_storage.key.abcdefg` } ``` -If a key has the `name` property set to `m.default`, then this key is treated as -the default key for the account. The default key is the one that all secrets -will be encrypted with, and that clients will try to use to decrypt data with, -unless the user specifies otherwise. Only one key can be marked as the default -at a time. +A key can be marked as the "default" key by setting the user's account_data +with event type `m.secret_storage.default_key` to the ID of the key. The +default key will be used to encrypet all secrets that the user would expect to +be available on all their clients. Unless the user specifies otherwise, +clients will try to use the default key to decrypt secrets. + +Clients MUST ensure that the key is trusted before using it to encrypt secrets. +One way to do that is to have the client that creates the key sign the key +description (as signed JSON) using the user's master cross-signing key. +Another way to do that is to prompt the user to enter the passphrase and ensure +that the generated private key correponds to the public key. #### Secret storage From 4fadace9c823112122b407db7281e486e347b048 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 28 Oct 2019 12:48:59 -0400 Subject: [PATCH 0870/1250] Update proposals/1946-secure_server-side_storage.md Co-Authored-By: David Baker --- proposals/1946-secure_server-side_storage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index a2dfb381..832144d1 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -50,7 +50,7 @@ A key with ID `abcdefg` is stored in `m.secret_storage.key.abcdefg` A key can be marked as the "default" key by setting the user's account_data with event type `m.secret_storage.default_key` to the ID of the key. The -default key will be used to encrypet all secrets that the user would expect to +default key will be used to encrypt all secrets that the user would expect to be available on all their clients. Unless the user specifies otherwise, clients will try to use the default key to decrypt secrets. From a6977f19c53e6ccd366b972d95e7ce4bef5eb5f8 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 28 Oct 2019 12:58:27 -0400 Subject: [PATCH 0871/1250] Update proposals/1219-storing-megolm-keys-serverside.md Co-Authored-By: aditsachde <23707194+aditsachde@users.noreply.github.com> --- proposals/1219-storing-megolm-keys-serverside.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1219-storing-megolm-keys-serverside.md b/proposals/1219-storing-megolm-keys-serverside.md index ff74eb16..95430fe2 100644 --- a/proposals/1219-storing-megolm-keys-serverside.md +++ b/proposals/1219-storing-megolm-keys-serverside.md @@ -129,7 +129,7 @@ results in 0, and ensure that the total length of the decoded string is 35 bytes. Clients must then remove the first two bytes and the last byte, and use the resulting string as the private key to decrypt backups. -#### Enconding the recovery key for server-side storage via MSC1946 +#### Encoding the recovery key for server-side storage via MSC1946 If MSC1946 is used to store the key on the server, it must be stored using the `account_data` type `m.megolm_backup.v1`. From 2bca44a2e524ef431ab18172c050f7ee7101ff9a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 28 Oct 2019 14:28:48 -0600 Subject: [PATCH 0872/1250] Remove extraneous backwards compatibility note --- api/client-server/administrative_contact.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 504e149d..9a59cb6b 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -258,9 +258,7 @@ paths: id_access_token: type: string description: |- - An access token previously registered with the identity server. Servers - can treat this as optional to distinguish between r0.5-compatible clients - and this specification version. + An access token previously registered with the identity server. sid: type: string description: The session identifier given by the identity server. From 6270983b7f0b6d4cba7c679e9dd9b7028d50dfdb Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Wed, 30 Oct 2019 14:36:47 -0500 Subject: [PATCH 0873/1250] MSC2334 - Change default room version to v5 Signed-off-by: Aaron Raimist --- proposals/2334-default-room-version-v5.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 proposals/2334-default-room-version-v5.md diff --git a/proposals/2334-default-room-version-v5.md b/proposals/2334-default-room-version-v5.md new file mode 100644 index 00000000..06ad652b --- /dev/null +++ b/proposals/2334-default-room-version-v5.md @@ -0,0 +1,17 @@ +# MSC2334 - Change default room version to v5 + +This MSC proposes changing the recommended default room version from v4 to v5. This implements steps 5 and 6 of the plan from [MSC2002](https://github.com/matrix-org/matrix-doc/issues/2002). + +Room version 5 enforces the `valid_until_ts` timestamp on signing keys as proposed in [MSC2076](https://github.com/matrix-org/matrix-doc/issues/2076). + +## Proposal + +When [MSC2077](https://github.com/matrix-org/matrix-doc/issues/2077) proposed room version 5, the default version continued to be v4 to allow old servers to continue to chat in newly created rooms. Server-Server API r0.1.2 (which contains the details on room version 5) and Synapse 1.0.0 (with support for room version 5) were both released more than 4 months ago which has given people plenty of time to update. Room version 5 should be the default room version so that newly created rooms enforce key-validity periods. + +## Potential issues + +Servers which do not support room version 5 will not be able to participate in newly created rooms on other servers. Hopefully this will encourage them to update their server. + +## Security considerations + +Room version 5 fixes known security vulnerabilities but that doesn't do much good if newly created rooms aren't using room version 5 by default. \ No newline at end of file From 14c32cc4bfa85a13a6350a4587959ef5a009f042 Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Wed, 30 Oct 2019 16:20:17 -0500 Subject: [PATCH 0874/1250] Wrap lines --- proposals/2334-default-room-version-v5.md | 24 +++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/proposals/2334-default-room-version-v5.md b/proposals/2334-default-room-version-v5.md index 06ad652b..e511aafd 100644 --- a/proposals/2334-default-room-version-v5.md +++ b/proposals/2334-default-room-version-v5.md @@ -1,17 +1,29 @@ -# MSC2334 - Change default room version to v5 +# [MSC2334](https://github.com/matrix-org/matrix-doc/pull/2334) - Change default room version to v5 -This MSC proposes changing the recommended default room version from v4 to v5. This implements steps 5 and 6 of the plan from [MSC2002](https://github.com/matrix-org/matrix-doc/issues/2002). +This MSC proposes changing the recommended default room version from v4 to v5. +This implements steps 5 and 6 of the plan from +[MSC2002](https://github.com/matrix-org/matrix-doc/issues/2002). -Room version 5 enforces the `valid_until_ts` timestamp on signing keys as proposed in [MSC2076](https://github.com/matrix-org/matrix-doc/issues/2076). +Room version 5 enforces the `valid_until_ts` timestamp on signing keys as +proposed in [MSC2076](https://github.com/matrix-org/matrix-doc/issues/2076). ## Proposal -When [MSC2077](https://github.com/matrix-org/matrix-doc/issues/2077) proposed room version 5, the default version continued to be v4 to allow old servers to continue to chat in newly created rooms. Server-Server API r0.1.2 (which contains the details on room version 5) and Synapse 1.0.0 (with support for room version 5) were both released more than 4 months ago which has given people plenty of time to update. Room version 5 should be the default room version so that newly created rooms enforce key-validity periods. +When [MSC2077](https://github.com/matrix-org/matrix-doc/issues/2077) proposed +room version 5, the default version continued to be v4 to allow old servers to +continue to chat in newly created rooms. Server-Server API r0.1.2 (which +contains the details on room version 5) and Synapse 1.0.0 (with support for room +version 5) were both released more than 4 months ago which has given people +plenty of time to update. Room version 5 should be the default room version so +that newly created rooms enforce key-validity periods. ## Potential issues -Servers which do not support room version 5 will not be able to participate in newly created rooms on other servers. Hopefully this will encourage them to update their server. +Servers which do not support room version 5 will not be able to participate in +newly created rooms on other servers. Hopefully this will encourage them to +update their server. ## Security considerations -Room version 5 fixes known security vulnerabilities but that doesn't do much good if newly created rooms aren't using room version 5 by default. \ No newline at end of file +Room version 5 fixes known security vulnerabilities but that doesn't do much +good if newly created rooms aren't using room version 5 by default. \ No newline at end of file From ae163ab8180ab2072970f94f6426323a7de69405 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Fri, 1 Nov 2019 14:05:54 +0000 Subject: [PATCH 0875/1250] remove some lies about markdown being bad (#2337) --- meta/documentation_style.rst | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/meta/documentation_style.rst b/meta/documentation_style.rst index e59ad229..e3d363c4 100644 --- a/meta/documentation_style.rst +++ b/meta/documentation_style.rst @@ -8,10 +8,7 @@ in. Format ------ -We use restructured text throughout all the documentation. You should NOT use -markdown (github-flavored or otherwise). This format was chosen partly because -Sphinx only supports RST. - +Documentation is written either in github-flavored markdown or RST. Sections -------- From 3e42cf528ba65f5025e534fac66cbad98529a5a5 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 1 Nov 2019 15:38:14 -0400 Subject: [PATCH 0876/1250] Apply suggestions from code review Co-Authored-By: David Baker --- proposals/1756-cross-signing.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 2e4f1b43..72b74121 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -19,7 +19,7 @@ MSC1680 is presented below. ## Proposal -Each user has three sets of key pairs: +Each user has three key pairs: - a *master* cross-signing key pair that is used to identify themselves and to sign their other cross-signing keys, @@ -29,7 +29,7 @@ Each user has three sets of key pairs: When one user (e.g. Alice) verifies another user's (Bob's) identity, Alice will sign Bob's master key with her user-signing key. (This will mean that verification methods will need to be modified to pass along the public part of -the master key.) Alice's device will trust Bob's device if: +Bob's master key.) Alice's device will trust Bob's device if: - Alice's device is using a master key that has signed her user-signing key, - Alice's user-signing key has signed Bob's master key, @@ -56,7 +56,7 @@ clients should still make efforts to store the private part securely, or not store it at all. Clients will need to balance the security of the keys with the usability of signing users and devices when performing key verification. -The private halves of a user's cross-signing keys be stored encrypted on the +The private halves of a user's cross-signing keys may be stored encrypted on the server so that they may be retrieved by new devices, or shared between devices using [MSC1946](https://github.com/matrix-org/matrix-doc/pull/1946). When handled in this way, the keys must be base64-encoded, and use the names From a51805cfe7f4666726be3642319b85894d287bf2 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 1 Nov 2019 23:10:14 -0400 Subject: [PATCH 0877/1250] Apply suggestions from code review Co-Authored-By: Kitsune Ral --- proposals/2313-ban-lists.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/proposals/2313-ban-lists.md b/proposals/2313-ban-lists.md index 284ebf23..ba0273a1 100644 --- a/proposals/2313-ban-lists.md +++ b/proposals/2313-ban-lists.md @@ -1,8 +1,8 @@ # MSC2313: Ban lists -Matrix is an open network and anyone can participate in it. As a result, a +Matrix is an open network and anyone can participate in it. As a result, a very wide range of content exists, and it is important to empower users to be -able to select which content they wish to see, and wish they to block. By +able to select which content they wish to see, and which they wish to block. By extension, room moderators and server admins should also be able to select which content they do not wish to host in their rooms and servers. @@ -11,7 +11,7 @@ should not be deciding what content is undesirable for any particular entity and should instead be empowering those entities to make their own decisions. This proposal introduces ban lists as a basic mechanism to help users manage this process, by providing a way of modelling sets of servers, rooms and users -which can then be used to make filtering decisions. This proposal makes no +which can then be used to make filtering decisions. This proposal makes no attempt at interpreting the model and actually making those decisions however. To reaffirm: where this proposal says that some content is undesirable it does not intend to @@ -22,9 +22,9 @@ use a ban list which prevents birthday cake from coming across their field of vi ## Proposal -Ban lists are represented in rooms, allowing for structures and concepts to be reused without +Ban lists are stored as room state events, allowing for structures and concepts to be reused without defining a new room version. This proposal does not make any restrictions on how the rooms -are configured, just that the state events described here are represented in the room. For +are configured, just that the state events described here are represented in a room. For example, a room which is invite only is just as valid as a room that is not: the important details are specific state events and not the accessibility, retention, or other aspects of the room. @@ -33,7 +33,7 @@ Ban lists are stored as `m.room.rule.` state events, with state keys being assigned by the sender. The `` is currently one of `user`, `room`, and `server`. Three fields are defined in `content`: -* `entity` (`string`) - **Required.** The entity/entities affected. Simple globs are supported +* `entity` (`string`) - **Required.** The entity/entities the recommendation applies to. Simple globs are supported for defining entities (`*` and `?` as wildcards, just like `m.room.server_acl`). * `recommendation` (`enum`) - **Required.** The action subscribed entities should take against the described entity. Currently only `m.ban` is defined (see below). @@ -103,7 +103,8 @@ a simple implementation is as follows: * Applied to a room: The user should be banned from the room (either on sight or immediately). * Applied to a server: The user should not be allowed to send invites to users on the server. * Is a room... - * Applied to a user: The user should leave the room and not join it (MSC2270-style ignore). + * Applied to a user: The user should leave the room and not join it + ([MSC2270](https://github.com/matrix-org/matrix-doc/pull/2270)-style ignore). * Applied to a room: No-op because a room cannot ban itself. * Applied to a server: The server should prevent users from joining the room and from receiving invites to it (similar to the `shutdown_room` API in Synapse). From 30106aaaacf6c2e2c10bcd95963202466a7a1b3b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 4 Nov 2019 21:14:18 +0200 Subject: [PATCH 0878/1250] Add section about backwards compatibility Signed-off-by: Tulir Asokan --- proposals/2244-mass-redactions.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/proposals/2244-mass-redactions.md b/proposals/2244-mass-redactions.md index b2d35dff..4f410356 100644 --- a/proposals/2244-mass-redactions.md +++ b/proposals/2244-mass-redactions.md @@ -17,6 +17,17 @@ It would be easiest to do this before MSC2174 is written into the spec, as then only one migration would be needed: from an event-level redacts string to a content-level redacts array. +### Backwards compatibility +There is no easy way to stay fully compatible with *older* clients, so the +proposed solution is to not support them. In order to not break old clients +completely, servers should still add a `redacts` string containing one of the +redacted event IDs to the top level of `m.room.redaction` events in *newer* +room versions when serving such events over the Client-Server API. + +Like MSC2174, for improved compatibility with *newer* clients, servers should +add a `redacts` array to the `content` of `m.room.redaction` events in *older* +room versions when serving such events over the Client-Server API. + ### Number of redactions Room v4+ event IDs are 44 bytes long, which means the federation event size limit would cap a single redaction event at a bit less than 1500 targets. From e95eafb2ba6b12d010b2b3c3e651424793ba2e72 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 4 Nov 2019 15:17:51 -0700 Subject: [PATCH 0879/1250] Clarify that submit_url is without authentication The request is authorized by its parameters, not by an additional access token. Fixes https://github.com/matrix-org/matrix-doc/issues/2298 --- api/client-server/administrative_contact.yaml | 7 ++++--- api/client-server/definitions/request_token_response.yaml | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 9a59cb6b..fc231b60 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -157,9 +157,10 @@ paths: An optional field containing a URL where the client must submit the validation token to, with identical parameters to the Identity Service API's ``POST - /validate/email/submitToken`` endpoint. The homeserver must - send this token to the user (if applicable), who should - then be prompted to provide it to the client. + /validate/email/submitToken`` endpoint (without the requirement + for an access token). The homeserver must send this token to the + user (if applicable), who should then be prompted to provide it + to the client. If this field is not present, the client can assume that verification will happen without the client's involvement diff --git a/api/client-server/definitions/request_token_response.yaml b/api/client-server/definitions/request_token_response.yaml index e47db8a0..45201a20 100644 --- a/api/client-server/definitions/request_token_response.yaml +++ b/api/client-server/definitions/request_token_response.yaml @@ -25,9 +25,9 @@ properties: description: |- An optional field containing a URL where the client must submit the validation token to, with identical parameters to the Identity Service - API's ``POST /validate/email/submitToken`` endpoint. The homeserver must - send this token to the user (if applicable), who should then be - prompted to provide it to the client. + API's ``POST /validate/email/submitToken`` endpoint (without the requirement + for an access token). The homeserver must send this token to the user (if + applicable), who should then be prompted to provide it to the client. If this field is not present, the client can assume that verification will happen without the client's involvement provided the homeserver From 1dfe2ade0839dd037d8deaa23282518fa253b943 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 4 Nov 2019 15:19:10 -0700 Subject: [PATCH 0880/1250] Changelog --- changelogs/client_server/newsfragments/2341.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2341.clarification diff --git a/changelogs/client_server/newsfragments/2341.clarification b/changelogs/client_server/newsfragments/2341.clarification new file mode 100644 index 00000000..a941db1b --- /dev/null +++ b/changelogs/client_server/newsfragments/2341.clarification @@ -0,0 +1 @@ +Clarify that the ``submit_url`` field is without authentication. From 284b15495b2e0fe7dcefcb77f58643f59edc2952 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 4 Nov 2019 15:25:49 -0700 Subject: [PATCH 0881/1250] Clarify what format the `country` is on phone number inputs Fixes https://github.com/matrix-org/matrix-doc/issues/1982 --- api/identity/definitions/request_msisdn_validation.yaml | 4 ++-- changelogs/client_server/newsfragments/2342.clarification | 1 + specification/client_server_api.rst | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2342.clarification diff --git a/api/identity/definitions/request_msisdn_validation.yaml b/api/identity/definitions/request_msisdn_validation.yaml index 018bd733..93cea2ed 100644 --- a/api/identity/definitions/request_msisdn_validation.yaml +++ b/api/identity/definitions/request_msisdn_validation.yaml @@ -30,8 +30,8 @@ properties: country: type: string description: |- - The two-letter uppercase ISO country code that the number in - ``phone_number`` should be parsed as if it were dialled from. + The two-letter uppercase ISO-3166-1 alpha-2 country code that the + number in ``phone_number`` should be parsed as if it were dialled from. example: "GB" phone_number: type: string diff --git a/changelogs/client_server/newsfragments/2342.clarification b/changelogs/client_server/newsfragments/2342.clarification new file mode 100644 index 00000000..09f4b191 --- /dev/null +++ b/changelogs/client_server/newsfragments/2342.clarification @@ -0,0 +1 @@ +Clarify the expected phone number format. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index d1d5dee4..7e420b8c 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1042,6 +1042,9 @@ wishes to canonicalise the phone number, then it can use the "phone": "" } +The ``country`` is the two-letter uppercase ISO-3166-1 alpha-2 country code +that the number in ``phone`` should be parsed as if it were dialled from. + Login ~~~~~ From b662a33081eaf894acf389721d0731cbbbf80f44 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 4 Nov 2019 15:47:25 -0700 Subject: [PATCH 0882/1250] Recommend that clients don't preview URLs in encrypted rooms Any stronger of a recommendation would probably require a MSC due to the behaviour change. Fixes https://github.com/matrix-org/matrix-doc/issues/2120 --- api/client-server/content-repo.yaml | 8 ++++++++ changelogs/client_server/newsfragments/2343.clarification | 1 + 2 files changed, 9 insertions(+) create mode 100644 changelogs/client_server/newsfragments/2343.clarification diff --git a/api/client-server/content-repo.yaml b/api/client-server/content-repo.yaml index a9a0c2f6..577e63b8 100644 --- a/api/client-server/content-repo.yaml +++ b/api/client-server/content-repo.yaml @@ -340,6 +340,14 @@ paths: "/preview_url": get: summary: "Get information about a URL for a client" + description: |- + Get information about a URL for the client. Typically this is called when a + client sees a URL in a message and wants to render a preview for the user. + + .. Note:: + Clients should consider avoiding this endpoint for URLs posted in encrypted + rooms. + operationId: getUrlPreview produces: ["application/json"] security: diff --git a/changelogs/client_server/newsfragments/2343.clarification b/changelogs/client_server/newsfragments/2343.clarification new file mode 100644 index 00000000..5b16858b --- /dev/null +++ b/changelogs/client_server/newsfragments/2343.clarification @@ -0,0 +1 @@ +Clarify that clients should consider not requesting URL previews in encrypted rooms. From 021c056efc200f968bb1c4c4eb99273c25e8247b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 4 Nov 2019 15:55:20 -0700 Subject: [PATCH 0883/1250] Add filter query param to /context This was missed as part of lazy-loading. Fixes https://github.com/matrix-org/matrix-doc/issues/2338 --- api/client-server/event_context.yaml | 11 +++++++++++ .../client_server/newsfragments/2344.clarification | 1 + 2 files changed, 12 insertions(+) create mode 100644 changelogs/client_server/newsfragments/2344.clarification diff --git a/api/client-server/event_context.yaml b/api/client-server/event_context.yaml index 3bea351c..e0c74cbf 100644 --- a/api/client-server/event_context.yaml +++ b/api/client-server/event_context.yaml @@ -59,6 +59,17 @@ paths: description: |- The maximum number of events to return. Default: 10. x-example: 3 + - in: query + name: filter + type: string + description: |- + The ID of a filter created using the filter API or a filter JSON + object encoded as a string. The server will detect whether it is + an ID or a JSON object by whether the first character is a ``"{"`` + open brace. + + See `Filtering <#filtering>`_ for more information. + x-example: "66696p746572" responses: 200: description: The events and state surrounding the requested event. diff --git a/changelogs/client_server/newsfragments/2344.clarification b/changelogs/client_server/newsfragments/2344.clarification new file mode 100644 index 00000000..8c92d31e --- /dev/null +++ b/changelogs/client_server/newsfragments/2344.clarification @@ -0,0 +1 @@ +Add missing information on how filters are meant to work with ``/context``. From 3d954f93b5240f84894ec0be555f5e5292f8acef Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 4 Nov 2019 15:57:58 -0700 Subject: [PATCH 0884/1250] Clarify that the room ID is the object key in /sync responses Fixes https://github.com/matrix-org/matrix-doc/issues/2269 --- api/client-server/sync.yaml | 9 ++++++--- .../client_server/newsfragments/2345.clarification | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2345.clarification diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 00a332d9..bf804792 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -136,7 +136,8 @@ paths: title: Joined Rooms type: object description: |- - The rooms that the user has joined. + The rooms that the user has joined, mapped as room ID to + room information. additionalProperties: title: Joined Room type: object @@ -249,7 +250,8 @@ paths: title: Invited Rooms type: object description: |- - The rooms that the user has been invited to. + The rooms that the user has been invited to, mapped as room ID to + room information. additionalProperties: title: Invited Room type: object @@ -280,7 +282,8 @@ paths: title: Left rooms type: object description: |- - The rooms that the user has left or been banned from. + The rooms that the user has left or been banned from, mapped as room ID to + room information. additionalProperties: title: Left Room type: object diff --git a/changelogs/client_server/newsfragments/2345.clarification b/changelogs/client_server/newsfragments/2345.clarification new file mode 100644 index 00000000..9ddb8dd1 --- /dev/null +++ b/changelogs/client_server/newsfragments/2345.clarification @@ -0,0 +1 @@ +Clarify what the keys are for rooms in ``/sync``. From f012da17a164165c1f7b91dc13f507835e1a44be Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 5 Nov 2019 16:00:55 -0700 Subject: [PATCH 0885/1250] Explain why e2e previews are bad --- api/client-server/content-repo.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/client-server/content-repo.yaml b/api/client-server/content-repo.yaml index 577e63b8..d596dbda 100644 --- a/api/client-server/content-repo.yaml +++ b/api/client-server/content-repo.yaml @@ -346,7 +346,9 @@ paths: .. Note:: Clients should consider avoiding this endpoint for URLs posted in encrypted - rooms. + rooms. Encrypted rooms often contain more sensitive information the users + do not want to share with the homeserver, and this can mean that the URLs + being shared should also not be shared with the homeserver. operationId: getUrlPreview produces: ["application/json"] From e59bb20dc36b7620008407fa2d0f86f715ab9e48 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 5 Nov 2019 16:08:15 -0700 Subject: [PATCH 0886/1250] Try to clarify the filter information on /context --- api/client-server/event_context.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/api/client-server/event_context.yaml b/api/client-server/event_context.yaml index e0c74cbf..b1c9956c 100644 --- a/api/client-server/event_context.yaml +++ b/api/client-server/event_context.yaml @@ -63,10 +63,9 @@ paths: name: filter type: string description: |- - The ID of a filter created using the filter API or a filter JSON - object encoded as a string. The server will detect whether it is - an ID or a JSON object by whether the first character is a ``"{"`` - open brace. + A JSON ``RoomEventFilter`` to filter the returned events with. The + filter can be applied before or/and after the ``limit`` parameter - + whichever the homeserver prefers. See `Filtering <#filtering>`_ for more information. x-example: "66696p746572" From 3e035c917283c559966b6d6f5cc6d1180fa87cc6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 5 Nov 2019 16:14:04 -0700 Subject: [PATCH 0887/1250] Make room version 5 the default room version. As per [MSC2334](https://github.com/matrix-org/matrix-doc/pull/2334) --- specification/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/index.rst b/specification/index.rst index c337d417..728383ab 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -540,7 +540,7 @@ some other reason. Versions can switch between stable and unstable periodically for a variety of reasons, including discovered security vulnerabilities and age. Clients should not ask room administrators to upgrade their rooms if the room is -running a stable version. Servers SHOULD use room version 4 as the default room +running a stable version. Servers SHOULD use room version 5 as the default room version when creating new rooms. The available room versions are: From a1e5a96cf8eb00028f9ffb5b97f37c7e45d7fff6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 6 Nov 2019 10:42:08 -0700 Subject: [PATCH 0888/1250] Update api/client-server/event_context.yaml Co-Authored-By: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- api/client-server/event_context.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client-server/event_context.yaml b/api/client-server/event_context.yaml index b1c9956c..f76cbff1 100644 --- a/api/client-server/event_context.yaml +++ b/api/client-server/event_context.yaml @@ -64,7 +64,7 @@ paths: type: string description: |- A JSON ``RoomEventFilter`` to filter the returned events with. The - filter can be applied before or/and after the ``limit`` parameter - + filter may be applied before or/and after the ``limit`` parameter - whichever the homeserver prefers. See `Filtering <#filtering>`_ for more information. From 9f01850f7aa6fa6ec96f383716b1b0eff326e309 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 6 Nov 2019 10:43:11 -0700 Subject: [PATCH 0889/1250] Add some words about where the filter is applied --- api/client-server/event_context.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/api/client-server/event_context.yaml b/api/client-server/event_context.yaml index f76cbff1..5fbfc198 100644 --- a/api/client-server/event_context.yaml +++ b/api/client-server/event_context.yaml @@ -64,8 +64,10 @@ paths: type: string description: |- A JSON ``RoomEventFilter`` to filter the returned events with. The - filter may be applied before or/and after the ``limit`` parameter - - whichever the homeserver prefers. + filter is only applied to ``events_before``, ``events_after``, and + ``state``. It is not applied to the ``event`` itself. The filter may + be applied before or/and after the ``limit`` parameter - whichever the + homeserver prefers. See `Filtering <#filtering>`_ for more information. x-example: "66696p746572" From df202dd493252b053c2c5841dde0431b2ecadbca Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 6 Nov 2019 12:37:46 -0700 Subject: [PATCH 0890/1250] Identity Service r0.3.0 release --- changelogs/identity_service.rst | 17 +++++++++++++++++ .../identity_service/newsfragments/2254.feature | 1 - .../identity_service/newsfragments/2255.new | 1 - .../identity_service/newsfragments/2258.new | 1 - .../identity_service/newsfragments/2287.new | 1 - 5 files changed, 17 insertions(+), 4 deletions(-) delete mode 100644 changelogs/identity_service/newsfragments/2254.feature delete mode 100644 changelogs/identity_service/newsfragments/2255.new delete mode 100644 changelogs/identity_service/newsfragments/2258.new delete mode 100644 changelogs/identity_service/newsfragments/2287.new diff --git a/changelogs/identity_service.rst b/changelogs/identity_service.rst index cb06709d..7cccc0cf 100644 --- a/changelogs/identity_service.rst +++ b/changelogs/identity_service.rst @@ -1,3 +1,20 @@ +r0.3.0 +====== + +New Endpoints +------------- + +- Add ``/account``, ``/account/register``, and ``/account/logout`` to authenticate with the identity server. (`#2255 `_) +- Add endpoints for accepting and handling terms of service. (`#2258 `_) +- Add ``/hash_details`` and a new ``/lookup`` endpoint for performing hashed association lookups. (`#2287 `_) + + +Backwards Compatible Changes +---------------------------- + +- Deprecate the v1 API in favour of an authenticated v2 API. (`#2254 `_) + + r0.2.1 ====== diff --git a/changelogs/identity_service/newsfragments/2254.feature b/changelogs/identity_service/newsfragments/2254.feature deleted file mode 100644 index 089d01fe..00000000 --- a/changelogs/identity_service/newsfragments/2254.feature +++ /dev/null @@ -1 +0,0 @@ -Deprecate the v1 API in favour of an authenticated v2 API. diff --git a/changelogs/identity_service/newsfragments/2255.new b/changelogs/identity_service/newsfragments/2255.new deleted file mode 100644 index fcb6ba88..00000000 --- a/changelogs/identity_service/newsfragments/2255.new +++ /dev/null @@ -1 +0,0 @@ -Add ``/account``, ``/account/register``, and ``/account/logout`` to authenticate with the identity server. diff --git a/changelogs/identity_service/newsfragments/2258.new b/changelogs/identity_service/newsfragments/2258.new deleted file mode 100644 index 06b9efff..00000000 --- a/changelogs/identity_service/newsfragments/2258.new +++ /dev/null @@ -1 +0,0 @@ -Add endpoints for accepting and handling terms of service. diff --git a/changelogs/identity_service/newsfragments/2287.new b/changelogs/identity_service/newsfragments/2287.new deleted file mode 100644 index 7d575bc9..00000000 --- a/changelogs/identity_service/newsfragments/2287.new +++ /dev/null @@ -1 +0,0 @@ -Add ``/hash_details`` and a new ``/lookup`` endpoint for performing hashed association lookups. From f361c756d2a748d84d6c2f541909e47490a4200e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 6 Nov 2019 12:43:13 -0700 Subject: [PATCH 0891/1250] Client Server r0.6.0 release --- changelogs/client_server.rst | 44 +++++++++++++++++++ .../newsfragments/2125.clarification | 1 - .../newsfragments/2129.clarification | 1 - .../newsfragments/2131.clarification | 1 - .../newsfragments/2132.clarification | 1 - .../newsfragments/2133.clarification | 1 - .../newsfragments/2136.clarification | 1 - .../newsfragments/2148.clarification | 1 - .../newsfragments/2152.clarification | 1 - .../newsfragments/2157.clarification | 1 - .../newsfragments/2204.clarification | 1 - .../newsfragments/2215.clarification | 1 - .../newsfragments/2223.clarification | 1 - .../client_server/newsfragments/2234.feature | 1 - .../newsfragments/2247.clarification | 1 - .../client_server/newsfragments/2255.breaking | 1 - .../client_server/newsfragments/2279.feature | 1 - .../client_server/newsfragments/2281.feature | 1 - .../client_server/newsfragments/2282.new | 1 - .../client_server/newsfragments/2310.feature | 1 - .../newsfragments/2341.clarification | 1 - .../newsfragments/2342.clarification | 1 - .../newsfragments/2343.clarification | 1 - .../newsfragments/2344.clarification | 1 - .../newsfragments/2345.clarification | 1 - 25 files changed, 44 insertions(+), 24 deletions(-) delete mode 100644 changelogs/client_server/newsfragments/2125.clarification delete mode 100644 changelogs/client_server/newsfragments/2129.clarification delete mode 100644 changelogs/client_server/newsfragments/2131.clarification delete mode 100644 changelogs/client_server/newsfragments/2132.clarification delete mode 100644 changelogs/client_server/newsfragments/2133.clarification delete mode 100644 changelogs/client_server/newsfragments/2136.clarification delete mode 100644 changelogs/client_server/newsfragments/2148.clarification delete mode 100644 changelogs/client_server/newsfragments/2152.clarification delete mode 100644 changelogs/client_server/newsfragments/2157.clarification delete mode 100644 changelogs/client_server/newsfragments/2204.clarification delete mode 100644 changelogs/client_server/newsfragments/2215.clarification delete mode 100644 changelogs/client_server/newsfragments/2223.clarification delete mode 100644 changelogs/client_server/newsfragments/2234.feature delete mode 100644 changelogs/client_server/newsfragments/2247.clarification delete mode 100644 changelogs/client_server/newsfragments/2255.breaking delete mode 100644 changelogs/client_server/newsfragments/2279.feature delete mode 100644 changelogs/client_server/newsfragments/2281.feature delete mode 100644 changelogs/client_server/newsfragments/2282.new delete mode 100644 changelogs/client_server/newsfragments/2310.feature delete mode 100644 changelogs/client_server/newsfragments/2341.clarification delete mode 100644 changelogs/client_server/newsfragments/2342.clarification delete mode 100644 changelogs/client_server/newsfragments/2343.clarification delete mode 100644 changelogs/client_server/newsfragments/2344.clarification delete mode 100644 changelogs/client_server/newsfragments/2345.clarification diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index c56a1073..47686221 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -1,3 +1,47 @@ +r0.6.0 +====== + +Breaking Changes +---------------- + +- Add a required ``id_access_token`` to many places which require an ``id_server`` parameter. (`#2255 `_) + + +New Endpoints +------------- + +- Add ``POST /account/3pid/unbind`` for removing a 3PID from an identity server. (`#2282 `_) + + +Backwards Compatible Changes +---------------------------- + +- Add ``M_USER_DEACTIVATED`` error code. (`#2234 `_) +- Remove ``bind_msisdn`` and ``bind_email`` from ``/register`` now that the identity server's bind endpoint requires authentication. (`#2279 `_) +- Add ``m.identity_server`` account data for tracking the user's preferred identity server. (`#2281 `_) +- Deprecate ``id_server`` and make it optional in several places. (`#2310 `_) + + +Spec Clarifications +------------------- + +- Add missing format fields to ``m.room.message$m.notice`` schema. (`#2125 `_) +- Remove "required" designation from the ``url`` field of certain ``m.room.message`` msgtypes. (`#2129 `_) +- Fix various typos throughout the specification. (`#2131 `_, `#2136 `_, `#2148 `_, `#2215 `_) +- Clarify the distinction between ``m.key.verification.start`` and its ``m.sas.v1`` variant. (`#2132 `_) +- Fix link to Olm signing specification. (`#2133 `_) +- Clarify the conditions for the ``.m.rule.room_one_to_one`` push rule. (`#2152 `_) +- Clarify the encryption algorithms supported by the device of the device keys example. (`#2157 `_) +- Clarify that ``/rooms/:roomId/event/:eventId`` returns a Matrix error. (`#2204 `_) +- Add a missing ``state_key`` check on ``.m.rule.tombstone``. (`#2223 `_) +- Fix the ``m.room_key_request`` ``action`` value, setting it from ``cancel_request`` to ``request_cancellation``. (`#2247 `_) +- Clarify that the ``submit_url`` field is without authentication. (`#2341 `_) +- Clarify the expected phone number format. (`#2342 `_) +- Clarify that clients should consider not requesting URL previews in encrypted rooms. (`#2343 `_) +- Add missing information on how filters are meant to work with ``/context``. (`#2344 `_) +- Clarify what the keys are for rooms in ``/sync``. (`#2345 `_) + + r0.5.0 ====== diff --git a/changelogs/client_server/newsfragments/2125.clarification b/changelogs/client_server/newsfragments/2125.clarification deleted file mode 100644 index c71cdfff..00000000 --- a/changelogs/client_server/newsfragments/2125.clarification +++ /dev/null @@ -1 +0,0 @@ -Add missing format fields to ``m.room.message$m.notice`` schema. diff --git a/changelogs/client_server/newsfragments/2129.clarification b/changelogs/client_server/newsfragments/2129.clarification deleted file mode 100644 index 9d67deac..00000000 --- a/changelogs/client_server/newsfragments/2129.clarification +++ /dev/null @@ -1 +0,0 @@ -Remove "required" designation from the ``url`` field of certain ``m.room.message`` msgtypes. diff --git a/changelogs/client_server/newsfragments/2131.clarification b/changelogs/client_server/newsfragments/2131.clarification deleted file mode 100644 index 3ccb2333..00000000 --- a/changelogs/client_server/newsfragments/2131.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various typos throughout the specification. diff --git a/changelogs/client_server/newsfragments/2132.clarification b/changelogs/client_server/newsfragments/2132.clarification deleted file mode 100644 index b8a4cc8a..00000000 --- a/changelogs/client_server/newsfragments/2132.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify the distinction between ``m.key.verification.start`` and its ``m.sas.v1`` variant. diff --git a/changelogs/client_server/newsfragments/2133.clarification b/changelogs/client_server/newsfragments/2133.clarification deleted file mode 100644 index 3a003179..00000000 --- a/changelogs/client_server/newsfragments/2133.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix link to Olm signing specification. diff --git a/changelogs/client_server/newsfragments/2136.clarification b/changelogs/client_server/newsfragments/2136.clarification deleted file mode 100644 index 3ccb2333..00000000 --- a/changelogs/client_server/newsfragments/2136.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various typos throughout the specification. diff --git a/changelogs/client_server/newsfragments/2148.clarification b/changelogs/client_server/newsfragments/2148.clarification deleted file mode 100644 index 3ccb2333..00000000 --- a/changelogs/client_server/newsfragments/2148.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various typos throughout the specification. diff --git a/changelogs/client_server/newsfragments/2152.clarification b/changelogs/client_server/newsfragments/2152.clarification deleted file mode 100644 index 03fde9ff..00000000 --- a/changelogs/client_server/newsfragments/2152.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify the conditions for the ``.m.rule.room_one_to_one`` push rule. diff --git a/changelogs/client_server/newsfragments/2157.clarification b/changelogs/client_server/newsfragments/2157.clarification deleted file mode 100644 index 5c1d549b..00000000 --- a/changelogs/client_server/newsfragments/2157.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify the encryption algorithms supported by the device of the device keys example. diff --git a/changelogs/client_server/newsfragments/2204.clarification b/changelogs/client_server/newsfragments/2204.clarification deleted file mode 100644 index 7a66b08b..00000000 --- a/changelogs/client_server/newsfragments/2204.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that ``/rooms/:roomId/event/:eventId`` returns a Matrix error. diff --git a/changelogs/client_server/newsfragments/2215.clarification b/changelogs/client_server/newsfragments/2215.clarification deleted file mode 100644 index 3ccb2333..00000000 --- a/changelogs/client_server/newsfragments/2215.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various typos throughout the specification. diff --git a/changelogs/client_server/newsfragments/2223.clarification b/changelogs/client_server/newsfragments/2223.clarification deleted file mode 100644 index 165b7e13..00000000 --- a/changelogs/client_server/newsfragments/2223.clarification +++ /dev/null @@ -1 +0,0 @@ -Add a missing ``state_key`` check on ``.m.rule.tombstone``. diff --git a/changelogs/client_server/newsfragments/2234.feature b/changelogs/client_server/newsfragments/2234.feature deleted file mode 100644 index bb1883b3..00000000 --- a/changelogs/client_server/newsfragments/2234.feature +++ /dev/null @@ -1 +0,0 @@ -Add ``M_USER_DEACTIVATED`` error code. diff --git a/changelogs/client_server/newsfragments/2247.clarification b/changelogs/client_server/newsfragments/2247.clarification deleted file mode 100644 index 43553399..00000000 --- a/changelogs/client_server/newsfragments/2247.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix the ``m.room_key_request`` ``action`` value, setting it from ``cancel_request`` to ``request_cancellation``. diff --git a/changelogs/client_server/newsfragments/2255.breaking b/changelogs/client_server/newsfragments/2255.breaking deleted file mode 100644 index f9c8c6e1..00000000 --- a/changelogs/client_server/newsfragments/2255.breaking +++ /dev/null @@ -1 +0,0 @@ -Add a required ``id_access_token`` to many places which require an ``id_server`` parameter. diff --git a/changelogs/client_server/newsfragments/2279.feature b/changelogs/client_server/newsfragments/2279.feature deleted file mode 100644 index a1fdf168..00000000 --- a/changelogs/client_server/newsfragments/2279.feature +++ /dev/null @@ -1 +0,0 @@ -Remove ``bind_msisdn`` and ``bind_email`` from ``/register`` now that the identity server's bind endpoint requires authentication. diff --git a/changelogs/client_server/newsfragments/2281.feature b/changelogs/client_server/newsfragments/2281.feature deleted file mode 100644 index 7c235423..00000000 --- a/changelogs/client_server/newsfragments/2281.feature +++ /dev/null @@ -1 +0,0 @@ -Add ``m.identity_server`` account data for tracking the user's preferred identity server. diff --git a/changelogs/client_server/newsfragments/2282.new b/changelogs/client_server/newsfragments/2282.new deleted file mode 100644 index 3395758d..00000000 --- a/changelogs/client_server/newsfragments/2282.new +++ /dev/null @@ -1 +0,0 @@ -Add ``POST /account/3pid/unbind`` for removing a 3PID from an identity server. diff --git a/changelogs/client_server/newsfragments/2310.feature b/changelogs/client_server/newsfragments/2310.feature deleted file mode 100644 index 0169d23b..00000000 --- a/changelogs/client_server/newsfragments/2310.feature +++ /dev/null @@ -1 +0,0 @@ -Deprecate ``id_server`` and make it optional in several places. diff --git a/changelogs/client_server/newsfragments/2341.clarification b/changelogs/client_server/newsfragments/2341.clarification deleted file mode 100644 index a941db1b..00000000 --- a/changelogs/client_server/newsfragments/2341.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that the ``submit_url`` field is without authentication. diff --git a/changelogs/client_server/newsfragments/2342.clarification b/changelogs/client_server/newsfragments/2342.clarification deleted file mode 100644 index 09f4b191..00000000 --- a/changelogs/client_server/newsfragments/2342.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify the expected phone number format. diff --git a/changelogs/client_server/newsfragments/2343.clarification b/changelogs/client_server/newsfragments/2343.clarification deleted file mode 100644 index 5b16858b..00000000 --- a/changelogs/client_server/newsfragments/2343.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that clients should consider not requesting URL previews in encrypted rooms. diff --git a/changelogs/client_server/newsfragments/2344.clarification b/changelogs/client_server/newsfragments/2344.clarification deleted file mode 100644 index 8c92d31e..00000000 --- a/changelogs/client_server/newsfragments/2344.clarification +++ /dev/null @@ -1 +0,0 @@ -Add missing information on how filters are meant to work with ``/context``. diff --git a/changelogs/client_server/newsfragments/2345.clarification b/changelogs/client_server/newsfragments/2345.clarification deleted file mode 100644 index 9ddb8dd1..00000000 --- a/changelogs/client_server/newsfragments/2345.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify what the keys are for rooms in ``/sync``. From 50647e646e108d672eccbccae025791dbb29d038 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 6 Nov 2019 12:44:41 -0700 Subject: [PATCH 0892/1250] Add r0.6.0 to the list of spec versions. --- specification/client_server_api.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 7e420b8c..84cde946 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -45,6 +45,7 @@ Other versions of this specification The following other versions are also available, in reverse chronological order: - `HEAD `_: Includes all changes since the latest versioned release. +- `r0.6.0 `_ - `r0.5.0 `_ - `r0.4.0 `_ - `r0.3.0 `_ From 7351c0cd1e552e691ef338887d7112b72f6849c9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 6 Nov 2019 12:47:09 -0700 Subject: [PATCH 0893/1250] Add missing versions to identity spec --- specification/identity_service_api.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specification/identity_service_api.rst b/specification/identity_service_api.rst index f389cbc7..7e5a0f02 100644 --- a/specification/identity_service_api.rst +++ b/specification/identity_service_api.rst @@ -51,6 +51,8 @@ Other versions of this specification The following other versions are also available, in reverse chronological order: - `HEAD `_: Includes all changes since the latest versioned release. +- `r0.3.0 `_ +- `r0.2.1 `_ - `r0.2.0 `_ - `r0.1.0 `_ From 5b6d6fe498196735deed1397f377cc8d67bc65ce Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 7 Nov 2019 08:49:59 -0700 Subject: [PATCH 0894/1250] Update changelogs/client_server.rst Co-Authored-By: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- changelogs/client_server.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index 47686221..a5173fd0 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -4,7 +4,7 @@ r0.6.0 Breaking Changes ---------------- -- Add a required ``id_access_token`` to many places which require an ``id_server`` parameter. (`#2255 `_) +- Add ``id_access_token`` as a required request parameter to a few endpoints which require an ``id_server`` parameter as part of `MSC2140 `_. (`#2255 `_) New Endpoints From 5cc5908dd5ca6362314b14637d4fe1a03e6cb3e7 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 7 Nov 2019 18:45:29 -0500 Subject: [PATCH 0895/1250] Update proposals/1946-secure_server-side_storage.md Co-Authored-By: Matthew Hodgson --- proposals/1946-secure_server-side_storage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index 832144d1..4c5f9b4d 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -201,7 +201,7 @@ devices that it did not send an `m.secret.request` event to. Clients MUST ensure that they only share secrets with other devices that are allowed to see them. For example, clients SHOULD only share secrets with -devices that are verified and MAY prompt the user to confirm sharing the +the user’s own devices that are verified and MAY prompt the user to confirm sharing the secret. If a feature allows secrets to be stored or shared, then for consistency it From e8ce135a411e5fa2715f9d1cbd57f0fc232bc98f Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 7 Nov 2019 19:00:33 -0500 Subject: [PATCH 0896/1250] add clarification and examples --- proposals/1946-secure_server-side_storage.md | 29 ++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index 4c5f9b4d..aa4fd8f9 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -57,8 +57,9 @@ clients will try to use the default key to decrypt secrets. Clients MUST ensure that the key is trusted before using it to encrypt secrets. One way to do that is to have the client that creates the key sign the key description (as signed JSON) using the user's master cross-signing key. -Another way to do that is to prompt the user to enter the passphrase and ensure -that the generated private key correponds to the public key. +Another way to do that is to prompt the user to enter the passphrase used to +generate the encryption key and ensure that the generated private key +corresponds to the public key. #### Secret storage @@ -79,6 +80,8 @@ Example: Some secret is encrypted using keys with ID `key_id_1` and `key_id_2`: +`org.example.some.secret`: + ```json { "encrypted": { @@ -95,6 +98,28 @@ Some secret is encrypted using keys with ID `key_id_1` and `key_id_2`: } ``` +and the key descriptions for the keys would be: + +`m.secret_storage.key.key_id_1`: + +```json +{ + "name": "Some key", + "algorithm": "m.secret_storage.v1.curve25519-aes-sha2", + // ... other properties according to algorithm +} +``` + +`m.secret_storage.key.key_id_2`: + +```json +{ + "name": "Some other key", + "algorithm": "m.secret_storage.v1.curve25519-aes-sha2", + // ... other properties according to algorithm +} +``` + #### Encryption algorithms ##### `m.secret_storage.v1.curve25519-aes-sha2` From dcbdb94693edcff28efbb813302c90248258cbcc Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 8 Nov 2019 09:03:49 -0700 Subject: [PATCH 0897/1250] Add explanation --- proposals/2284-optional-identity-server-discovery.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/2284-optional-identity-server-discovery.md b/proposals/2284-optional-identity-server-discovery.md index 2da7018f..940f3381 100644 --- a/proposals/2284-optional-identity-server-discovery.md +++ b/proposals/2284-optional-identity-server-discovery.md @@ -2,7 +2,9 @@ Currently the specification requires that clients `FAIL_ERROR` (hard failure - do not continue) when the `.well-known` file for `m.identity_server` points to somewhere invalid or is invalid -itself. +itself. This can cause problems for clients if they either don't need an identity server to +function (and are forced to validate it anyways) or the client ends up having to disable all +their login UX because the identity server is misconfigured/down. This proposal aims to change that by allowing clients to make a conscious decision to continue with the invalid identity server configuration, provided the homeserver configuration is valid. From daa610659b334c25a68adfd6516ef086fa104013 Mon Sep 17 00:00:00 2001 From: Alexey Murz Korepov Date: Sun, 10 Nov 2019 16:45:01 +0300 Subject: [PATCH 0898/1250] =?UTF-8?q?Typo:=20later=20user=20=C2=BB=20later?= =?UTF-8?q?=20use?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- specification/modules/content_repo.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/content_repo.rst b/specification/modules/content_repo.rst index 1e3d1866..192250d2 100644 --- a/specification/modules/content_repo.rst +++ b/specification/modules/content_repo.rst @@ -19,7 +19,7 @@ Content repository .. _module:content: The content repository (or "media repository") allows users to upload -files to their homeserver for later user. For example, files which the +files to their homeserver for later use. For example, files which the user wants to send to a room would be uploaded here, as would an avatar the user wants to use. From fc793557f8d7e0a71ff671fb97b86d4529910e43 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 12 Nov 2019 10:48:38 -0500 Subject: [PATCH 0899/1250] make the default key event an object --- proposals/1946-secure_server-side_storage.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index aa4fd8f9..fd907e53 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -49,10 +49,11 @@ A key with ID `abcdefg` is stored in `m.secret_storage.key.abcdefg` ``` A key can be marked as the "default" key by setting the user's account_data -with event type `m.secret_storage.default_key` to the ID of the key. The -default key will be used to encrypt all secrets that the user would expect to -be available on all their clients. Unless the user specifies otherwise, -clients will try to use the default key to decrypt secrets. +with event type `m.secret_storage.default_key` to an object that has the ID of +the key as its `key` property. The default key will be used to encrypt all +secrets that the user would expect to be available on all their clients. +Unless the user specifies otherwise, clients will try to use the default key to +decrypt secrets. Clients MUST ensure that the key is trusted before using it to encrypt secrets. One way to do that is to have the client that creates the key sign the key From d93d8fe9b5237a787361b80be7c4885c51ca684c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 13 Nov 2019 10:36:41 -0700 Subject: [PATCH 0900/1250] Add a changelog --- changelogs/client_server/newsfragments/2351.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2351.clarification diff --git a/changelogs/client_server/newsfragments/2351.clarification b/changelogs/client_server/newsfragments/2351.clarification new file mode 100644 index 00000000..902a9c3f --- /dev/null +++ b/changelogs/client_server/newsfragments/2351.clarification @@ -0,0 +1 @@ +Fix various spelling errors throughout the specification. From f610235cd65392b1a63d8017cd78758d8f59dbda Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 18 Nov 2019 09:38:17 -0700 Subject: [PATCH 0901/1250] Rename the MSC to be better targeted --- ...sts.md => 2313-moderation-policy-rooms.md} | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) rename proposals/{2313-ban-lists.md => 2313-moderation-policy-rooms.md} (88%) diff --git a/proposals/2313-ban-lists.md b/proposals/2313-moderation-policy-rooms.md similarity index 88% rename from proposals/2313-ban-lists.md rename to proposals/2313-moderation-policy-rooms.md index ba0273a1..5899a233 100644 --- a/proposals/2313-ban-lists.md +++ b/proposals/2313-moderation-policy-rooms.md @@ -1,4 +1,4 @@ -# MSC2313: Ban lists +# MSC2313: Moderation policies as rooms (ban lists) Matrix is an open network and anyone can participate in it. As a result, a very wide range of content exists, and it is important to empower users to be @@ -9,8 +9,8 @@ which content they do not wish to host in their rooms and servers. The protocol's position in this solution should be one of neutrality: it should not be deciding what content is undesirable for any particular entity and should instead be empowering those entities to make their own decisions. This -proposal introduces ban lists as a basic mechanism to help users manage this -process, by providing a way of modelling sets of servers, rooms and users +proposal introduces "moderation policy rooms" as a basic mechanism to help users +manage this process, by providing a way of modelling sets of servers, rooms and users which can then be used to make filtering decisions. This proposal makes no attempt at interpreting the model and actually making those decisions however. @@ -18,18 +18,18 @@ To reaffirm: where this proposal says that some content is undesirable it does n bias the reader into what that could entail. Undesirability is purely in the hands of the entity perceiving the content. For example, someone who believes birthday cake is undesirable is perfectly valid in taking that position and is encouraged by this proposal to set up or -use a ban list which prevents birthday cake from coming across their field of view. +use a policy room which prevents birthday cake from coming across their field of view. ## Proposal -Ban lists are stored as room state events, allowing for structures and concepts to be reused without -defining a new room version. This proposal does not make any restrictions on how the rooms -are configured, just that the state events described here are represented in a room. For -example, a room which is invite only is just as valid as a room that is not: the important -details are specific state events and not the accessibility, retention, or other aspects -of the room. +Moderation policy lists, also known as ban lists in this proposal, are stored as room state events, +allowing for structures and concepts to be reused without defining a new room version. This +proposal does not make any restrictions on how the rooms are configured, just that the state +events described here are represented in a room. For example, a room which is invite only is +just as valid as a room that is not: the important details are specific state events and not +the accessibility, retention, or other aspects of the room. -Ban lists are stored as `m.room.rule.` state events, with state keys being arbitrary IDs +Ban lists are stored as `m.moderation.rule.` state events, with state keys being arbitrary IDs assigned by the sender. The `` is currently one of `user`, `room`, and `server`. Three fields are defined in `content`: @@ -48,7 +48,7 @@ An example set of minimal state events for banning `@alice:example.org`, `!matri ```json [ { - "type": "m.room.rule.user", + "type": "m.moderation.rule.user", "state_key": "rule_1", "content": { "entity": "@alice:example.org", @@ -57,7 +57,7 @@ An example set of minimal state events for banning `@alice:example.org`, `!matri } }, { - "type": "m.room.rule.room", + "type": "m.moderation.rule.room", "state_key": "rule_2", "content": { "entity": "!matrix:example.org", @@ -66,7 +66,7 @@ An example set of minimal state events for banning `@alice:example.org`, `!matri } }, { - "type": "m.room.rule.server", + "type": "m.moderation.rule.server", "state_key": "rule_3", "content": { "entity": "evil.example.org", @@ -75,7 +75,7 @@ An example set of minimal state events for banning `@alice:example.org`, `!matri } }, { - "type": "m.room.rule.server", + "type": "m.moderation.rule.server", "state_key": "rule_4", "content": { "entity": "*.evil.example.org", @@ -193,7 +193,7 @@ This proposal is partially implemented by [mjolnir](https://github.com/matrix-or using the `org.matrix.mjolnir.*` namespace until this becomes stable. This results in the following mappings: -* `m.room.rule.user` => `org.matrix.mjolnir.rule.user` -* `m.room.rule.room` => `org.matrix.mjolnir.rule.room` -* `m.room.rule.server` => `org.matrix.mjolnir.rule.server` +* `m.moderation.rule.user` => `org.matrix.mjolnir.rule.user` +* `m.moderation.rule.room` => `org.matrix.mjolnir.rule.room` +* `m.moderation.rule.server` => `org.matrix.mjolnir.rule.server` * `m.ban` => `org.matrix.mjolnir.ban` From c7b3d998537d21694a166b4a6a4cf0490ebc0cc2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 19 Nov 2019 11:53:07 -0700 Subject: [PATCH 0902/1250] m.policy.rule won the debate --- proposals/2313-moderation-policy-rooms.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/proposals/2313-moderation-policy-rooms.md b/proposals/2313-moderation-policy-rooms.md index 5899a233..0fe9d7b1 100644 --- a/proposals/2313-moderation-policy-rooms.md +++ b/proposals/2313-moderation-policy-rooms.md @@ -29,7 +29,7 @@ events described here are represented in a room. For example, a room which is in just as valid as a room that is not: the important details are specific state events and not the accessibility, retention, or other aspects of the room. -Ban lists are stored as `m.moderation.rule.` state events, with state keys being arbitrary IDs +Ban lists are stored as `m.policy.rule.` state events, with state keys being arbitrary IDs assigned by the sender. The `` is currently one of `user`, `room`, and `server`. Three fields are defined in `content`: @@ -48,7 +48,7 @@ An example set of minimal state events for banning `@alice:example.org`, `!matri ```json [ { - "type": "m.moderation.rule.user", + "type": "m.policy.rule.user", "state_key": "rule_1", "content": { "entity": "@alice:example.org", @@ -57,7 +57,7 @@ An example set of minimal state events for banning `@alice:example.org`, `!matri } }, { - "type": "m.moderation.rule.room", + "type": "m.policy.rule.room", "state_key": "rule_2", "content": { "entity": "!matrix:example.org", @@ -66,7 +66,7 @@ An example set of minimal state events for banning `@alice:example.org`, `!matri } }, { - "type": "m.moderation.rule.server", + "type": "m.policy.rule.server", "state_key": "rule_3", "content": { "entity": "evil.example.org", @@ -75,7 +75,7 @@ An example set of minimal state events for banning `@alice:example.org`, `!matri } }, { - "type": "m.moderation.rule.server", + "type": "m.policy.rule.server", "state_key": "rule_4", "content": { "entity": "*.evil.example.org", @@ -193,7 +193,7 @@ This proposal is partially implemented by [mjolnir](https://github.com/matrix-or using the `org.matrix.mjolnir.*` namespace until this becomes stable. This results in the following mappings: -* `m.moderation.rule.user` => `org.matrix.mjolnir.rule.user` -* `m.moderation.rule.room` => `org.matrix.mjolnir.rule.room` -* `m.moderation.rule.server` => `org.matrix.mjolnir.rule.server` +* `m.policy.rule.user` => `org.matrix.mjolnir.rule.user` +* `m.policy.rule.room` => `org.matrix.mjolnir.rule.room` +* `m.policy.rule.server` => `org.matrix.mjolnir.rule.server` * `m.ban` => `org.matrix.mjolnir.ban` From 3b2f897c7e7d5a5ff40e99228967c06b762861cf Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 20 Nov 2019 11:48:36 -0500 Subject: [PATCH 0903/1250] Apply suggestions from code review Co-Authored-By: Matthew Hodgson --- proposals/1756-cross-signing.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 72b74121..05e02a4f 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -69,11 +69,11 @@ keys, respectively. Currently, users will only be allowed to see * signatures made by their own master, self-signing or user-signing keys, * signatures made by their own devices about their own master key, -* signatures made by other users' self-signing keys about the other users' own +* signatures made by other users' self-signing keys about their own respective devices, -* signatures made by other users' master keys about the other users' +* signatures made by other users' master keys about their respective self-signing key, or -* signatures made by other users' devices about the other users' master keys. +* signatures made by other users' devices about their respective master keys. This is done in order to preserve the privacy of social connections. Future proposals may define mechanisms for distributing signatures to other users in @@ -84,7 +84,7 @@ order to allow for other web-of-trust use cases. Users who have verified individual devices may wish to migrate these verifications to use cross-signing instead. In order to aid with this, signatures of a user's master key, made by their own devices, may be uploaded -to the server. If another client sees that the user's master key has a valid +to the server. If another user's client sees that that a given user's master key has a valid signature from a device that was previously verified, then the client may choose to trust and sign the master key. The client should take precautions to ensure that a stolen device cannot be used to cause it to trust a malicious From 82260689c946dda84f5dc4231e50755e86226719 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 20 Nov 2019 11:55:10 -0500 Subject: [PATCH 0904/1250] add link to migrating from device verifications --- proposals/1756-cross-signing.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 05e02a4f..f4ae6011 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -73,7 +73,9 @@ Currently, users will only be allowed to see devices, * signatures made by other users' master keys about their respective self-signing key, or -* signatures made by other users' devices about their respective master keys. +* signatures made by other users' devices about their respective master keys + (these signatures are used for [migrating from device + verifications](#migrating-from-device-verifications)). This is done in order to preserve the privacy of social connections. Future proposals may define mechanisms for distributing signatures to other users in From 29745d04fb669ce2b23c470ca68f164eb05590f6 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 26 Nov 2019 11:19:57 +0000 Subject: [PATCH 0905/1250] erikj/msc_membership_reasons --- proposals/2367-membership-reasons.md | 77 ++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 proposals/2367-membership-reasons.md diff --git a/proposals/2367-membership-reasons.md b/proposals/2367-membership-reasons.md new file mode 100644 index 00000000..479fce34 --- /dev/null +++ b/proposals/2367-membership-reasons.md @@ -0,0 +1,77 @@ +# Allowing Reasons in all Membership Events + +Currently users can specify a reason for kicking or banning users in a room +that both the target and other users in a room can see. This is useful to +explain *why* an action without having to send separate messages. + +The proposal extends this to all events, including invites, invite rejections +and leaves for similar reasons. + +## Proposal + +Allow `reason` field to be specified for all of the following APIs: + +``` +POST /_matrix/client/r0/rooms/{roomId}/invite +POST /_matrix/client/r0/rooms/{roomId}/leave +POST /_matrix/client/r0/rooms/{roomId}/kick +POST /_matrix/client/r0/rooms/{roomId}/ban +POST /_matrix/client/r0/rooms/{roomId}/unban +POST /_matrix/client/r0/rooms/{roomId}/join +POST /_matrix/client/r0/join/{roomIdOrAlias} +``` + +If specified the `reason` field will be added to the generated membership +event's content. + +Clients may choose to display the reason for membership events in a room, +though may not do so if e.g. they have collapsed a set of membership changes. + +Clients should not display an invite reason by default to the invitee as this +allows a classic abuse and harassment vector. However, clients may wish to show +invite reasons from known¹ senders, or have a button that allows viewing any +invite reason. + +## Use Cases + +Some basic use cases and examples are given below. + +### Kick/ban + +Kicking and banning already allow specifying a reason to allow giving a reason +for the moderation action (e.g. "Banned for spamming"). + +### Leaving a Room + +A user may wish to leave a room e.g. because the room is no longer relevant +to them, allowing them to specify a reason means they can easily step out of +the room quietly without having to send a message to explain their actions. + +### Invite + +This can be useful to give some context for an invite, e.g. "Alice invites Bob +to get some feedback on the membership reasons MSC". + +### Rejecting an Invite + +If Alice has invited Bob (and many others) to a room to discuss going to a +concert then Bob may wish to simply reject the invite if he can't make it. +Adding a "will be out of town" reason to the rejection helps Alice to know why +her invite was rejected. + +### Joining room + +Adding a reason for joining could be used e.g. by automated bots to say why +they're joining. For example a bridge bot may join a room when asked to bridge +the room to an external network, in which case they may have a reason such as +"BridgeBot joined to bridge the room to RemoteNetwork at the request of Alice". + +## Potential Issues + +The main issue here is ensuring that the invite reason cannot be used as an +abuse vector, however if clients follow the recommendations above this concern +should be mitigated. + +--- + +¹ This is left up to implementations to decide, if they wish to do so. From f054ffe7607e4a15c52385d60b51dc1ffe74b5e2 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 26 Nov 2019 11:40:38 +0000 Subject: [PATCH 0906/1250] Add note about using PUT /state/m.room.member/ --- proposals/2367-membership-reasons.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/2367-membership-reasons.md b/proposals/2367-membership-reasons.md index 479fce34..b43c909c 100644 --- a/proposals/2367-membership-reasons.md +++ b/proposals/2367-membership-reasons.md @@ -19,11 +19,15 @@ POST /_matrix/client/r0/rooms/{roomId}/ban POST /_matrix/client/r0/rooms/{roomId}/unban POST /_matrix/client/r0/rooms/{roomId}/join POST /_matrix/client/r0/join/{roomIdOrAlias} +PUT /_matrix/client/r0/rooms/{roomId}/state/m.room.member/{userID} ``` If specified the `reason` field will be added to the generated membership event's content. +*Note: `/state/m.room.member` API currently allows this as clients can specify +arbitrary content already* + Clients may choose to display the reason for membership events in a room, though may not do so if e.g. they have collapsed a set of membership changes. From ad383351c2e5263556ee73ee95082e17c4ff2483 Mon Sep 17 00:00:00 2001 From: Isaiah Inuwa Date: Fri, 29 Nov 2019 10:16:23 -0600 Subject: [PATCH 0907/1250] Rename nonce to txn_id. Reorganize for clarity. Signed-Off-By: Isaiah Inuwa --- specification/client_server_api.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 84cde946..50ffff8f 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -740,22 +740,23 @@ To use this authentication type, clients should submit an auth dict as follows: "session": "" } -The ``nonce`` should be a random string generated by the client for the -request. The same ``nonce`` should be used if retrying the request. A client may receive a login ``token`` via some external service, such as email or SMS. Note that a login token is separate from an access token, the latter providing general authentication to various API endpoints. -The ``txn_id`` may be used by the server to disallow other devices from using -the token, thus providing "single use" tokens while still allowing the device -to retry the request. This would be done by tying the token to the ``txn_id`` +Additionally, the server must encode the user id in the ``token``; there is +therefore no need for the client to submit a separate username. + +The ``txn_id`` should be a random string generated by the client for the +request. The same ``txn_id`` should be used if retrying the request. The +``txn_id`` may be used by the server to disallow other devices from using the +token, thus providing "single use" tokens while still allowing the device to +retry the request. This would be done by tying the token to the ``txn_id`` server side, as well as potentially invalidating the token completely once the device has successfully logged in (e.g. when we receive a request from the newly provisioned access_token). -The server must encode the user id in the ``token``. There is therefore no need -for the client to submit a separate username. OAuth2-based <<<<<<<<<<<< From b7234c7fd34b4788f1a4158cff0148c028a652f2 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 29 Nov 2019 15:51:50 -0500 Subject: [PATCH 0908/1250] add unstable prefix section to proposal template --- proposals/0000-proposal-template.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/proposals/0000-proposal-template.md b/proposals/0000-proposal-template.md index cf79ed99..e50aed8b 100644 --- a/proposals/0000-proposal-template.md +++ b/proposals/0000-proposal-template.md @@ -93,3 +93,13 @@ of concerns where possible.* By having a template available, people would know what the desired detail for a proposal is. This is not considered a risk because it is important that people understand the proposal process from start to end. + +## Unstable prefix + +*If a proposal is implemented before it is included in the spec, then implementers must ensure that the +implementation is compatible with the final version that lands in the spec. This generally means that +experimental implementations should use `/unstable` endpoints, and use vendor prefixes where necessary. +For more information, see [MSC2324](https://github.com/matrix-org/matrix-doc/pull/2324). This section +should be used to document things such as what endpoints and names are being used while the feature is +in development, the name of the unstable feature flag to use to detect support for the feature, or what +migration steps are needed to switch to newer versions of the proposal.* From c549bf201bd85ca9630032bb5ae5af32d88cc879 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Mon, 2 Dec 2019 14:54:59 +0000 Subject: [PATCH 0909/1250] Clarify POST instead of GET for federation key query --- proposals/1756-cross-signing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index f4ae6011..98041987 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -216,12 +216,12 @@ response: } ``` -Similarly, the federation endpoints `GET /user/keys/query` and `POST +Similarly, the federation endpoints `POST /user/keys/query` and `POST /user/devices/{userId}` will include the master and self-signing keys. (It will not include the user-signing key because it is not intended to be visible to other users.) -`POST /keys/query` +`POST /user/keys/query` ``` json { From 71faffc9ed9bbdbe020101e3ff19543f034804e6 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Mon, 2 Dec 2019 14:59:48 +0000 Subject: [PATCH 0910/1250] Update example to show keys wrapped by user ID --- proposals/1756-cross-signing.md | 40 ++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 98041987..4b5904bc 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -432,27 +432,31 @@ response: } } }, - "master_key": { - "user_id": "@alice:example.com", - "usage": ["master"], - "keys": { - "ed25519:base64+master+public+key": "base64+master+public+key" - }, - "signatures": { - "@alice:example.com": { - "ed25519:HIJKLMN": "base64+signature+of+master+key" + "master_keys": { + "@alice:example.com": { + "user_id": "@alice:example.com", + "usage": ["master"], + "keys": { + "ed25519:base64+master+public+key": "base64+master+public+key" + }, + "signatures": { + "@alice:example.com": { + "ed25519:HIJKLMN": "base64+signature+of+master+key" + } } } }, - "self_signing_key": { - "user_id": "@alice:example.com", - "usage": ["self_signing"], - "keys": { - "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key" - }, - "signatures": { - "@alice:example.com": { - "ed25519:base64+master+public+key": "base64+signature" + "self_signing_keys": { + "@alice:example.com": { + "user_id": "@alice:example.com", + "usage": ["self_signing"], + "keys": { + "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key" + }, + "signatures": { + "@alice:example.com": { + "ed25519:base64+master+public+key": "base64+signature" + } } } } From 1cf322bc2a546a870a80f03297af020e802e7b43 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 3 Dec 2019 11:43:56 -0700 Subject: [PATCH 0911/1250] MSC2324: Facilitating early releases of software dependent on spec (#2324) --- proposals/2324-when-to-ship.md | 124 +++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 proposals/2324-when-to-ship.md diff --git a/proposals/2324-when-to-ship.md b/proposals/2324-when-to-ship.md new file mode 100644 index 00000000..1335bfab --- /dev/null +++ b/proposals/2324-when-to-ship.md @@ -0,0 +1,124 @@ +# MSC2324: Facilitating early releases of software dependent on spec + +*Note*: This is a process change MSC, not a change to the spec itself. + +There's currently an unanswered question by the spec process: when is it +safe to start using stable endpoints or to present a feature as "stable"? +Historically this question would receive very different answers depending +on who you asked, so in an effort to come up with a concise answer the +following process change is proposed. + +## Proposal + +The new process, from start to finish, is proposed as: + +1. Have an idea for a feature. +2. Optionally: implement the feature using unstable endpoints, vendor prefixes, + and unstable feature flags as appropriate. + * When using unstable endpoints, they MUST include a vendor prefix. For + example: `/_matrix/client/unstable/com.example/login`. Vendor prefixes + throughout this proposal always use the Java package naming convention. + * Unstable endpoints **do not** inherit from stable (`/r0`) APIs. Previously, + one could access the entirety of the Matrix API through `/unstable` however + this is generally considered a bad practice. Therefore an implementation + can no longer assume that because its feature-specific endpoint exists that + any other endpoint will exist in the same unstable namespace. + * If the client needs to be sure the server supports the feature, an unstable + feature flag that MUST be vendor prefixed is to be used. This kind of flag + shows up in the `unstable_features` field of `/versions` as, for example, + `com.example.new_login`. + * You can ship the feature at *any* time, so long as you are able to accept + the technical debt that results from needing to provide adequate backwards + and forwards compatibility for the vendor prefixed implementation. The + implementation MUST support the flag disappearing and be generally safe for + users. Note that implementations early in the MSC review process may also be + required to provide backwards compatibility with earlier editions of the + proposal. + * If you don't want to support the technical debt (or if it's impossible to + provide adequate backwards/forwards compatibility - e.g. a user authentication + change which can't be safely rolled back), do not implement the feature and + wait for Step 7. + * If at any point the idea changes, the feature flag should also change so + that implementations can adapt as needed. +3. In parallel, or ahead of implementation, open an MSC and solicit review. +4. Before a FCP (Final Comment Period) can be called, the Spec Core Team will + require that evidence to prove the MSC works be presented. A typical example + of this is an implementation of the MSC (which does not necessarily need to have been shipped anywhere). +5. FCP is gone through, and assuming nothing is flagged the MSC lands. +6. A spec PR is written to incorporate the changes into Matrix. +7. A spec release happens. +8. Implementations switch to using stable prefixes (e.g.: `/r0`) if the server + supports the specification version released. If the server doesn't advertise + the specification version, but does have the feature flag, unstable prefixes + should still be used. +9. A transition period of about 2 months starts immediately after the spec release, before + implementations start to loudly encourage other implementations to switch to stable + endpoints. For example, the Synapse team should start asking the Riot team to + support the stable endpoints (as per Step 8) 2 months after the spec release if they + haven't already. + +It's worth repeating that this process generally only applies if the implementation +wants to ship the feature ahead of the spec being available. By doing so, it takes +on the risk that the spec/MSC may change and it must adapt. If the implementation +is unable to take on that risk, or simply doesn't mind waiting, it should go through +the spec process without shipping an unstable implementation. + +To help MSCs get incorporated by implementations as stable features, the spec core +team plans to release the specification more often. How often is undefined and is +largely a case-by-case basis. + +To reiterate: + +* Implementations MUST NOT use stable endpoints before the MSC is in the spec. This + includes NOT using stable endpoints post-FCP. +* Implementations CAN ship features that are exposed by default to users before an + MSC has been merged to the spec, provided they follow the process above. +* Implementations SHOULD be wary of the technical debt they are incurring by moving + faster than the spec. + +To clarify: + +* The vendor prefix is chosen by the developer of the feature, using the Java package + naming convention. For example, `org.matrix` is the foundation's vendor prefix. +* The vendor prefixes, unstable feature flags, and unstable endpoints should be included + in the MSC so other developers can benefit. The MSC MUST still say what the stable + endpoints are to look like. + +### Specific examples outside of the client-server API + +There are some instances where a change might be made outside of the client-server API, +which is where much of this proposal is targetted. The general spirit of the process +should be followed where possible, if implementations decide to work ahead of spec releases. + +#### Room versions + +When a new room version is needed, implementations MUST use vendor-prefixed versions +before using the namespace reserved for Matrix (see https://matrix.org/docs/spec/#room-versions). +A room version is considered released once it is listed as an "available room version" in +the spec. Often a new room version is accompanied with a server-server API release, but +doesn't have to be. + +#### Server-server / Identity / Push / Appservice API + +These APIs don't yet have a `/versions` endpoint or similar. Typically behaviour changes in +these APIs are introduced with backwards compatibility in mind (try X and if that fails fall +back to Y) and therefore don't always need a flag to indicate support. If a flag were to +be required, an `unstable_features` or similar array would need to be exposed somewhere. + +#### Changes to request/response parameters + +Parameters being added to request/response bodies and query strings MUST be vendor-prefixed +per the proposed process. For example, a new JSON field might be `{"org.matrix.example": true}` +with the proposal being for `example` being added. A query string parameter would be prefixed +the same way: `?org.matrix.example=true`. + +If the MSC is simply adding fields to already-versioned endpoints, it does not need to put +the whole endpoint into the `/unstable` namespace provided the new parameters are prefixed +appropriately. + +#### .well-known and other APIs that can't be versioned + +Best effort is appreciated. Typically these endpoints will be receiving minor behavioural +changes or new fields. New fields should be appropriately prefixed, and behaviour changes +should be rolled out cautiously by implementations (waiting until after FCP has concluded +is probably best to ensure there's no major problems with the new behaviour). From c2ffef051f7c67028c41d5a87a25a712fa1e8fcf Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Thu, 5 Dec 2019 09:27:37 -0700 Subject: [PATCH 0912/1250] Clarify description of user directory Signed off by Stuart Mumford --- api/client-server/users.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client-server/users.yaml b/api/client-server/users.yaml index 98744719..da8cf03f 100644 --- a/api/client-server/users.yaml +++ b/api/client-server/users.yaml @@ -31,7 +31,7 @@ paths: post: summary: Searches the user directory. description: |- - Performs a search for users on the homeserver. The homeserver may + Performs a search for users. The homeserver may determine which subset of users are searched, however the homeserver MUST at a minimum consider the users the requesting user shares a room with and those who reside in public rooms (known to the homeserver). From 4d0bd5b9e206619ed7f3075d90f13a53be82b109 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sat, 7 Dec 2019 15:12:55 -0700 Subject: [PATCH 0913/1250] Changelog --- changelogs/client_server/newsfragments/2381.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2381.clarification diff --git a/changelogs/client_server/newsfragments/2381.clarification b/changelogs/client_server/newsfragments/2381.clarification new file mode 100644 index 00000000..70bd6d18 --- /dev/null +++ b/changelogs/client_server/newsfragments/2381.clarification @@ -0,0 +1 @@ +Minor clarification for what the user directory searches. From 7cfc4b09a69766c66484771918e804b7fed79e51 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sat, 7 Dec 2019 15:31:42 -0700 Subject: [PATCH 0914/1250] Changelog --- changelogs/client_server/newsfragments/2369.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2369.clarification diff --git a/changelogs/client_server/newsfragments/2369.clarification b/changelogs/client_server/newsfragments/2369.clarification new file mode 100644 index 00000000..c7fd0fd9 --- /dev/null +++ b/changelogs/client_server/newsfragments/2369.clarification @@ -0,0 +1 @@ +Minor clarifications to token-based User-Interactive Authentication. From ccc7bcabbc2625618bd884b641b78de1e52eba90 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sat, 7 Dec 2019 15:32:43 -0700 Subject: [PATCH 0915/1250] id -> ID while we're here --- specification/client_server_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 50ffff8f..eb32d3b4 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -745,7 +745,7 @@ A client may receive a login ``token`` via some external service, such as email or SMS. Note that a login token is separate from an access token, the latter providing general authentication to various API endpoints. -Additionally, the server must encode the user id in the ``token``; there is +Additionally, the server must encode the user ID in the ``token``; there is therefore no need for the client to submit a separate username. The ``txn_id`` should be a random string generated by the client for the From 47b94b62c48fee542e8c727069046d5bb6f235b2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sat, 7 Dec 2019 15:57:24 -0700 Subject: [PATCH 0916/1250] Add some github stuff (PR templates, funding) --- .github/FUNDING.yml | 2 ++ .../PULL_REQUEST_TEMPLATE/ready-proposal.md | 19 ++++++++++++++++++ .github/PULL_REQUEST_TEMPLATE/spec-change.md | 16 +++++++++++++++ .github/PULL_REQUEST_TEMPLATE/wip-proposal.md | 20 +++++++++++++++++++ 4 files changed, 57 insertions(+) create mode 100644 .github/FUNDING.yml create mode 100644 .github/PULL_REQUEST_TEMPLATE/ready-proposal.md create mode 100644 .github/PULL_REQUEST_TEMPLATE/spec-change.md create mode 100644 .github/PULL_REQUEST_TEMPLATE/wip-proposal.md diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..afc29f01 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +patreon: matrixdotorg +liberapay: matrixdotorg diff --git a/.github/PULL_REQUEST_TEMPLATE/ready-proposal.md b/.github/PULL_REQUEST_TEMPLATE/ready-proposal.md new file mode 100644 index 00000000..afa808b8 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/ready-proposal.md @@ -0,0 +1,19 @@ +--- +name: Proposal ready for review +about: A proposal that is ready for review by the core team and community. +title: '' +labels: proposal, proposal-in-review +assignees: '' + +--- + + + +### Pull Request Checklist + + + +* [ ] Pull request includes a [changelog file](https://github.com/matrix-org/matrix-doc/blob/master/CONTRIBUTING.rst#adding-to-the-changelog) +* [ ] Pull request includes a [sign off](https://github.com/matrix-org/matrix-doc/blob/master/CONTRIBUTING.rst#sign-off) +* [ ] Pull request includes ['Rendered' link](https://matrix.org/docs/spec/proposals#process) above. +* [ ] Pull request title and file name include this PR's number as the MSC number. diff --git a/.github/PULL_REQUEST_TEMPLATE/spec-change.md b/.github/PULL_REQUEST_TEMPLATE/spec-change.md new file mode 100644 index 00000000..d2f6e874 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/spec-change.md @@ -0,0 +1,16 @@ +--- +name: Spec clarification/not a proposal +about: A change that's not a spec proposal, such as a clarification to the spec itself. +title: '' +labels: '' +assignees: '' + +--- + +### Pull Request Checklist + + + +* [ ] Pull request includes a [changelog file](https://github.com/matrix-org/matrix-doc/blob/master/CONTRIBUTING.rst#adding-to-the-changelog) +* [ ] Pull request includes a [sign off](https://github.com/matrix-org/matrix-doc/blob/master/CONTRIBUTING.rst#sign-off) +* [ ] Pull request is classified as ['other changes'](https://github.com/matrix-org/matrix-doc/blob/master/CONTRIBUTING.rst#other-changes) diff --git a/.github/PULL_REQUEST_TEMPLATE/wip-proposal.md b/.github/PULL_REQUEST_TEMPLATE/wip-proposal.md new file mode 100644 index 00000000..34e26187 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/wip-proposal.md @@ -0,0 +1,20 @@ +--- +name: WIP Proposal +about: A proposal that isn't quite ready for formal review yet. +title: '[WIP] Your Proposal Title' +labels: proposal +assignees: '' + +--- + + + +### Pull Request Checklist + + + +* [ ] Pull request includes a [changelog file](https://github.com/matrix-org/matrix-doc/blob/master/CONTRIBUTING.rst#adding-to-the-changelog) +* [ ] Pull request includes a [sign off](https://github.com/matrix-org/matrix-doc/blob/master/CONTRIBUTING.rst#sign-off) +* [ ] A ['Rendered' link](https://matrix.org/docs/spec/proposals#process) above. +* [ ] Update the title and file name of your proposal to match this PR's number (after opening). +* [ ] Ask in [#matrix-spec:matrix.org](https://matrix.to/#/#matrix-spec:matrix.org) to get this marked as ready for review, once it is ready for review. From 3aba6e3eebc4a75051ab38046cb9b5815d84fc85 Mon Sep 17 00:00:00 2001 From: Carolin Beer Date: Sun, 15 Dec 2019 14:37:10 +0100 Subject: [PATCH 0917/1250] Change state_type to event_type I couldn't find any other reference to a state_type within the entire specification. I assume this is supposed to be the event_type? This aligns with the description of changes resulting from a state update. --- specification/rooms/v1.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index a720b41a..10eee54d 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -94,7 +94,7 @@ results of the resolution so far. 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 +``event_ids`` for the same ``(event_type, state_key)``. The events thus affected are said to be *conflicting* events. From e2e83b130d072f26f1e0384824288a2e63f99fab Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 16 Dec 2019 15:15:46 -0500 Subject: [PATCH 0918/1250] initial proposal for reporting of withheld keys --- proposals/xxxx-reporting-no-key-sent.md | 58 +++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 proposals/xxxx-reporting-no-key-sent.md diff --git a/proposals/xxxx-reporting-no-key-sent.md b/proposals/xxxx-reporting-no-key-sent.md new file mode 100644 index 00000000..79157f1d --- /dev/null +++ b/proposals/xxxx-reporting-no-key-sent.md @@ -0,0 +1,58 @@ +# Reporting that decryption keys are withheld + +When an encrypted message is sent in a room, the megolm key might not be +sent to all devices present in the room. Sometimes this may be inadvertent (for +example, if the sending device is not aware of some devices that have joined), +but some times, this may be purposeful. For example, the sender may have +blacklisted certain devices or users, or may be choosing to not send the megolm +key to devices that they have not verified yet. + +Currently, when this happens, there is no feedback given to the affected +devices; devices that have not received keys do not know why they did not +receive the key, and so cannot inform the user as to whether it is expected +that the message cannot be decrypted. To address this, senders can send a +message to devices indicating that they purposely did not send a megolm +key. + +A similar issue happens with keyshare requests; devices are not informed when +other devices decide not to send back keys, and so do not know whether to +expect to receive a key in response to the request. + +## Proposal + +Devices that purposely do not send megolm keys to a device may instead send an +`m.room_key.withheld` event as a to-device message to the device to indicate +that it should not expect to receive keys for the message. This message may +also be sent in reply to a `m.room_key_request`. The `m.room.no_key` event has +the properties: + +- `room_id`: Required. The ID of the room that the session belongs to. +- `session_id`: Required. The ID of the session. +- `code`: An machine-readable code for why the key was not sent. + Possible values are: + - `m.blacklisted`: the user/device was blacklisted + - `m.unverified`: the user/devices is unverified + - `m.unauthorised`: the user/device is not allowed have the key. For + example, this would usually be sent in response to a key request if the + user was not in the room when the message was sent + - `m.unavailable`: sent in reply to a key request if the device that the key + is requested from does not have the requested key +- `reason`: A human-readable reason for why the key was not sent. If there is + a `code`, this should be a human-readable representation of `code`. The + receiving client should only use this string if it does not understand the + `code` or if `code` is not provided. + +## Potential issues + +This does not handle all possible reasons why a device may not have received +megolm keys. + +## Security considerations + +A user might not want to notify another user of the reason why it was not sent +the keys. Sending `m.room_key.witheld`, or specifying the `reason`/`code` are +optional. + +## Unstable prefix + +While in development, clients will send events of type `org.matrix.room_key.witheld`. From e658b1707088887fe1d422a00c609cd1e92a4ab6 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 16 Dec 2019 15:47:03 -0500 Subject: [PATCH 0919/1250] initial version of spec for key backups --- .../definitions/key_backup_data.yaml | 50 ++ api/client-server/key_backup.yaml | 774 ++++++++++++++++++ .../modules/end_to_end_encryption.rst | 125 +++ 3 files changed, 949 insertions(+) create mode 100644 api/client-server/definitions/key_backup_data.yaml create mode 100644 api/client-server/key_backup.yaml diff --git a/api/client-server/definitions/key_backup_data.yaml b/api/client-server/definitions/key_backup_data.yaml new file mode 100644 index 00000000..5111a663 --- /dev/null +++ b/api/client-server/definitions/key_backup_data.yaml @@ -0,0 +1,50 @@ +# Copyright 2019 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: KeyBackupData +description: "The key data" +properties: + first_message_index: + description: |- + The index of the first message in the session that the key can decrypt. + type: integer + example: 1 + forwarded_count: + description: |- + The number of times this key has been forwarded. + type: integer + example: 0 + is_verified: + description: |- + Whether the device backing up the key was verified the device that the key + is from. + type: boolean + example: false + session_data: + description: |- + Algorithm-dependent data. See the documentation for the backup + algorithms in `Server-side key backups`_ for more information on the + expected format of the data. + type: object + example: { + "ephemeral": "base64+ephemeral+key", + "ciphertext": "base64+ciphertext+of+JSON+data", + "mac": "base64+mac+of+ciphertext" + } +required: + - first_message_index + - forwarded_count + - is_verified + - session_data diff --git a/api/client-server/key_backup.yaml b/api/client-server/key_backup.yaml new file mode 100644 index 00000000..c55b8f27 --- /dev/null +++ b/api/client-server/key_backup.yaml @@ -0,0 +1,774 @@ +# Copyright 2019 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. +swagger: '2.0' +info: + title: "Matrix Client-Server Key Backup 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: + "/room_keys/version": + post: + summary: Create a new backup. + description: |- + Creates a new backup + operationId: postRoomKeysVersion + security: + - accessToken: [] + parameters: + - in: body + name: version + description: "The backup configuration" + schema: + type: object + properties: + algorithm: + description: The algorithm used for storing backups. + type: string + enum: ["m.megolm_backup.v1.curve25519-aes-sha2"] + example: "m.megolm_backup.v1.curve25519-aes-sha2" + auth_data: + description: |- + Algorithm-dependent data. See the documentation for the backup + algorithms in `Server-side key backups`_ for more information on the + expected format of the data. + type: object + example: { + "public_key": "abcdefg", + "signatures": { + "@alice:example.org": { + "ed25519:deviceid": "signature" + } + } + } + required: + - algorithm + - auth_data + responses: + 200: + description: + The version of the new backup. + schema: + type: object + properties: + version: + type: string + description: The backup version + example: "1" + required: + - version + tags: + - End-to-end encryption + "/room_keys/version/{version}": + get: + summary: Get information about an existing backup. + description: |- + Get information about an existing backup. + operationId: getRoomKeysVersion + security: + - accessToken: [] + parameters: + - in: path + type: string + name: version + description: |- + Optional. The backup version to get. If omitted, the current backup + is returned. + required: false + x-example: "1" + responses: + 200: + description: + The information about the requested backup. + schema: + type: object + properties: + algorithm: + type: string + description: The algorithm used for storing backups. + type: string + enum: ["m.megolm_backup.v1.curve25519-aes-sha2"] + example: "m.megolm_backup.v1.curve25519-aes-sha2" + auth_data: + description: |- + Algorithm-dependent data. See the documentation for the backup + algorithms in `Server-side key backups`_ for more information on the + expected format of the data. + type: object + example: { + "public_key": "abcdefg", + "signatures": { + "@alice:example.org": { + "ed25519:deviceid": "signature" + } + } + } + count: + description: The number of key stored in the backup. + type: integer + example: 42 + etag: + description: |- + An opaque string representing stored keys in the backup. + Clients can compare it with the ``etag`` value they received + in the request of their last key storage request. If not + equal, another client has modified the backup. + type: string + example: "anopaquestring" + version: + type: string + description: The backup version + example: "1" + required: + - algorithm + - auth_data + - count + - etag + - version + 404: + description: + The backup specified does not exist + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } + schema: + "$ref": "definitions/errors/error.yaml" + tags: + - End-to-end encryption + put: + summary: Update information about an existing backup. + description: |- + Update information about an existing backup. Only ``auth_data`` can be modified. + operationId: putRoomKeysVersion + security: + - accessToken: [] + parameters: + - in: path + type: string + name: version + description: |- + The backup version to update. + required: true + x-example: "1" + - in: body + name: version + description: "The backup configuration" + schema: + type: object + properties: + algorithm: + description: |- + The algorithm used for storing backups. Must be the same as + the algorithm currently used by the backup. + type: string + enum: ["m.megolm_backup.v1.curve25519-aes-sha2"] + example: "m.megolm_backup.v1.curve25519-aes-sha2" + auth_data: + description: |- + Algorithm-dependent data. See the documentation for the backup + algorithms in `Server-side key backups`_ for more information on the + expected format of the data. + type: object + example: { + "public_key": "abcdefg", + "signatures": { + "@alice:example.org": { + "ed25519:deviceid": "signature" + } + } + } + version: + description: |- + The backup version. If present, must be the same as the + version in the path parameter. + type: string + example: "1" + required: + - algorithm + - auth_data + responses: + 200: + description: The update succeeded + schema: + type: object + properties: {} + 404: + description: The backup specified does not exist + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } + schema: + "$ref": "definitions/errors/error.yaml" + tags: + - End-to-end encryption + "/room_keys/keys/{roomId}/{sessionId}": + put: + summary: Store a key in the backup + description: |- + Store a key in the backup. + operationId: postRoomKeysKeyRoomIdSessionId + security: + - accessToken: [] + parameters: + - in: query + type: string + name: version + description: |- + The backup in which to store the key. Must be the current backup. + required: true + x-example: "1" + - in: path + type: string + name: roomId + description: The ID of the room that the key is for. + required: true + x-example: "!roomid:example.org" + - in: path + type: string + name: sessionId + description: The ID of the megolm session that the key is for. + required: true + x-example: "sessionid" + - in: body + name: data + description: "The key data" + schema: + "$ref": "definitions/key_backup_data.yaml" + responses: + 200: + description: The update succeeded + schema: + type: object + properties: + etag: + description: |- + The new etag value representing stored keys in the backup. + See ``GET /room_keys/version/{version}`` for more details. + type: string + example: "abcdefg" + count: + description: The number of keys stored in the backup + type: integer + example: 10 + required: + - etag + - count + 403: + description: |- + The version specified does not match the current backup version. + The current version will be included in the ``current_version`` + field. + examples: + application/json: { + "errcode": "M_WRONG_ROOM_KEYS_VERSION", + "error": "Wrong backup version.", + "current_version": "42" + } + schema: + "$ref": "definitions/errors/error.yaml" + tags: + - End-to-end encryption + get: + summary: Retrieve a key from the backup + description: |- + Retrieve a key from the backup. + operationId: getRoomKeysKeyRoomIdSessionId + security: + - accessToken: [] + parameters: + - in: query + type: string + name: version + description: |- + The backup from which to retrieve the key + required: true + x-example: "1" + - in: path + type: string + name: roomId + description: The ID of the room that the requested key is for. + required: true + x-example: "!roomid:example.org" + - in: path + type: string + name: sessionId + description: The ID of the megolm session whose key is requested. + required: true + x-example: "sessionid" + responses: + 200: + description: The key data + schema: + "$ref": "definitions/key_backup_data.yaml" + 404: + description: The key or backup was not found. + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "Key not found." + } + schema: + "$ref": "definitions/errors/error.yaml" + delete: + summary: Delete a key from the backup + description: |- + Delete a key from the backup. + operationId: deleteRoomKeysKeyRoomIdSessionId + security: + - accessToken: [] + parameters: + - in: query + type: string + name: version + description: |- + The backup from which to delete the key + required: true + x-example: "1" + - in: path + type: string + name: roomId + description: The ID of the room that the specified key is for. + required: true + x-example: "!roomid:example.org" + - in: path + type: string + name: sessionId + description: The ID of the megolm session whose key is to be deleted. + required: true + x-example: "sessionid" + responses: + 200: + description: The update succeeded + schema: + type: object + properties: + etag: + description: |- + The new etag value representing stored keys in the backup. + See ``GET /room_keys/version/{version}`` for more details. + type: string + example: "abcdefg" + count: + description: The number of keys stored in the backup + type: integer + example: 10 + required: + - etag + - count + 404: + description: |- + The backup was not found. + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } + schema: + "$ref": "definitions/errors/error.yaml" + "/room_keys/keys/{roomId}": + put: + summary: Store several keys in the backup for a given room. + description: |- + Store a key in the backup. + operationId: postRoomKeysKeyRoomId + security: + - accessToken: [] + parameters: + - in: query + type: string + name: version + description: |- + The backup in which to store the keys. Must be the current backup. + required: true + x-example: "1" + - in: path + type: string + name: roomId + description: The ID of the room that the keys are for. + required: true + x-example: "!roomid:example.org" + - in: body + description: "The backup data" + name: backupData + schema: + type: object + properties: + sessions: + type: object + description: |- + A map of session IDs to key data. + additionalProperties: + allOf: + - $ref: "definitions/key_backup_data.yaml" + example: { + "sessionid1": { + "ephemeral": "base64+ephemeral+key", + "ciphertext": "base64+ciphertext+of+JSON+data", + "mac": "base64+mac+of+ciphertext" + } + } + responses: + 200: + description: The update succeeded + schema: + type: object + properties: + etag: + description: |- + The new etag value representing stored keys in the backup. + See ``GET /room_keys/version/{version}`` for more details. + type: string + example: "abcdefg" + count: + description: The number of keys stored in the backup + type: integer + example: 10 + required: + - etag + - count + 403: + description: |- + The version specified does not match the current backup version. + The current version will be included in the ``current_version`` + field. + examples: + application/json: { + "errcode": "M_WRONG_ROOM_KEYS_VERSION", + "error": "Wrong backup version.", + "current_version": "42" + } + schema: + "$ref": "definitions/errors/error.yaml" + 404: + description: |- + The backup was not found. + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } + schema: + "$ref": "definitions/errors/error.yaml" + tags: + - End-to-end encryption + get: + summary: Retrieve the keys from the backup for a given room + description: |- + Retrieve the keys from the backup for a given room + operationId: getRoomKeysKeyRoomId + security: + - accessToken: [] + parameters: + - in: query + type: string + name: version + description: |- + The backup from which to retrieve the key + required: true + x-example: "1" + - in: path + type: string + name: roomId + description: The ID of the room that the requested key is for. + required: true + x-example: "!roomid:example.org" + responses: + 200: + description: |- + The key data. If no keys are found, then an object with an empty + ``sessions`` property will be returned (``{"sessions": {}}``). + schema: + type: object + properties: + sessions: + type: object + description: |- + A map of session IDs to key data. + additionalProperties: + allOf: + - $ref: "definitions/key_backup_data.yaml" + example: { + "sessionid1": { + "ephemeral": "base64+ephemeral+key", + "ciphertext": "base64+ciphertext+of+JSON+data", + "mac": "base64+mac+of+ciphertext" + } + } + 404: + description: |- + The backup was not found. + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } + schema: + "$ref": "definitions/errors/error.yaml" + delete: + summary: Delete a key from the backup + description: |- + Delete a key from the backup. + operationId: deleteRoomKeysKeyRoomId + security: + - accessToken: [] + parameters: + - in: query + type: string + name: version + description: |- + The backup from which to delete the key + required: true + x-example: "1" + - in: path + type: string + name: roomId + description: The ID of the room that the specified key is for. + required: true + x-example: "!roomid:example.org" + responses: + 200: + description: The update succeeded + schema: + type: object + properties: + etag: + description: |- + The new etag value representing stored keys in the backup. + See ``GET /room_keys/version/{version}`` for more details. + type: string + example: "abcdefg" + count: + description: The number of keys stored in the backup + type: integer + example: 10 + required: + - etag + - count + 404: + description: |- + The backup was not found. + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } + schema: + "$ref": "definitions/errors/error.yaml" + "/room_keys/keys": + put: + summary: Store several keys in the backup. + description: |- + Store several keys in the backup. + operationId: postRoomKeysKey + security: + - accessToken: [] + parameters: + - in: query + type: string + name: version + description: |- + The backup in which to store the keys. Must be the current backup. + required: true + x-example: "1" + - in: body + description: "The backup data" + name: backupData + schema: + type: object + properties: + rooms: + type: object + description: |- + A map of room IDs to session IDs to key data. + additionalProperties: + type: object + additionalProperties: + allOf: + - $ref: "definitions/key_backup_data.yaml" + example: { + "!room:example.org": { + "sessions": { + "sessionid1": { + "ephemeral": "base64+ephemeral+key", + "ciphertext": "base64+ciphertext+of+JSON+data", + "mac": "base64+mac+of+ciphertext" + } + } + } + } + responses: + 200: + description: The update succeeded + schema: + type: object + properties: + etag: + description: |- + The new etag value representing stored keys in the backup. + See ``GET /room_keys/version/{version}`` for more details. + type: string + example: "abcdefg" + count: + description: The number of keys stored in the backup + type: integer + example: 10 + required: + - etag + - count + 403: + description: |- + The version specified does not match the current backup version. + The current version will be included in the ``current_version`` + field. + examples: + application/json: { + "errcode": "M_WRONG_ROOM_KEYS_VERSION", + "error": "Wrong backup version.", + "current_version": "42" + } + schema: + "$ref": "definitions/errors/error.yaml" + 404: + description: |- + The backup was not found. + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } + schema: + "$ref": "definitions/errors/error.yaml" + tags: + - End-to-end encryption + get: + summary: Retrieve the keys from the backup for a given room + description: |- + Retrieve the keys from the backup for a given room + operationId: getRoomKeysKeyRoomId + security: + - accessToken: [] + parameters: + - in: query + type: string + name: version + description: |- + The backup from which to retrieve the keys. If omitted, the keys are + retrieved from the current backup. + x-example: "1" + - in: path + type: string + name: roomId + description: The ID of the room that the requested key is for. + required: true + x-example: "!roomid:example.org" + responses: + 200: + description: |- + The key data. If no keys are found, then an object with an empty + ``rooms`` property will be returned (``{"rooms": {}}``). + schema: + type: object + properties: + rooms: + type: object + description: |- + A map of room IDs to session IDs to key data. + additionalProperties: + type: object + additionalProperties: + allOf: + - $ref: "definitions/key_backup_data.yaml" + example: { + "!room:example.org": { + "sessions": { + "sessionid1": { + "ephemeral": "base64+ephemeral+key", + "ciphertext": "base64+ciphertext+of+JSON+data", + "mac": "base64+mac+of+ciphertext" + } + } + } + } + 404: + description: The backup was not found. + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version." + } + schema: + "$ref": "definitions/errors/error.yaml" + delete: + summary: Delete a key from the backup + description: |- + Delete a key from the backup. + operationId: deleteRoomKeysKeyRoomId + security: + - accessToken: [] + parameters: + - in: query + type: string + name: version + description: |- + The backup from which to delete the key + required: true + x-example: "1" + - in: path + type: string + name: roomId + description: The ID of the room that the specified key is for. + required: true + x-example: "!roomid:example.org" + responses: + 200: + description: The update succeeded + schema: + type: object + properties: + etag: + description: |- + The new etag value representing stored keys in the backup. + See ``GET /room_keys/version/{version}`` for more details. + type: string + example: "abcdefg" + count: + description: The number of keys stored in the backup + type: integer + example: 10 + required: + - etag + - count + 404: + description: |- + The backup was not found. + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } + schema: + "$ref": "definitions/errors/error.yaml" diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 7758e2c1..ce9ea4db 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -767,6 +767,126 @@ previously-received ``request`` message with the same ``request_id`` and A reasonable strategy is for a user's client to only send keys requested by the verified devices of the same user. +Server-side key backups +~~~~~~~~~~~~~~~~~~~~~~~ + +Devices may upload encrypted copies of keys to the server. When a device tries +to read a message that it does not have keys for, it may request the key from +the server and decrypt it. Backups are per-user, and users may replace backups +with new backups. + +In contrast with `Key requests`_, Server-side key backups do not require another +device to be online from which to request keys. However, as the session keys are +stored on the server encrypted, it requires users to enter a decryption key to +decrypt the session keys. + +To create a backup, a client will call ``POST /room_keys/version`` and define +how the keys are to be encrypted through the backup's ``auth_data``; other +clients can discover the backup by calling ``GET /room_keys/version``. Keys +are encrypted according to the backups ``auth_data`` and added to the backup by +calling ``PUT /room_keys/keys?version=$v`` or one of its variants, and can be +retrieved by calling ``GET /room_keys/keys?version=$v`` or one of its variants. +Backups can also be deleted using ``DELETE /room_keys/version``, or individual +keys can be deleted using ``DELETE /room_key/keys?version=$v`` or one of its +variants. + +Clients must only store keys in backups after they have ensured that the +``auth_data`` is trusted, either by checking the signatures on it, or by +deriving the public key from a private key that it obtained from a trusted +source. + +When a client uploads a key for a session that the server already has a key +for, the server will choose to either keep the existing key or replace it with +the new key based on the key metadata as follows: + +- if the keys have different values for ``is_verified``, then it will 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, then + it will keep the key with a lower ``forwarded_count``. + +Recovery key +<<<<<<<<<<<< + +If the recovery key (the private half of the backup encryption key) is +presented to the user to save, it is presented as a string constructed as +follows: + +1. The 256-bit curve25519 private key is prepended by the bytes ``0x8B`` and + ``0x01`` +2. All the bytes in the string above, including the two header bytes, are XORed + together to form a parity byte. This parity byte is appended to the byte + string. +3. The byte string is encoded using base58, using the same mapping as is used + for Bitcoin addresses. +4. A space should be added after every 4th character. + +When reading in a recovery key, clients must disregard whitespace, and perform +the reverse of steps 1 through 3. + +Backup algorithm: ``m.megolm_backup.v1.curve25519-aes-sha2`` +<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + +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`` + +.. table:: + :widths: auto + + ========== =========== ====================================================== + Parameter Type Description + ========== =========== ====================================================== + public_key string Required. The curve25519 public key used to encrypt + the backups, encoded in unpadded base64. + signatures {string: Optional. Signatures of the ``auth_data``, as Signed + {string: JSON + string}} + ========== =========== ====================================================== + +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: + + .. table:: + :widths: auto + + =============================== ======== ========================================= + 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``. + sender_key string Required. Unpadded base64-encoded + device curve25519 key. + sender_claimed_keys {string: Required. Object containing the + string} identity key for the sending device. + forwarding_curve25519_key_chain [string] Required. Zero or more curve25519 keys + for devices who forwarded the session key. + session_key string Required. Unpadded base64-encoded + session key in `session-sharing format + `_. + =============================== ======== ========================================= + +2. Generate an ephemeral curve25519 key, and perform an ECDH with the ephemeral + key and the backup's public key to generate a shared secret. The public + half of the ephemeral key, encoded using unpadded base64, becomes the ``ephemeral`` + property of the ``session_data``. +3. Using the shared secret, generate 80 bytes by performing an HKDF using + SHA-256 as the hash, with a salt of 32 bytes of 0, and with the empty string + as the info. The first 32 bytes are used as the AES key, the next 32 bytes + are used as the MAC key, and the last 16 bytes are used as the AES + initialization vector. +4. Stringify the JSON object, and encrypt it using AES-CBC-256 with PKCS#7 + padding. This encrypted data, encoded using unpadded base64, becomes the + ``ciphertext`` property of the ``session_data``. +5. Pass the raw encrypted data (prior to base64 encoding) through HMAC-SHA-256 + using the MAC key generated above. The first 8 bytes of the resulting MAC + are base64-encoded, and become the ``mac`` property of the ``session_data``. + Key exports ~~~~~~~~~~~ @@ -1089,6 +1209,11 @@ Key management API {{keys_cs_http_api}} +Key Backup API +~~~~~~~~~~~~~~ + +{{key_backup_cs_http_api}} + .. anchor for link from /sync api spec .. |device_lists_sync| replace:: End-to-end encryption From 59e337187b97fa5eb1a8349477577e12019331bd Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 16 Dec 2019 15:54:42 -0500 Subject: [PATCH 0920/1250] remove duplicated line --- api/client-server/key_backup.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/api/client-server/key_backup.yaml b/api/client-server/key_backup.yaml index c55b8f27..5d7050a8 100644 --- a/api/client-server/key_backup.yaml +++ b/api/client-server/key_backup.yaml @@ -106,7 +106,6 @@ paths: algorithm: type: string description: The algorithm used for storing backups. - type: string enum: ["m.megolm_backup.v1.curve25519-aes-sha2"] example: "m.megolm_backup.v1.curve25519-aes-sha2" auth_data: From 4cde800ea10df3e34c359a6e878e1252bd81bdba Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 16 Dec 2019 17:25:20 -0500 Subject: [PATCH 0921/1250] fix validation errors --- api/client-server/key_backup.yaml | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/api/client-server/key_backup.yaml b/api/client-server/key_backup.yaml index 5d7050a8..3663731e 100644 --- a/api/client-server/key_backup.yaml +++ b/api/client-server/key_backup.yaml @@ -92,9 +92,9 @@ paths: type: string name: version description: |- - Optional. The backup version to get. If omitted, the current backup - is returned. - required: false + The backup version to get. When an empty string, the trailing slash + is optional, and the current backup is returned. + required: true x-example: "1" responses: 200: @@ -678,12 +678,6 @@ paths: The backup from which to retrieve the keys. If omitted, the keys are retrieved from the current backup. x-example: "1" - - in: path - type: string - name: roomId - description: The ID of the room that the requested key is for. - required: true - x-example: "!roomid:example.org" responses: 200: description: |- @@ -736,12 +730,6 @@ paths: The backup from which to delete the key required: true x-example: "1" - - in: path - type: string - name: roomId - description: The ID of the room that the specified key is for. - required: true - x-example: "!roomid:example.org" responses: 200: description: The update succeeded From 90bf2b3b46c17d44c36472a3aebed8e6734f0c87 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 16 Dec 2019 17:40:05 -0500 Subject: [PATCH 0922/1250] add changelog --- changelogs/client_server/2387.new | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/2387.new diff --git a/changelogs/client_server/2387.new b/changelogs/client_server/2387.new new file mode 100644 index 00000000..a709a5fa --- /dev/null +++ b/changelogs/client_server/2387.new @@ -0,0 +1 @@ +Add key backup (``/room_keys/*``) endpoints. From a62c817745bc393a2023810ac502251b5a7f5d7c Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 17 Dec 2019 11:07:04 -0500 Subject: [PATCH 0923/1250] Apply suggestions from code review Co-Authored-By: Matthew Hodgson --- api/client-server/definitions/key_backup_data.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/client-server/definitions/key_backup_data.yaml b/api/client-server/definitions/key_backup_data.yaml index 5111a663..8f8de999 100644 --- a/api/client-server/definitions/key_backup_data.yaml +++ b/api/client-server/definitions/key_backup_data.yaml @@ -23,12 +23,12 @@ properties: example: 1 forwarded_count: description: |- - The number of times this key has been forwarded. + The number of times this key has been forwarded via key-sharing between devices. type: integer example: 0 is_verified: description: |- - Whether the device backing up the key was verified the device that the key + Whether the device backing up the key verified the device that the key is from. type: boolean example: false From 912b3cbc95734a4b301375afce0241078d4bb89d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 30 Dec 2019 16:29:56 -0700 Subject: [PATCH 0924/1250] Move auth events selection to a more appropriate section of the spec This was pretty buried, and feels like a common question. --- .../newsfragments/2392.clarification | 1 + specification/server_server_api.rst | 44 ++++++++++--------- 2 files changed, 25 insertions(+), 20 deletions(-) create mode 100644 changelogs/server_server/newsfragments/2392.clarification diff --git a/changelogs/server_server/newsfragments/2392.clarification b/changelogs/server_server/newsfragments/2392.clarification new file mode 100644 index 00000000..b09420e4 --- /dev/null +++ b/changelogs/server_server/newsfragments/2392.clarification @@ -0,0 +1 @@ +Move auth event selection to a more obvious location. diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 62f6916a..a3a57dbf 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -391,28 +391,9 @@ creating a new event in this room should populate the new event's | E4 -.. _`auth events selection`: - -The ``auth_events`` field of a PDU identifies the set of events which give the -sender permission to send the event. The ``auth_events`` for the -``m.room.create`` event in a room is empty; for other events, it should be the -following subset of the room state: - -- The ``m.room.create`` event. -- The current ``m.room.power_levels`` event, if any. -- The sender's current ``m.room.member`` event, if any. -- If type is ``m.room.member``: - - - The target's current ``m.room.member`` event, if any. - - If ``membership`` is ``join`` or ``invite``, the current - ``m.room.join_rules`` event, if any. - - If membership is ``invite`` and ``content`` contains a - ``third_party_invite`` property, the current - ``m.room.third_party_invite`` event with ``state_key`` matching - ``content.third_party_invite.signed.token``, if any. - For a full schema of what a PDU looks like, see the `room version specification`_. + Checks performed on receipt of a PDU ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -466,6 +447,29 @@ specified above. Each room version can have a different algorithm for how the rules work, and which rules are applied. For more detailed information, please see the `room version specification`_. + +Auth events selection +^^^^^^^^^^^^^^^^^^^^^ + +The ``auth_events`` field of a PDU identifies the set of events which give the +sender permission to send the event. The ``auth_events`` for the +``m.room.create`` event in a room is empty; for other events, it should be the +following subset of the room state: + +- The ``m.room.create`` event. +- The current ``m.room.power_levels`` event, if any. +- The sender's current ``m.room.member`` event, if any. +- If type is ``m.room.member``: + + - The target's current ``m.room.member`` event, if any. + - If ``membership`` is ``join`` or ``invite``, the current + ``m.room.join_rules`` event, if any. + - If membership is ``invite`` and ``content`` contains a + ``third_party_invite`` property, the current + ``m.room.third_party_invite`` event with ``state_key`` matching + ``content.third_party_invite.signed.token``, if any. + + Rejection +++++++++ From f59aa563dd6626bbff56bae92d4af82cb56a367f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 1 Jan 2020 11:59:37 -0700 Subject: [PATCH 0925/1250] Add missing tags to push rules endpoints Without the tags, the endpoints don't end up in the swagger. No changelog for this because it doesn't affect the spec itself. --- api/client-server/pushrules.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/client-server/pushrules.yaml b/api/client-server/pushrules.yaml index a1cbc354..32c3c9a1 100644 --- a/api/client-server/pushrules.yaml +++ b/api/client-server/pushrules.yaml @@ -498,6 +498,8 @@ paths: type: boolean description: Whether the push rule is enabled or not. required: ["enabled"] + tags: + - Push notifications put: summary: "Enable or disable a push rule." description: |- @@ -601,6 +603,8 @@ paths: items: type: string required: ["actions"] + tags: + - Push notifications put: summary: "Set the actions for a push rule." description: |- From 82a626a98a0f6b9ad6cf8db14576c3c10dfa54d2 Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Thu, 2 Jan 2020 02:30:24 -0600 Subject: [PATCH 0926/1250] Fix link to v4 event ID format in identity service spec Signed-off-by: Aaron Raimist --- specification/identity_service_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/identity_service_api.rst b/specification/identity_service_api.rst index 7e5a0f02..704f763e 100644 --- a/specification/identity_service_api.rst +++ b/specification/identity_service_api.rst @@ -336,7 +336,7 @@ it would first format the query as ``alice@example.org email ThePepperGoesHere`` After formatting each query, the string is run through SHA-256 as defined by `RFC 4634 `_. The resulting bytes are then encoded using URL-Safe `Unpadded Base64`_ (similar to `room version 4's -event ID format <../../rooms/v4.html#event-ids>`_). +event ID format <../rooms/v4.html#event-ids>`_). An example set of queries when using the pepper ``matrixrocks`` would be:: From c87802587a4320610c13cba00f0978faf8f3a2f6 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 2 Jan 2020 17:02:19 -0500 Subject: [PATCH 0927/1250] fix typos, add information --- proposals/xxxx-reporting-no-key-sent.md | 32 +++++++++++++++++++++---- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/proposals/xxxx-reporting-no-key-sent.md b/proposals/xxxx-reporting-no-key-sent.md index 79157f1d..46ec8c7f 100644 --- a/proposals/xxxx-reporting-no-key-sent.md +++ b/proposals/xxxx-reporting-no-key-sent.md @@ -26,9 +26,12 @@ that it should not expect to receive keys for the message. This message may also be sent in reply to a `m.room_key_request`. The `m.room.no_key` event has the properties: -- `room_id`: Required. The ID of the room that the session belongs to. -- `session_id`: Required. The ID of the session. -- `code`: An machine-readable code for why the key was not sent. +- `room_id`: Required if `code` is not `m.no_olm`. The ID of the room that the + session belongs to. +- `algorithm`: Required. The encryption algorithm that the key is for. +- `session_id`: Required if `code` is not `m.no_olm`. The ID of the session. +- `sender_key`: Required. The key of the session creator. +- `code`: A machine-readable code for why the key was not sent. Possible values are: - `m.blacklisted`: the user/device was blacklisted - `m.unverified`: the user/devices is unverified @@ -37,11 +40,29 @@ the properties: user was not in the room when the message was sent - `m.unavailable`: sent in reply to a key request if the device that the key is requested from does not have the requested key + - `m.no_olm`: an olm session could not be established. This may happen, for + example, if the sender was unable to obtain a one-time key from the + recipient. - `reason`: A human-readable reason for why the key was not sent. If there is a `code`, this should be a human-readable representation of `code`. The receiving client should only use this string if it does not understand the `code` or if `code` is not provided. +An `m.room_key.withheld` event should only be sent once per session; the +recipient of the event should assume that the event applies to all messages in +that session. If a sender unblocks a recipient, it may re-use the existing +session for which the recipient was previously informed that it was blocked, in +which case, the recipient of the `m.room_key.withheld` message should assume +that the event applies to all messages in the session prior to the index of the +first key that it has received for that session. + +A `code` of `m.no_olm` is used to indicate that the sender is unable to +establish an olm session with the recipient. When this happens, multiple +sessions will be affected. In order to avoid filling the recipient's device +mailbox, the sender should only send one `m.room_key.withheld` message with no +`room_id` nor `session_id` set. FIXME: how does the recipient determine which +sessions the notification applies to? + ## Potential issues This does not handle all possible reasons why a device may not have received @@ -50,9 +71,10 @@ megolm keys. ## Security considerations A user might not want to notify another user of the reason why it was not sent -the keys. Sending `m.room_key.witheld`, or specifying the `reason`/`code` are +the keys. Sending `m.room_key.withheld`, or specifying the `reason`/`code` are optional. ## Unstable prefix -While in development, clients will send events of type `org.matrix.room_key.witheld`. +While in development, clients will send events of type +`org.matrix.room_key.withheld`. From 654a9574bedd540d8a5547ab24fbd67319a039e2 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 2 Jan 2020 17:05:12 -0500 Subject: [PATCH 0928/1250] rename to match MSC number --- ...xxx-reporting-no-key-sent.md => 2399-reporting-no-key-sent.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/{xxxx-reporting-no-key-sent.md => 2399-reporting-no-key-sent.md} (100%) diff --git a/proposals/xxxx-reporting-no-key-sent.md b/proposals/2399-reporting-no-key-sent.md similarity index 100% rename from proposals/xxxx-reporting-no-key-sent.md rename to proposals/2399-reporting-no-key-sent.md From 8e888b916cdb00fdaed76810bc9a5abc0a9b19bd Mon Sep 17 00:00:00 2001 From: Isaiah Inuwa Date: Sat, 18 Jan 2020 09:09:42 -0600 Subject: [PATCH 0929/1250] Fix spelling mistakes. --- api/client-server/definitions/request_email_validation.yaml | 2 +- api/client-server/definitions/request_msisdn_validation.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/client-server/definitions/request_email_validation.yaml b/api/client-server/definitions/request_email_validation.yaml index 2d789d05..d24c42b5 100644 --- a/api/client-server/definitions/request_email_validation.yaml +++ b/api/client-server/definitions/request_email_validation.yaml @@ -23,7 +23,7 @@ allOf: include a port. This parameter is ignored when the homeserver handles 3PID verification. - This parameter is deprected with a plan to be removed in a future specification + This parameter is deprecated with a plan to be removed in a future specification version for ``/account/password`` and ``/register`` requests. example: "id.example.com" id_access_token: diff --git a/api/client-server/definitions/request_msisdn_validation.yaml b/api/client-server/definitions/request_msisdn_validation.yaml index 54988fd4..54897e63 100644 --- a/api/client-server/definitions/request_msisdn_validation.yaml +++ b/api/client-server/definitions/request_msisdn_validation.yaml @@ -23,7 +23,7 @@ allOf: include a port. This parameter is ignored when the homeserver handles 3PID verification. - This parameter is deprected with a plan to be removed in a future specification + This parameter is deprecated with a plan to be removed in a future specification version for ``/account/password`` and ``/register`` requests. example: "id.example.com" id_access_token: From 715d2d674b42ba982c3f06543bcbc3fb0cb736f9 Mon Sep 17 00:00:00 2001 From: Isaiah Inuwa Date: Sat, 18 Jan 2020 14:12:24 -0600 Subject: [PATCH 0930/1250] Add changelog for spelling. --- changelogs/client_server/newsfragments/2415.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2415.clarification diff --git a/changelogs/client_server/newsfragments/2415.clarification b/changelogs/client_server/newsfragments/2415.clarification new file mode 100644 index 00000000..d1a7dbfe --- /dev/null +++ b/changelogs/client_server/newsfragments/2415.clarification @@ -0,0 +1 @@ +Fix misspelling of _deprecated_. \ No newline at end of file From b47de28da543f165795812afa366cacd64211a01 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 24 Jan 2020 00:40:33 +0100 Subject: [PATCH 0931/1250] MSC2422: Allow color on font tag Signed-off-by: Nicolas Werner --- .../2422-allow-color-attribute-on-font-tag.md | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 proposals/2422-allow-color-attribute-on-font-tag.md diff --git a/proposals/2422-allow-color-attribute-on-font-tag.md b/proposals/2422-allow-color-attribute-on-font-tag.md new file mode 100644 index 00000000..4287a696 --- /dev/null +++ b/proposals/2422-allow-color-attribute-on-font-tag.md @@ -0,0 +1,38 @@ +# MSC2422: Allow `color` as attribute for `` in messages + +Currently the spec requires you to use `data-mx-color` instead of the standard +`color` html attribute for the `` tag. This is probably done to make it +consistent with ``, where you may not want to allow a generic style tag for. + +On the other hand the /rainbow command on almost every client just uses the +`color` attribute of the `` tag. While some clients support +`data-mx-color` (i.e. Riot Web), most clients don't. Most clients support +rendering `color` however. + +It would probably be for the best to allow or even prefer `color` on the +`` tag. + +## Proposal + +Add the `color` attribute to the allowed attributes of `` in section +13.2.1.7. Allow only hexcodes as allowed value for this attribute for now. + +## Potential issues + +- We now have a redundant attribute in the spec. While it matches, what the + clients currently do, it may be better to fix each client instead. +- Clients may not sanitize the color attribute and will let other color values + through, increasing compatibility issues again. +- Clients may never support the data-mx-* attributes now. +- Old messages could loose their color +- This proposal doesn't touch span at all, maybe it should? + +## Alternatives + +- fix the clients +- remove the `data-mx-color` and `data-mx-bg-color` attributes entirely, leaving + us just with `color` for `` +- Add a section to tell the clients to prefer `color` over `mx-data-color` +- Spec an entirely different format for messages (that would probably not make + this proposal obsolete) + From 2e2f1c1174e4487d79b23f2cb9604f62066dd0c6 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Tue, 4 Feb 2020 16:50:50 +0000 Subject: [PATCH 0932/1250] Extend the scope of casefolding to the whole address --- proposals/2265-email-lowercase.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/2265-email-lowercase.md b/proposals/2265-email-lowercase.md index 935e6f2c..5a1db682 100644 --- a/proposals/2265-email-lowercase.md +++ b/proposals/2265-email-lowercase.md @@ -1,4 +1,4 @@ -# Proposal for mandating case folding when processing e-mail address localparts +# Proposal for mandating case folding when processing e-mail addresses [RFC822](https://tools.ietf.org/html/rfc822#section-3.4.7) mandates that localparts in e-mail addresses must be processed with the original case @@ -22,8 +22,8 @@ Sydent. This proposal suggests changing the specification of the e-mail 3PID type in [the Matrix spec appendices](https://matrix.org/docs/spec/appendices#pid-types) -to mandate that, before any processing, e-mail address localparts must go -through a full case folding based on [the unicode mapping +to mandate that, before any processing, e-mail addresses must go through a full +case folding based on [the unicode mapping file](https://www.unicode.org/Public/8.0.0/ucd/CaseFolding.txt), on top of having their domain lowercased. From 6911171e83fbf322e42565f1f6a217ea24d73924 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 5 Feb 2020 22:29:56 +0100 Subject: [PATCH 0933/1250] Fix key export format example Signed-off-by: Nicolas Werner --- .../newsfragments/2430.clarification | 1 + .../modules/end_to_end_encryption.rst | 32 +++++++++---------- 2 files changed, 16 insertions(+), 17 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2430.clarification diff --git a/changelogs/client_server/newsfragments/2430.clarification b/changelogs/client_server/newsfragments/2430.clarification new file mode 100644 index 00000000..56be0c1a --- /dev/null +++ b/changelogs/client_server/newsfragments/2430.clarification @@ -0,0 +1 @@ +Fix key export format example to match the specification. diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 7758e2c1..af7b2c59 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -844,24 +844,22 @@ Example: .. code:: json - { - "sessions": [ - { - "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": "", - }, - "session_id": "X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ", - "session_key": "AgAAAADxKHa9uFxcXzwYoNueL5Xqi69IkD4sni8Llf..." + [ + { + "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": "", }, - ... - ] - } + "session_id": "X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ", + "session_key": "AgAAAADxKHa9uFxcXzwYoNueL5Xqi69IkD4sni8Llf..." + }, + ... + ] Messaging Algorithms -------------------- From 41072fcaa90d94ded06fe27c467ff652832a832b Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 7 Feb 2020 15:28:19 -0500 Subject: [PATCH 0934/1250] Apply suggestions from code review Co-Authored-By: Matthew Hodgson --- api/client-server/key_backup.yaml | 4 ++-- specification/modules/end_to_end_encryption.rst | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/api/client-server/key_backup.yaml b/api/client-server/key_backup.yaml index 3663731e..b409dfbf 100644 --- a/api/client-server/key_backup.yaml +++ b/api/client-server/key_backup.yaml @@ -67,7 +67,7 @@ paths: responses: 200: description: - The version of the new backup. + The version id of the new backup. schema: type: object properties: @@ -123,7 +123,7 @@ paths: } } count: - description: The number of key stored in the backup. + description: The number of keys stored in the backup. type: integer example: 42 etag: diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index ce9ea4db..63690924 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -786,6 +786,7 @@ clients can discover the backup by calling ``GET /room_keys/version``. Keys are encrypted according to the backups ``auth_data`` and added to the backup by calling ``PUT /room_keys/keys?version=$v`` or one of its variants, and can be retrieved by calling ``GET /room_keys/keys?version=$v`` or one of its variants. +Keys can only be written to the most recently created version of the backup. Backups can also be deleted using ``DELETE /room_keys/version``, or individual keys can be deleted using ``DELETE /room_key/keys?version=$v`` or one of its variants. From 6bd4b3c08a7a5137700c8fbf76008b27de92efe0 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 10 Feb 2020 20:29:38 +0000 Subject: [PATCH 0935/1250] MSC: Updated semantics for publishing room aliases --- proposals/2432-revised-alias-publishing.md | 225 +++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 proposals/2432-revised-alias-publishing.md diff --git a/proposals/2432-revised-alias-publishing.md b/proposals/2432-revised-alias-publishing.md new file mode 100644 index 00000000..8ef08f7d --- /dev/null +++ b/proposals/2432-revised-alias-publishing.md @@ -0,0 +1,225 @@ +# MSC2432: Updated semantics for publishing room aliases + +This MSC offers an alternative to [MSC2260](https://github.com/matrix-org/matrix-doc/issues/2260). + +## Background + +The [`m.room.aliases`](https://matrix.org/docs/spec/client_server/r0.6.0#m-room-aliases) +state event exists to list the available aliases for a given room. This serves +two purposes: + + * It allows existing members of the room to discover alternative aliases, + which may be useful for them to pass this knowledge on to others trying to + join. + + * Secondarily, it helps to educate users about how Matrix works by + illustrating multiple aliases per room and giving a perception of the size + of the network. + +However, it has problems: + + * Any user in the entire ecosystem can create aliases for rooms, which are + then unilaterally added to `m.room.aliases`, and room admins are unable to + remove them. This is an abuse + vector (https://github.com/matrix-org/matrix-doc/issues/625). + + * For various reasons, the `m.room.aliases` event tends to get out of sync + with the actual aliases (https://github.com/matrix-org/matrix-doc/issues/2262). + +## Proposal + +We propose that that room moderators should be able to manually curate a list +of "official" aliases for their room, instead of matrix servers automatically +publishing lists of all room aliases into the room state. No particular +guarantees are offered that this alias list is entirely accurate: it becomes +room moderators' responsibilty to keep it so. + +Meanwhile, the aliases that map to a given room on a given server become +the ultimate responsibility of the administrators of that server. We give them +tools to inspect the alias list and clean it up when necessary, in addition to +the current tools which allow restriction of who can create aliases in the +first place. + +A detailed list of proposed modifications to the Matrix spec follows: + + * `m.room.aliases` loses any special meaning within the spec. In particular: + + * Clients should no longer format it specially in room timelines. + + * Clients and servers should no longer consider `m.room.aliases` when + [calculating the display name for a + room](https://matrix.org/docs/spec/client_server/r0.6.0#calculating-the-display-name-for-a-room). + + (Note: servers follow the room display-name algorithm when calculating + room names for certain types of push notification.) + + * A future room version will remove the special [authorization +rules](https://matrix.org/docs/spec/rooms/v1#authorization-rules) and +[redaction rules](https://matrix.org/docs/spec/client_server/r0.6.0#redactions). + + * [`m.room.canonical_alias`](https://matrix.org/docs/spec/client_server/r0.6.0#m-room-canonical-alias) + is extended to include a new `alt_aliases` property. This, if present, + should be a list of alternative aliases for the room. An example event might + look like: + + ```json + { + "content": { + "alias": "#somewhere:localhost", + "alt_aliases": [ + "#somewhere:overthere.com", + "#somewhereelse:example.com" + ] + }, + "room_id": "!jEsUZKDJdhlrceRyVU:example.org", + "state_key": "", + "type": "m.room.canonical_alias" + } + ``` + + It is valid for `alt_aliases` to be non-empty even if `alias` is absent or + empty. This means that no alias has been picked out as the 'main' alias. + + (Note: although the spec currently claims that `alias` is mandatory, Synapse + generates `m.room.canonical` alias events with no `alias` property when the + main alias is deleted. This change would legitimise that behaviour.) + + (For clarity: it is not proposed that the `alt_aliases` be considered when + calculating the displayname for a room.) + + * [`PUT /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}`](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-rooms-roomid-state-eventtype-statekey) + is extended to recommend that servers validate any *new* aliases added to + `m.room.canonical_alias` by checking that it is a valid alias according to + the [syntax](https://matrix.org/docs/spec/appendices#room-aliases), and by + looking up the alias and and that it corresponds to the expected room ID. + + (Note: Synapse currently implements this check on the main alias, though + this is unspecced.) + + (TODO: what error code should be returned if the alias is invalid, or if it + points to the wrong room?) + + * Currently, [`PUT /_matrix/client/r0/directory/room/{roomAlias}`](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-directory-room-roomalias) + attempts to send updated `m.room.aliases` events on the caller's + behalf. (This is implemented in Synapse but does not appear to be explicitly + specced.) This functionality should be removed. + + * Currently, [`DELETE /_matrix/client/r0/directory/room/{roomAlias}`](https://matrix.org/docs/spec/client_server/r0.6.0#delete-matrix-client-r0-directory-room-roomalias), + attempts to send updated `m.room.aliases` and/or `m.room.canonical_alias` + events on the caller's behalf, removing any aliases which have been + deleted. (Again, this is implemented in Synapse but does not appear to be + explicitly specced.) The `m.room.aliases` functionality should be removed, + and the `m.room.canonical_alias` functionality should be extended to cover + `alt_aliases`. As today, no error occurs if the caller does not have + permission to send such an event. + + * A new api endpoint, `GET /_matrix/client/r0/rooms/{roomId}/aliases` is + added, which returns the list of aliases currently defined on the local + server for the given room. The response looks like: + + ```json + { + "aliases": [ + "#somewhere:example.com", + "#somewhereelse:example.com", + "#special_alias:example.com" + ] + } + ``` + + This API can be called by any current member of the room (calls from other + users result in `M_FORBIDDEN`). + + TODO: should this be tied in with `history_visibilty` to allow peeking from + non-members? On the one hand that feels like pointless clutter; on the other + it feels like it makes it more consistent with peekable rooms. + +Various APIs are currently subject to implementation-defined access +restrictions. No change to the specification is changed in this regard +(implementations will continue to be free to impose their own +restrictions). Nevertheless as part of this MSC it is useful to consider some +proposed changes to Synapse's implementation: + + * No change: `PUT /_matrix/client/r0/directory/room/{roomAlias}`: Synapse + only allows access to current members of the room, and also exposes some + configuration options which allow restriction of which users are allowed to + create aliases in general. + + * `DELETE /_matrix/client/r0/directory/room/{roomAlias}`: in this case, + currently Synapse restricts its use to the user that created the alias, and + server admins. + + It is proposed to extend this to local users who have a power-level + sufficient to send an `m.room.canonical_alias` event in the room that the + alias currently points to. + + * [`PUT /_matrix/client/r0/directory/list/room/{roomId}`](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-directory-list-room-roomid) + and the corresponding unspecced `DELETE` api (both of which set the + visibility of a room in the public directory): currently Synapse restricts + their use to server admins and local users who have a PL sufficient to send + an `m.room.aliases` event in the room (ignoring the special auth + rules). This will be changed to check against the PL required to send an + `m.room.canonical_alias` event. + +It is envisaged that Matrix clients will then change their "Room Settings" user +interface to display the aliases from `m.room.canonical_alias` instead of those +in `m.room.aliases`, as well as giving moderators the ability to update that +list. Clients might also wish to use the new `GET +/_matrix/client/r0/rooms/{roomId}/aliases` endpoint to obtain and display the +currently-available local aliases, though given that this list may be subject +to abuse, it should probably not be shown by default. + +### Future work + +This work isn't considered part of this MSC, but rather a potential extension +for the future. + + * It may be useful to be able to query remote servers for their alias + list. This could be done by extending `GET + /_matrix/client/r0/rooms/{roomId}/aliases` to take a `server_name` + parameter, and defining an API in the server_server spec which will expose + the requested information, subject to the calling homeserver having at least + one user with a right to see it. + + * Similarly, room moderators may wish to be able to delete aliases on a remote + server for their room. We could envisage a fedaration API which allows such + a request to be made, subject to the calling homeserver having at least one + moderator in the room. + +## Potential issues + +The biggest problem with this proposal is that existing clients, which rely on +`m.room.aliases` in one way or another, will lose functionality. In particular, +they may not know about aliases that exist, or they may look at outdated +`m.room.aliases` events that list aliases that no longer exist. However, since +`m.room.aliases` is best-effort anyway, these are both problems that exist to +some extent today. + +## Alternatives + +We considered continuing to use `m.room.aliases` to advertise room aliases +instead of `m.room.canonical_alias`, but the significant changes in semantics +made that seem inappropriate. + +We also considered using separate state events for each advertised alias, +rather than listing them all in one event. This might increase the number of +aliases which can be advertised, and help to reduce races when editing the +list. However, the 64KB limit of an event still allows room for hundreds of +aliases of any sane length, and we don't expect the list to be changing +frequently enough for races to be a practical concern. Ultimately the added +complexity seemed redundant. + +A previous suggestion was +[MSC2260](https://github.com/matrix-org/matrix-doc/issues/2260), which proposed +keeping `m.room.aliases` largely as-is, but giving room moderators tools to +control who can send them via room power-levels. We dismissed it for the +reasons set out at +https://github.com/matrix-org/matrix-doc/pull/2260#issuecomment-584207073. + +## Security considerations + +None currently identified. + +## Unstable prefix + +TBD. From 95ff26679bf4f780509e73d2201cafe9ce40c111 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 11 Feb 2020 11:16:56 +0000 Subject: [PATCH 0936/1250] Apply suggestions from code review Co-Authored-By: Matthew Hodgson Co-Authored-By: Hubert Chathi --- proposals/2432-revised-alias-publishing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/2432-revised-alias-publishing.md b/proposals/2432-revised-alias-publishing.md index 8ef08f7d..0afdf195 100644 --- a/proposals/2432-revised-alias-publishing.md +++ b/proposals/2432-revised-alias-publishing.md @@ -32,7 +32,7 @@ We propose that that room moderators should be able to manually curate a list of "official" aliases for their room, instead of matrix servers automatically publishing lists of all room aliases into the room state. No particular guarantees are offered that this alias list is entirely accurate: it becomes -room moderators' responsibilty to keep it so. +room moderators' responsibility to keep it so. Meanwhile, the aliases that map to a given room on a given server become the ultimate responsibility of the administrators of that server. We give them @@ -182,7 +182,7 @@ for the future. one user with a right to see it. * Similarly, room moderators may wish to be able to delete aliases on a remote - server for their room. We could envisage a fedaration API which allows such + server for their room. We could envisage a federation API which allows such a request to be made, subject to the calling homeserver having at least one moderator in the room. From 3ee9a7d654050219f09487ce7b6bd9584827a6c2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 12 Feb 2020 21:03:11 -0700 Subject: [PATCH 0937/1250] Attempt to convert MSC2324 to reality We've been using this in practice for a while now, so we should document it more officially. MSC: https://github.com/matrix-org/matrix-doc/pull/2324 --- specification/proposals_intro.rst | 102 +++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 82a4225b..3f70345f 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -230,7 +230,8 @@ follows: comments and in relevant rooms on Matrix. Discussion outside of GitHub should be summarised in a comment on the PR. - When a member of the Spec Core Team believes that no new discussion points are - being made, they will propose a motion for a final comment period (FCP), + being made, and the proposal has suitable evidence of working (see `implementing a + proposal`_ below), they will propose a motion for a final comment period (FCP), along with a *disposition* of either merge, close or postpone. This FCP is provided to allow a short period of time for any invested party to provide a final objection before a major decision is made. If sufficient reasoning is @@ -341,6 +342,105 @@ Closed proposal-closed A proposal which Obsolete obsolete A proposal which has been made obsolete by another proposal or decision elsewhere. =============================== ============================= ==================================== +Implementing a proposal +----------------------- + +As part of the proposal process the spec core team will require evidence of the MSC +working in order for it to move into FCP. This can usually be a branch/pull request +to whichever implementation of choice that proves the MSC works in practice, though +in some cases the MSC itself will be small enough to be considered proven. Where it's +unclear if a MSC will require an implementation proof, ask in `#matrix-spec:matrix.org +`_. + +Early adoption of a MSC/idea +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To help facilitate early releases of software dependent on a spec release, implementations +are required to use the following process to ensure that the official Matrix namespace +is not cluttered with development or testing data. + +.. Note:: + Proof of concept implementations that are solely left on a branch/unreleased and for + demonstrating that a particular MSC works do not have to follow this. Note that the + ``develop`` branch adopted by some projects is still subject to this process. + +The process for an implementation willing to be ahead of a spec release is: + +1. Have an idea for a feature. +2. Implement the feature using unstable endpoints, vendor prefixes, and unstable + feature flags as appropriate. + + * When using unstable endpoints, they MUST include a vendor prefix. For example: + `/_matrix/client/unstable/com.example/login`. Vendor prefixes throughout Matrix + always use the Java package naming convention. The MSC for the feature should + identify which preferred vendor prefix is to be used by early adopters. + * Unstable endpoints **do not** inherit from stable (e.g. `/r0`) APIs. Implementations + cannot assume that a particular endpoint will exist in the unstable namespace + even if the server advertises support for the feature. + * If the client needs to be sure the server supports the feature, an unstable + feature flag that MUST be vendor prefixed is to be used. This kind of flag shows + up in the ``unstable_features`` section of ``/versions`` as, for example, + ``com.example.new_login``. The MSC for the feature should identify which preferred + feature flag is to be used by early adopters. + * When using this approach correctly, the implementation can ship/release the + feature at any time, so long as the implementation is able to accept the technical + debt that results from needing to provide adequate backwards and forwards + compatibility. The implementation MUST support the flag disappearing and be + generally safe for users. Note that implementations early in the MSC review + process may also be required to provide backwards compatibility with earlier + editions of the proposal. + * If the implementation cannot support the technical debt (or if it's impossible + to provide forwards/backwards compatibility - e.g. a user authentication change + which can't be safely rolled back), the implementation should not attempt to + implement the feature and instead wait for a spec release. + * If at any point the idea changes, the feature flag should also change so that + implementations can adapt as needed. + +3. In parallel, or ahead of implementation, open an MSC and solicit review per above. +4. Before FCP can be called, the Spec Core Team will require evidence of the MSC + working as proposed. A typical example of this is an implementation of the MSC, + though the implementation does not need to be shipped anywhere and can therefore + avoid the forwards/backwards compatibility concerns mentioned here. +5. FCP is gone through, and assuming nothing is flagged the MSC lands. +6. A spec PR is written to incorporate the changes into Matrix. +7. A spec release happens. +8. Implementations switch to using stable prefixes (e.g.: ``/r0``) if the server + supports the specification version released. If the server doesn't advertise the + specification version, but does have the feature flag, unstable prefixes should + still be used. +9. A transition period of about 2 months starts immediately after the spec release, + before implementations start to loudly encourage other implementations to switch + to stable endpoints. For example, a server implementation should start asking + client implementations to support the stable endpoints 2 months after the spec + release, if they haven't already. The same applies in the reverse: if clients + cannot switch to stable prefixes because server implementations haven't started + supporting the new spec release, some noise should be raised in the general direction + of the implementation. + + * Please be considerate when being noisy to implementations. A gentle reminder + in their issue tracker is generally good enough. + +.. Note:: + MSCs MUST still describe what the stable endpoints/feature looks like with a note + towards the bottom for what the unstable feature flag/prefixes are. For example, + a MSC would propose `/_matrix/client/r0/new/endpoint`, not `/_matrix/client/unstable/ + com.example/new/endpoint`. + +In summary: + +* Implementations MUST NOT use stable endpoints before the MSC is in the spec. This + includes NOT using stable endpoints before a spec release happens, but after FCP has + passed. +* Implementations are able to ship features that are exposed to users by default before + an MSC has been merged to the spec, provided they follow the process above. +* Implementations SHOULD be wary of the technical debt they are incurring by moving faster + than the spec. +* The vendor prefix is chosen by the developer of the feature, using the Java package + naming convention. The foundation's preferred vendor prefix is `org.matrix`. +* The vendor prefixes, unstable feature flags, and unstable endpoints should be included + in the MSC, though the MSC MUST be written in a way that proposes new stable endpoints. + Typically this is solved by a small table at the bottom mapping the various values + from stable to unstable. Proposal Tracking ----------------- From c7942d1cecda30511a10d5b971cb58bb30fa9be3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 12 Feb 2020 21:58:57 -0700 Subject: [PATCH 0938/1250] Spec moderation policy rooms (MSC2313) MSC: https://github.com/matrix-org/matrix-doc/pull/2313 --- event-schemas/examples/m.policy.rule.room | 10 ++ event-schemas/examples/m.policy.rule.server | 10 ++ event-schemas/examples/m.policy.rule.user | 10 ++ event-schemas/moderation_policy_rule.yaml | 30 ++++ event-schemas/schema/m.policy.rule.room | 15 ++ event-schemas/schema/m.policy.rule.server | 15 ++ event-schemas/schema/m.policy.rule.user | 15 ++ specification/feature_profiles.rst | 2 + specification/modules/moderation_policies.rst | 129 ++++++++++++++++++ specification/targets.yaml | 1 + 10 files changed, 237 insertions(+) create mode 100644 event-schemas/examples/m.policy.rule.room create mode 100644 event-schemas/examples/m.policy.rule.server create mode 100644 event-schemas/examples/m.policy.rule.user create mode 100644 event-schemas/moderation_policy_rule.yaml create mode 100644 event-schemas/schema/m.policy.rule.room create mode 100644 event-schemas/schema/m.policy.rule.server create mode 100644 event-schemas/schema/m.policy.rule.user create mode 100644 specification/modules/moderation_policies.rst diff --git a/event-schemas/examples/m.policy.rule.room b/event-schemas/examples/m.policy.rule.room new file mode 100644 index 00000000..5a532cb5 --- /dev/null +++ b/event-schemas/examples/m.policy.rule.room @@ -0,0 +1,10 @@ +{ + "$ref": "core/state_event.json", + "type": "m.policy.rule.room", + "state_key": "rule:#*:example.org", + "content": { + "entity": "#*:example.org", + "recommendation": "m.ban", + "reason": "undesirable content" + } +} diff --git a/event-schemas/examples/m.policy.rule.server b/event-schemas/examples/m.policy.rule.server new file mode 100644 index 00000000..3d740a28 --- /dev/null +++ b/event-schemas/examples/m.policy.rule.server @@ -0,0 +1,10 @@ +{ + "$ref": "core/state_event.json", + "type": "m.policy.rule.server", + "state_key": "rule:*.example.org", + "content": { + "entity": "*.example.org", + "recommendation": "m.ban", + "reason": "undesirable engagement" + } +} diff --git a/event-schemas/examples/m.policy.rule.user b/event-schemas/examples/m.policy.rule.user new file mode 100644 index 00000000..eb3832da --- /dev/null +++ b/event-schemas/examples/m.policy.rule.user @@ -0,0 +1,10 @@ +{ + "$ref": "core/state_event.json", + "type": "m.policy.rule.user", + "state_key": "rule:@alice*:example.org", + "content": { + "entity": "@alice*:example.org", + "recommendation": "m.ban", + "reason": "undesirable behaviour" + } +} diff --git a/event-schemas/moderation_policy_rule.yaml b/event-schemas/moderation_policy_rule.yaml new file mode 100644 index 00000000..34ad4d9a --- /dev/null +++ b/event-schemas/moderation_policy_rule.yaml @@ -0,0 +1,30 @@ +# Copyright 2020 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. +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. + type: string + recommendation: + description: The suggested action to take. Currently only ``m.ban`` is specified. + type: string + reason: + description: The human-readable description for the ``recommendation``. + type: string +type: object +required: + - entity + - recommendation + - reason diff --git a/event-schemas/schema/m.policy.rule.room b/event-schemas/schema/m.policy.rule.room new file mode 100644 index 00000000..ff81543e --- /dev/null +++ b/event-schemas/schema/m.policy.rule.room @@ -0,0 +1,15 @@ +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: A moderation policy rule which affects room IDs and room aliases. +properties: + content: + $ref: "../moderation_policy_rule.yaml" + state_key: + description: An arbitrary string decided upon by the sender. + type: string + type: + enum: + - m.policy.rule.room + type: string +type: object diff --git a/event-schemas/schema/m.policy.rule.server b/event-schemas/schema/m.policy.rule.server new file mode 100644 index 00000000..ca37e8ff --- /dev/null +++ b/event-schemas/schema/m.policy.rule.server @@ -0,0 +1,15 @@ +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: A moderation policy rule which affects servers. +properties: + content: + $ref: "../moderation_policy_rule.yaml" + state_key: + description: An arbitrary string decided upon by the sender. + type: string + type: + enum: + - m.policy.rule.server + type: string +type: object diff --git a/event-schemas/schema/m.policy.rule.user b/event-schemas/schema/m.policy.rule.user new file mode 100644 index 00000000..4fa65ad8 --- /dev/null +++ b/event-schemas/schema/m.policy.rule.user @@ -0,0 +1,15 @@ +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: A moderation policy rule which affects users. +properties: + content: + $ref: "../moderation_policy_rule.yaml" + state_key: + description: An arbitrary string decided upon by the sender. + type: string + type: + enum: + - m.policy.rule.user + type: string +type: object diff --git a/specification/feature_profiles.rst b/specification/feature_profiles.rst index bb638380..8a3caf87 100644 --- a/specification/feature_profiles.rst +++ b/specification/feature_profiles.rst @@ -61,6 +61,7 @@ Summary `Stickers`_ Optional Optional Optional Optional Optional `Server ACLs`_ Optional Optional Optional Optional Optional `Server Notices`_ Optional Optional Optional Optional Optional + `Moderation policies`_ Optional Optional Optional Optional Optional ===================================== ========== ========== ========== ========== ========== *Please see each module for more details on what clients need to implement.* @@ -94,6 +95,7 @@ Summary .. _Stickers: `module:stickers`_ .. _Server ACLs: `module:server-acls`_ .. Server Notices already has a link elsewhere. +.. _Moderation Policies: `module:moderation-policies`_ Clients ------- diff --git a/specification/modules/moderation_policies.rst b/specification/modules/moderation_policies.rst new file mode 100644 index 00000000..8992ceb1 --- /dev/null +++ b/specification/modules/moderation_policies.rst @@ -0,0 +1,129 @@ +.. Copyright 2020 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. + +Moderation policy lists +======================= + +.. _module:moderation-policies: + +With Matrix being an open network where anyone can participate, a very wide +range of content exists and it is important that users are empowered to select +which content they wish to see, and which content they wish to block. By +extension, room moderators and server admins should also be able to select +which content they do not wish to host in their rooms and servers. + +The protocol's position on this is one of neutrality: it should not be deciding +what content is undesirable for any particular entity and should instead be +empowering those entities to make their own decisions. As such, a generic +framework for communicating "moderation policy lists" or "moderation policy rooms" +is described. Note that this module only describes the data structures and not +how they should be interpreting: the entity making the decisions on filtering +is best positioned to interpret the rules how it sees fit. + +Moderation policy lists are stored as room state events. There are no restrictions +on how the rooms can be configured (they could be public, private, encrypted, etc). + +There are currently 3 kinds of entities which can be affected by rules: ``user``, +``server``, and ``room``. All 3 are described with ``m.policy.rule.`` state +events. The ``state_key`` for a policy rule is an arbitrary string decided by the +sender of the rule. + +Rules contain recommendations and reasons for the rule existing. The ``reason`` +is a human-readable string which describes the ``recommendation``. Currently only +one recommendation, ``m.ban``, is specified. + +``m.ban`` recommendation +------------------------ + +When this recommendation is used, the entities affected by the rule should be +banned from participation where possible. The enforcement of this is deliberately +left as an implementation detail to avoid the protocol imposing its opinion on how +the policy list is to be interpreted. However, a suggestion for a simple implementation +is as follows: + +* Is a ``user`` rule... + + * Applied to a user: The user should be added to the subscriber's ignore list. + * Applied to a room: The user should be banned from the room (either on sight or immediately). + * Applied to a server: The user should not be allowed to send invites to users on the server. + +* Is a ``room`` rule... + + * Applied to a user: The user should leave the room and not join it + (`MSC2270 `_-style ignore). + * Applied to a room: No-op because a room cannot ban itself. + * Applied to a server: The server should prevent users from joining the room and from receiving + invites to it. + +* Is a ``server`` rule... + + * Applied to a user: The user should not receive events or invites from the server. + * Applied to a room: The server is added as a denied server in the ACLs. + * Applied to a server: The subscriber should avoid federating with the server as much as + possible by blocking invites from the server and not sending traffic unless strictly + required (no outbound invites). + +Subscribing to policy lists +--------------------------- + +This is deliberatly left as an implementation detail. For implementations using the +Client-Server API, this could be as easy as joining or peeking the room. Joining or peeking +is not required, however: an implementation could poll for updates or use a different +technique for receiving updates to the policy's rules. + +Sharing +------- + +In addition to sharing a direct reference to the room which contains the policy's rules, +plain http or https URLs can be used to share links to the list. When the URL is approached +with a ``Accept: application/json`` header or has ``.json`` appended to the end of the URL, it +should return a JSON object containing a ``room_uri`` property which references the room. +Currently this would be a ``matrix.to`` URI, however in future it could be a Matrix-schemed +URI instead. When not approached with the intent of JSON, the service could return a +user-friendly page describing what is 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 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. + +{{m_policy_rule_user_event}} + +{{m_policy_rule_room_event}} + +{{m_policy_rule_server_event}} + +Client behaviour +---------------- +As described above, the client behaviour is deliberatly left undefined. + +Server behaviour +---------------- +Servers have no additional requirements placed on them by this module. + + +Security considerations +----------------------- +This module could be used to build a system of shared blacklists, which may create +a divide within established communities if not carefully deployed. This may well not +be a suitable solution for all communities. + +Depending on how implementations handle subscriptions, user IDs may be linked to +policy lists and therefore expose the views of that user. For example, a client implementation +which joins the user to the policy room would expose the user's ID to observers of the +policy room. In future, `MSC1228 `_ +and `MSC1777 `_ (or similar) could +help solve this concern. diff --git a/specification/targets.yaml b/specification/targets.yaml index 2cd911ba..4e0b068d 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -91,6 +91,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/mentions.rst - modules/room_upgrades.rst - modules/server_notices.rst + - modules/moderation_policies.rst title_styles: ["=", "-", "~", "+", "^", "`", "@", ":"] From da047523e32a863c7c0d0704a7c89787920b9310 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 12 Feb 2020 22:00:56 -0700 Subject: [PATCH 0939/1250] Changelog --- changelogs/client_server/newsfragments/2434.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2434.feature diff --git a/changelogs/client_server/newsfragments/2434.feature b/changelogs/client_server/newsfragments/2434.feature new file mode 100644 index 00000000..2b8f36f5 --- /dev/null +++ b/changelogs/client_server/newsfragments/2434.feature @@ -0,0 +1 @@ +Added data structures for defining moderation policies in rooms per `MSC2313 `_. From 7a878bb6c34c2f39507de63a8a2416196d90f05b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 12 Feb 2020 22:01:58 -0700 Subject: [PATCH 0940/1250] Fix location of changelog entries and synergize them --- changelogs/client_server/{ => newsfragments}/2245.clarification | 0 changelogs/client_server/newsfragments/2415.clarification | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename changelogs/client_server/{ => newsfragments}/2245.clarification (100%) diff --git a/changelogs/client_server/2245.clarification b/changelogs/client_server/newsfragments/2245.clarification similarity index 100% rename from changelogs/client_server/2245.clarification rename to changelogs/client_server/newsfragments/2245.clarification diff --git a/changelogs/client_server/newsfragments/2415.clarification b/changelogs/client_server/newsfragments/2415.clarification index d1a7dbfe..902a9c3f 100644 --- a/changelogs/client_server/newsfragments/2415.clarification +++ b/changelogs/client_server/newsfragments/2415.clarification @@ -1 +1 @@ -Fix misspelling of _deprecated_. \ No newline at end of file +Fix various spelling errors throughout the specification. From 6d475ebd5777600e70ed0737845f9b5d21bba59a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 17 Feb 2020 12:56:28 -0700 Subject: [PATCH 0941/1250] Remove whitespace Co-Authored-By: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- specification/modules/moderation_policies.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/specification/modules/moderation_policies.rst b/specification/modules/moderation_policies.rst index 8992ceb1..2e85fb07 100644 --- a/specification/modules/moderation_policies.rst +++ b/specification/modules/moderation_policies.rst @@ -114,7 +114,6 @@ Server behaviour ---------------- Servers have no additional requirements placed on them by this module. - Security considerations ----------------------- This module could be used to build a system of shared blacklists, which may create From 786772f7646f8767c008872abc6fc41b9fe7b809 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 18 Feb 2020 16:24:46 +0000 Subject: [PATCH 0942/1250] Update proposals/2432-revised-alias-publishing.md Co-Authored-By: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- proposals/2432-revised-alias-publishing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2432-revised-alias-publishing.md b/proposals/2432-revised-alias-publishing.md index 0afdf195..a6887264 100644 --- a/proposals/2432-revised-alias-publishing.md +++ b/proposals/2432-revised-alias-publishing.md @@ -81,7 +81,7 @@ rules](https://matrix.org/docs/spec/rooms/v1#authorization-rules) and empty. This means that no alias has been picked out as the 'main' alias. (Note: although the spec currently claims that `alias` is mandatory, Synapse - generates `m.room.canonical` alias events with no `alias` property when the + generates `m.room.canonical_alias` events with no `alias` property when the main alias is deleted. This change would legitimise that behaviour.) (For clarity: it is not proposed that the `alt_aliases` be considered when From 645dbcc0912624a32d070b2c7ae30d936f1e2f7b Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 19 Feb 2020 07:25:34 +0000 Subject: [PATCH 0943/1250] make room alias lists peekable --- proposals/2432-revised-alias-publishing.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/proposals/2432-revised-alias-publishing.md b/proposals/2432-revised-alias-publishing.md index a6887264..4a5d95ad 100644 --- a/proposals/2432-revised-alias-publishing.md +++ b/proposals/2432-revised-alias-publishing.md @@ -128,11 +128,8 @@ rules](https://matrix.org/docs/spec/rooms/v1#authorization-rules) and ``` This API can be called by any current member of the room (calls from other - users result in `M_FORBIDDEN`). - - TODO: should this be tied in with `history_visibilty` to allow peeking from - non-members? On the one hand that feels like pointless clutter; on the other - it feels like it makes it more consistent with peekable rooms. + users result in `M_FORBIDDEN`). For rooms with `history_visibility` set to + `world_readable`, it can also be called by users outside the room. Various APIs are currently subject to implementation-defined access restrictions. No change to the specification is changed in this regard From 30d762cc72ad179ceb612dea046418770546714e Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 19 Feb 2020 07:25:49 +0000 Subject: [PATCH 0944/1250] document unstable prefixes/feature flags --- proposals/2432-revised-alias-publishing.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/proposals/2432-revised-alias-publishing.md b/proposals/2432-revised-alias-publishing.md index 4a5d95ad..81d59e71 100644 --- a/proposals/2432-revised-alias-publishing.md +++ b/proposals/2432-revised-alias-publishing.md @@ -219,4 +219,11 @@ None currently identified. ## Unstable prefix -TBD. +While this feature is in development, the following names will be in use: + +| Proposed final name | Name while in development | +| `GET /_matrix/client/r0/rooms/{roomId}/aliases` | `GET /_matrix/client/unstable/org.matrix.msc2432/rooms/{roomId}/aliases` | + +Servers will indicate support for the new endpoint via a non-empty value for feature flag +`org.matrix.msc2432` in `unstable_features` in the response to `GET +/_matrix/client/versions`. From 98a6cd0f45426beca4eb1e0334573a1ea3748642 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Wed, 19 Feb 2020 07:29:55 +0000 Subject: [PATCH 0945/1250] fix table --- proposals/2432-revised-alias-publishing.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/2432-revised-alias-publishing.md b/proposals/2432-revised-alias-publishing.md index 81d59e71..c527a14e 100644 --- a/proposals/2432-revised-alias-publishing.md +++ b/proposals/2432-revised-alias-publishing.md @@ -222,6 +222,7 @@ None currently identified. While this feature is in development, the following names will be in use: | Proposed final name | Name while in development | +| --- | --- | | `GET /_matrix/client/r0/rooms/{roomId}/aliases` | `GET /_matrix/client/unstable/org.matrix.msc2432/rooms/{roomId}/aliases` | Servers will indicate support for the new endpoint via a non-empty value for feature flag From 8b9ea10e11bd0a460211e1826543fe17f2667e19 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 19 Feb 2020 07:31:57 +0000 Subject: [PATCH 0946/1250] server admins can list aliases --- proposals/2432-revised-alias-publishing.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/2432-revised-alias-publishing.md b/proposals/2432-revised-alias-publishing.md index c527a14e..433ce0f6 100644 --- a/proposals/2432-revised-alias-publishing.md +++ b/proposals/2432-revised-alias-publishing.md @@ -131,6 +131,9 @@ rules](https://matrix.org/docs/spec/rooms/v1#authorization-rules) and users result in `M_FORBIDDEN`). For rooms with `history_visibility` set to `world_readable`, it can also be called by users outside the room. + Servers might also choose to allow access to other users such as server + administrators. + Various APIs are currently subject to implementation-defined access restrictions. No change to the specification is changed in this regard (implementations will continue to be free to impose their own From e151ba96acfbd67febc1869c0326b1fb7c4c4dc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96rjan=20Fors?= Date: Mon, 24 Feb 2020 09:45:46 +0100 Subject: [PATCH 0947/1250] Fix typo for upgrade MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Örjan Fors --- api/client-server/room_upgrades.yaml | 2 +- changelogs/client_server.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/client-server/room_upgrades.yaml b/api/client-server/room_upgrades.yaml index 55ee14dc..3aaaadcb 100644 --- a/api/client-server/room_upgrades.yaml +++ b/api/client-server/room_upgrades.yaml @@ -90,4 +90,4 @@ paths: schema: "$ref": "definitions/errors/error.yaml" tags: - - Room ugprades + - Room upgrades diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index a5173fd0..bc12da5c 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -74,7 +74,7 @@ Backwards Compatible Changes - Support optional features by having clients query for capabilities. (`#1829 `_, `#1879 `_) - Add ``M_RESOURCE_LIMIT_EXCEEDED`` as an error code for when homeservers exceed limits imposed on them. (`#1874 `_) - Emit ``M_UNSUPPORTED_ROOM_VERSION`` error codes where applicable on ``/createRoom`` and ``/invite`` APIs. (`#1908 `_) -- Add a ``.m.rule.tombstone`` default push rule for room ugprade notifications. (`#2020 `_) +- Add a ``.m.rule.tombstone`` default push rule for room upgrade notifications. (`#2020 `_) - Add support for sending server notices to clients. (`#2026 `_) - Add MSISDN (phone number) support to User-Interactive Authentication. (`#2030 `_) - Add the option to lazy-load room members for increased client performance. (`#2035 `_) From 4e123ca12113bd0587ac641503f0e8da9f6af4f0 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Sat, 29 Feb 2020 23:29:33 +0000 Subject: [PATCH 0948/1250] Update proposals/2432-revised-alias-publishing.md Co-Authored-By: Kitsune Ral --- proposals/2432-revised-alias-publishing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2432-revised-alias-publishing.md b/proposals/2432-revised-alias-publishing.md index 433ce0f6..dff72df5 100644 --- a/proposals/2432-revised-alias-publishing.md +++ b/proposals/2432-revised-alias-publishing.md @@ -135,7 +135,7 @@ rules](https://matrix.org/docs/spec/rooms/v1#authorization-rules) and administrators. Various APIs are currently subject to implementation-defined access -restrictions. No change to the specification is changed in this regard +restrictions. No change to the specification is introduced in this regard (implementations will continue to be free to impose their own restrictions). Nevertheless as part of this MSC it is useful to consider some proposed changes to Synapse's implementation: From 420180a69ddd25d44b1c7c048d809b05683978f4 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Tue, 3 Mar 2020 12:30:19 -0500 Subject: [PATCH 0949/1250] MSC: Remove query_auth federation endpoint. --- .gitignore | 1 + ...x-remove-query_auth-federation-endpoint.md | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 proposals/xxxx-remove-query_auth-federation-endpoint.md diff --git a/.gitignore b/.gitignore index 800be2fa..9cc27b85 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ *.swp _rendered.rst /.vscode/ +/.idea/ diff --git a/proposals/xxxx-remove-query_auth-federation-endpoint.md b/proposals/xxxx-remove-query_auth-federation-endpoint.md new file mode 100644 index 00000000..7930c5f8 --- /dev/null +++ b/proposals/xxxx-remove-query_auth-federation-endpoint.md @@ -0,0 +1,31 @@ +# MSCxxxx: Remove the `query_auth` federation endpoint + +The `query_auth` federation endpoint is unused by Synapse and should be removed. +The current implementation in Synapse is broken and will return a 500 error in +some situations. + +## Proposal + +Remove: + +* [POST `/_matrix/federation/v1/query_auth/{roomId}/{eventId}`](https://matrix.org/docs/spec/server_server/r0.1.3#post-matrix-federation-v1-query-auth-roomid-eventid) + +## Potential issues + +Removing this endpoint impacts backwards compatibility. + +In practice, removing this endpoint should have minimal impact. Since 1.5.0rc1 +of Synapse this endpoint is not called (see [#6214](https://github.com/matrix-org/synapse/pull/6214)). +During removal it was noted that the code to call this endpoint was already +unreachable. + +Note that it seems like this was initially supported in Synapse v0.7.0. It is +not clear at what point it became unused. + +## Alternatives + +The endpoint could be deprecated in removed in a future version of the specification. + +## Security considerations + +None. From c3420770ad3a559217ee5ae7a5998b1c78960055 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Tue, 3 Mar 2020 13:15:32 -0500 Subject: [PATCH 0950/1250] Clarify history of endpoint. --- ...x-remove-query_auth-federation-endpoint.md | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/proposals/xxxx-remove-query_auth-federation-endpoint.md b/proposals/xxxx-remove-query_auth-federation-endpoint.md index 7930c5f8..387f2efa 100644 --- a/proposals/xxxx-remove-query_auth-federation-endpoint.md +++ b/proposals/xxxx-remove-query_auth-federation-endpoint.md @@ -1,26 +1,39 @@ # MSCxxxx: Remove the `query_auth` federation endpoint The `query_auth` federation endpoint is unused by Synapse and should be removed. -The current implementation in Synapse is broken and will return a 500 error in -some situations. +The current implementation in Synapse is not robust and will return a 500 error +in some situations. ## Proposal -Remove: +Remove the following endpoint: * [POST `/_matrix/federation/v1/query_auth/{roomId}/{eventId}`](https://matrix.org/docs/spec/server_server/r0.1.3#post-matrix-federation-v1-query-auth-roomid-eventid) ## Potential issues -Removing this endpoint impacts backwards compatibility. +Removing this endpoint impacts backwards compatibility, in practice removing +this endpoint should have minimal impact as it was an unused error path in +Synapse. The federation client code to call this endpoint was removed in Synapse +v1.5.0rc1. -In practice, removing this endpoint should have minimal impact. Since 1.5.0rc1 -of Synapse this endpoint is not called (see [#6214](https://github.com/matrix-org/synapse/pull/6214)). -During removal it was noted that the code to call this endpoint was already -unreachable. +Note that dendrite has never implemented this federation endpoint. + +### History + +This endpoint (and the federation client code) to call it was initially +added in Synapse v0.7.0 (see [#43](https://github.com/matrix-org/synapse/pull/43)). +The federation client code was heavily modified for v1.0.0rc1 (see +[#5227](https://github.com/matrix-org/synapse/pull/5227/)), -Note that it seems like this was initially supported in Synapse v0.7.0. It is -not clear at what point it became unused. +The federation client code to call this endpoint was removed in v1.5.0rc1 of +Synapse (see [#6214](https://github.com/matrix-org/synapse/pull/6214). After +that point this endpoint is not called). + +During removal it was noted that the code to call this endpoint was already +unreachable. It seems that this code was never reachable and was meant for an +error situation which was never built out (see `git log -S NOT_ANCESTOR`, the +error condition is never assigned). ## Alternatives From 6754d5ba5f4e98ed67c5771a7176cd7d3ecba582 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Tue, 3 Mar 2020 16:18:59 -0500 Subject: [PATCH 0951/1250] Move filename based on MSC #. --- ...ndpoint.md => 2451-remove-query_auth-federation-endpoint.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename proposals/{xxxx-remove-query_auth-federation-endpoint.md => 2451-remove-query_auth-federation-endpoint.md} (96%) diff --git a/proposals/xxxx-remove-query_auth-federation-endpoint.md b/proposals/2451-remove-query_auth-federation-endpoint.md similarity index 96% rename from proposals/xxxx-remove-query_auth-federation-endpoint.md rename to proposals/2451-remove-query_auth-federation-endpoint.md index 387f2efa..d5c2af4d 100644 --- a/proposals/xxxx-remove-query_auth-federation-endpoint.md +++ b/proposals/2451-remove-query_auth-federation-endpoint.md @@ -1,4 +1,4 @@ -# MSCxxxx: Remove the `query_auth` federation endpoint +# MSC2451: Remove the `query_auth` federation endpoint The `query_auth` federation endpoint is unused by Synapse and should be removed. The current implementation in Synapse is not robust and will return a 500 error From 68357a7d23420b069308cfbe99244168307230d6 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 4 Mar 2020 07:31:38 -0500 Subject: [PATCH 0952/1250] Fix a typo in -> and. Co-Authored-By: Matthew Hodgson --- proposals/2451-remove-query_auth-federation-endpoint.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2451-remove-query_auth-federation-endpoint.md b/proposals/2451-remove-query_auth-federation-endpoint.md index d5c2af4d..0d84069e 100644 --- a/proposals/2451-remove-query_auth-federation-endpoint.md +++ b/proposals/2451-remove-query_auth-federation-endpoint.md @@ -37,7 +37,7 @@ error condition is never assigned). ## Alternatives -The endpoint could be deprecated in removed in a future version of the specification. +The endpoint could be deprecated and removed in a future version of the specification. ## Security considerations From 61715f6452bfda06b273d1fc8a94b9412f4910b6 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 4 Mar 2020 08:07:05 -0500 Subject: [PATCH 0953/1250] Update and expand the proposal based on feedback and additional info. --- ...1-remove-query_auth-federation-endpoint.md | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/proposals/2451-remove-query_auth-federation-endpoint.md b/proposals/2451-remove-query_auth-federation-endpoint.md index 0d84069e..b2d8bc9f 100644 --- a/proposals/2451-remove-query_auth-federation-endpoint.md +++ b/proposals/2451-remove-query_auth-federation-endpoint.md @@ -1,8 +1,19 @@ # MSC2451: Remove the `query_auth` federation endpoint -The `query_auth` federation endpoint is unused by Synapse and should be removed. -The current implementation in Synapse is not robust and will return a 500 error -in some situations. +This API was added without sufficient thought nor testing. The endpoint isn't +used in any known implementations, and we do not believe it to be necessary +for federation to work. The only known implementation (in Synapse) was not fully +fleshed out and is broken. + +For background, the idea behind this endpoint was that two homeservers would be +able to share state events with the hope of filling in missing state from one +of homeservers allowing state resolution to complete. This was to protect +against a joining server not providing the full (or providing stale) state. + +In addition to the ideas above not coming to fruition, it is unclear whether the +current design of this endpoint would be sufficient. If this state negotiation +feature is needed in the future it should be redesigned from scratch via the MSC +proposal process. ## Proposal @@ -17,7 +28,8 @@ this endpoint should have minimal impact as it was an unused error path in Synapse. The federation client code to call this endpoint was removed in Synapse v1.5.0rc1. -Note that dendrite has never implemented this federation endpoint. +There is no evidence of other homeserver implementations having implemented this +endpoint. ### History From 438ff8fc1d19f89cbf77583b95a3dbe55d4c6b96 Mon Sep 17 00:00:00 2001 From: "DeepBlueV7.X" Date: Thu, 5 Mar 2020 21:02:09 +0000 Subject: [PATCH 0954/1250] Update proposals/2422-allow-color-attribute-on-font-tag.md Co-Authored-By: Travis Ralston --- proposals/2422-allow-color-attribute-on-font-tag.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proposals/2422-allow-color-attribute-on-font-tag.md b/proposals/2422-allow-color-attribute-on-font-tag.md index 4287a696..7a87f143 100644 --- a/proposals/2422-allow-color-attribute-on-font-tag.md +++ b/proposals/2422-allow-color-attribute-on-font-tag.md @@ -1,6 +1,6 @@ # MSC2422: Allow `color` as attribute for `` in messages -Currently the spec requires you to use `data-mx-color` instead of the standard +Currently the spec recommends that you to use `data-mx-color` instead of the standard `color` html attribute for the `` tag. This is probably done to make it consistent with ``, where you may not want to allow a generic style tag for. @@ -35,4 +35,3 @@ Add the `color` attribute to the allowed attributes of `` in section - Add a section to tell the clients to prefer `color` over `mx-data-color` - Spec an entirely different format for messages (that would probably not make this proposal obsolete) - From 6b2752c4c2c0fd183224f22ed339226362ddddfd Mon Sep 17 00:00:00 2001 From: "DeepBlueV7.X" Date: Thu, 5 Mar 2020 21:02:23 +0000 Subject: [PATCH 0955/1250] Update proposals/2422-allow-color-attribute-on-font-tag.md Co-Authored-By: Travis Ralston --- proposals/2422-allow-color-attribute-on-font-tag.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2422-allow-color-attribute-on-font-tag.md b/proposals/2422-allow-color-attribute-on-font-tag.md index 7a87f143..9e4b1645 100644 --- a/proposals/2422-allow-color-attribute-on-font-tag.md +++ b/proposals/2422-allow-color-attribute-on-font-tag.md @@ -15,7 +15,7 @@ It would probably be for the best to allow or even prefer `color` on the ## Proposal Add the `color` attribute to the allowed attributes of `` in section -13.2.1.7. Allow only hexcodes as allowed value for this attribute for now. +13.2.1.7. No changes to the allowable values from the HTML spec are made here. ## Potential issues From da795e582478da464defd8f68d2635ea1c41eabc Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 5 Mar 2020 17:24:29 -0700 Subject: [PATCH 0956/1250] Apply suggestions from code review Co-Authored-By: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- specification/proposals_intro.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 3f70345f..c3b312ce 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -385,14 +385,14 @@ The process for an implementation willing to be ahead of a spec release is: * When using this approach correctly, the implementation can ship/release the feature at any time, so long as the implementation is able to accept the technical debt that results from needing to provide adequate backwards and forwards - compatibility. The implementation MUST support the flag disappearing and be + compatibility. The implementation MUST support the flag (and server-side implementation) disappearing and be generally safe for users. Note that implementations early in the MSC review process may also be required to provide backwards compatibility with earlier editions of the proposal. * If the implementation cannot support the technical debt (or if it's impossible to provide forwards/backwards compatibility - e.g. a user authentication change which can't be safely rolled back), the implementation should not attempt to - implement the feature and instead wait for a spec release. + implement the feature and should instead wait for a spec release. * If at any point the idea changes, the feature flag should also change so that implementations can adapt as needed. @@ -429,7 +429,7 @@ The process for an implementation willing to be ahead of a spec release is: In summary: * Implementations MUST NOT use stable endpoints before the MSC is in the spec. This - includes NOT using stable endpoints before a spec release happens, but after FCP has + includes NOT using stable endpoints in the period between completion of FCP and release of the spec. passed. * Implementations are able to ship features that are exposed to users by default before an MSC has been merged to the spec, provided they follow the process above. From e6c7eac023e6b55404fa14d9eebf9e462f097f67 Mon Sep 17 00:00:00 2001 From: Runster Date: Fri, 6 Mar 2020 18:11:28 +0100 Subject: [PATCH 0957/1250] Correct name of Phil Zimmermann --- specification/modules/end_to_end_encryption.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index af7b2c59..631b182a 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -505,7 +505,7 @@ framework outlined above. SAS verification is intended to be a highly interactiv process for users, and as such exposes verfiication methods which are easier for users to use. -The verification process is heavily inspired by Phil Zimmerman's ZRTP key agreement +The verification process is heavily inspired by Phil Zimmermann's ZRTP key agreement handshake. A key part of key agreement in ZRTP is the hash commitment: the party that begins the Diffie-Hellman key sharing sends a hash of their part of the Diffie-Hellman exchange, and does not send their part of the Diffie-Hellman exchange until they have From 7666b9fea71ff2129cc4690ae45e9d2a2e6fc58e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 6 Mar 2020 10:56:19 -0700 Subject: [PATCH 0958/1250] Add changelog for name correction https://github.com/matrix-org/matrix-doc/pull/2453 --- changelogs/client_server/newsfragments/2453.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2453.clarification diff --git a/changelogs/client_server/newsfragments/2453.clarification b/changelogs/client_server/newsfragments/2453.clarification new file mode 100644 index 00000000..902a9c3f --- /dev/null +++ b/changelogs/client_server/newsfragments/2453.clarification @@ -0,0 +1 @@ +Fix various spelling errors throughout the specification. From b760ec2d747281294634bec051064191d4fd3357 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sat, 7 Mar 2020 14:57:32 +0100 Subject: [PATCH 0959/1250] Add comments why alternatives to MSC2422 weren't chosen --- .../2422-allow-color-attribute-on-font-tag.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/proposals/2422-allow-color-attribute-on-font-tag.md b/proposals/2422-allow-color-attribute-on-font-tag.md index 9e4b1645..3fb03aa5 100644 --- a/proposals/2422-allow-color-attribute-on-font-tag.md +++ b/proposals/2422-allow-color-attribute-on-font-tag.md @@ -29,9 +29,11 @@ Add the `color` attribute to the allowed attributes of `` in section ## Alternatives -- fix the clients -- remove the `data-mx-color` and `data-mx-bg-color` attributes entirely, leaving - us just with `color` for `` -- Add a section to tell the clients to prefer `color` over `mx-data-color` -- Spec an entirely different format for messages (that would probably not make - this proposal obsolete) +- fix the clients + -> This currently seems not feasible. Multiple clients started using color first (i.e. RiotX, Gomuks) and if it isn't spelled out explicitly in the spec, this will probably continue. +- remove the `data-mx-color` and `data-mx-bg-color` attributes entirely, leaving us just with `color` for `` + -> This would break old messages and can be done independently of this proposal at a later date, if it is deemed useful. +- Add a section to tell the clients to prefer `color` over `mx-data-color` + -> I don't really know, why mx-data-* was chosen, but I assume there was a reason, so I don't want to change that. +- Spec an entirely different format for messages (that would probably not make this proposal obsolete) + -> This wouldn't fix the issue, where some client may choose to remove the color tag, since it is dicouraged in the spec. Migration would probably also take a while, so this proposal is a quick solution, that doesn't prevent other solutions at a later date. From 2d85422a2ff500cb79fcf88c82fa5c73fc4f4b1a Mon Sep 17 00:00:00 2001 From: "DeepBlueV7.X" Date: Sat, 7 Mar 2020 18:34:07 +0000 Subject: [PATCH 0960/1250] Update proposals/2422-allow-color-attribute-on-font-tag.md Co-Authored-By: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/2422-allow-color-attribute-on-font-tag.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2422-allow-color-attribute-on-font-tag.md b/proposals/2422-allow-color-attribute-on-font-tag.md index 3fb03aa5..11f06bff 100644 --- a/proposals/2422-allow-color-attribute-on-font-tag.md +++ b/proposals/2422-allow-color-attribute-on-font-tag.md @@ -19,7 +19,7 @@ Add the `color` attribute to the allowed attributes of `` in section ## Potential issues -- We now have a redundant attribute in the spec. While it matches, what the +- We now have a redundant attribute in the spec. While it matches what the clients currently do, it may be better to fix each client instead. - Clients may not sanitize the color attribute and will let other color values through, increasing compatibility issues again. From 79b2e5263d296a735d3346bf4eb8882841671fb6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sat, 7 Mar 2020 14:05:05 -0700 Subject: [PATCH 0961/1250] Update specification/proposals_intro.rst Co-Authored-By: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- specification/proposals_intro.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index c3b312ce..5ee82dc3 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -393,7 +393,7 @@ The process for an implementation willing to be ahead of a spec release is: to provide forwards/backwards compatibility - e.g. a user authentication change which can't be safely rolled back), the implementation should not attempt to implement the feature and should instead wait for a spec release. - * If at any point the idea changes, the feature flag should also change so that + * If at any point after early release, the idea changes in a backwards-incompatible way, the feature flag should also change so that implementations can adapt as needed. 3. In parallel, or ahead of implementation, open an MSC and solicit review per above. From c69a747bae52296f8a7fe930090c64c98227cd73 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Mon, 9 Mar 2020 12:31:06 -0400 Subject: [PATCH 0962/1250] Convert the initial Google Doc to Markdown. --- proposals/xxxx-ui-interactive-auth-for-sso.md | 262 ++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 proposals/xxxx-ui-interactive-auth-for-sso.md diff --git a/proposals/xxxx-ui-interactive-auth-for-sso.md b/proposals/xxxx-ui-interactive-auth-for-sso.md new file mode 100644 index 00000000..fc7413fe --- /dev/null +++ b/proposals/xxxx-ui-interactive-auth-for-sso.md @@ -0,0 +1,262 @@ +# User-Interactive Auth for SSO-backed homeservers + +## Background + +Certain endpoints, such as `DELETE /_matrix/client/r0/devices/{deviceId}` and +`POST /_matrix/client/r0/account/3pid/add`, require the user to reconfirm their +identity, as a guard against a leaked access token being used to take over an +entire account. + +On a normal homeserver, this is done by prompting the user to enter their +password. However, on a homeserver where users authenticate via a single-sign-on +system, the user doesn't have a password, so this doesn't work. Instead we need +to delegate that check to the SSO system. + +At the protocol level, this means adding support for SSO to +[user-interactive auth](https://matrix.org/docs/spec/client_server/r0.6.0#user-interactive-authentication-api). + +### The current implementation + +Or, "how UI Auth works, in practice": + +When the client calls one of the protected endpoints, it initially returns a 401 +response. For example: + +``` +POST /_matrix/client/r0/delete_devices HTTP/1.1 +Content-Type: application/json + +{ + "devices": ["FSVVTZRRAA"] +} + +HTTP/1.1 401 Unauthorized +Content-Type: application/json + +{ + "flows": [ + { + "stages": [ + "m.login.password" + ] + } + ], + "params": {}, + "session": "dTKfsLHSAJeAhqfxUsvrIVJd" +} +``` + +The client: + +* inspects the "flows" list +* discovers there is a flow it knows how to follow +* carries out the first "stage" of that flow (m.login.password) + +ie, the client prompts the user to enter a password. + +The client then resubmits with an additional 'auth' param, with "type" giving +the name of the authentication type it has just carried out. That completes the +authentication flow, so the server is now happy, and returns a 200: + +``` +POST /_matrix/client/r0/delete_devices HTTP/1.1 +Content-Type: application/json + +{ + "devices": ["FSVVTZRRAA"], + "auth": { + "session":"dTKfsLHSAJeAhqfxUsvrIVJd", + "type":"m.login.password", + "identifier":{"type":"m.id.user", "user":"@userid:matrix.org"}, + "password":"" + } +} + + +HTTP/1.1 200 OK +Content-Type: application/json +Content-Length: 179 + +{} +``` + +## Proposal + +We add an `m.login.sso` authentication type to the UI auth spec. There are no +additional params as part of this auth type. + +1. If the client wants to complete that authentication type, it opens a browser + window for `/_matrix/client/r0/auth/m.login.sso/fallback/web?session=<...>` + with session set to the UI-Auth session id (from the "auth" dict). + + The homeserver returns a page which says words to the effect of "A client is + trying to remove a device/add an email address/take over your account. To + confirm this action, **re-authenticate with single sign-on**. If you did not + expect this, your account may be compromised!" + + See security section below. +2. The link, once the user clicks on it, goes to the SSO provider's page. +3. The SSO provider validates the user, and redirects the browser back to the + homeserver. +4. The homeserver validates the response from the SSO provider, updates the + user-interactive auth session to show that the SSO has completed, serves the + fallback auth completion page as specced: + https://matrix.org/docs/spec/client_server/r0.6.0#fallback +5. The client resubmits its original request, with its original session id, + which now hopefully completes. + +Note that the post-SSO URL on the homeserver is left up to the homeserver +implementation rather than forming part of the spec. + +* SAML2 servers typically only support one URL per service provider, so in + practice it will need to be the same as that already used for the login flow + (for synapse, it's /_matrix/saml2/authn_response) - and the server needs to + be able to figure out if it's doing SSO for a login attempt or an SSO + attempt. +* CAS doesn't have the same restriction. + +### Example flow: + +0. Client submits the request, which the server says requires SSO: + + ``` + POST /_matrix/client/r0/delete_devices HTTP/1.1 + Content-Type: application/json + Authorization: Bearer xyzzy + + { + "devices": ["FSVVTZRRAA"] + } + + HTTP/1.1 401 Unauthorized + Content-Type: application/json + + { + "flows": [ + { + "stages": [ + "m.login.sso" + ] + } + ], + "params": {}, + "session": "dTKfsLHSAJeAhqfxUsvrIVJd" + } + ``` + +1. Client opens a browser window for the fallback endpoint: + + ``` + GET /_matrix/client/r0/auth/m.login.sso/fallback/web + ?session=dTKfsLHSAJeAhqfxUsvrIVJd HTTP/1.1 + + HTTP/1.1 200 OK + + + can delete device pls? + clicky + + ``` + +2. The user clicks the confirmation link which goes to the SSO provider's site: + + ``` + GET https://sso_provider/validate?SAMLRequest= HTTP/1.1 + + ... SAML/CAS stuff + ``` + +3. The SSO provider validates the user and ends up redirecting the browser back + to the homeserver. (The example below shows a 302 for simplicity but SAML normally uses a 200 with an html
, with javascript to automatically submit it.) + + ``` + HTTP/1.1 302 Moved + Location: https://homeserver/_matrix/saml2/authn_response? + SAMLResponse= + ``` + +4. The browser sends the SSO response to the homeserver, which validates it and + shows the fallback auth completion page: + + ``` + GET /_matrix/saml2/authn_response?SAMLResponse= + + + HTTP/1.1 200 OK + + + +

Thank you.

+

You may now close this window and return to the application.

+ ``` + +5. The client closes the browser popup if it is still open, and resubmits its + original request, which now succeeds: + + ``` + POST /_matrix/client/r0/delete_devices HTTP/1.1 + Content-Type: application/json + Authorization: Bearer xyzzy + + { + "auth": { + "session": "dTKfsLHSAJeAhqfxUsvrIVJd" + } + } + + HTTP/1.1 200 OK + Content-Type: application/json + + {} + ``` + +A few notes: + +* The security of this relies on UI-Auth sessions only being used for the same + request as they were initiated for. I don't think that's currently enforced. +* We might consider an alternative client flow where the fallback auth ends up + redirecting to a given URI, instead of doing javascript postMessage foo. I + think that's an orthogonal change to the fallback auth though. +* In theory, any clients that already implement the fallback process for + unknown authentication types will work fine without modification. + Unfortunately, I don't think Riot (on any platform) is among them. + +## Security considerations + +Recall that the thing we are trying to guard against here is a single leaked +access-token being used to take over an entire account. So let's assume the +attacker has got hold of an access token for your account. What happens if we + skip the confirmation step? + +The attacker, who has your access token, starts a UI-Auth session to add his +email address to your account. + +He then sends you a link "hey, check out this cool video!"; the link leads (via +an innocent-looking url shortener) to +`/_matrix/client/r0/auth/m.login.sso/fallback/web?session=<...>`, with the ID of +the session that he just created. + +Recall that we're skipping the confirmation step, so the server redirects +straight to the SSO provider. + +It's common for SSO providers to redirect straight back to the app if you've +recently authenticated with them; even in the best case, the SSO provider shows +some innocent message along the lines of "Confirm that you want to sign in to +". + +So the SSO completes, and the attacker's session is validated. + +By telling the user what's about to happen as clearly as we can, and making them +confirm, we can mitigate this problem. + +## Unstable prefix + +We should use a vendor prefix here until this hits the spec. + +`org.matrix.login.sso` ? \ No newline at end of file From f48bbd32788ec8734fbaaa85728197632aeffd61 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Mon, 9 Mar 2020 14:00:28 -0400 Subject: [PATCH 0963/1250] Attempt to clarify the MSC. --- proposals/xxxx-ui-interactive-auth-for-sso.md | 90 ++++++++++--------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/proposals/xxxx-ui-interactive-auth-for-sso.md b/proposals/xxxx-ui-interactive-auth-for-sso.md index fc7413fe..5b6f396d 100644 --- a/proposals/xxxx-ui-interactive-auth-for-sso.md +++ b/proposals/xxxx-ui-interactive-auth-for-sso.md @@ -1,6 +1,4 @@ -# User-Interactive Auth for SSO-backed homeservers - -## Background +# User-Interactive Auth for SSO-backed homeserver Certain endpoints, such as `DELETE /_matrix/client/r0/devices/{deviceId}` and `POST /_matrix/client/r0/account/3pid/add`, require the user to reconfirm their @@ -9,15 +7,17 @@ entire account. On a normal homeserver, this is done by prompting the user to enter their password. However, on a homeserver where users authenticate via a single-sign-on -system, the user doesn't have a password, so this doesn't work. Instead we need -to delegate that check to the SSO system. +system, the user doesn't have a password registered with the homeserver. Instead +we need to delegate that check to the SSO system. At the protocol level, this means adding support for SSO to [user-interactive auth](https://matrix.org/docs/spec/client_server/r0.6.0#user-interactive-authentication-api). -### The current implementation +In theory, any clients that already implement the fallback process for unknown +authentication types will work fine without modification. It is unknown whether +this is widely supported among clients. -Or, "how UI Auth works, in practice": +### UI Auth Overview When the client calls one of the protected endpoints, it initially returns a 401 response. For example: @@ -52,7 +52,7 @@ The client: * discovers there is a flow it knows how to follow * carries out the first "stage" of that flow (m.login.password) -ie, the client prompts the user to enter a password. +In this example, the client prompts the user to enter a password. The client then resubmits with an additional 'auth' param, with "type" giving the name of the authentication type it has just carried out. That completes the @@ -89,24 +89,25 @@ additional params as part of this auth type. window for `/_matrix/client/r0/auth/m.login.sso/fallback/web?session=<...>` with session set to the UI-Auth session id (from the "auth" dict). - The homeserver returns a page which says words to the effect of "A client is - trying to remove a device/add an email address/take over your account. To - confirm this action, **re-authenticate with single sign-on**. If you did not - expect this, your account may be compromised!" + The homeserver returns a page which asks for the user's confirmation before + proceeding. See the security considerations section below for why this is + necessary. For example, the page could say words to the effect of: - See security section below. + > A client is trying to remove a device/add an email address/take over your + > account. To confirm this action, **re-authenticate with single sign-on**. + > If you did not expect this, your account may be compromised! 2. The link, once the user clicks on it, goes to the SSO provider's page. 3. The SSO provider validates the user, and redirects the browser back to the homeserver. 4. The homeserver validates the response from the SSO provider, updates the - user-interactive auth session to show that the SSO has completed, serves the - fallback auth completion page as specced: - https://matrix.org/docs/spec/client_server/r0.6.0#fallback + user-interactive auth session to show that the SSO has completed, + [serves the fallback auth completion page as specced](https://matrix.org/docs/spec/client_server/r0.6.0#fallback). 5. The client resubmits its original request, with its original session id, - which now hopefully completes. + which now should complete. Note that the post-SSO URL on the homeserver is left up to the homeserver -implementation rather than forming part of the spec. +implementation rather than forming part of the specification, choices might be +limited by the chosen SSO implementation, for example: * SAML2 servers typically only support one URL per service provider, so in practice it will need to be the same as that already used for the login flow @@ -216,47 +217,50 @@ implementation rather than forming part of the spec. {} ``` -A few notes: +## Alternatives -* The security of this relies on UI-Auth sessions only being used for the same - request as they were initiated for. I don't think that's currently enforced. -* We might consider an alternative client flow where the fallback auth ends up - redirecting to a given URI, instead of doing javascript postMessage foo. I - think that's an orthogonal change to the fallback auth though. -* In theory, any clients that already implement the fallback process for - unknown authentication types will work fine without modification. - Unfortunately, I don't think Riot (on any platform) is among them. +An alternative client flow where the fallback auth ends up redirecting to a +given URI, instead of doing JavaScript postMessage foo could be considered. +This is probably an orthogonal change to the fallback auth though. ## Security considerations +### Why we need user to confirm before the SSO flow + Recall that the thing we are trying to guard against here is a single leaked access-token being used to take over an entire account. So let's assume the -attacker has got hold of an access token for your account. What happens if we - skip the confirmation step? +attacker has got hold of an access token for your account. What happens if the +confirmation step is skipped? -The attacker, who has your access token, starts a UI-Auth session to add his -email address to your account. +The attacker, who has your access token, starts a UI Authentication session to +add their email address to your account. -He then sends you a link "hey, check out this cool video!"; the link leads (via -an innocent-looking url shortener) to +They then sends you a link "hey, check out this cool video!"; the link leads (via +an innocent-looking URL shortener or some other phishing technique) to `/_matrix/client/r0/auth/m.login.sso/fallback/web?session=<...>`, with the ID of the session that he just created. -Recall that we're skipping the confirmation step, so the server redirects -straight to the SSO provider. +Since there is no confirmation step, the server redirects directly to the SSO +provider. It's common for SSO providers to redirect straight back to the app if you've recently authenticated with them; even in the best case, the SSO provider shows -some innocent message along the lines of "Confirm that you want to sign in to -". +an innocent message along the lines of "Confirm that you want to sign in to +". -So the SSO completes, and the attacker's session is validated. +After redirecting back to the homeserver, the SSO is completed and the +attacker's session is validated. They are now able to make their malicious +change to your account. -By telling the user what's about to happen as clearly as we can, and making them -confirm, we can mitigate this problem. +This problem can be mitigated by clearly telling the user what is about to happen. -## Unstable prefix +### Reusing UI-Auth sessions -We should use a vendor prefix here until this hits the spec. +The security of this relies on UI-Auth sessions only being used for the same +request as they were initiated for. It is not believed that this is currently +enforced. + +## Unstable prefix -`org.matrix.login.sso` ? \ No newline at end of file +A vendor prefix of `org.matrix.login.sso` (instead of `m.login.sso` is proposed +until this is part of the specification. From 4d177753e1e8043b92f9bcec0c4501b9a2802a63 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Mon, 9 Mar 2020 15:05:37 -0400 Subject: [PATCH 0964/1250] Move proposal to proper proposal number. --- ...active-auth-for-sso.md => 2454-ui-interactive-auth-for-sso.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/{xxxx-ui-interactive-auth-for-sso.md => 2454-ui-interactive-auth-for-sso.md} (100%) diff --git a/proposals/xxxx-ui-interactive-auth-for-sso.md b/proposals/2454-ui-interactive-auth-for-sso.md similarity index 100% rename from proposals/xxxx-ui-interactive-auth-for-sso.md rename to proposals/2454-ui-interactive-auth-for-sso.md From 570398e045476fcf4e289367d4856d44b0882b67 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Tue, 10 Mar 2020 10:00:58 -0400 Subject: [PATCH 0965/1250] Remove section on the how the authentication currently works and just reference the specification. --- proposals/2454-ui-interactive-auth-for-sso.md | 65 +------------------ 1 file changed, 1 insertion(+), 64 deletions(-) diff --git a/proposals/2454-ui-interactive-auth-for-sso.md b/proposals/2454-ui-interactive-auth-for-sso.md index 5b6f396d..bfad25a9 100644 --- a/proposals/2454-ui-interactive-auth-for-sso.md +++ b/proposals/2454-ui-interactive-auth-for-sso.md @@ -11,75 +11,12 @@ system, the user doesn't have a password registered with the homeserver. Instead we need to delegate that check to the SSO system. At the protocol level, this means adding support for SSO to -[user-interactive auth](https://matrix.org/docs/spec/client_server/r0.6.0#user-interactive-authentication-api). +[user-interactive authentication API](https://matrix.org/docs/spec/client_server/r0.6.0#user-interactive-authentication-api). In theory, any clients that already implement the fallback process for unknown authentication types will work fine without modification. It is unknown whether this is widely supported among clients. -### UI Auth Overview - -When the client calls one of the protected endpoints, it initially returns a 401 -response. For example: - -``` -POST /_matrix/client/r0/delete_devices HTTP/1.1 -Content-Type: application/json - -{ - "devices": ["FSVVTZRRAA"] -} - -HTTP/1.1 401 Unauthorized -Content-Type: application/json - -{ - "flows": [ - { - "stages": [ - "m.login.password" - ] - } - ], - "params": {}, - "session": "dTKfsLHSAJeAhqfxUsvrIVJd" -} -``` - -The client: - -* inspects the "flows" list -* discovers there is a flow it knows how to follow -* carries out the first "stage" of that flow (m.login.password) - -In this example, the client prompts the user to enter a password. - -The client then resubmits with an additional 'auth' param, with "type" giving -the name of the authentication type it has just carried out. That completes the -authentication flow, so the server is now happy, and returns a 200: - -``` -POST /_matrix/client/r0/delete_devices HTTP/1.1 -Content-Type: application/json - -{ - "devices": ["FSVVTZRRAA"], - "auth": { - "session":"dTKfsLHSAJeAhqfxUsvrIVJd", - "type":"m.login.password", - "identifier":{"type":"m.id.user", "user":"@userid:matrix.org"}, - "password":"" - } -} - - -HTTP/1.1 200 OK -Content-Type: application/json -Content-Length: 179 - -{} -``` - ## Proposal We add an `m.login.sso` authentication type to the UI auth spec. There are no From 78e08c1987460cd14eba27f503b95b6dc4083a29 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Tue, 10 Mar 2020 10:11:08 -0400 Subject: [PATCH 0966/1250] Attempt to clarify the proposed changes. --- proposals/2454-ui-interactive-auth-for-sso.md | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/proposals/2454-ui-interactive-auth-for-sso.md b/proposals/2454-ui-interactive-auth-for-sso.md index bfad25a9..d3cab51b 100644 --- a/proposals/2454-ui-interactive-auth-for-sso.md +++ b/proposals/2454-ui-interactive-auth-for-sso.md @@ -1,4 +1,4 @@ -# User-Interactive Auth for SSO-backed homeserver +# User-Interactive Authentication for SSO-backed homeserver Certain endpoints, such as `DELETE /_matrix/client/r0/devices/{deviceId}` and `POST /_matrix/client/r0/account/3pid/add`, require the user to reconfirm their @@ -10,17 +10,21 @@ password. However, on a homeserver where users authenticate via a single-sign-on system, the user doesn't have a password registered with the homeserver. Instead we need to delegate that check to the SSO system. -At the protocol level, this means adding support for SSO to +At the protocol level, this means adding support for SSO to the [user-interactive authentication API](https://matrix.org/docs/spec/client_server/r0.6.0#user-interactive-authentication-api). -In theory, any clients that already implement the fallback process for unknown -authentication types will work fine without modification. It is unknown whether -this is widely supported among clients. +In theory, once SSO is added as a possible flow for authentication any clients +that already implement the [fallback process for unknown authentication types](https://matrix.org/docs/spec/client_server/r0.6.0#fallback) +will work fine without modification. It is unknown whether this is widely +supported among clients. ## Proposal -We add an `m.login.sso` authentication type to the UI auth spec. There are no -additional params as part of this auth type. +An [additional authentication type](https://matrix.org/docs/spec/client_server/r0.6.0#authentication-types) +of `m.login.sso` is added to the user-interactive authentication specification. +There are no additional parameters as part of this authentication type. + +When choosing this authentication flow, the following should occur: 1. If the client wants to complete that authentication type, it opens a browser window for `/_matrix/client/r0/auth/m.login.sso/fallback/web?session=<...>` @@ -91,8 +95,9 @@ limited by the chosen SSO implementation, for example: HTTP/1.1 200 OK - can delete device pls? - clicky + A client is trying to remove a device from your account. To confirm this + action, re-authenticate with single sign-on. + If you did not expect this, your account may be compromised! ``` @@ -101,11 +106,12 @@ limited by the chosen SSO implementation, for example: ``` GET https://sso_provider/validate?SAMLRequest= HTTP/1.1 - ... SAML/CAS stuff + ``` 3. The SSO provider validates the user and ends up redirecting the browser back - to the homeserver. (The example below shows a 302 for simplicity but SAML normally uses a 200 with an html , with javascript to automatically submit it.) + to the homeserver. The example below shows a 302 for simplicity, this might + vary based on SSO implementation. ``` HTTP/1.1 302 Moved @@ -191,13 +197,13 @@ change to your account. This problem can be mitigated by clearly telling the user what is about to happen. -### Reusing UI-Auth sessions +### Reusing User Interactive Authentication sessions -The security of this relies on UI-Auth sessions only being used for the same -request as they were initiated for. It is not believed that this is currently -enforced. +The security of this relies on User Interactive Authentication sessions only +being used for the same request as they were initiated for. It is not believed +that this is currently enforced. ## Unstable prefix -A vendor prefix of `org.matrix.login.sso` (instead of `m.login.sso` is proposed +A vendor prefix of `org.matrix.login.sso` is proposed (instead of `m.login.sso`) until this is part of the specification. From 1facf7ff12834ad06fcaff9ee5e2cdf9d1302837 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Thu, 12 Mar 2020 14:14:20 -0400 Subject: [PATCH 0967/1250] Add an MSC proposal for how to handle sessions when modifying a password. --- ...sword-modification-invalidating-devices.md | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 proposals/2457-password-modification-invalidating-devices.md diff --git a/proposals/2457-password-modification-invalidating-devices.md b/proposals/2457-password-modification-invalidating-devices.md new file mode 100644 index 00000000..910e7b62 --- /dev/null +++ b/proposals/2457-password-modification-invalidating-devices.md @@ -0,0 +1,53 @@ +# Invalidating devices during password modification + +There are multiple use cases for why a user might want to modify their password: + +* Adopting a password manager (to use a unique password or more secure password). +* Password rotation. +* Re-secure a compromised account. +* ... probably tons of others ... + +These can be summarized into two groups: + +1. "My account has been compromised and I need to re-secure it." +2. "I just want to change my password." + +The [current Matrix specification](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-password) +does not provide a way to differentiate between these use cases. It gives no +guidance into what should happen to other sessions / devices when a password is +modified and leaves it up to the implementation. + +It is reasonable for a client to want to specify this behavior to offer two +different workflows: + +1. Modify a password and log all other devices out (for use when an account has + been compromised). +2. Modify a password and do not touch any session data (for use in a + non-malicious situations). + +Alternately a client may default to whichever workflow is best for their users. + +## Proposal + +An optional field is added to the JSON body body of the [password reset endpoint](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-password) +called `logout_devices`. This is a boolean flag (defaulting to `true`) that +signals to whether other devices and sessions should be invalidated after +modifying the password. + +## Potential issues + +While Synapse defaults to the behavior of invalidating other devices and +sessions this may not be true of other implementations. Thus, a default of +`true` may not be backwards compatible. It might be more prudent to specify that +the behavior of not specifying the `logout_devices` flag is undefined. + +## Alternatives + +Provide a new endpoint in a future version that supports an additional field (as +above), using a new endpoint would avoid backwards compatibility issues. + +## Security considerations + +By defaulting to invalidating devices and sessions the security considerations +of this endpoint should remain intact. A client will need to be modified to +choose to keep other devices active. From 61b306f8a8a63005f2ab131d32cbf1d5409ddada Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Fri, 13 Mar 2020 07:12:57 -0400 Subject: [PATCH 0968/1250] Remove concerns about backwards compatibility. --- ...-password-modification-invalidating-devices.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/proposals/2457-password-modification-invalidating-devices.md b/proposals/2457-password-modification-invalidating-devices.md index 910e7b62..9af6e229 100644 --- a/proposals/2457-password-modification-invalidating-devices.md +++ b/proposals/2457-password-modification-invalidating-devices.md @@ -36,15 +36,18 @@ modifying the password. ## Potential issues -While Synapse defaults to the behavior of invalidating other devices and -sessions this may not be true of other implementations. Thus, a default of -`true` may not be backwards compatible. It might be more prudent to specify that -the behavior of not specifying the `logout_devices` flag is undefined. +The specification states: + +> The homeserver SHOULD NOT revoke the access token provided in the request, +> however all other access tokens for the user should be revoked if the request +> succeeds. + +Defaulting `logout_devices` to `true` should be backwards compatible. ## Alternatives -Provide a new endpoint in a future version that supports an additional field (as -above), using a new endpoint would avoid backwards compatibility issues. +A new endpoint could be provided in a future version of the specification that +supports an additional field (as described above). ## Security considerations From 2d2731efff99ddeb67bdb16a716ed1eba8660189 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Mon, 16 Mar 2020 10:42:17 -0400 Subject: [PATCH 0969/1250] Remove duplicated word. Co-Authored-By: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- proposals/2457-password-modification-invalidating-devices.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2457-password-modification-invalidating-devices.md b/proposals/2457-password-modification-invalidating-devices.md index 9af6e229..9b59156c 100644 --- a/proposals/2457-password-modification-invalidating-devices.md +++ b/proposals/2457-password-modification-invalidating-devices.md @@ -29,7 +29,7 @@ Alternately a client may default to whichever workflow is best for their users. ## Proposal -An optional field is added to the JSON body body of the [password reset endpoint](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-password) +An optional field is added to the JSON body of the [password reset endpoint](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-password) called `logout_devices`. This is a boolean flag (defaulting to `true`) that signals to whether other devices and sessions should be invalidated after modifying the password. From 7917d087f3874f07cfaf0750ed493ded95bc77ac Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 19 Mar 2020 15:21:50 +0000 Subject: [PATCH 0970/1250] clarifications --- proposals/2432-revised-alias-publishing.md | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/proposals/2432-revised-alias-publishing.md b/proposals/2432-revised-alias-publishing.md index dff72df5..4c2f010f 100644 --- a/proposals/2432-revised-alias-publishing.md +++ b/proposals/2432-revised-alias-publishing.md @@ -96,8 +96,16 @@ rules](https://matrix.org/docs/spec/rooms/v1#authorization-rules) and (Note: Synapse currently implements this check on the main alias, though this is unspecced.) - (TODO: what error code should be returned if the alias is invalid, or if it - points to the wrong room?) + The following error codes are specified: + + * HTTP 400, with `errcode: M_INVALID_PARAMETER` if an attempt is made to add + an entry which is not a well-formed alias (examples: too long, doesn't + start with `#`, doesn't contain a `:`). + + * HTTP 400, with `errcode: M_BAD_ALIAS` if an added alias does not point at + the given room (either because the alias doesn't exist, because it can't + be resolved due to an unreachable server, or because the alias points at a + different room). * Currently, [`PUT /_matrix/client/r0/directory/room/{roomAlias}`](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-directory-room-roomalias) attempts to send updated `m.room.aliases` events on the caller's @@ -110,8 +118,14 @@ rules](https://matrix.org/docs/spec/rooms/v1#authorization-rules) and deleted. (Again, this is implemented in Synapse but does not appear to be explicitly specced.) The `m.room.aliases` functionality should be removed, and the `m.room.canonical_alias` functionality should be extended to cover - `alt_aliases`. As today, no error occurs if the caller does not have - permission to send such an event. + `alt_aliases`. + + The behaviour if the calling user has permission to delete the alias but + does not have permission to send `m.room.canonical_alias` events in the room + (for example, by virtue of being a "server administrator", or by being the + user that created the alias) is implementation-defined. It is *recommended* + that in this case, the alias is deleted anyway, and a successful response is + returned to the client. * A new api endpoint, `GET /_matrix/client/r0/rooms/{roomId}/aliases` is added, which returns the list of aliases currently defined on the local From 2b71234f3c8cd39da78ae63553d1c97f9d9aed6e Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 19 Mar 2020 14:39:54 -0400 Subject: [PATCH 0971/1250] clarify first run of iterative auth checks --- specification/rooms/v2.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/rooms/v2.rst b/specification/rooms/v2.rst index 4e8365bf..afc114f8 100644 --- a/specification/rooms/v2.rst +++ b/specification/rooms/v2.rst @@ -148,8 +148,8 @@ 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 +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. 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 From a0fcb7d9e140ded9ed5ed8f4980bff6d5c02e3c1 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 19 Mar 2020 17:10:44 -0400 Subject: [PATCH 0972/1250] make code required, and some more details about no_olm --- proposals/2399-reporting-no-key-sent.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/proposals/2399-reporting-no-key-sent.md b/proposals/2399-reporting-no-key-sent.md index 46ec8c7f..58f2acb8 100644 --- a/proposals/2399-reporting-no-key-sent.md +++ b/proposals/2399-reporting-no-key-sent.md @@ -31,7 +31,7 @@ the properties: - `algorithm`: Required. The encryption algorithm that the key is for. - `session_id`: Required if `code` is not `m.no_olm`. The ID of the session. - `sender_key`: Required. The key of the session creator. -- `code`: A machine-readable code for why the key was not sent. +- `code`: Required. A machine-readable code for why the key was not sent. Possible values are: - `m.blacklisted`: the user/device was blacklisted - `m.unverified`: the user/devices is unverified @@ -43,10 +43,9 @@ the properties: - `m.no_olm`: an olm session could not be established. This may happen, for example, if the sender was unable to obtain a one-time key from the recipient. -- `reason`: A human-readable reason for why the key was not sent. If there is - a `code`, this should be a human-readable representation of `code`. The +- `reason`: A human-readable reason for why the key was not sent. The receiving client should only use this string if it does not understand the - `code` or if `code` is not provided. + `code`. An `m.room_key.withheld` event should only be sent once per session; the recipient of the event should assume that the event applies to all messages in @@ -60,8 +59,11 @@ A `code` of `m.no_olm` is used to indicate that the sender is unable to establish an olm session with the recipient. When this happens, multiple sessions will be affected. In order to avoid filling the recipient's device mailbox, the sender should only send one `m.room_key.withheld` message with no -`room_id` nor `session_id` set. FIXME: how does the recipient determine which -sessions the notification applies to? +`room_id` nor `session_id` set. In response to receiving this message, the +recipient may start an olm session with the sender, and send an `m.dummy` +message to notify the sender of the new olm session. The recipient may assume +that this `m.room_key.withheld` message applies to all encrypted room messages +sent before it receives the message. ## Potential issues @@ -71,8 +73,7 @@ megolm keys. ## Security considerations A user might not want to notify another user of the reason why it was not sent -the keys. Sending `m.room_key.withheld`, or specifying the `reason`/`code` are -optional. +the keys. Sending `m.room_key.withheld` is optional. ## Unstable prefix From 28dc6a05153437c76156ea022c7d2a7efe58be04 Mon Sep 17 00:00:00 2001 From: "DeepBlueV7.X" Date: Fri, 20 Mar 2020 20:29:44 +0000 Subject: [PATCH 0973/1250] Update proposals/2422-allow-color-attribute-on-font-tag.md Apply typo fix as suggested. Co-Authored-By: David Vo --- proposals/2422-allow-color-attribute-on-font-tag.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2422-allow-color-attribute-on-font-tag.md b/proposals/2422-allow-color-attribute-on-font-tag.md index 11f06bff..4e6a9ced 100644 --- a/proposals/2422-allow-color-attribute-on-font-tag.md +++ b/proposals/2422-allow-color-attribute-on-font-tag.md @@ -36,4 +36,4 @@ Add the `color` attribute to the allowed attributes of `` in section - Add a section to tell the clients to prefer `color` over `mx-data-color` -> I don't really know, why mx-data-* was chosen, but I assume there was a reason, so I don't want to change that. - Spec an entirely different format for messages (that would probably not make this proposal obsolete) - -> This wouldn't fix the issue, where some client may choose to remove the color tag, since it is dicouraged in the spec. Migration would probably also take a while, so this proposal is a quick solution, that doesn't prevent other solutions at a later date. + -> This wouldn't fix the issue, where some client may choose to remove the color tag, since it is discouraged in the spec. Migration would probably also take a while, so this proposal is a quick solution, that doesn't prevent other solutions at a later date. From e67ba0cd05e9021386253bace2be136f3cec0a11 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 20 Mar 2020 16:49:53 -0400 Subject: [PATCH 0974/1250] add note indicating similarity between key backup format and key exports also copy description of forwarding_curve25519_key_chain from key exports, since it's a better description --- specification/modules/end_to_end_encryption.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 63690924..a1ce68f6 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -861,12 +861,14 @@ The ``session_data`` field in the backups is constructed as follows: 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`_ events. sender_key string Required. Unpadded base64-encoded device curve25519 key. sender_claimed_keys {string: Required. Object containing the string} identity key for the sending device. - forwarding_curve25519_key_chain [string] Required. Zero or more curve25519 keys - for devices who forwarded the session key. session_key string Required. Unpadded base64-encoded session key in `session-sharing format `_. @@ -961,6 +963,9 @@ described as follows: 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`_ but adds the ``room_id`` and ``session_id`` fields. + Example: .. code:: json From 30586ed98c6862f3822616cee79ad15a406591fa Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 20 Mar 2020 16:55:56 -0400 Subject: [PATCH 0975/1250] remove extra space --- specification/modules/end_to_end_encryption.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index a1ce68f6..6945ce42 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -868,7 +868,7 @@ The ``session_data`` field in the backups is constructed as follows: sender_key string Required. Unpadded base64-encoded device curve25519 key. sender_claimed_keys {string: Required. Object containing the - string} identity key for the sending device. + string} identity key for the sending device. session_key string Required. Unpadded base64-encoded session key in `session-sharing format `_. From 4d808762da4968594c63068351598dbae7245784 Mon Sep 17 00:00:00 2001 From: Aaron Axvig Date: Mon, 23 Mar 2020 12:11:18 -0400 Subject: [PATCH 0976/1250] Change formatting from italics to code --- api/client-server/redaction.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client-server/redaction.yaml b/api/client-server/redaction.yaml index 58141049..907b1d16 100644 --- a/api/client-server/redaction.yaml +++ b/api/client-server/redaction.yaml @@ -37,7 +37,7 @@ paths: 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 + greater than or equal to the ``redact`` power level of the room may redact events there. operationId: redactEvent security: From fc03f7faa6e1d47ccc8470837beef1f43287929b Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Tue, 24 Mar 2020 12:42:15 -0400 Subject: [PATCH 0977/1250] Remove query_auth from the specification per MSC2451. --- api/server-server/event_auth.yaml | 134 ---------------------------- specification/server_server_api.rst | 1 - 2 files changed, 135 deletions(-) diff --git a/api/server-server/event_auth.yaml b/api/server-server/event_auth.yaml index 0db0d401..8f545e1d 100644 --- a/api/server-server/event_auth.yaml +++ b/api/server-server/event_auth.yaml @@ -72,137 +72,3 @@ paths: example: $ref: "examples/minimal_pdu.json" required: ['auth_chain'] - "/query_auth/{roomId}/{eventId}": - post: - summary: Compare auth chains with the receiving server - description: |- - Compares the auth chain provided with what the receiving server has for the - room ID and event ID combination. - - The auth difference can be calculated in two parts, where the "remote auth" - is the auth chain provided by the sending server and the "local auth" is the - auth chain the receiving server has. With those lists, the algorithm works - bottom-up after sorting each chain by depth then by event ID. The differences - are then discovered and returned as the response to this API call. - operationId: compareEventAuth - security: - - signedRequest: [] - parameters: - - in: path - name: roomId - type: string - description: The room ID to compare the auth chain in. - required: true - x-example: "!abc123:matrix.org" - - in: path - name: eventId - type: string - description: The event ID to compare the auth chain of. - required: true - x-example: "$helloworld:example.org" - - in: body - name: body - schema: - type: object - properties: - auth_chain: - type: array - description: |- - The auth chain (the "remote auth"). Note that events have a different - format depending on the room version - check the `room version specification`_ - for precise event formats. - items: - type: object - title: PDU - description: |- - The `PDUs <#pdus>`_ contained in the auth chain. The event format - varies depending on the room version - check the `room version specification`_ - for precise event formats. - properties: [] - example: - $ref: "examples/minimal_pdu.json" - missing: - type: array - description: |- - A list of event IDs that the sender thinks the receiver is missing. - items: - type: string - example: [] - rejects: - type: object - description: |- - The set of events that the sending server has rejected from the provided - auth chain. - - The ``string`` key is the event ID that was rejected. - additionalProperties: - type: object - title: Rejection Reason - properties: - reason: - type: enum - enum: ['auth_error', 'replaced', 'not_ancestor'] - description: |- - The reason for the event being rejected. - required: ['reason'] - example: { - "$some_event:example.org": { - "reason": "auth_error" - } - } - required: ['auth_chain'] - responses: - 200: - description: The auth chain differences, as determined by the receiver. - schema: - type: object - properties: - auth_chain: - type: array - description: |- - The auth chain the receiver has, and used to determine the auth - chain differences (the "local auth"). Note that events have a different - format depending on the room version - check the `room version specification`_ - for precise event formats. - items: - type: object - title: PDU - description: |- - The `PDUs <#pdus>`_ contained in the auth chain. The event format - varies depending on the room version - check the `room version specification`_ - for precise event formats. - properties: [] - example: - $ref: "examples/minimal_pdu.json" - missing: - type: array - description: |- - The list of event IDs that the receiver believes it is missing, - after comparing the "remote auth" and "local auth" chains. - items: - type: string - example: ["$a_missing_event:example.org"] - rejects: - type: object - description: |- - The set of events that the receiving server has rejected from the - auth chain, not including events that the sending server is missing - as determined from the difference algorithm. - - The ``string`` key is the event ID that was rejected. - additionalProperties: - type: object - title: Rejection Reason - properties: - reason: - type: enum - enum: ['auth_error', 'replaced', 'not_ancestor'] - description: |- - The reason for the event being rejected. - required: ['reason'] - example: { - "$some_event:example.org": { - "reason": "auth_error" - } - } - required: ['auth_chain', 'missing', 'rejects'] diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index a3a57dbf..f0a9a563 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -1077,7 +1077,6 @@ The following endpoint prefixes MUST be protected: * ``/_matrix/federation/v1/state_ids`` * ``/_matrix/federation/v1/backfill`` * ``/_matrix/federation/v1/event_auth`` -* ``/_matrix/federation/v1/query_auth`` * ``/_matrix/federation/v1/get_missing_events`` From 9944decacfe58c0a635b34bd30bdf8f3e4a73329 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Tue, 24 Mar 2020 13:17:22 -0400 Subject: [PATCH 0978/1250] Add changelog entry. --- changelogs/server_server/newsfragments/2470.removal | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/server_server/newsfragments/2470.removal diff --git a/changelogs/server_server/newsfragments/2470.removal b/changelogs/server_server/newsfragments/2470.removal new file mode 100644 index 00000000..3221f5bf --- /dev/null +++ b/changelogs/server_server/newsfragments/2470.removal @@ -0,0 +1 @@ +Remove the unused ``query_auth`` API per [MSC2451](https://github.com/matrix-org/matrix-doc/pull/2451). From 4f0ac741a2350a46231d320cf310718339d14a2d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 24 Mar 2020 11:22:05 -0600 Subject: [PATCH 0979/1250] Update changelogs/server_server/newsfragments/2470.removal --- changelogs/server_server/newsfragments/2470.removal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/server_server/newsfragments/2470.removal b/changelogs/server_server/newsfragments/2470.removal index 3221f5bf..51cdadd4 100644 --- a/changelogs/server_server/newsfragments/2470.removal +++ b/changelogs/server_server/newsfragments/2470.removal @@ -1 +1 @@ -Remove the unused ``query_auth`` API per [MSC2451](https://github.com/matrix-org/matrix-doc/pull/2451). +Remove the unused ``query_auth`` API per `MSC2451 `_. From f7ce75d36c2dc09b24cba7c6c8fcdd419992e659 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 24 Mar 2020 11:29:00 -0600 Subject: [PATCH 0980/1250] Support a 'removed endpoints' changelog type --- changelogs/README.md | 19 ++++++++++++------- changelogs/application_service/pyproject.toml | 15 ++++++++++----- changelogs/client_server/pyproject.toml | 15 ++++++++++----- changelogs/identity_service/pyproject.toml | 5 +++++ changelogs/push_gateway/pyproject.toml | 15 ++++++++++----- changelogs/server_server/pyproject.toml | 15 ++++++++++----- 6 files changed, 57 insertions(+), 27 deletions(-) diff --git a/changelogs/README.md b/changelogs/README.md index a5fb1fb7..5a5b6271 100644 --- a/changelogs/README.md +++ b/changelogs/README.md @@ -2,14 +2,14 @@ # Changelogs -[Towncrier](https://github.com/hawkowl/towncrier) is used to manage the changelog and +[Towncrier](https://github.com/hawkowl/towncrier) is used to manage the changelog and keep it up to date. Because of this, updating a changelog is really easy. ## How to update a changelog when releasing an API 1. Ensure you're in your Python 3 virtual environment 2. `cd` your way to the API you're releasing (eg: `cd changelogs/client_server`) -3. Run `towncrier --version "r0.4.0" --name "client-server" --yes` substituting the +3. Run `towncrier --version "r0.4.0" --name "client-server" --yes` substituting the variables as approprite. Note that `--name` is required although the value is ignored. 4. Commit the changes and finish the release process. @@ -26,27 +26,32 @@ For this example, we're going to pretend that the `server_server` API doesn't ex directory = "newsfragments" issue_format = "`#{issue} `_" title_format = "{version}" - + [[tool.towncrier.type]] directory = "breaking" name = "Breaking Changes" showcontent = true - + [[tool.towncrier.type]] directory = "deprecation" name = "Deprecations" showcontent = true - + [[tool.towncrier.type]] directory = "new" name = "New Endpoints" showcontent = true - + + [[tool.towncrier.type]] + directory = "removal" + name = "Removed Endpoints" + showcontent = true + [[tool.towncrier.type]] directory = "feature" name = "Backwards Compatible Changes" showcontent = true - + [[tool.towncrier.type]] directory = "clarification" name = "Spec Clarifications" diff --git a/changelogs/application_service/pyproject.toml b/changelogs/application_service/pyproject.toml index 44d430e8..278def78 100644 --- a/changelogs/application_service/pyproject.toml +++ b/changelogs/application_service/pyproject.toml @@ -3,27 +3,32 @@ directory = "newsfragments" issue_format = "`#{issue} `_" title_format = "{version}" - + [[tool.towncrier.type]] directory = "breaking" name = "Breaking Changes" showcontent = true - + [[tool.towncrier.type]] directory = "deprecation" name = "Deprecations" showcontent = true - + [[tool.towncrier.type]] directory = "new" name = "New Endpoints" showcontent = true - + + [[tool.towncrier.type]] + directory = "removal" + name = "Removed Endpoints" + showcontent = true + [[tool.towncrier.type]] directory = "feature" name = "Backwards Compatible Changes" showcontent = true - + [[tool.towncrier.type]] directory = "clarification" name = "Spec Clarifications" diff --git a/changelogs/client_server/pyproject.toml b/changelogs/client_server/pyproject.toml index 8fa3f6b5..eb9e7b4e 100644 --- a/changelogs/client_server/pyproject.toml +++ b/changelogs/client_server/pyproject.toml @@ -3,27 +3,32 @@ directory = "newsfragments" issue_format = "`#{issue} `_" title_format = "{version}" - + [[tool.towncrier.type]] directory = "breaking" name = "Breaking Changes" showcontent = true - + [[tool.towncrier.type]] directory = "deprecation" name = "Deprecations" showcontent = true - + [[tool.towncrier.type]] directory = "new" name = "New Endpoints" showcontent = true - + + [[tool.towncrier.type]] + directory = "removal" + name = "Removed Endpoints" + showcontent = true + [[tool.towncrier.type]] directory = "feature" name = "Backwards Compatible Changes" showcontent = true - + [[tool.towncrier.type]] directory = "clarification" name = "Spec Clarifications" diff --git a/changelogs/identity_service/pyproject.toml b/changelogs/identity_service/pyproject.toml index a7fe582d..2e50b9df 100644 --- a/changelogs/identity_service/pyproject.toml +++ b/changelogs/identity_service/pyproject.toml @@ -19,6 +19,11 @@ name = "New Endpoints" showcontent = true + [[tool.towncrier.type]] + directory = "removal" + name = "Removed Endpoints" + showcontent = true + [[tool.towncrier.type]] directory = "feature" name = "Backwards Compatible Changes" diff --git a/changelogs/push_gateway/pyproject.toml b/changelogs/push_gateway/pyproject.toml index dad1bc04..9f2595c9 100644 --- a/changelogs/push_gateway/pyproject.toml +++ b/changelogs/push_gateway/pyproject.toml @@ -3,27 +3,32 @@ directory = "newsfragments" issue_format = "`#{issue} `_" title_format = "{version}" - + [[tool.towncrier.type]] directory = "breaking" name = "Breaking Changes" showcontent = true - + [[tool.towncrier.type]] directory = "deprecation" name = "Deprecations" showcontent = true - + [[tool.towncrier.type]] directory = "new" name = "New Endpoints" showcontent = true - + + [[tool.towncrier.type]] + directory = "removal" + name = "Removed Endpoints" + showcontent = true + [[tool.towncrier.type]] directory = "feature" name = "Backwards Compatible Changes" showcontent = true - + [[tool.towncrier.type]] directory = "clarification" name = "Spec Clarifications" diff --git a/changelogs/server_server/pyproject.toml b/changelogs/server_server/pyproject.toml index 98478527..6a9dca1d 100644 --- a/changelogs/server_server/pyproject.toml +++ b/changelogs/server_server/pyproject.toml @@ -3,27 +3,32 @@ directory = "newsfragments" issue_format = "`#{issue} `_" title_format = "{version}" - + [[tool.towncrier.type]] directory = "breaking" name = "Breaking Changes" showcontent = true - + [[tool.towncrier.type]] directory = "deprecation" name = "Deprecations" showcontent = true - + [[tool.towncrier.type]] directory = "new" name = "New Endpoints" showcontent = true - + + [[tool.towncrier.type]] + directory = "removal" + name = "Removed Endpoints" + showcontent = true + [[tool.towncrier.type]] directory = "feature" name = "Backwards Compatible Changes" showcontent = true - + [[tool.towncrier.type]] directory = "clarification" name = "Spec Clarifications" From eb17e5d826008a82ca197866a03761ddb6fe9480 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 14 Feb 2020 16:20:10 -0500 Subject: [PATCH 0981/1250] switch to symmetric algorithm --- proposals/1946-secure_server-side_storage.md | 60 ++++++++++---------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index fd907e53..59f02d8b 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -123,38 +123,33 @@ and the key descriptions for the keys would be: #### Encryption algorithms -##### `m.secret_storage.v1.curve25519-aes-sha2` - -The public key is stored in the `pubkey` property of the `m.secret_storage.key.[key -ID]` account_data as a base64-encoded string. - -The data is encrypted and MACed as follows: - -1. Generate an ephemeral curve25519 key, and perform an ECDH with the ephemeral - key and the public key to generate a shared secret. The public half of the - ephemeral key, encoded using base64, becomes the `ephemeral` property. -2. Using the shared secret, generate 80 bytes by performing an HKDF using - SHA-256 as the hash, with a salt of 32 bytes of 0, and with the empty string - as the info. The first 32 bytes are used as the AES key, the next 32 bytes - are used as the MAC key, and the last 16 bytes are used as the AES - initialization vector. -4. Encrypt the data using AES-CBC-256 with PKCS#7 padding. This encrypted - data, encoded using base64, becomes the `ciphertext` property. -5. Pass the raw encrypted data (prior to base64 encoding) through HMAC-SHA-256 - using the MAC key generated above. The first 8 bytes of the resulting MAC - are base64-encoded, and become the `mac` property. - -(The key HKDF, AES, and HMAC steps are the same as what are used for encryption -in olm and megolm.) - -For example, the `m.secret_storage.key.[key ID]` for a key using this algorithm +##### `m.secret_storage.v1.aes-hmac-sha2` + +Secrets are encrypted using AES-CTR-256 and MACed using HMAC-SHA-256. The data +is encrypted and MACed as follows: + +1. Given the secret storage key, generate 64 bytes by performing an HKDF with + SHA-256 as the hash, a salt of 32 bytes of 0, and with the secret name as + the info. The first 32 bytes are used as the AES key, and the next 32 bytes + are used as the MAC key +2. Generate 16 random bytes, set bit 63 to 0 (in order to work around + differences in AES-CTR implementations), and use this as the AES + initialization vector. This becomes the `iv` property, encoded using base64. +3. Encrypt the data using AES-CTR-256 using the AES key generated above. This + encrypted data, encoded using base64, becomes the `ciphertext` property. +4. Pass the raw encrypted data (prior to base64 encoding) through HMAC-SHA-256 + using the MAC key generated above. The resulting MAC is base64-encoded and + becomes the `mac` property. + +(We use AES-CTR to match file encryption and key exports.) + +For example, the `m.secret_storage.key.key_id` for a key using this algorithm could look like: ```json { "name": "m.default", - "algorithm": "m.secret_storage.v1.curve25519-aes-sha2", - "pubkey": "base64+public+key" + "algorithm": "m.secret_storage.v1.aes-hmac-sha2" } ``` @@ -164,8 +159,8 @@ and data encrypted using this algorithm could look like this: { "encrypted": { "key_id": { + "iv": "16+bytes+base64", "ciphertext": "base64+encoded+encrypted+data", - "ephemeral": "base64+ephemeral+key", "mac": "base64+encoded+mac" } } @@ -174,7 +169,7 @@ and data encrypted using this algorithm could look like this: ###### Keys -When a user is given a raw key for `m.secret_storage.v1.curve25519-aes-sha2`, +When a user is given a raw key for `m.secret_storage.v1.aes-hmac-sha2`, it will be encoded as follows (this is the same as what is proposed in MSC1703): * prepend the two bytes 0x8b and 0x01 to the key @@ -200,7 +195,8 @@ ID]` account-data: "passphrase": { "algorithm": "m.pbkdf2", "salt": "MmMsAlty", - "iterations": 100000 + "iterations": 100000, + "bits": 256 }, ... } @@ -209,7 +205,9 @@ ID]` account-data: **`m.pbkdf2`** The key is generated using PBKDF2 using the salt given in the `salt` parameter, -and the number of iterations given in the `iterations` parameter. +and the number of iterations given in the `iterations` parameter. The key size +that is generated is given by the `bits` parameter, or 256 bits if no `bits` +parameter is given. ### Sharing From f7ebda040e4c9d476da81cd6bd48e56b3affa805 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 24 Mar 2020 15:35:32 -0400 Subject: [PATCH 0982/1250] update some examples to use new algorithm name --- proposals/1946-secure_server-side_storage.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index 59f02d8b..61950b5f 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -43,7 +43,7 @@ A key with ID `abcdefg` is stored in `m.secret_storage.key.abcdefg` ```json { "name": "Some key", - "algorithm": "m.secret_storage.v1.curve25519-aes-sha2", + "algorithm": "m.secret_storage.v1.aes-hmac-sha2", // ... other properties according to algorithm } ``` @@ -106,7 +106,7 @@ and the key descriptions for the keys would be: ```json { "name": "Some key", - "algorithm": "m.secret_storage.v1.curve25519-aes-sha2", + "algorithm": "m.secret_storage.v1.aes-hmac-sha2", // ... other properties according to algorithm } ``` @@ -116,7 +116,7 @@ and the key descriptions for the keys would be: ```json { "name": "Some other key", - "algorithm": "m.secret_storage.v1.curve25519-aes-sha2", + "algorithm": "m.secret_storage.v1.aes-hmac-sha2", // ... other properties according to algorithm } ``` From 76dd16b854b8b0d94fcced863fa0751d2fff4bcd Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 24 Mar 2020 16:18:44 -0400 Subject: [PATCH 0983/1250] add proposal to switch to symmetric crypto --- proposals/1946-secure_server-side_storage.md | 6 ++ proposals/xxxx-symmetric-ssss.md | 76 ++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 proposals/xxxx-symmetric-ssss.md diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index 61950b5f..5263e8c7 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -8,6 +8,12 @@ decryption key for the backups on the server, or cross-signing ([MSC1756](https://github.com/matrix-org/matrix-doc/pull/1756)) can store the signing keys. This proposal presents a standardized way of storing such data. +## Changes + +- [MSCxxxx](https://github.com/matrix-org/matrix-doc/pull/xxxx) changed the + encryption algorithm used from an asymmetric algorithm (Curve25519) to a + symmetric algorithm (AES). + ## Proposal Secrets are data that clients need to use and that are sent through or stored diff --git a/proposals/xxxx-symmetric-ssss.md b/proposals/xxxx-symmetric-ssss.md new file mode 100644 index 00000000..bde9fa95 --- /dev/null +++ b/proposals/xxxx-symmetric-ssss.md @@ -0,0 +1,76 @@ +# Symmetric SSSS + +[MSC1946 (Secure Secret Storage and +Sharing)](https://github.com/matrix-org/matrix-doc/pull/1946) proposed a way of +storing encrypted secrets on the server. In the proposal, secrets were +encrypted using a Curve25519 key, which was chosen to allow easier migration +from key backups that we created before the backup key was stored using it. + +However this does not provide any guarantees that data stored using the +proposal came from a trusted source. To remedy this, we propose to change the +encryption to use AES with a MAC to ensure that only someone who knows the key +is able to store data. + +## Proposal + +* The `m.secret_storage.v1.curve25519-aes-sha2` method proposed in MSC1946 is + removed. + +* A new method, `m.secret_storage.v1.aes-hmac-sha2`, is added. With this + method, the Secret Storage key may be any size (though 256 bits is + recommended), and data is encrypted as follows: + + 1. Given the secret storage key, generate 64 bytes by performing an HKDF with + SHA-256 as the hash, a salt of 32 bytes of 0, and with the secret name as + the info. The first 32 bytes are used as the AES key, and the next 32 bytes + are used as the MAC key + 2. Generate 16 random bytes, set bit 63 to 0 (in order to work around + differences in AES-CTR implementations), and use this as the AES + initialization vector. This becomes the `iv` property, encoded using base64. + 3. Encrypt the data using AES-CTR-256 using the AES key generated above. This + encrypted data, encoded using base64, becomes the `ciphertext` property. + 4. Pass the raw encrypted data (prior to base64 encoding) through HMAC-SHA-256 + using the MAC key generated above. The resulting MAC is base64-encoded and + becomes the `mac` property. + + (We use AES-CTR to match file encryption and key exports.) + + If the key Secret Storage key is generated from a passphrase, information + about how to generate the key is stored in the `passphrase` property of the + key's account-data in a similar manner to what was done with the original + `m.secret_storage.v1.curve25519-aes-sha2` method, except that there is an + optional `bits` parameter that defaults to 256, and indicates the number of + bits that should be generated from PBKDF2 (in other words, the size of the + key). + +* The `passthrough` property specified in the "Enconding the recovery key for + server-side storage via MSC1946" section of MSC1219 is removed. The primary + purpose of that property was to allow easy migration of pre-MSC1946 backups, + so that users could reuse the backup recovery key as the Secret Storage key + without needing to re-enter the recovery key. However, since we are now + using a symmetric encryption algorithm, the client needs to know the key that + is used to encrypt, so the purpose of the field cannot be fulfilled. + + +## Potential issues + +Users who have data stored using the old encryption algorithm will need their +data migrated. Clients that support the old algorithm but not the new +algorithm will not be able to use the migrated secrets until they are updated +with the new algorithms. This should not be a major problem because the only +clients that are known to have implemented the old algorithm are Riot +Web/Android/iOS, and they have been upgraded to implement the new algorithm. + + +## Alternatives + +Rather than switching to a symmetric encryption algorithm, we could stay with +an asymmetric encryption algorithm, and add on a method to authenticate the +data. However, it is much safer to use well-known cryptographic methods rather +than trying to invent something new. Since the main reason for using an +asymmetric scheme was to ease migration from older key backups without +requiring the user to re-enter the key, but this is no longer possible due to +the need to authenticate the data using the Secret Storage key, there is no +reason to stay with an asymmetric algorithm. It is also better to use +cryptographic methods already used in Matrix where possible, rather than +introducing something new. From 4b21e44e5f1f4dd52afa9555ba509f4755e7de37 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 24 Mar 2020 16:24:09 -0400 Subject: [PATCH 0984/1250] use the MSC number --- proposals/1946-secure_server-side_storage.md | 2 +- proposals/{xxxx-symmetric-ssss.md => 2472-symmetric-ssss.md} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename proposals/{xxxx-symmetric-ssss.md => 2472-symmetric-ssss.md} (100%) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index 5263e8c7..a73fee4c 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -10,7 +10,7 @@ signing keys. This proposal presents a standardized way of storing such data. ## Changes -- [MSCxxxx](https://github.com/matrix-org/matrix-doc/pull/xxxx) changed the +- [MSC2472](https://github.com/matrix-org/matrix-doc/pull/2472) changed the encryption algorithm used from an asymmetric algorithm (Curve25519) to a symmetric algorithm (AES). diff --git a/proposals/xxxx-symmetric-ssss.md b/proposals/2472-symmetric-ssss.md similarity index 100% rename from proposals/xxxx-symmetric-ssss.md rename to proposals/2472-symmetric-ssss.md From eb48863c4044105b86d62997d88a086eda22e690 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Thu, 26 Mar 2020 11:47:32 -0400 Subject: [PATCH 0985/1250] Markdown formatting. Co-Authored-By: Hubert Chathi --- proposals/2454-ui-interactive-auth-for-sso.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2454-ui-interactive-auth-for-sso.md b/proposals/2454-ui-interactive-auth-for-sso.md index d3cab51b..3532a2fc 100644 --- a/proposals/2454-ui-interactive-auth-for-sso.md +++ b/proposals/2454-ui-interactive-auth-for-sso.md @@ -52,7 +52,7 @@ limited by the chosen SSO implementation, for example: * SAML2 servers typically only support one URL per service provider, so in practice it will need to be the same as that already used for the login flow - (for synapse, it's /_matrix/saml2/authn_response) - and the server needs to + (for synapse, it's `/_matrix/saml2/authn_response`) - and the server needs to be able to figure out if it's doing SSO for a login attempt or an SSO attempt. * CAS doesn't have the same restriction. From 745f8c09df6f948f9083449b2b0848444776855e Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Fri, 27 Mar 2020 13:59:37 -0400 Subject: [PATCH 0986/1250] Fix incorrect statement about the current spec's guidance. --- .../2457-password-modification-invalidating-devices.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/2457-password-modification-invalidating-devices.md b/proposals/2457-password-modification-invalidating-devices.md index 9b59156c..ccde2ac6 100644 --- a/proposals/2457-password-modification-invalidating-devices.md +++ b/proposals/2457-password-modification-invalidating-devices.md @@ -13,9 +13,9 @@ These can be summarized into two groups: 2. "I just want to change my password." The [current Matrix specification](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-password) -does not provide a way to differentiate between these use cases. It gives no -guidance into what should happen to other sessions / devices when a password is -modified and leaves it up to the implementation. +does not provide a way to differentiate between these use cases. It currently +specifies behavior that fits well into the first use-case above: that the +sessions except the current session should be revoked. It is reasonable for a client to want to specify this behavior to offer two different workflows: From edd75703e2e51eab8ccf611a01486eb26e6929e9 Mon Sep 17 00:00:00 2001 From: Aaron Axvig Date: Sat, 28 Mar 2020 18:32:53 -0400 Subject: [PATCH 0987/1250] Improved steps for building docs on Windows --- README.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.rst b/README.rst index ace8ebdd..d7b75876 100644 --- a/README.rst +++ b/README.rst @@ -66,6 +66,8 @@ The above will write the rendered version of the specification to Windows users ~~~~~~~~~~~~~ +The ``source`` program does not exist on Windows, so instead run one of the +``activate`` files in ``.\env\Scripts\`` to activate the virtual environment. If you're on Windows Vista or higher, be sure that the "Symbolic Links" option was selected when installing Git prior to cloning this repository. If @@ -81,6 +83,24 @@ cloned matrix-doc directory and run the following:: This will delete the file and replace it with a symlink. Git should not detect this as a change, and you should be able to go back to building the project. +Powershell doesn't have ``mklink`` so use cmd. Or, here is the full set of +steps for Powershell: + +.. code-block:: powershell + + virtualenv -p python3 env + .\env\Scripts\pip.exe install -r .\scripts\requirements.txt + + .\env\Scripts\activate.ps1 # Adds a global function 'deactivate' for leaving the env when you are done. + .\Scripts\gendoc.py + + # If you get errors: + cd api\client-server\definitions + del event-schemas + New-Item -ItemType SymbolicLink -Name event-schemas -Value "..\..\..\event-schemas" + cd ..\..\..\ + .\scripts\gendoc.py + Generating the OpenAPI (Swagger) specs -------------------------------------- From 2f5d8a4a271982a786ded1b2dc23a02e35c95583 Mon Sep 17 00:00:00 2001 From: aaronaxvig Date: Mon, 30 Mar 2020 14:32:45 -0400 Subject: [PATCH 0988/1250] Removed PowerShell stuff Clarified to use Command Prompt as recommended is pull request #2479, removed all PowerShell stuff. --- README.rst | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/README.rst b/README.rst index d7b75876..01ea8e72 100644 --- a/README.rst +++ b/README.rst @@ -73,7 +73,7 @@ If you're on Windows Vista or higher, be sure that the "Symbolic Links" option was selected when installing Git prior to cloning this repository. If you're still seeing errors about files not being found it is likely because the symlink at ``api/client-server/definitions/event-schemas`` looks like a -file. To correct the problem, open an Administrative/Elevated shell in your +file. To correct the problem, open an Administrative/Elevated Command Prompt in your cloned matrix-doc directory and run the following:: cd api\client-server\definitions @@ -83,24 +83,6 @@ cloned matrix-doc directory and run the following:: This will delete the file and replace it with a symlink. Git should not detect this as a change, and you should be able to go back to building the project. -Powershell doesn't have ``mklink`` so use cmd. Or, here is the full set of -steps for Powershell: - -.. code-block:: powershell - - virtualenv -p python3 env - .\env\Scripts\pip.exe install -r .\scripts\requirements.txt - - .\env\Scripts\activate.ps1 # Adds a global function 'deactivate' for leaving the env when you are done. - .\Scripts\gendoc.py - - # If you get errors: - cd api\client-server\definitions - del event-schemas - New-Item -ItemType SymbolicLink -Name event-schemas -Value "..\..\..\event-schemas" - cd ..\..\..\ - .\scripts\gendoc.py - Generating the OpenAPI (Swagger) specs -------------------------------------- From 943d9386bb3d7e87e439eed10b5fd5c0057e360b Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 30 Mar 2020 17:43:46 -0400 Subject: [PATCH 0989/1250] remove requirement to sign the key, since it is no longer used to trust it --- proposals/1946-secure_server-side_storage.md | 12 ++---------- proposals/2472-symmetric-ssss.md | 4 ++++ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index a73fee4c..ca4230de 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -38,9 +38,8 @@ Each key has an ID, and the description of the key is stored in the user's account_data using the event type `m.secret_storage.key.[key ID]`. The contents of the account data for the key will include an `algorithm` property, which indicates the encryption algorithm used, as well as a `name` property, which is -a human-readable name. The contents will be signed as signed JSON using the -user's master cross-signing key. Other properties depend on the encryption -algorithm, and are described below. +a human-readable name. Other properties depend on the encryption algorithm, +and are described below. Example: @@ -61,13 +60,6 @@ secrets that the user would expect to be available on all their clients. Unless the user specifies otherwise, clients will try to use the default key to decrypt secrets. -Clients MUST ensure that the key is trusted before using it to encrypt secrets. -One way to do that is to have the client that creates the key sign the key -description (as signed JSON) using the user's master cross-signing key. -Another way to do that is to prompt the user to enter the passphrase used to -generate the encryption key and ensure that the generated private key -corresponds to the public key. - #### Secret storage Encrypted data is stored in the user's account_data using the event type diff --git a/proposals/2472-symmetric-ssss.md b/proposals/2472-symmetric-ssss.md index bde9fa95..4827e2cd 100644 --- a/proposals/2472-symmetric-ssss.md +++ b/proposals/2472-symmetric-ssss.md @@ -51,6 +51,10 @@ is able to store data. using a symmetric encryption algorithm, the client needs to know the key that is used to encrypt, so the purpose of the field cannot be fulfilled. +* Signing the Secret Storage key with the user's master cross-signing key is no + longer required. The key is trusted on the basis of the user entering the + key/passphrase. + ## Potential issues From 4a3f9ec63ade930eaafad5b62d9ccb912893ba9a Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 30 Mar 2020 17:44:06 -0400 Subject: [PATCH 0990/1250] add information to check the key --- proposals/1946-secure_server-side_storage.md | 12 +++++++++++- proposals/2472-symmetric-ssss.md | 8 ++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index ca4230de..5e24b3ae 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -141,13 +141,23 @@ is encrypted and MACed as follows: (We use AES-CTR to match file encryption and key exports.) +For the purposes of allowing clients to check whether a user has correctly +entered the key, clients should: + + 1. encrypt and MAC a message consisting of 32 bytes of 0 as described above, + using the empty string as the info parameter to the HKDF in step 1. + 2. store the `iv` and `mac` in the `m.secret_storage.key.[key ID]` + account-data. + For example, the `m.secret_storage.key.key_id` for a key using this algorithm could look like: ```json { "name": "m.default", - "algorithm": "m.secret_storage.v1.aes-hmac-sha2" + "algorithm": "m.secret_storage.v1.aes-hmac-sha2", + "iv": "random+data", + "mac": "mac+of+encrypted+zeros" } ``` diff --git a/proposals/2472-symmetric-ssss.md b/proposals/2472-symmetric-ssss.md index 4827e2cd..7fe9f179 100644 --- a/proposals/2472-symmetric-ssss.md +++ b/proposals/2472-symmetric-ssss.md @@ -43,6 +43,14 @@ is able to store data. bits that should be generated from PBKDF2 (in other words, the size of the key). +* For the purposes of allowing clients to check whether a user has correctly + entered the key, clients should: + + 1. encrypt and MAC a message consisting of 32 bytes of 0 as described above, + using the empty string as the info parameter to the HKDF in step 1. + 2. store the `iv` and `mac` in the `m.secret_storage.key.[key ID]` + account-data. + * The `passthrough` property specified in the "Enconding the recovery key for server-side storage via MSC1946" section of MSC1219 is removed. The primary purpose of that property was to allow easy migration of pre-MSC1946 backups, From 4cfcda57fb3676d6de6145bb9bd1f9de60645559 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 1 Apr 2020 10:48:05 -0400 Subject: [PATCH 0991/1250] Clarify that the only new item here is the new authentication type. --- proposals/2454-ui-interactive-auth-for-sso.md | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/proposals/2454-ui-interactive-auth-for-sso.md b/proposals/2454-ui-interactive-auth-for-sso.md index 3532a2fc..fff96dcf 100644 --- a/proposals/2454-ui-interactive-auth-for-sso.md +++ b/proposals/2454-ui-interactive-auth-for-sso.md @@ -22,11 +22,27 @@ supported among clients. An [additional authentication type](https://matrix.org/docs/spec/client_server/r0.6.0#authentication-types) of `m.login.sso` is added to the user-interactive authentication specification. -There are no additional parameters as part of this authentication type. + +There are no additional parameters as part of this authentication type. As per +the user-interactive authentication specification the only parameter include in +the `auth` dictionary should be the session ID from the homeserver, e.g.: + +```json +{ + "auth": { + "session": "" + } +} +``` + +### Detailed fallback authentication flow: + +The following is a re-iteration of the [fallback authentication flow](https://matrix.org/docs/spec/client_server/r0.6.0#fallback), +but with details filled in for the proposed new authentication type. When choosing this authentication flow, the following should occur: -1. If the client wants to complete that authentication type, it opens a browser +1. If the client wants to complete authentication using SSO, it opens a browser window for `/_matrix/client/r0/auth/m.login.sso/fallback/web?session=<...>` with session set to the UI-Auth session id (from the "auth" dict). @@ -59,6 +75,10 @@ limited by the chosen SSO implementation, for example: ### Example flow: +A more complete example is provided below in which a user attempts to delete +a device and is pushed into the user interactive authentication process with +SSO being the only possible flow. + 0. Client submits the request, which the server says requires SSO: ``` @@ -163,7 +183,7 @@ limited by the chosen SSO implementation, for example: ## Alternatives An alternative client flow where the fallback auth ends up redirecting to a -given URI, instead of doing JavaScript postMessage foo could be considered. +given URI, instead of doing JavaScript `postMessage` foo could be considered. This is probably an orthogonal change to the fallback auth though. ## Security considerations @@ -200,8 +220,9 @@ This problem can be mitigated by clearly telling the user what is about to happe ### Reusing User Interactive Authentication sessions The security of this relies on User Interactive Authentication sessions only -being used for the same request as they were initiated for. It is not believed -that this is currently enforced. +being used for the same request as they were initiated for. This security is not +only a concern for the proposed SSO authentication type. It is not believed +that this is currently enforced in implementations. ## Unstable prefix From 5ae8a8bcfd563ef0d472d0560beba53798897e3c Mon Sep 17 00:00:00 2001 From: Ben Parsons Date: Tue, 7 Apr 2020 14:37:55 +0100 Subject: [PATCH 0992/1250] fix pagination in scraper --- scripts/proposals.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/proposals.py b/scripts/proposals.py index 27cc6cfb..96904ce4 100755 --- a/scripts/proposals.py +++ b/scripts/proposals.py @@ -38,7 +38,7 @@ def getpage(url): pagecount = 1 for link in resp.links.values(): if link['rel'] == 'last': - pagecount = int(re.search('page=(.+?)', link['url']).group(1)) + pagecount = int(re.search('page=(.+)', link['url']).group(1)) val = resp.json() if not isinstance(val, list): From 7c037d2490203d156e9def41f43ce255d863d48b Mon Sep 17 00:00:00 2001 From: Ben Parsons Date: Tue, 7 Apr 2020 15:26:48 +0100 Subject: [PATCH 0993/1250] improve capture and add example --- scripts/proposals.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/proposals.py b/scripts/proposals.py index 96904ce4..faa10a83 100755 --- a/scripts/proposals.py +++ b/scripts/proposals.py @@ -38,7 +38,10 @@ def getpage(url): pagecount = 1 for link in resp.links.values(): if link['rel'] == 'last': - pagecount = int(re.search('page=(.+)', link['url']).group(1)) + # we extract the pagecount from the `page` param of the last url + # in the response, eg + # 'https://api.github.com/repositories/24998719/issues?state=all&labels=proposal&page=10' + pagecount = int(re.search('page=(\d+)', link['url']).group(1)) val = resp.json() if not isinstance(val, list): From af7cf84083cf17de938102bfac1951caebc89c3e Mon Sep 17 00:00:00 2001 From: Lukas Lihotzki Date: Tue, 7 Apr 2020 17:54:09 +0200 Subject: [PATCH 0994/1250] Fix iv parameter description Signed-off-by: Lukas Lihotzki --- specification/modules/end_to_end_encryption.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 631b182a..4b433f17 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -277,7 +277,7 @@ Parameter Type Description ========= ================ ===================================================== url string **Required.** The URL to the file. key JWK **Required.** A `JSON Web Key`_ object. -iv string **Required.** The Initialisation Vector used by +iv string **Required.** The 128-bit unique counter block used by AES-CTR, encoded as unpadded base64. hashes {string: string} **Required.** A map from an algorithm name to a hash of the ciphertext, encoded as unpadded base64. Clients From b908b8e777840741587d22c6c1bbf25f69ecaeab Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 7 Apr 2020 13:13:52 -0600 Subject: [PATCH 0995/1250] Add changelog --- changelogs/client_server/newsfragments/2492.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2492.clarification diff --git a/changelogs/client_server/newsfragments/2492.clarification b/changelogs/client_server/newsfragments/2492.clarification new file mode 100644 index 00000000..88c478ec --- /dev/null +++ b/changelogs/client_server/newsfragments/2492.clarification @@ -0,0 +1 @@ +Clarify the IV data type for encrypted files. From f6879c897bace91ccfe0cb102f490e9dc5619cde Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 15 Apr 2020 07:39:00 -0400 Subject: [PATCH 0996/1250] Fix minor grammatical fixes. Co-Authored-By: Hubert Chathi --- proposals/2454-ui-interactive-auth-for-sso.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/2454-ui-interactive-auth-for-sso.md b/proposals/2454-ui-interactive-auth-for-sso.md index fff96dcf..e39facfb 100644 --- a/proposals/2454-ui-interactive-auth-for-sso.md +++ b/proposals/2454-ui-interactive-auth-for-sso.md @@ -13,7 +13,7 @@ we need to delegate that check to the SSO system. At the protocol level, this means adding support for SSO to the [user-interactive authentication API](https://matrix.org/docs/spec/client_server/r0.6.0#user-interactive-authentication-api). -In theory, once SSO is added as a possible flow for authentication any clients +In theory, once SSO is added as a possible flow for authentication, any clients that already implement the [fallback process for unknown authentication types](https://matrix.org/docs/spec/client_server/r0.6.0#fallback) will work fine without modification. It is unknown whether this is widely supported among clients. @@ -24,7 +24,7 @@ An [additional authentication type](https://matrix.org/docs/spec/client_server/r of `m.login.sso` is added to the user-interactive authentication specification. There are no additional parameters as part of this authentication type. As per -the user-interactive authentication specification the only parameter include in +the user-interactive authentication specification, the only parameter included in the `auth` dictionary should be the session ID from the homeserver, e.g.: ```json @@ -57,7 +57,7 @@ When choosing this authentication flow, the following should occur: 3. The SSO provider validates the user, and redirects the browser back to the homeserver. 4. The homeserver validates the response from the SSO provider, updates the - user-interactive auth session to show that the SSO has completed, + user-interactive auth session to show that the SSO has completed, and [serves the fallback auth completion page as specced](https://matrix.org/docs/spec/client_server/r0.6.0#fallback). 5. The client resubmits its original request, with its original session id, which now should complete. From 9103a0a3980192f78d65f2f9c08f8e6a5d3e726b Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 16 Apr 2020 14:58:27 -0400 Subject: [PATCH 0997/1250] minor clarifications and corrections --- proposals/1756-cross-signing.md | 4 ++-- proposals/1946-secure_server-side_storage.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/1756-cross-signing.md b/proposals/1756-cross-signing.md index 4b5904bc..de08422a 100644 --- a/proposals/1756-cross-signing.md +++ b/proposals/1756-cross-signing.md @@ -216,7 +216,7 @@ response: } ``` -Similarly, the federation endpoints `POST /user/keys/query` and `POST +Similarly, the federation endpoints `POST /user/keys/query` and `GET /user/devices/{userId}` will include the master and self-signing keys. (It will not include the user-signing key because it is not intended to be visible to other users.) @@ -463,7 +463,7 @@ response: } ``` -Similarly, the federation endpoints `GET /user/keys/query` and `POST +Similarly, the federation endpoints `POST /user/keys/query` and `GET /user/devices/{userId}` will include the new signatures for her own devices or master key, but not signatures made by her user-signing key. diff --git a/proposals/1946-secure_server-side_storage.md b/proposals/1946-secure_server-side_storage.md index fd907e53..3f386d5e 100644 --- a/proposals/1946-secure_server-side_storage.md +++ b/proposals/1946-secure_server-side_storage.md @@ -66,7 +66,7 @@ corresponds to the public key. Encrypted data is stored in the user's account_data using the event type defined by the feature that uses the data. For example, decryption keys for -key backups could be stored under the type `m.megolm_backup.v1.recovery_key`, +key backups could be stored under the type `m.megolm_backup.v1`, or the self-signing key for cross-signing could be stored under the type `m.cross_signing.self_signing`. From 3c34d83082f445ea7f5bd80720f87bf2fa749721 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 22 Apr 2020 13:37:50 -0600 Subject: [PATCH 0998/1250] Add some words about what categories are --- specification/proposals_intro.rst | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 82a4225b..47cb58fc 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -341,6 +341,35 @@ Closed proposal-closed A proposal which Obsolete obsolete A proposal which has been made obsolete by another proposal or decision elsewhere. =============================== ============================= ==================================== +Categories +---------- + +We use category labels on MSCs to place them into a track of work. The spec core team +decides which of the tracks they are focusing on for the next while and generally makes +an effort to pull MSCs out of that category when possible. + +The current categories are: + +============ ================= ====================================== +Name Github Label Description +============ ================= ====================================== +Core kind:core Important for the protocol's success. +Feature kind:feature Nice to have additions to the spec. +Maintenance kind:maintenance Fixes or clarifies existing spec. +============ ================= ====================================== + +Some examples of core MSCs would be aggregations, cross-signing, and groups/communities. +These are the sorts of things that if not implemented could cause the protocol to +fail or become second-class. Features would be areas like enhanced media APIs, +new transports, and bookmarks in comparison. Finally, maintenance MSCs would include +improving error codes, clarifying what is required of an API, and adding properties +to an API which makes it easier to use. + +The spec core team assigns a category to each MSC based on the descriptions above. +This can mean that new MSCs get categorized into an area the team isn't focused on, +though that can always change as priorities evolve. We still encourage that MSCs be +opened, even if not the focus for the time being, as they can still make progress and +even be merged without the spec core team focusing on them specifically. Proposal Tracking ----------------- From b5868a59d64e30829ee28ae19f773a565399846f Mon Sep 17 00:00:00 2001 From: Rudi Floren Date: Wed, 22 Apr 2020 22:18:28 +0200 Subject: [PATCH 0999/1250] Fix typo in Fed. API request auth python example Fixes the typo in the Request Authentication python example. It seems like a copy paste error. Closes: #2509 Signed-off-by: Rudi Floren --- specification/server_server_api.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index f0a9a563..655a8cfc 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -316,8 +316,8 @@ Example python code: "destination": destination_name, } - if content_json is not None: - request["content"] = content + if content is not None: + request_json["content"] = content signed_json = sign_json(request_json, origin_name, origin_signing_key) From 2bc798dcfa9cebed32c31c5083b365d59efadefc Mon Sep 17 00:00:00 2001 From: Rudi Floren Date: Wed, 22 Apr 2020 22:21:36 +0200 Subject: [PATCH 1000/1250] Add changelog newsfragment --- changelogs/server_server/newsfragments/2510 | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/server_server/newsfragments/2510 diff --git a/changelogs/server_server/newsfragments/2510 b/changelogs/server_server/newsfragments/2510 new file mode 100644 index 00000000..c9cf10be --- /dev/null +++ b/changelogs/server_server/newsfragments/2510 @@ -0,0 +1 @@ +Fix typo in Request Authentication python example From 97b23da9f6fd52368bee002102f7de9f8e246cdd Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 22 Apr 2020 14:27:22 -0600 Subject: [PATCH 1001/1250] Update changelog entry for 2510 clarification --- changelogs/server_server/newsfragments/2510 | 1 - changelogs/server_server/newsfragments/2510.clarification | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 changelogs/server_server/newsfragments/2510 create mode 100644 changelogs/server_server/newsfragments/2510.clarification diff --git a/changelogs/server_server/newsfragments/2510 b/changelogs/server_server/newsfragments/2510 deleted file mode 100644 index c9cf10be..00000000 --- a/changelogs/server_server/newsfragments/2510 +++ /dev/null @@ -1 +0,0 @@ -Fix typo in Request Authentication python example diff --git a/changelogs/server_server/newsfragments/2510.clarification b/changelogs/server_server/newsfragments/2510.clarification new file mode 100644 index 00000000..9c96c5a5 --- /dev/null +++ b/changelogs/server_server/newsfragments/2510.clarification @@ -0,0 +1 @@ +Fix typo in Request Authentication python example. From 16905a2f5bf3cea32ee0567b8bfd4883d64bccc6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 22 Apr 2020 14:31:34 -0600 Subject: [PATCH 1002/1250] Make the spec core team the Spec Core Team --- specification/proposals_intro.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 47cb58fc..771d2d6a 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -344,7 +344,7 @@ Obsolete obsolete A proposal which Categories ---------- -We use category labels on MSCs to place them into a track of work. The spec core team +We use category labels on MSCs to place them into a track of work. The Spec Core Team decides which of the tracks they are focusing on for the next while and generally makes an effort to pull MSCs out of that category when possible. @@ -365,11 +365,11 @@ new transports, and bookmarks in comparison. Finally, maintenance MSCs would inc improving error codes, clarifying what is required of an API, and adding properties to an API which makes it easier to use. -The spec core team assigns a category to each MSC based on the descriptions above. +The Spec Core Team assigns a category to each MSC based on the descriptions above. This can mean that new MSCs get categorized into an area the team isn't focused on, though that can always change as priorities evolve. We still encourage that MSCs be opened, even if not the focus for the time being, as they can still make progress and -even be merged without the spec core team focusing on them specifically. +even be merged without the Spec Core Team focusing on them specifically. Proposal Tracking ----------------- From c441e74b273d592ba5c42c101858dfea7c2096e7 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Wed, 29 Apr 2020 20:11:23 +0200 Subject: [PATCH 1003/1250] README.rst: fix the contributor's surname --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 01ea8e72..61c27f15 100644 --- a/README.rst +++ b/README.rst @@ -46,7 +46,7 @@ To use the scripts, it is best to create a Python 3.4+ virtualenv as follows:: virtualenv -p python3 env env/bin/pip install -r scripts/requirements.txt -(Benjamin Synders has contributed a script for `Nix`_ users, which can be +(Benjamin Saunders has contributed a script for `Nix`_ users, which can be invoked with ``nix-shell scripts/contrib/shell.nix``.) .. TODO: Possibly we need some libs installed; should record what they are. From 202bf8abb109b628a52eb4a7f3b52dcc81a05c39 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Wed, 29 Apr 2020 20:12:51 +0200 Subject: [PATCH 1004/1250] Cleanup summaries and descriptions --- api/client-server/content-repo.yaml | 21 +++++++++++---------- api/client-server/joining.yaml | 17 ++++++++++------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/api/client-server/content-repo.yaml b/api/client-server/content-repo.yaml index d596dbda..5fd1f12d 100644 --- a/api/client-server/content-repo.yaml +++ b/api/client-server/content-repo.yaml @@ -163,9 +163,10 @@ paths: - Media "/download/{serverName}/{mediaId}/{fileName}": get: - summary: |- - Download content from the content repository. This is the same as - the download endpoint above, except permitting a desired file name. + summary: Download content from the content repository overriding the file name + description: |- + This is the same as the download endpoint above, except permitting + a desired file name. operationId: getContentOverrideName produces: ["*/*"] parameters: @@ -233,9 +234,9 @@ paths: - Media "/thumbnail/{serverName}/{mediaId}": get: - summary: |- - Download a thumbnail of content from the content repository. See the `thumbnailing <#thumbnails>`_ - section for more information. + summary: Download a thumbnail of content from the content repository + description: |- + See the `thumbnailing <#thumbnails>`_ section for more information. operationId: getContentThumbnail produces: ["image/jpeg", "image/png"] parameters: @@ -283,10 +284,10 @@ paths: x-example: false required: false default: true - description: | - Indicates to the server that it should not attempt to fetch the media if it is deemed - remote. This is to prevent routing loops where the server contacts itself. Defaults to - true if not provided. + description: |- + Indicates to the server that it should not attempt to fetch + the media if it is deemed remote. This is to prevent routing loops + where the server contacts itself. Defaults to true if not provided. responses: 200: description: "A thumbnail of the requested content." diff --git a/api/client-server/joining.yaml b/api/client-server/joining.yaml index af38d6f9..4da86022 100644 --- a/api/client-server/joining.yaml +++ b/api/client-server/joining.yaml @@ -31,7 +31,8 @@ paths: post: summary: Start the requesting user participating in a particular room. description: |- - *Note that this API requires a room ID, not alias.* ``/join/{roomIdOrAlias}`` *exists if you have a room alias.* + *Note that this API requires a room ID, not alias.* + ``/join/{roomIdOrAlias}`` *exists if you have a room alias.* This API starts a user participating in a particular room, if that user is allowed to participate in that room. After this call, the client is @@ -40,10 +41,6 @@ paths: After a user has joined a room, the room will appear as an entry in the response of the |/initialSync|_ and |/sync|_ APIs. - - If a ``third_party_signed`` was supplied, the homeserver must verify - that it matches a pending ``m.room.third_party_invite`` event in the - room, and perform key validity checking if required by the event. operationId: joinRoomById security: - accessToken: [] @@ -56,6 +53,10 @@ paths: x-example: "!d41d8cd:matrix.org" - in: body name: third_party_signed + description: |- + If supplied, the homeserver must verify that it matches a pending + ``m.room.third_party_invite`` event in the room, and perform + key validity checking if required by the event. schema: type: object properties: @@ -79,7 +80,8 @@ paths: required: ["room_id"] 403: description: |- - You do not have permission to join the room. A meaningful ``errcode`` and description error text will be returned. Example reasons for rejection are: + You do not have permission to join the room. A meaningful ``errcode`` + and description error text will be returned. Example reasons for rejection are: - The room is invite-only and the user was not invited. - The user has been banned from the room. @@ -155,7 +157,8 @@ paths: required: ["room_id"] 403: description: |- - You do not have permission to join the room. A meaningful ``errcode`` and description error text will be returned. Example reasons for rejection are: + You do not have permission to join the room. A meaningful ``errcode`` + and description error text will be returned. Example reasons for rejection are: - The room is invite-only and the user was not invited. - The user has been banned from the room. From 0ae597626af258c133ac285220754ccbd663bae6 Mon Sep 17 00:00:00 2001 From: David Vo Date: Fri, 1 May 2020 00:32:15 +1000 Subject: [PATCH 1005/1250] Fix .m.rule.contains_user_name push rule to highlight Signed-off-by: David Vo --- specification/modules/push.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/specification/modules/push.rst b/specification/modules/push.rst index c9489987..ebf1aef2 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -473,6 +473,9 @@ Definition (as a ``content`` rule): { "set_tweak": "sound", "value": "default" + }, + { + "set_tweak": "highlight" } ] } From b8efb5ac4701554c5eda7ca7ba3a8f2a880c93b5 Mon Sep 17 00:00:00 2001 From: David Vo Date: Fri, 1 May 2020 15:27:20 +1000 Subject: [PATCH 1006/1250] Add changelog for 2519 Signed-off-by: David Vo --- changelogs/client_server/newsfragments/2519.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2519.clarification diff --git a/changelogs/client_server/newsfragments/2519.clarification b/changelogs/client_server/newsfragments/2519.clarification new file mode 100644 index 00000000..eb3fb6a8 --- /dev/null +++ b/changelogs/client_server/newsfragments/2519.clarification @@ -0,0 +1 @@ +Fix the ``.m.rule.contains_user_name`` default push rule to set the highlight tweak, matching Synapse and users' expectations. From 411b3f432b57e9f1f6d3a170cd159020fb26bd74 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 1 May 2020 10:25:47 -0600 Subject: [PATCH 1007/1250] Update changelog --- changelogs/client_server/newsfragments/2519.clarification | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/client_server/newsfragments/2519.clarification b/changelogs/client_server/newsfragments/2519.clarification index eb3fb6a8..4b32da1e 100644 --- a/changelogs/client_server/newsfragments/2519.clarification +++ b/changelogs/client_server/newsfragments/2519.clarification @@ -1 +1 @@ -Fix the ``.m.rule.contains_user_name`` default push rule to set the highlight tweak, matching Synapse and users' expectations. +Fix the ``.m.rule.contains_user_name`` default push rule to set the highlight tweak. From 958e1b4a2e2ffd7dd4210818daf88385325ac0c4 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Mon, 4 May 2020 14:36:52 -0400 Subject: [PATCH 1008/1250] Make the spec changes for MSC 2457. --- api/client-server/registration.yaml | 8 ++++++-- changelogs/client_server/newsfragments/2523.feature | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2523.feature diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 8114299e..ecc7a6fa 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -328,8 +328,7 @@ paths: The homeserver may change the flows available depending on whether a valid access token is provided. The homeserver SHOULD NOT revoke the - access token provided in the request, however all other access tokens - for the user should be revoked if the request succeeds. + access token provided in the request. security: - accessToken: [] operationId: changePassword @@ -343,6 +342,11 @@ paths: type: string description: The new password for the account. example: "ihatebananas" + logout_devices: + type: boolean + description: |- + Whether other access tokens should be revoked if the request succeeds. Defaults to true. + example: true auth: description: |- Additional authentication information for the user-interactive authentication API. diff --git a/changelogs/client_server/newsfragments/2523.feature b/changelogs/client_server/newsfragments/2523.feature new file mode 100644 index 00000000..6f690ea4 --- /dev/null +++ b/changelogs/client_server/newsfragments/2523.feature @@ -0,0 +1 @@ +Optionally invalidate other access tokens during password modification per `MSC 2457 `_. From 0c582ea8c71658b71e76210d30f2ece5c3ea8644 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Mon, 4 May 2020 16:21:19 -0400 Subject: [PATCH 1009/1250] Apply suggestions from code review Co-authored-by: Travis Ralston --- api/client-server/registration.yaml | 3 ++- changelogs/client_server/newsfragments/2523.feature | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index ecc7a6fa..c3f544c1 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -345,7 +345,8 @@ paths: logout_devices: type: boolean description: |- - Whether other access tokens should be revoked if the request succeeds. Defaults to true. + Whether the other access tokens, and their associated devices, for the user should be + revoked if the request succeeds. Defaults to true. example: true auth: description: |- diff --git a/changelogs/client_server/newsfragments/2523.feature b/changelogs/client_server/newsfragments/2523.feature index 6f690ea4..e45d1c2f 100644 --- a/changelogs/client_server/newsfragments/2523.feature +++ b/changelogs/client_server/newsfragments/2523.feature @@ -1 +1 @@ -Optionally invalidate other access tokens during password modification per `MSC 2457 `_. +Optionally invalidate other access tokens during password modification per `MSC2457 `_. From 1e330c942307259ffdf076940ca70b7ba33da83e Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Mon, 4 May 2020 16:23:31 -0400 Subject: [PATCH 1010/1250] Clarify revocation behavior. --- api/client-server/registration.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index c3f544c1..50ce4a96 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -328,7 +328,8 @@ paths: The homeserver may change the flows available depending on whether a valid access token is provided. The homeserver SHOULD NOT revoke the - access token provided in the request. + access token provided in the request. Whether other access tokens for + the user are revoked depends on the request parameters. security: - accessToken: [] operationId: changePassword From e89521d1951976cb2a3bca9509e5e501b7fd6325 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 4 May 2020 22:08:22 -0400 Subject: [PATCH 1011/1250] some fixes (spelling, RST, and naming) --- api/client-server/keys.yaml | 2 +- specification/modules/end_to_end_encryption.rst | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/api/client-server/keys.yaml b/api/client-server/keys.yaml index 69e39def..e172ea8a 100644 --- a/api/client-server/keys.yaml +++ b/api/client-server/keys.yaml @@ -101,7 +101,7 @@ paths: responses: 200: description: - The provided keys were sucessfully uploaded. + The provided keys were successfully uploaded. schema: type: object properties: diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 4b433f17..0223d9f5 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -565,9 +565,9 @@ The process between Alice and Bob verifying each other would be: they match or not. #. Assuming they match, Alice and Bob's devices calculate the HMAC of their own device keys and a comma-separated sorted list of of the key IDs that they wish the other user - to verify, using SHA-256 as the hash function. HMAC is defined in [RFC 2104](https://tools.ietf.org/html/rfc2104). + to verify, using SHA-256 as the hash function. HMAC is defined in `RFC 2104 `_. The key for the HMAC is different for each item and is calculated by generating - 32 bytes (256 bits) using `the key verification HKDF <#SAS-HKDF>`_. + 32 bytes (256 bits) using `the key verification HKDF <#sas-hkdf>`_. #. Alice's device sends Bob's device a ``m.key.verification.mac`` message containing the MAC of Alice's device keys and the MAC of her key IDs to be verified. Bob's device does the same for Bob's device keys and key IDs concurrently with Alice. @@ -653,14 +653,14 @@ are used in addition to those already specified: {{m_key_verification_mac_event}} -.. _`SAS-HKDF`: +.. _sas-hkdf: HKDF calculation <<<<<<<<<<<<<<<< -In all of the SAS methods, HKDF is as defined in [RFC 5869](https://tools.ietf.org/html/rfc5869) +In all of the SAS methods, HKDF is as defined in `RFC 5869 `_ and uses the previously agreed-upon hash function for the hash function. The shared -secret is supplied as the input keying material. No salt is used, and the input +secret is supplied as the input keying material. No salt is used, and the info parameter is the concatenation of: * The string ``MATRIX_KEY_VERIFICATION_SAS``. @@ -677,7 +677,7 @@ parameter is the concatenation of: For verification of each party's device keys, HKDF is as defined in RFC 5869 and uses SHA-256 as the hash function. The shared secret is supplied as the input keying -material. No salt is used, and in the input parameter is the concatenation of: +material. No salt is used, and in the info parameter is the concatenation of: * The string ``MATRIX_KEY_VERIFICATION_MAC``. * The Matrix ID of the user whose key is being MAC-ed. @@ -691,7 +691,7 @@ material. No salt is used, and in the input parameter is the concatenation of: SAS method: ``decimal`` <<<<<<<<<<<<<<<<<<<<<<< -Generate 5 bytes using `HKDF <#SAS-HKDF>`_ then take sequences of 13 bits to +Generate 5 bytes using `HKDF <#sas-hkdf>`_ then take sequences of 13 bits to convert to decimal numbers (resulting in 3 numbers between 0 and 8191 inclusive each). Add 1000 to each calculated number. @@ -708,7 +708,7 @@ such as dashes, or with the numbers on individual lines. SAS method: ``emoji`` <<<<<<<<<<<<<<<<<<<<< -Generate 6 bytes using `HKDF <#SAS-HKDF>`_ then split the first 42 bits into +Generate 6 bytes using `HKDF <#sas-hkdf>`_ then split the first 42 bits into 7 groups of 6 bits, similar to how one would base64 encode something. Convert each group of 6 bits to a number and use the following table to get the corresponding emoji: From 9dc6e00335e2c91f14c46fd75acbac0a9bb5dc4f Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 4 May 2020 22:49:34 -0400 Subject: [PATCH 1012/1250] draft of proposal for SAS --- proposals/xxxx-sas-v2.md | 50 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 proposals/xxxx-sas-v2.md diff --git a/proposals/xxxx-sas-v2.md b/proposals/xxxx-sas-v2.md new file mode 100644 index 00000000..b4652ff8 --- /dev/null +++ b/proposals/xxxx-sas-v2.md @@ -0,0 +1,50 @@ +# SAS verification, v2 + +## Proposal + +A new `key_agreement_protocol`, `curve25519-hkdf-sha256` is introduced. It is +the same as `curve25519` except that the info parameter for the HKDF is the +concatenation of: + + * The string `MATRIX_KEY_VERIFICATION_SAS|`. + * The Matrix ID of the user who sent the `m.key.verification.start` message, + followed by `|`. + * The Device ID of the device which sent the `m.key.verification.start` + message, followed by `|`. + * The public key from the `m.key.verification.key` message sent by the device + which sent the `m.key.verification.start` message, followed by `|`. + * The Matrix ID of the user who sent the `m.key.verification.accept` message, + followed by `|`. + * The Device ID of the device which sent the `m.key.verification.accept` + message, followed by `|`. + * The public key from the `m.key.verification.key` message sent by the device + which sent the `m.key.verification.accept` message, followed by `|`. + * The `transaction_id` being used. + +A new `message_authentication_code` method, `hkdf-hmac-sha256.v2` is introduced. It +is the same as `hkdf-hmac-sha256`, except that the info parameter for the HKDF +is the concatenation of: + + * The string `MATRIX_KEY_VERIFICATION_MAC|`. + * The Matrix ID of the user whose key is being MAC-ed, followed by `|`. + * The Device ID of the device sending the MAC, followed by `|`. + * The Matrix ID of the other user, followed by `|`. + * The Device ID of the device receiving the MAC, followed by `|`. + * The transaction_id being used, followed by `|`. + * The Key ID of the key being MAC-ed, or the string `KEY_IDS` if the item + being MAC-ed is the list of key IDs. + +A new `short_authentication_string` method, `emoji.v2` is introduced. It is +the same as `emoji`, but emoji number 34 is changed from 🔧 (`U+1F527` Spanner) +to ⭐ (`U+2B50` Star). + +The `key_agreement_protocol` `curve25519`, `message_authentication_code` +`hkdf-hmac-sha256`, and `short_authentication_string` `emoji` are deprecated. + +## Potential issues + +## Alternatives + +## Security considerations + +## Unstable prefix From 6e339542562dfc00c77b2abc91d18b0476f48854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 5 May 2020 12:11:51 +0200 Subject: [PATCH 1013/1250] client-server: Mark the event_id when putting room events as required. --- api/client-server/room_send.yaml | 2 ++ api/client-server/room_state.yaml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/api/client-server/room_send.yaml b/api/client-server/room_send.yaml index 6963f76c..fc8f3339 100644 --- a/api/client-server/room_send.yaml +++ b/api/client-server/room_send.yaml @@ -85,5 +85,7 @@ paths: type: string description: |- A unique identifier for the event. + required: + - event_id tags: - Room participation diff --git a/api/client-server/room_state.yaml b/api/client-server/room_state.yaml index 62168f26..640e2009 100644 --- a/api/client-server/room_state.yaml +++ b/api/client-server/room_state.yaml @@ -92,6 +92,8 @@ paths: type: string description: |- A unique identifier for the event. + required: + - event_id 403: description: |- The sender doesn't have permission to send the event into the room. From 3054ac572fb518499dd53eb21334788d9d3def68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 5 May 2020 12:17:54 +0200 Subject: [PATCH 1014/1250] changelogs: Fragment for the event id when putting room events clarification. --- changelogs/client_server/newsfragments/2525.clarification | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/client_server/newsfragments/2525.clarification diff --git a/changelogs/client_server/newsfragments/2525.clarification b/changelogs/client_server/newsfragments/2525.clarification new file mode 100644 index 00000000..e93444bf --- /dev/null +++ b/changelogs/client_server/newsfragments/2525.clarification @@ -0,0 +1,2 @@ +Clarification that the event ids are required in the response when putting room +events. From b0e8fd648df7fd9119a0e472710be3e46d3c6483 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 5 May 2020 09:21:58 -0600 Subject: [PATCH 1015/1250] Apply suggestions from code review --- changelogs/client_server/newsfragments/2525.clarification | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/changelogs/client_server/newsfragments/2525.clarification b/changelogs/client_server/newsfragments/2525.clarification index e93444bf..df1fc538 100644 --- a/changelogs/client_server/newsfragments/2525.clarification +++ b/changelogs/client_server/newsfragments/2525.clarification @@ -1,2 +1 @@ -Clarification that the event ids are required in the response when putting room -events. +Clarify that an ``event_id`` is returned when sending events. From 9980b83dd4bd120a055e8544240121b38cbb628f Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 5 May 2020 15:14:24 -0400 Subject: [PATCH 1016/1250] add changelog --- changelogs/client_server/newsfragments/2524.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2524.clarification diff --git a/changelogs/client_server/newsfragments/2524.clarification b/changelogs/client_server/newsfragments/2524.clarification new file mode 100644 index 00000000..cf36c3ba --- /dev/null +++ b/changelogs/client_server/newsfragments/2524.clarification @@ -0,0 +1 @@ +Fix various wording and markup issues in the end-to-end encryption section. From 6ede023b35e735f262886d8f02dc3523527443e9 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 5 May 2020 16:06:21 -0400 Subject: [PATCH 1017/1250] make the changelog match others so they get combined --- changelogs/client_server/newsfragments/2524.clarification | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/client_server/newsfragments/2524.clarification b/changelogs/client_server/newsfragments/2524.clarification index cf36c3ba..902a9c3f 100644 --- a/changelogs/client_server/newsfragments/2524.clarification +++ b/changelogs/client_server/newsfragments/2524.clarification @@ -1 +1 @@ -Fix various wording and markup issues in the end-to-end encryption section. +Fix various spelling errors throughout the specification. From e0b4a3c9121689e0ec1cbdf9351236d8004166d4 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 5 May 2020 17:02:16 -0400 Subject: [PATCH 1018/1250] Apply suggestions from code review Co-authored-by: Travis Ralston --- api/client-server/key_backup.yaml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/api/client-server/key_backup.yaml b/api/client-server/key_backup.yaml index b409dfbf..543a1992 100644 --- a/api/client-server/key_backup.yaml +++ b/api/client-server/key_backup.yaml @@ -31,14 +31,14 @@ paths: post: summary: Create a new backup. description: |- - Creates a new backup + Creates a new backup. operationId: postRoomKeysVersion security: - accessToken: [] parameters: - in: body name: version - description: "The backup configuration" + description: "The backup configuration." schema: type: object properties: @@ -73,7 +73,7 @@ paths: properties: version: type: string - description: The backup version + description: The backup version. example: "1" required: - version @@ -146,12 +146,12 @@ paths: - version 404: description: - The backup specified does not exist + The backup specified does not exist. examples: application/json: { - "errcode": "M_NOT_FOUND", - "error": "Unknown backup version" - } + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } schema: "$ref": "definitions/errors/error.yaml" tags: @@ -209,12 +209,12 @@ paths: - auth_data responses: 200: - description: The update succeeded + description: The update succeeded. schema: type: object properties: {} 404: - description: The backup specified does not exist + description: The backup specified does not exist. examples: application/json: { "errcode": "M_NOT_FOUND", @@ -226,7 +226,7 @@ paths: - End-to-end encryption "/room_keys/keys/{roomId}/{sessionId}": put: - summary: Store a key in the backup + summary: Store a key in the backup. description: |- Store a key in the backup. operationId: postRoomKeysKeyRoomIdSessionId @@ -254,12 +254,12 @@ paths: x-example: "sessionid" - in: body name: data - description: "The key data" + description: "The key data." schema: "$ref": "definitions/key_backup_data.yaml" responses: 200: - description: The update succeeded + description: The update succeeded. schema: type: object properties: From 8ff1c26ef22449fad5526a8861304a88826ae48d Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 5 May 2020 17:28:54 -0400 Subject: [PATCH 1019/1250] fix indentation --- .../definitions/key_backup_data.yaml | 8 +- api/client-server/key_backup.yaml | 142 +++++++++--------- 2 files changed, 75 insertions(+), 75 deletions(-) diff --git a/api/client-server/definitions/key_backup_data.yaml b/api/client-server/definitions/key_backup_data.yaml index 8f8de999..6a3b4042 100644 --- a/api/client-server/definitions/key_backup_data.yaml +++ b/api/client-server/definitions/key_backup_data.yaml @@ -39,10 +39,10 @@ properties: expected format of the data. type: object example: { - "ephemeral": "base64+ephemeral+key", - "ciphertext": "base64+ciphertext+of+JSON+data", - "mac": "base64+mac+of+ciphertext" - } + "ephemeral": "base64+ephemeral+key", + "ciphertext": "base64+ciphertext+of+JSON+data", + "mac": "base64+mac+of+ciphertext" + } required: - first_message_index - forwarded_count diff --git a/api/client-server/key_backup.yaml b/api/client-server/key_backup.yaml index 543a1992..bdca769e 100644 --- a/api/client-server/key_backup.yaml +++ b/api/client-server/key_backup.yaml @@ -54,13 +54,13 @@ paths: expected format of the data. type: object example: { - "public_key": "abcdefg", - "signatures": { - "@alice:example.org": { - "ed25519:deviceid": "signature" - } + "public_key": "abcdefg", + "signatures": { + "@alice:example.org": { + "ed25519:deviceid": "signature" } } + } required: - algorithm - auth_data @@ -115,13 +115,13 @@ paths: expected format of the data. type: object example: { - "public_key": "abcdefg", - "signatures": { - "@alice:example.org": { - "ed25519:deviceid": "signature" - } + "public_key": "abcdefg", + "signatures": { + "@alice:example.org": { + "ed25519:deviceid": "signature" } } + } count: description: The number of keys stored in the backup. type: integer @@ -191,13 +191,13 @@ paths: expected format of the data. type: object example: { - "public_key": "abcdefg", - "signatures": { - "@alice:example.org": { - "ed25519:deviceid": "signature" - } + "public_key": "abcdefg", + "signatures": { + "@alice:example.org": { + "ed25519:deviceid": "signature" } } + } version: description: |- The backup version. If present, must be the same as the @@ -283,10 +283,10 @@ paths: field. examples: application/json: { - "errcode": "M_WRONG_ROOM_KEYS_VERSION", - "error": "Wrong backup version.", - "current_version": "42" - } + "errcode": "M_WRONG_ROOM_KEYS_VERSION", + "error": "Wrong backup version.", + "current_version": "42" + } schema: "$ref": "definitions/errors/error.yaml" tags: @@ -327,9 +327,9 @@ paths: description: The key or backup was not found. examples: application/json: { - "errcode": "M_NOT_FOUND", - "error": "Key not found." - } + "errcode": "M_NOT_FOUND", + "error": "Key not found." + } schema: "$ref": "definitions/errors/error.yaml" delete: @@ -383,9 +383,9 @@ paths: The backup was not found. examples: application/json: { - "errcode": "M_NOT_FOUND", - "error": "Unknown backup version" - } + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } schema: "$ref": "definitions/errors/error.yaml" "/room_keys/keys/{roomId}": @@ -424,12 +424,12 @@ paths: allOf: - $ref: "definitions/key_backup_data.yaml" example: { - "sessionid1": { - "ephemeral": "base64+ephemeral+key", - "ciphertext": "base64+ciphertext+of+JSON+data", - "mac": "base64+mac+of+ciphertext" - } + "sessionid1": { + "ephemeral": "base64+ephemeral+key", + "ciphertext": "base64+ciphertext+of+JSON+data", + "mac": "base64+mac+of+ciphertext" } + } responses: 200: description: The update succeeded @@ -467,9 +467,9 @@ paths: The backup was not found. examples: application/json: { - "errcode": "M_NOT_FOUND", - "error": "Unknown backup version" - } + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } schema: "$ref": "definitions/errors/error.yaml" tags: @@ -511,20 +511,20 @@ paths: allOf: - $ref: "definitions/key_backup_data.yaml" example: { - "sessionid1": { - "ephemeral": "base64+ephemeral+key", - "ciphertext": "base64+ciphertext+of+JSON+data", - "mac": "base64+mac+of+ciphertext" - } + "sessionid1": { + "ephemeral": "base64+ephemeral+key", + "ciphertext": "base64+ciphertext+of+JSON+data", + "mac": "base64+mac+of+ciphertext" } + } 404: description: |- The backup was not found. examples: application/json: { - "errcode": "M_NOT_FOUND", - "error": "Unknown backup version" - } + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } schema: "$ref": "definitions/errors/error.yaml" delete: @@ -572,9 +572,9 @@ paths: The backup was not found. examples: application/json: { - "errcode": "M_NOT_FOUND", - "error": "Unknown backup version" - } + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } schema: "$ref": "definitions/errors/error.yaml" "/room_keys/keys": @@ -609,16 +609,16 @@ paths: allOf: - $ref: "definitions/key_backup_data.yaml" example: { - "!room:example.org": { - "sessions": { - "sessionid1": { - "ephemeral": "base64+ephemeral+key", - "ciphertext": "base64+ciphertext+of+JSON+data", - "mac": "base64+mac+of+ciphertext" - } + "!room:example.org": { + "sessions": { + "sessionid1": { + "ephemeral": "base64+ephemeral+key", + "ciphertext": "base64+ciphertext+of+JSON+data", + "mac": "base64+mac+of+ciphertext" } } } + } responses: 200: description: The update succeeded @@ -645,10 +645,10 @@ paths: field. examples: application/json: { - "errcode": "M_WRONG_ROOM_KEYS_VERSION", - "error": "Wrong backup version.", - "current_version": "42" - } + "errcode": "M_WRONG_ROOM_KEYS_VERSION", + "error": "Wrong backup version.", + "current_version": "42" + } schema: "$ref": "definitions/errors/error.yaml" 404: @@ -656,9 +656,9 @@ paths: The backup was not found. examples: application/json: { - "errcode": "M_NOT_FOUND", - "error": "Unknown backup version" - } + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } schema: "$ref": "definitions/errors/error.yaml" tags: @@ -696,23 +696,23 @@ paths: allOf: - $ref: "definitions/key_backup_data.yaml" example: { - "!room:example.org": { - "sessions": { - "sessionid1": { - "ephemeral": "base64+ephemeral+key", - "ciphertext": "base64+ciphertext+of+JSON+data", - "mac": "base64+mac+of+ciphertext" - } + "!room:example.org": { + "sessions": { + "sessionid1": { + "ephemeral": "base64+ephemeral+key", + "ciphertext": "base64+ciphertext+of+JSON+data", + "mac": "base64+mac+of+ciphertext" } } } + } 404: description: The backup was not found. examples: application/json: { - "errcode": "M_NOT_FOUND", - "error": "Unknown backup version." - } + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version." + } schema: "$ref": "definitions/errors/error.yaml" delete: @@ -754,8 +754,8 @@ paths: The backup was not found. examples: application/json: { - "errcode": "M_NOT_FOUND", - "error": "Unknown backup version" - } + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } schema: "$ref": "definitions/errors/error.yaml" From 5f3ee44cfbcfbdf625170788ad7fb8d91627d5fc Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 5 May 2020 18:09:17 -0400 Subject: [PATCH 1020/1250] add more suggestions from review --- api/client-server/key_backup.yaml | 14 ++++++++++---- specification/modules/end_to_end_encryption.rst | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/api/client-server/key_backup.yaml b/api/client-server/key_backup.yaml index bdca769e..ae729d62 100644 --- a/api/client-server/key_backup.yaml +++ b/api/client-server/key_backup.yaml @@ -73,7 +73,7 @@ paths: properties: version: type: string - description: The backup version. + description: The backup version. This is an opaque string. example: "1" required: - version @@ -92,8 +92,10 @@ paths: type: string name: version description: |- - The backup version to get. When an empty string, the trailing slash - is optional, and the current backup is returned. + The backup version to get, as returned in the ``version`` parameter + of the response in `POST /_matrix/client/r0/room_keys/version`_ or + this endpoint. When an empty string, the trailing slash is + optional, and the current backup is returned. required: true x-example: "1" responses: @@ -168,7 +170,11 @@ paths: type: string name: version description: |- - The backup version to update. + The backup version to update, as returned in the ``version`` + parameter in the response of `POST + /_matrix/client/r0/room_keys/version`_ or `GET + /_matrix/client/r0/room_keys/version/{version}`_. Unlike with the + ``GET`` version of this endpoint, this may not be empty. required: true x-example: "1" - in: body diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 6945ce42..8e4b0739 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -819,8 +819,8 @@ follows: 2. All the bytes in the string above, including the two header bytes, are XORed together to form a parity byte. This parity byte is appended to the byte string. -3. The byte string is encoded using base58, using the same mapping as is used - for Bitcoin addresses. +3. The byte string is encoded using base58, using the same `mapping as is used + for Bitcoin addresses `_. 4. A space should be added after every 4th character. When reading in a recovery key, clients must disregard whitespace, and perform From 3d1c33ed1b0f788135d5e03cbf49dafa04919698 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 5 May 2020 18:09:35 -0400 Subject: [PATCH 1021/1250] move API definitions into backup section --- specification/modules/end_to_end_encryption.rst | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 8e4b0739..48a2d6ca 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -890,6 +890,8 @@ The ``session_data`` field in the backups is constructed as follows: using the MAC key generated above. The first 8 bytes of the resulting MAC are base64-encoded, and become the ``mac`` property of the ``session_data``. +{{key_backup_cs_http_api}} + Key exports ~~~~~~~~~~~ @@ -1215,11 +1217,6 @@ Key management API {{keys_cs_http_api}} -Key Backup API -~~~~~~~~~~~~~~ - -{{key_backup_cs_http_api}} - .. anchor for link from /sync api spec .. |device_lists_sync| replace:: End-to-end encryption From fffed943bcdfc3b016a5c03ce4fa66c35160220b Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 5 May 2020 19:18:04 -0400 Subject: [PATCH 1022/1250] proposal to add endpoint to delete backups --- proposals/xxxx-add-delete-backup.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 proposals/xxxx-add-delete-backup.md diff --git a/proposals/xxxx-add-delete-backup.md b/proposals/xxxx-add-delete-backup.md new file mode 100644 index 00000000..b84de399 --- /dev/null +++ b/proposals/xxxx-add-delete-backup.md @@ -0,0 +1,14 @@ +# Add ability to delete key backups + +[MSC1219](https://github.com/matrix-org/matrix-doc/issues/1219) defined a +mechanism for key backups. However, it inadvertently omitted the endpoint to +delete an entire key backup. This proposal adds the endpoint. + +## Proposal + +An endpoint is added, `DELETE /room_keys/version/{version}`, that deletes a +backup version. Both the information about the key backup, as well as all keys +associated with the backup should be deleted. Like `POST +/room_keys/version/{version}`, and unlike `GET /room_keys/version/{version}`, +`{version}` cannot be empty, to ensure that the wrong backup is not +accidentally deleted. From 0b39308a139276a3ed02297bac4e9a5f99032a3e Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 5 May 2020 19:20:20 -0400 Subject: [PATCH 1023/1250] rename to use msc number --- .../{xxxx-add-delete-backup.md => 2526-add-delete-backup.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename proposals/{xxxx-add-delete-backup.md => 2526-add-delete-backup.md} (93%) diff --git a/proposals/xxxx-add-delete-backup.md b/proposals/2526-add-delete-backup.md similarity index 93% rename from proposals/xxxx-add-delete-backup.md rename to proposals/2526-add-delete-backup.md index b84de399..e4d589e3 100644 --- a/proposals/xxxx-add-delete-backup.md +++ b/proposals/2526-add-delete-backup.md @@ -1,4 +1,4 @@ -# Add ability to delete key backups +# MSC2526: Add ability to delete key backups [MSC1219](https://github.com/matrix-org/matrix-doc/issues/1219) defined a mechanism for key backups. However, it inadvertently omitted the endpoint to From 0145191d43d4c9021bc43ad3bb36caae468d6537 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 5 May 2020 20:00:45 -0400 Subject: [PATCH 1024/1250] add links to endpoints and add delete endpoint --- api/client-server/key_backup.yaml | 37 +++++++++++++++++++ .../modules/end_to_end_encryption.rst | 21 ++++++----- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/api/client-server/key_backup.yaml b/api/client-server/key_backup.yaml index ae729d62..387621e6 100644 --- a/api/client-server/key_backup.yaml +++ b/api/client-server/key_backup.yaml @@ -230,6 +230,43 @@ paths: "$ref": "definitions/errors/error.yaml" tags: - End-to-end encryption + delete: + summary: Delete an existing key backup. + description: |- + Delete an existing key backup. Both the information about the backup, + as well as all key data related to the backup will be deleted. + operationId: deleteRoomKeysVersion + security: + - accessToken: [] + parameters: + - in: path + type: string + name: version + description: |- + The backup version to delete, as returned in the ``version`` + parameter in the response of `POST + /_matrix/client/r0/room_keys/version`_ or `GET + /_matrix/client/r0/room_keys/version/{version}`_. Unlike with the + ``GET`` version of this endpoint, this may not be empty. + required: true + x-example: "1" + responses: + 200: + description: The delete succeeded. + schema: + type: object + properties: {} + 404: + description: The backup specified does not exist. + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } + schema: + "$ref": "definitions/errors/error.yaml" + tags: + - End-to-end encryption "/room_keys/keys/{roomId}/{sessionId}": put: summary: Store a key in the backup. diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 48a2d6ca..d6c87bc3 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -780,15 +780,18 @@ device to be online from which to request keys. However, as the session keys are stored on the server encrypted, it requires users to enter a decryption key to decrypt the session keys. -To create a backup, a client will call ``POST /room_keys/version`` and define -how the keys are to be encrypted through the backup's ``auth_data``; other -clients can discover the backup by calling ``GET /room_keys/version``. Keys -are encrypted according to the backups ``auth_data`` and added to the backup by -calling ``PUT /room_keys/keys?version=$v`` or one of its variants, and can be -retrieved by calling ``GET /room_keys/keys?version=$v`` or one of its variants. -Keys can only be written to the most recently created version of the backup. -Backups can also be deleted using ``DELETE /room_keys/version``, or individual -keys can be deleted using ``DELETE /room_key/keys?version=$v`` or one of its +To create a backup, a client will call `POST +/_matrix/client/r0/room_keys/version`_ and define how the keys are to be +encrypted through the backup's ``auth_data``; other clients can discover the +backup by calling `GET /_matrix/client/r0/room_keys/version/{version}`_, +setting ``{version}`` to the empty string. Keys are encrypted according to the +backups ``auth_data`` and added to the backup by calling `PUT +/_matrix/client/r0/room_keys/keys`_ or one of its variants, and can be +retrieved by calling `GET /_matrix/client/r0/room_keys/keys`_ or one of its +variants. Keys can only be written to the most recently created version of the +backup. Backups can also be deleted using `DELETE +/_matrix/client/r0/room_keys/version/{version}`_, or individual keys can be +deleted using `DELETE /_matrix/client/r0/room_keys/keys`_ or one of its variants. Clients must only store keys in backups after they have ensured that the From 6b8b31ce638d82fed94957bb1b6c33bc71fd92cb Mon Sep 17 00:00:00 2001 From: Gnuxie <50846879+Gnuxie@users.noreply.github.com> Date: Wed, 6 May 2020 17:10:39 +0100 Subject: [PATCH 1025/1250] correct use of required annotation in json-schema https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.3 --- api/server-server/definitions/keys.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/api/server-server/definitions/keys.yaml b/api/server-server/definitions/keys.yaml index 8bc6c563..1e025a52 100644 --- a/api/server-server/definitions/keys.yaml +++ b/api/server-server/definitions/keys.yaml @@ -20,7 +20,6 @@ properties: server_name: type: string description: DNS name of the homeserver. - required: true example: "example.org" verify_keys: type: object @@ -31,7 +30,6 @@ properties: algorithm and ``abc123`` being the version in the example below). Together, this forms the Key ID. The version must have characters matching the regular expression ``[a-zA-Z0-9_]``. - required: true additionalProperties: type: object title: Verify Key @@ -44,8 +42,8 @@ properties: key: type: string description: The `Unpadded Base64`_ encoded key. - required: true example: "VGhpcyBzaG91bGQgYmUgYSByZWFsIGVkMjU1MTkgcGF5bG9hZA" + required: ["key"] old_verify_keys: type: object description: |- @@ -69,13 +67,12 @@ properties: type: integer format: int64 description: POSIX timestamp in milliseconds for when this key expired. - required: true example: 1532645052628 key: type: string description: The `Unpadded Base64`_ encoded key. - required: true example: "VGhpcyBzaG91bGQgYmUgeW91ciBvbGQga2V5J3MgZWQyNTUxOSBwYXlsb2FkLg" + required: ["expired_ts", "key"] signatures: type: object description: Digital signatures for this object signed using the ``verify_keys``. @@ -103,3 +100,4 @@ properties: publishes a key which is valid for a significant amount of time without a way for the homeserver owner to revoke it. example: 1052262000000 +required: ["server_name", "verify_keys"] From a896729ac2ec68b794cbf8ee3b8e29e3ccfb6078 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 6 May 2020 17:11:41 -0400 Subject: [PATCH 1026/1250] some more clarifications and indentation fixes --- api/client-server/key_backup.yaml | 24 ++++++++++++++----- .../modules/end_to_end_encryption.rst | 10 ++++---- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/api/client-server/key_backup.yaml b/api/client-server/key_backup.yaml index 387621e6..0f7ff25b 100644 --- a/api/client-server/key_backup.yaml +++ b/api/client-server/key_backup.yaml @@ -219,13 +219,25 @@ paths: schema: type: object properties: {} + 400: + description: |- + A parameter was incorrect. For example, the ``algorithm`` does not + match the current backup algorithm, or the ``version`` in the body + does not match the ``version`` in the path. + examples: + application/json: { + "errcode": "M_INVALID_PARAM", + "error": "Algorithm does not match" + } + schema: + "$ref": "definitions/errors/error.yaml" 404: description: The backup specified does not exist. examples: application/json: { - "errcode": "M_NOT_FOUND", - "error": "Unknown backup version" - } + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } schema: "$ref": "definitions/errors/error.yaml" tags: @@ -260,9 +272,9 @@ paths: description: The backup specified does not exist. examples: application/json: { - "errcode": "M_NOT_FOUND", - "error": "Unknown backup version" - } + "errcode": "M_NOT_FOUND", + "error": "Unknown backup version" + } schema: "$ref": "definitions/errors/error.yaml" tags: diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index d6c87bc3..8f26477a 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -846,9 +846,8 @@ following format: ========== =========== ====================================================== public_key string Required. The curve25519 public key used to encrypt the backups, encoded in unpadded base64. - signatures {string: Optional. Signatures of the ``auth_data``, as Signed - {string: JSON - string}} + signatures Signatures Optional. Signatures of the ``auth_data``, as Signed + JSON ========== =========== ====================================================== The ``session_data`` field in the backups is constructed as follows: @@ -870,8 +869,9 @@ The ``session_data`` field in the backups is constructed as follows: `m.forwarded_room_key`_ events. sender_key string Required. Unpadded base64-encoded device curve25519 key. - sender_claimed_keys {string: Required. Object containing the - string} identity key for the sending device. + sender_claimed_keys {string: Required. A map from algorithm name + string} (``ed25519``) to the identity key + for the sending device. session_key string Required. Unpadded base64-encoded session key in `session-sharing format `_. From 6613cd89a668f400a82a8a9f36b961768d77090f Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Thu, 7 May 2020 15:42:04 +0100 Subject: [PATCH 1027/1250] 2454-ui-interactive-auth-for-sso.md: markup fix --- proposals/2454-ui-interactive-auth-for-sso.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2454-ui-interactive-auth-for-sso.md b/proposals/2454-ui-interactive-auth-for-sso.md index e39facfb..18112c5f 100644 --- a/proposals/2454-ui-interactive-auth-for-sso.md +++ b/proposals/2454-ui-interactive-auth-for-sso.md @@ -209,7 +209,7 @@ provider. It's common for SSO providers to redirect straight back to the app if you've recently authenticated with them; even in the best case, the SSO provider shows an innocent message along the lines of "Confirm that you want to sign in to -". +\". After redirecting back to the homeserver, the SSO is completed and the attacker's session is validated. They are now able to make their malicious From 9065d1aa143e06a42fd36e59d923d0756ae6225d Mon Sep 17 00:00:00 2001 From: Ben Parsons Date: Thu, 7 May 2020 15:45:33 +0100 Subject: [PATCH 1028/1250] proposal to use existing events as captions for images --- proposals/2529-text-messages-as-captions.md | 37 +++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 proposals/2529-text-messages-as-captions.md diff --git a/proposals/2529-text-messages-as-captions.md b/proposals/2529-text-messages-as-captions.md new file mode 100644 index 00000000..df76e325 --- /dev/null +++ b/proposals/2529-text-messages-as-captions.md @@ -0,0 +1,37 @@ +# Use existing m.room.message/m.text events as captions for images + +## Background + +There is a demand to be able to apply a text caption to an image, as is possible in other chat platforms. In Matrix this is not possible, so people will generally send two events: one `m.image`, then a `m.text` event immediately afterward to simulate a caption. + +Better would be to able to explicitly mark an event as a caption. + +## Proposal + +Allow an optional `m.relates_to` field in the `content` field of a text message event. + +Example: + +``` +... + "content": { + "body": "Caption text", + "msgtype": "m.text", + "m.relates_to": { + "event_id": "$(some image event)", + "rel_type": "m.caption" + } + }, +``` + +If a client recognises the `rel_type`, they can render the caption with the image rather than as a separate message in the timeline. + +The benefit of this is that if a client doesn't support or recognise the `m.caption`, it can ignore the relation and just render the message inline. + +This would not require aggregation from the server since there will always be a need to send the event separately anyway. + +## Potential issues + +* Not sure how this relates to the broader questions discussed in MSC1849 +* This is catering to a narrow use-case requirement. There may be a more general solution available +* Would MSC1767 (extensible events) obsolete this? From c704da1449eb18127a4fa4b8028f6dbfb3e1fd9d Mon Sep 17 00:00:00 2001 From: Ben Parsons Date: Thu, 7 May 2020 15:49:18 +0100 Subject: [PATCH 1029/1250] remove proposal --- proposals/2529-text-messages-as-captions.md | 37 --------------------- 1 file changed, 37 deletions(-) delete mode 100644 proposals/2529-text-messages-as-captions.md diff --git a/proposals/2529-text-messages-as-captions.md b/proposals/2529-text-messages-as-captions.md deleted file mode 100644 index df76e325..00000000 --- a/proposals/2529-text-messages-as-captions.md +++ /dev/null @@ -1,37 +0,0 @@ -# Use existing m.room.message/m.text events as captions for images - -## Background - -There is a demand to be able to apply a text caption to an image, as is possible in other chat platforms. In Matrix this is not possible, so people will generally send two events: one `m.image`, then a `m.text` event immediately afterward to simulate a caption. - -Better would be to able to explicitly mark an event as a caption. - -## Proposal - -Allow an optional `m.relates_to` field in the `content` field of a text message event. - -Example: - -``` -... - "content": { - "body": "Caption text", - "msgtype": "m.text", - "m.relates_to": { - "event_id": "$(some image event)", - "rel_type": "m.caption" - } - }, -``` - -If a client recognises the `rel_type`, they can render the caption with the image rather than as a separate message in the timeline. - -The benefit of this is that if a client doesn't support or recognise the `m.caption`, it can ignore the relation and just render the message inline. - -This would not require aggregation from the server since there will always be a need to send the event separately anyway. - -## Potential issues - -* Not sure how this relates to the broader questions discussed in MSC1849 -* This is catering to a narrow use-case requirement. There may be a more general solution available -* Would MSC1767 (extensible events) obsolete this? From 77783b8fc3dc6edb9c6048f359a19e781b2c8c50 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Wed, 29 Apr 2020 20:14:12 +0200 Subject: [PATCH 1030/1250] Remove extraneous quotes, fix a typo filter.yaml: quotes under |- were taken literally. notifications.yaml: it's a number in the example, not a string --- api/client-server/filter.yaml | 2 +- api/client-server/notifications.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/client-server/filter.yaml b/api/client-server/filter.yaml index db215196..bf9396e2 100644 --- a/api/client-server/filter.yaml +++ b/api/client-server/filter.yaml @@ -119,7 +119,7 @@ paths: responses: 200: description: |- - "The filter defintion" + The filter definition. examples: application/json: { "room": { diff --git a/api/client-server/notifications.yaml b/api/client-server/notifications.yaml index 87341d41..8679cb91 100644 --- a/api/client-server/notifications.yaml +++ b/api/client-server/notifications.yaml @@ -49,7 +49,7 @@ paths: name: limit description: Limit on the number of events to return in this request. required: false - x-example: "20" + x-example: 20 - in: query name: only type: string From ff59fc1905259bb7853d88bd2736889797906a3c Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Fri, 8 May 2020 07:40:54 +0200 Subject: [PATCH 1031/1250] /keys/query: Add a title in the response The device keys structure in queryKeys is not the same as the one defined in device_keys.yaml (it adds things on top of it). Signed-off-by: Alexey Rusakov --- api/client-server/keys.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/api/client-server/keys.yaml b/api/client-server/keys.yaml index 69e39def..8c4a65f7 100644 --- a/api/client-server/keys.yaml +++ b/api/client-server/keys.yaml @@ -196,6 +196,7 @@ paths: additionalProperties: type: object additionalProperties: + title: DeviceInformation allOf: - $ref: definitions/device_keys.yaml properties: From 78f8d1322f220018d51281885ca237a724831366 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Fri, 8 May 2020 11:27:11 -0400 Subject: [PATCH 1032/1250] Add MSC2454 to the specification. --- .../client_server/newsfragments/2532.feature | 1 + specification/client_server_api.rst | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 changelogs/client_server/newsfragments/2532.feature diff --git a/changelogs/client_server/newsfragments/2532.feature b/changelogs/client_server/newsfragments/2532.feature new file mode 100644 index 00000000..cf74a289 --- /dev/null +++ b/changelogs/client_server/newsfragments/2532.feature @@ -0,0 +1 @@ +Add User-Interactive Authentication for SSO-backed homeserver per `MSC2454 `_. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index eb32d3b4..581f0c28 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -643,6 +643,7 @@ This specification defines the following auth types: - ``m.login.password`` - ``m.login.recaptcha`` - ``m.login.oauth2`` + - ``m.login.sso`` - ``m.login.email.identity`` - ``m.login.msisdn`` - ``m.login.token`` @@ -782,6 +783,38 @@ the auth code. Homeservers can choose any path for the ``redirect URI``. Once the OAuth flow has completed, the client retries the request with the session only, as above. +Single Sign-On +<<<<<<<<<<<<<< +:Type: + ``m.login.sso`` +:Description: + Authentication is supported by authorising with an external single sign-on + provider. + +A client wanting to complete authentication using SSO should use the +`Fallback`_ authentication flow by opening a browser window for +``/_matrix/client/r0/auth/m.login.sso/fallback/web?session=<...>`` with the +session parameter set to the session ID provied by the server. + +The homeserver should return a page which asks for the user's confirmation +before proceeding. For example, the page could say words to the effect of: + + A client is trying to remove a device/add an email address/take over your + account. To confirm this action, re-authenticate with single sign-on. If you + did not expect this, your account may be compromised! + +Once the user has confirmed they should be redirected to the single sign-on +provider's login page. Once the provider has validated the user, the browser is +redirected back to the homeserver. + +The homeserver then validates the response from the single sign-on provider and +updates the user-interactive authentication session to mark the single sign-on +stage has been completed. The browser is shown the fallback authentication +completion page. + +Once the flow has completed, the client retries the request with the session +only, as above. + Email-based (identity / homeserver) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< :Type: From 86d0d04ed19a3e6a15e0de5fa98874bcaa94e33a Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 11 May 2020 11:54:50 -0400 Subject: [PATCH 1033/1250] don't include unrelated changes --- proposals/xxxx-sas-v2.md | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/proposals/xxxx-sas-v2.md b/proposals/xxxx-sas-v2.md index b4652ff8..0e689c30 100644 --- a/proposals/xxxx-sas-v2.md +++ b/proposals/xxxx-sas-v2.md @@ -21,25 +21,11 @@ concatenation of: which sent the `m.key.verification.accept` message, followed by `|`. * The `transaction_id` being used. -A new `message_authentication_code` method, `hkdf-hmac-sha256.v2` is introduced. It -is the same as `hkdf-hmac-sha256`, except that the info parameter for the HKDF -is the concatenation of: - - * The string `MATRIX_KEY_VERIFICATION_MAC|`. - * The Matrix ID of the user whose key is being MAC-ed, followed by `|`. - * The Device ID of the device sending the MAC, followed by `|`. - * The Matrix ID of the other user, followed by `|`. - * The Device ID of the device receiving the MAC, followed by `|`. - * The transaction_id being used, followed by `|`. - * The Key ID of the key being MAC-ed, or the string `KEY_IDS` if the item - being MAC-ed is the list of key IDs. - -A new `short_authentication_string` method, `emoji.v2` is introduced. It is -the same as `emoji`, but emoji number 34 is changed from 🔧 (`U+1F527` Spanner) -to ⭐ (`U+2B50` Star). - -The `key_agreement_protocol` `curve25519`, `message_authentication_code` -`hkdf-hmac-sha256`, and `short_authentication_string` `emoji` are deprecated. +The differences from `curve25519` are the addition of the public keys, and the +addition of `|` as delimiter between the fields. + +The `key_agreement_protocol` `curve25519` is deprecated and may be removed in +the future. ## Potential issues From e85f6c31a3f6d2f93de402347edae4500d95b383 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Mon, 11 May 2020 15:14:11 -0400 Subject: [PATCH 1034/1250] Fix a typo found in review. Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- specification/client_server_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 581f0c28..fce879a2 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -794,7 +794,7 @@ Single Sign-On A client wanting to complete authentication using SSO should use the `Fallback`_ authentication flow by opening a browser window for ``/_matrix/client/r0/auth/m.login.sso/fallback/web?session=<...>`` with the -session parameter set to the session ID provied by the server. +session parameter set to the session ID provided by the server. The homeserver should return a page which asks for the user's confirmation before proceeding. For example, the page could say words to the effect of: From 3556b8457f5bde619c6e81c9b996c43fc86fb78d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 11 May 2020 21:05:26 -0600 Subject: [PATCH 1035/1250] Add changelog for 2527 --- changelogs/server_server/newsfragments/2527.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/server_server/newsfragments/2527.clarification diff --git a/changelogs/server_server/newsfragments/2527.clarification b/changelogs/server_server/newsfragments/2527.clarification new file mode 100644 index 00000000..329d5da2 --- /dev/null +++ b/changelogs/server_server/newsfragments/2527.clarification @@ -0,0 +1 @@ +Clarify which fields are required on the key server endpoints. From f156938821cba90bb555af45dac28c01b460524f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 12 May 2020 16:10:14 -0600 Subject: [PATCH 1036/1250] Update v6 room proposal for modern activity --- proposals/2240-rooms-v6.md | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/proposals/2240-rooms-v6.md b/proposals/2240-rooms-v6.md index a67a1ad7..fddbdc9c 100644 --- a/proposals/2240-rooms-v6.md +++ b/proposals/2240-rooms-v6.md @@ -1,21 +1,14 @@ # MSC2240: Room Version 6 -A new room version, `6`, is proposed using [room version 5](https://matrix.org/docs/spec/rooms/v5.html) -as a starting point and incorporating the following MSCs: +A new room version, `6`, is proposed using [room version 5](https://matrix.org/docs/spec/rooms/v5.html) as a base +and incorporating the following MSCs: -* [MSC2174](https://github.com/matrix-org/matrix-doc/pull/2174) - Moving the `redacts` key. -* [MSC2175](https://github.com/matrix-org/matrix-doc/pull/2175) - Removing the `creator` from create events. -* [MSC2176](https://github.com/matrix-org/matrix-doc/pull/2176) - Modern redaction rules. * [MSC2209](https://github.com/matrix-org/matrix-doc/pull/2209) - Including notifications in power level auth rules. -* [MSC2212](https://github.com/matrix-org/matrix-doc/pull/2212) - Third party user power levels. -* [MSC2213](https://github.com/matrix-org/matrix-doc/pull/2213) - Rejoinability of invite-only rooms. -* [MSC1849](https://github.com/matrix-org/matrix-doc/pull/1849) - Event aggregations/relationships. +* [MSC2212](https://github.com/matrix-org/matrix-doc/pull/2432) - Alias event authorisation and redaction. +* PLACEHOLDER - Something to do with integers. -MSCs which require a new room version and are excluded from v6 are: -* [MSC2214](https://github.com/matrix-org/matrix-doc/pull/2214) - Joining upgraded private rooms. - This MSC is excluded due to the solution not being fully worked out. As this v6 proposal progresses, - it is possible for it to be included in the future. +Though other MSCs are capable of being included in this version, they do not have sufficient implementation to be +considered stable enough for v6 rooms. A future room version may still include them. - -Room version 6 upon being added to the specification shall be considered stable. No other room versions -are affected by this MSC. +Room version 6 upon being added to the specification shall be considered stable. No other room versions are affected +by this MSC. From 42ae5c966a1256e3ff2ec1945c45529dc92fae68 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 12 May 2020 19:02:39 -0600 Subject: [PATCH 1037/1250] Clarify the limits of prev_events and auth_events Fixes https://github.com/matrix-org/matrix-doc/issues/2307 These restrictions are due to a Synapse change which never made it to the spec prior to the MSC process. This is therefore documenting an omission. Synapse's numbers are verified here: https://github.com/matrix-org/synapse/blob/207b1737ee0acd226359d59ce3b7f7d46111b1c8/synapse/handlers/federation.py#L1183-L1213 ... and Synapse's handling of the backfill endpoint is described here: https://github.com/matrix-org/synapse/blob/207b1737ee0acd226359d59ce3b7f7d46111b1c8/synapse/handlers/federation.py#L829-L837 This also includes a mention that https://github.com/matrix-org/matrix-doc/pull/1594 should render the `auth_events` limitation unnecessary. No changes are required to the the "checks on receipt of a PDU" section of the server-server spec as it starts with "must be a valid event", to which an event is invalid if it contains too many prev or auth events. --- api/server-server/backfill.yaml | 8 ++++++++ api/server-server/definitions/pdu_v3.yaml | 6 ++++++ api/server-server/definitions/pdu_v4.yaml | 6 ++++++ api/server-server/definitions/unsigned_pdu_base.yaml | 6 ++++++ 4 files changed, 26 insertions(+) diff --git a/api/server-server/backfill.yaml b/api/server-server/backfill.yaml index 2ed6298c..d53de6c0 100644 --- a/api/server-server/backfill.yaml +++ b/api/server-server/backfill.yaml @@ -63,6 +63,14 @@ paths: description: |- A transaction containing the PDUs that preceded the given event(s), including the given event(s), up to the given limit. + + .. Note:: + Though the PDU definitions require that ``prev_events`` and ``auth_events`` be limited + in number, the response of backfill MUST NOT be validated on these specific restrictions. + + Due to historical reasons, it is possible that events which were previously accepted + would now be rejected by these limitations. The events should be rejected per usual by + the ``/send``, ``/get_missing_events``, and remaining endpoints. schema: $ref: "definitions/unlimited_pdu_transaction.yaml" "/get_missing_events/{roomId}": diff --git a/api/server-server/definitions/pdu_v3.yaml b/api/server-server/definitions/pdu_v3.yaml index 38105098..3e69d941 100644 --- a/api/server-server/definitions/pdu_v3.yaml +++ b/api/server-server/definitions/pdu_v3.yaml @@ -32,6 +32,10 @@ allOf: description: |- Event IDs for the authorization events that would allow this event to be in the room. + + Must contain less than or equal to 10 events. Note that if the relevant + auth event selection rules are used, this restriction should never be + encountered. example: ["$base64EncodedHash", "$AnotherEvent"] prev_events: type: array @@ -41,6 +45,8 @@ allOf: description: |- Event IDs for the most recent events in the room that the homeserver was aware of when it made this event. + + Must contain less than or equal to 20 events. example: ["$base64EncodedHash", "$AnotherEvent"] hashes: type: object diff --git a/api/server-server/definitions/pdu_v4.yaml b/api/server-server/definitions/pdu_v4.yaml index a045e657..d22956c6 100644 --- a/api/server-server/definitions/pdu_v4.yaml +++ b/api/server-server/definitions/pdu_v4.yaml @@ -32,6 +32,10 @@ allOf: description: |- Event IDs for the authorization events that would allow this event to be in the room. + + Must contain less than or equal to 10 events. Note that if the relevant + auth event selection rules are used, this restriction should never be + encountered. example: ["$URLsafe-base64EncodedHash", "$Another_Event"] prev_events: type: array @@ -41,6 +45,8 @@ allOf: description: |- Event IDs for the most recent events in the room that the homeserver was aware of when it made this event. + + Must contain less than or equal to 20 events. example: ["$URLsafe-base64EncodedHash", "$Another_Event"] required: - auth_events diff --git a/api/server-server/definitions/unsigned_pdu_base.yaml b/api/server-server/definitions/unsigned_pdu_base.yaml index 283e4fed..f1485b55 100644 --- a/api/server-server/definitions/unsigned_pdu_base.yaml +++ b/api/server-server/definitions/unsigned_pdu_base.yaml @@ -53,6 +53,8 @@ properties: 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. + + Must contain less than or equal to 20 events. items: type: array maxItems: 2 @@ -84,6 +86,10 @@ properties: description: |- Event IDs and reference hashes for the authorization events that would allow this event to be in the room. + + Must contain less than or equal to 10 events. Note that if the relevant + auth event selection rules are used, this restriction should never be + encountered. items: type: array maxItems: 2 From 9599c3bc99bd1e7a2914d868f7349da4e9707b6f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 12 May 2020 19:03:53 -0600 Subject: [PATCH 1038/1250] changelog --- changelogs/server_server/newsfragments/2538.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/server_server/newsfragments/2538.clarification diff --git a/changelogs/server_server/newsfragments/2538.clarification b/changelogs/server_server/newsfragments/2538.clarification new file mode 100644 index 00000000..be6f769e --- /dev/null +++ b/changelogs/server_server/newsfragments/2538.clarification @@ -0,0 +1 @@ +Clarify the limits of ``prev_event``s and ``auth_events`` for PDUs. From 05228bf40be9eb89b225924f74b497119d1dac62 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 12 May 2020 19:13:16 -0600 Subject: [PATCH 1039/1250] ``s -> s`` --- changelogs/server_server/newsfragments/2538.clarification | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/server_server/newsfragments/2538.clarification b/changelogs/server_server/newsfragments/2538.clarification index be6f769e..4b709a8d 100644 --- a/changelogs/server_server/newsfragments/2538.clarification +++ b/changelogs/server_server/newsfragments/2538.clarification @@ -1 +1 @@ -Clarify the limits of ``prev_event``s and ``auth_events`` for PDUs. +Clarify the limits of ``prev_events`` and ``auth_events`` for PDUs. From 7797c187275c5e340b2d4ef54aa8d4ef331a5012 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 13 May 2020 11:22:51 -0400 Subject: [PATCH 1040/1250] Add MSC2540 for stricter validation of event JSON. --- proposals/2540-stricter-event-validation.md | 55 +++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 proposals/2540-stricter-event-validation.md diff --git a/proposals/2540-stricter-event-validation.md b/proposals/2540-stricter-event-validation.md new file mode 100644 index 00000000..9763b4f4 --- /dev/null +++ b/proposals/2540-stricter-event-validation.md @@ -0,0 +1,55 @@ +# MSC2540: Stricter event validation: JSON compliance + +## Background + +There has been [prior discussions](https://github.com/matrix-org/matrix-doc/issues/1646) +about validating events more strictly. This MSC proposes fixing a small piece of +this: JSON compliance. + +The [Canonical JSON](https://matrix.org/docs/spec/appendices#canonical-json) +specification requires that numbers that are serialized in JSON are integers in +the range of [-2 ^ 53 + 1, 2 ^ 53 - 1], which matches the requirements of +[section 6 of RFC 7159](https://tools.ietf.org/html/rfc7159). Note that it is +not explicit, but all floats are invalid. + +It is worth mentioning that there are common extensions to JSON which produce +invalid JSON according to the Matrix specification, some programming langauges +even support these by default. One common additional feature is handling +"special" float values: `Infinity`, `-Infinity`, and `NaN`. + + +## Proposal + +In a future room version, Matrix server implementations should strictly enforce +the Canonical JSON specification for events. + +The rationale for doing this in a future room version is to avoid a split brain +room -- where some federated servers believe an event is valid and others reject +it as invalid. Rooms will be able to opt into this behavior as part of a room +version upgrade. + + +## Potential issues + +N/A + + +## Alternatives + +It could be argued that this MSC is unnecessary since it does not add any new +requirements for handling of JSON data. Unfortunately starting to enforce these +requirements in current rooms could cause federation to break as homeservers +will disagree on whether events are valid. + + +## Security considerations + +N/A + + +## Unstable prefix + +A room versions of `org.matrix.strict_canonicaljson` until a future room version +is available. This room version will use +[room version 5](https://matrix.org/docs/spec/rooms/v5) as base and include the +above modifications. From 11587a53849b4e898fd13b8051a8417619590879 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 13 May 2020 11:25:31 -0400 Subject: [PATCH 1041/1250] Small clarification. --- proposals/2540-stricter-event-validation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2540-stricter-event-validation.md b/proposals/2540-stricter-event-validation.md index 9763b4f4..81acd970 100644 --- a/proposals/2540-stricter-event-validation.md +++ b/proposals/2540-stricter-event-validation.md @@ -21,7 +21,7 @@ even support these by default. One common additional feature is handling ## Proposal In a future room version, Matrix server implementations should strictly enforce -the Canonical JSON specification for events. +the JSON compliance of the Canonical JSON specification for events. The rationale for doing this in a future room version is to avoid a split brain room -- where some federated servers believe an event is valid and others reject From d8e6e17bd378481e7f411f83c1fe30b001b9fb18 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 13 May 2020 09:42:14 -0600 Subject: [PATCH 1042/1250] Incorporate integers MSC --- proposals/2240-rooms-v6.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2240-rooms-v6.md b/proposals/2240-rooms-v6.md index fddbdc9c..9555f97c 100644 --- a/proposals/2240-rooms-v6.md +++ b/proposals/2240-rooms-v6.md @@ -5,7 +5,7 @@ and incorporating the following MSCs: * [MSC2209](https://github.com/matrix-org/matrix-doc/pull/2209) - Including notifications in power level auth rules. * [MSC2212](https://github.com/matrix-org/matrix-doc/pull/2432) - Alias event authorisation and redaction. -* PLACEHOLDER - Something to do with integers. +* [MSC2540](https://github.com/matrix-org/matrix-doc/pull/2540) - Integers in canonical JSON compliance. Though other MSCs are capable of being included in this version, they do not have sufficient implementation to be considered stable enough for v6 rooms. A future room version may still include them. From a6ae757e7a977805b9ff32ea52fade0db73709f5 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 13 May 2020 12:47:46 -0400 Subject: [PATCH 1043/1250] Fix typo --- proposals/2399-reporting-no-key-sent.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2399-reporting-no-key-sent.md b/proposals/2399-reporting-no-key-sent.md index 58f2acb8..b31644dc 100644 --- a/proposals/2399-reporting-no-key-sent.md +++ b/proposals/2399-reporting-no-key-sent.md @@ -23,7 +23,7 @@ expect to receive a key in response to the request. Devices that purposely do not send megolm keys to a device may instead send an `m.room_key.withheld` event as a to-device message to the device to indicate that it should not expect to receive keys for the message. This message may -also be sent in reply to a `m.room_key_request`. The `m.room.no_key` event has +also be sent in reply to a `m.room_key_request`. The `m.room_key.withheld` event has the properties: - `room_id`: Required if `code` is not `m.no_olm`. The ID of the room that the From bbbd9c4c33a5641da7bf247d9f7967278ef0802c Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 13 May 2020 12:50:09 -0400 Subject: [PATCH 1044/1250] Update wording to avoid demand-style language. Co-authored-by: Travis Ralston --- proposals/2540-stricter-event-validation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2540-stricter-event-validation.md b/proposals/2540-stricter-event-validation.md index 81acd970..d5d31b46 100644 --- a/proposals/2540-stricter-event-validation.md +++ b/proposals/2540-stricter-event-validation.md @@ -20,7 +20,7 @@ even support these by default. One common additional feature is handling ## Proposal -In a future room version, Matrix server implementations should strictly enforce +In a future room version, Matrix server implementations are to strictly enforce the JSON compliance of the Canonical JSON specification for events. The rationale for doing this in a future room version is to avoid a split brain From 03588cbf0dfe47b8eb6bcc0dbb53a1c39115044a Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 13 May 2020 14:02:50 -0400 Subject: [PATCH 1045/1250] Be clearer about errors and what to do with current room versions. --- proposals/2540-stricter-event-validation.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/proposals/2540-stricter-event-validation.md b/proposals/2540-stricter-event-validation.md index d5d31b46..12996333 100644 --- a/proposals/2540-stricter-event-validation.md +++ b/proposals/2540-stricter-event-validation.md @@ -20,18 +20,26 @@ even support these by default. One common additional feature is handling ## Proposal -In a future room version, Matrix server implementations are to strictly enforce -the JSON compliance of the Canonical JSON specification for events. +In a future room version, homeserver implementations are to strictly enforce +the JSON compliance of the Canonical JSON specification for events. Events that +do not abide by these rules should be rejected with the error code `M_NOT_JSON`. The rationale for doing this in a future room version is to avoid a split brain room -- where some federated servers believe an event is valid and others reject it as invalid. Rooms will be able to opt into this behavior as part of a room version upgrade. +Homeserver implementations are not to strictly enforce this JSON compliance in +[stable room versions](https://matrix.org/docs/spec/#complete-list-of-room-versions). +The rationale is essentially the same as why a future room version is necessary, +this ensures that all federated servers treat the same events as valid. + ## Potential issues -N/A +Homeserver implementations might include JSON parsers which are stricter than +others. It may not be worthwhile or reasonable to loosen those restrictions for +stable room versions. ## Alternatives From 9ccfe61674e9e461978c46e2e52736b896da281e Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 13 May 2020 14:22:26 -0400 Subject: [PATCH 1046/1250] add some clarifications and add sharing withheld reason with other devices --- proposals/2399-reporting-no-key-sent.md | 35 +++++++++++++++++++------ 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/proposals/2399-reporting-no-key-sent.md b/proposals/2399-reporting-no-key-sent.md index b31644dc..9655574f 100644 --- a/proposals/2399-reporting-no-key-sent.md +++ b/proposals/2399-reporting-no-key-sent.md @@ -10,9 +10,9 @@ key to devices that they have not verified yet. Currently, when this happens, there is no feedback given to the affected devices; devices that have not received keys do not know why they did not receive the key, and so cannot inform the user as to whether it is expected -that the message cannot be decrypted. To address this, senders can send a -message to devices indicating that they purposely did not send a megolm -key. +that the message cannot be decrypted. To address this, this proposal defines a +message that senders can (optionally) send to devices indicating that they +purposely did not send a megolm key. A similar issue happens with keyshare requests; devices are not informed when other devices decide not to send back keys, and so do not know whether to @@ -59,17 +59,36 @@ A `code` of `m.no_olm` is used to indicate that the sender is unable to establish an olm session with the recipient. When this happens, multiple sessions will be affected. In order to avoid filling the recipient's device mailbox, the sender should only send one `m.room_key.withheld` message with no -`room_id` nor `session_id` set. In response to receiving this message, the -recipient may start an olm session with the sender, and send an `m.dummy` -message to notify the sender of the new olm session. The recipient may assume -that this `m.room_key.withheld` message applies to all encrypted room messages -sent before it receives the message. +`room_id` nor `session_id` set. If the sender retries and fails to create an +olm session again in the future, it should not send another +`m.room_key.withheld` message with a `code` of `m.no_olm`, unless another olm +session was previously established successfully. In response to receiving an +`m.room_key.withheld` message with a `code` of `m.no_olm`, the recipient may +start an olm session with the sender and send an `m.dummy` message to notify +the sender of the new olm session. The recipient may assume that this +`m.room_key.withheld` message applies to all encrypted room messages sent +before it receives the message. + +### Interaction with key sharing + +If Alice withholds a megolm session from Bob for some messages in a room, and +then later on decides to allow Bob to decrypt later messages, she can send Bob +the megolm session, ratcheted up to the point at which she allows Bob to +decrypt the messages. If Bob logs into a new device and uses key sharing to +obtain the decryption keys, the new device will be sent the megolm sessions +that have been ratcheted up. Bob's old device can include the reason that the +session was initially not shared by including a `withheld` property in the +`m.forwarded_room_key` message that is an object with the `code` and `reason` +properties from the `m.room_key.withheld` message. ## Potential issues This does not handle all possible reasons why a device may not have received megolm keys. +There is currently no way of indicating that part of a session was withheld in +key backups. + ## Security considerations A user might not want to notify another user of the reason why it was not sent From 1bae8ea6333fbc78e1bed50dfde35ad0d7fa8bbf Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 13 May 2020 19:24:34 -0400 Subject: [PATCH 1047/1250] we actually don't support the GET /room_key/versions/ with trailing slash --- api/client-server/key_backup.yaml | 77 ++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 6 deletions(-) diff --git a/api/client-server/key_backup.yaml b/api/client-server/key_backup.yaml index 0f7ff25b..2735c237 100644 --- a/api/client-server/key_backup.yaml +++ b/api/client-server/key_backup.yaml @@ -79,6 +79,74 @@ paths: - version tags: - End-to-end encryption + "/room_keys/version": + get: + summary: Get information about the latest backup version. + description: |- + Get information about the latest backup version. + operationId: getRoomKeysVersionCurrent + security: + - accessToken: [] + responses: + 200: + description: + The information about the backup. + schema: + type: object + properties: + algorithm: + type: string + description: The algorithm used for storing backups. + enum: ["m.megolm_backup.v1.curve25519-aes-sha2"] + example: "m.megolm_backup.v1.curve25519-aes-sha2" + auth_data: + description: |- + Algorithm-dependent data. See the documentation for the backup + algorithms in `Server-side key backups`_ for more information on the + expected format of the data. + type: object + example: { + "public_key": "abcdefg", + "signatures": { + "@alice:example.org": { + "ed25519:deviceid": "signature" + } + } + } + count: + description: The number of keys stored in the backup. + type: integer + example: 42 + etag: + description: |- + An opaque string representing stored keys in the backup. + Clients can compare it with the ``etag`` value they received + in the request of their last key storage request. If not + equal, another client has modified the backup. + type: string + example: "anopaquestring" + version: + type: string + description: The backup version + example: "1" + required: + - algorithm + - auth_data + - count + - etag + - version + 404: + description: + No backup exists. + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "No current backup version" + } + schema: + "$ref": "definitions/errors/error.yaml" + tags: + - End-to-end encryption "/room_keys/version/{version}": get: summary: Get information about an existing backup. @@ -94,8 +162,7 @@ paths: description: |- The backup version to get, as returned in the ``version`` parameter of the response in `POST /_matrix/client/r0/room_keys/version`_ or - this endpoint. When an empty string, the trailing slash is - optional, and the current backup is returned. + this endpoint. required: true x-example: "1" responses: @@ -173,8 +240,7 @@ paths: The backup version to update, as returned in the ``version`` parameter in the response of `POST /_matrix/client/r0/room_keys/version`_ or `GET - /_matrix/client/r0/room_keys/version/{version}`_. Unlike with the - ``GET`` version of this endpoint, this may not be empty. + /_matrix/client/r0/room_keys/version/{version}`_. required: true x-example: "1" - in: body @@ -258,8 +324,7 @@ paths: The backup version to delete, as returned in the ``version`` parameter in the response of `POST /_matrix/client/r0/room_keys/version`_ or `GET - /_matrix/client/r0/room_keys/version/{version}`_. Unlike with the - ``GET`` version of this endpoint, this may not be empty. + /_matrix/client/r0/room_keys/version/{version}`_. required: true x-example: "1" responses: From bd95568c8cb7ba69274aea2f049113c53dcbde31 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 13 May 2020 19:27:36 -0400 Subject: [PATCH 1048/1250] remove duplicate key --- api/client-server/key_backup.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/api/client-server/key_backup.yaml b/api/client-server/key_backup.yaml index 2735c237..f4e83bae 100644 --- a/api/client-server/key_backup.yaml +++ b/api/client-server/key_backup.yaml @@ -79,7 +79,6 @@ paths: - version tags: - End-to-end encryption - "/room_keys/version": get: summary: Get information about the latest backup version. description: |- From 6757c60d35cba656972c8e979f83ba3514b17350 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Thu, 14 May 2020 07:22:48 -0400 Subject: [PATCH 1049/1250] Specify the current stable room versions. Co-authored-by: Travis Ralston --- proposals/2540-stricter-event-validation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2540-stricter-event-validation.md b/proposals/2540-stricter-event-validation.md index 12996333..64a64dde 100644 --- a/proposals/2540-stricter-event-validation.md +++ b/proposals/2540-stricter-event-validation.md @@ -30,7 +30,7 @@ it as invalid. Rooms will be able to opt into this behavior as part of a room version upgrade. Homeserver implementations are not to strictly enforce this JSON compliance in -[stable room versions](https://matrix.org/docs/spec/#complete-list-of-room-versions). +[room versions 1, 2, 3, 4, and 5](https://matrix.org/docs/spec/#complete-list-of-room-versions). The rationale is essentially the same as why a future room version is necessary, this ensures that all federated servers treat the same events as valid. From 560eb6df71d974f71038c67f004092e9beca3076 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 14 May 2020 10:44:44 -0600 Subject: [PATCH 1050/1250] Fix MSC reference --- proposals/2240-rooms-v6.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2240-rooms-v6.md b/proposals/2240-rooms-v6.md index 9555f97c..2b3f1163 100644 --- a/proposals/2240-rooms-v6.md +++ b/proposals/2240-rooms-v6.md @@ -4,7 +4,7 @@ A new room version, `6`, is proposed using [room version 5](https://matrix.org/d and incorporating the following MSCs: * [MSC2209](https://github.com/matrix-org/matrix-doc/pull/2209) - Including notifications in power level auth rules. -* [MSC2212](https://github.com/matrix-org/matrix-doc/pull/2432) - Alias event authorisation and redaction. +* [MSC2432](https://github.com/matrix-org/matrix-doc/pull/2432) - Alias event authorisation and redaction. * [MSC2540](https://github.com/matrix-org/matrix-doc/pull/2540) - Integers in canonical JSON compliance. Though other MSCs are capable of being included in this version, they do not have sufficient implementation to be From c196cbcf42ccdab92de5f72b641a65ddf4462c8e Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 14 May 2020 13:01:24 -0400 Subject: [PATCH 1051/1250] add introduction and discourage new implementations from using old method --- proposals/xxxx-sas-v2.md | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/proposals/xxxx-sas-v2.md b/proposals/xxxx-sas-v2.md index 0e689c30..e4e4e320 100644 --- a/proposals/xxxx-sas-v2.md +++ b/proposals/xxxx-sas-v2.md @@ -1,9 +1,21 @@ -# SAS verification, v2 +# checking public keys in SAS verification + +The current SAS protocol does not ensure that the two users correctly received +each other's public keys. An attacker could send Alice and Bob public keys +that he has created and, if the attacker is lucky, could obtain the same shared +secret with both Alice and Bob, so that when they verify the SAS string, will +believe that the exchange was secure. + +To mitigate against this, Alice and Bob can use the two public keys in the +generation of the SAS string by including it in the info parameter of the HKDF. +Thus if an attacker sends them different public keys, the info parameters will +be different, and so the key generated by the HKDF will be different. ## Proposal -A new `key_agreement_protocol`, `curve25519-hkdf-sha256` is introduced. It is -the same as `curve25519` except that the info parameter for the HKDF is the +A new `key_agreement_protocol`, `curve25519-hkdf-sha256` is introduced, and +will be mandatory for clients to support when performing SAS verification. It +is the same as `curve25519` except that the info parameter for the HKDF is the concatenation of: * The string `MATRIX_KEY_VERIFICATION_SAS|`. @@ -25,12 +37,5 @@ The differences from `curve25519` are the addition of the public keys, and the addition of `|` as delimiter between the fields. The `key_agreement_protocol` `curve25519` is deprecated and may be removed in -the future. - -## Potential issues - -## Alternatives - -## Security considerations - -## Unstable prefix +the future. It will no longer be mandatory for clients to support, and new +implementations are discouraged from implementing it. From 0b6301ac80b95473ddaad44b644bbf7d5867ae92 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Fri, 15 May 2020 10:51:41 -0400 Subject: [PATCH 1052/1250] Fix grammar and typos from review. Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/2540-stricter-event-validation.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/2540-stricter-event-validation.md b/proposals/2540-stricter-event-validation.md index 64a64dde..94ec481e 100644 --- a/proposals/2540-stricter-event-validation.md +++ b/proposals/2540-stricter-event-validation.md @@ -13,7 +13,7 @@ the range of [-2 ^ 53 + 1, 2 ^ 53 - 1], which matches the requirements of not explicit, but all floats are invalid. It is worth mentioning that there are common extensions to JSON which produce -invalid JSON according to the Matrix specification, some programming langauges +invalid JSON according to the Matrix specification; some programming langauges even support these by default. One common additional feature is handling "special" float values: `Infinity`, `-Infinity`, and `NaN`. @@ -31,7 +31,7 @@ version upgrade. Homeserver implementations are not to strictly enforce this JSON compliance in [room versions 1, 2, 3, 4, and 5](https://matrix.org/docs/spec/#complete-list-of-room-versions). -The rationale is essentially the same as why a future room version is necessary, +The rationale is essentially the same as why a future room version is necessary: this ensures that all federated servers treat the same events as valid. @@ -57,7 +57,7 @@ N/A ## Unstable prefix -A room versions of `org.matrix.strict_canonicaljson` until a future room version +A room version of `org.matrix.strict_canonicaljson` until a future room version is available. This room version will use [room version 5](https://matrix.org/docs/spec/rooms/v5) as base and include the above modifications. From 007c8b57992137c19e2ded990e141bf0b9157eb1 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Fri, 15 May 2020 10:52:29 -0400 Subject: [PATCH 1053/1250] Clarify the range of valid values. --- proposals/2540-stricter-event-validation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2540-stricter-event-validation.md b/proposals/2540-stricter-event-validation.md index 94ec481e..3027be56 100644 --- a/proposals/2540-stricter-event-validation.md +++ b/proposals/2540-stricter-event-validation.md @@ -8,7 +8,7 @@ this: JSON compliance. The [Canonical JSON](https://matrix.org/docs/spec/appendices#canonical-json) specification requires that numbers that are serialized in JSON are integers in -the range of [-2 ^ 53 + 1, 2 ^ 53 - 1], which matches the requirements of +the inclusive range of `[-2 ^ 53 + 1, 2 ^ 53 - 1]`, which matches the requirements of [section 6 of RFC 7159](https://tools.ietf.org/html/rfc7159). Note that it is not explicit, but all floats are invalid. From e5fa76c8edc526bad233000019e9da8da17ce232 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Fri, 15 May 2020 10:53:26 -0400 Subject: [PATCH 1054/1250] Clarify range a bit more. --- proposals/2540-stricter-event-validation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2540-stricter-event-validation.md b/proposals/2540-stricter-event-validation.md index 3027be56..3d58411d 100644 --- a/proposals/2540-stricter-event-validation.md +++ b/proposals/2540-stricter-event-validation.md @@ -8,7 +8,7 @@ this: JSON compliance. The [Canonical JSON](https://matrix.org/docs/spec/appendices#canonical-json) specification requires that numbers that are serialized in JSON are integers in -the inclusive range of `[-2 ^ 53 + 1, 2 ^ 53 - 1]`, which matches the requirements of +the inclusive range of `[-(2^53) + 1, (2^53) - 1]`, which matches the requirements of [section 6 of RFC 7159](https://tools.ietf.org/html/rfc7159). Note that it is not explicit, but all floats are invalid. From bac9afa124b47ed722a74c00ef7c65d83308beb4 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 15 May 2020 12:14:46 -0400 Subject: [PATCH 1055/1250] document error codes and remove a statement that isn't true --- proposals/2526-add-delete-backup.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/2526-add-delete-backup.md b/proposals/2526-add-delete-backup.md index e4d589e3..b41fe5a3 100644 --- a/proposals/2526-add-delete-backup.md +++ b/proposals/2526-add-delete-backup.md @@ -8,7 +8,7 @@ delete an entire key backup. This proposal adds the endpoint. An endpoint is added, `DELETE /room_keys/version/{version}`, that deletes a backup version. Both the information about the key backup, as well as all keys -associated with the backup should be deleted. Like `POST -/room_keys/version/{version}`, and unlike `GET /room_keys/version/{version}`, -`{version}` cannot be empty, to ensure that the wrong backup is not -accidentally deleted. +associated with the backup should be deleted. If the specified version was +previously deleted, the endpoint succeeds, returning an HTTP code of 200. If +the specified version never existed, the endpoint returns an HTTP code of 404 +with a Matrix `errcode` of `M_NOT_FOUND`. From fae1165e1cc7eda27140267c08e6ee8f124142a1 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 15 May 2020 12:17:37 -0400 Subject: [PATCH 1056/1250] spec what to do if you try to delete a backup that's already deleted --- api/client-server/key_backup.yaml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/api/client-server/key_backup.yaml b/api/client-server/key_backup.yaml index f4e83bae..1a79db31 100644 --- a/api/client-server/key_backup.yaml +++ b/api/client-server/key_backup.yaml @@ -328,12 +328,16 @@ paths: x-example: "1" responses: 200: - description: The delete succeeded. + description: |- + The delete succeeded, or the specified backup was previously + deleted. schema: type: object properties: {} 404: - description: The backup specified does not exist. + description: |- + The backup specified does not exist. If the backup was previously + deleted, the call should succeed rather than returning an error. examples: application/json: { "errcode": "M_NOT_FOUND", From d24f15a3a91b19429d65dd516e8cded1c7a2b44f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 15 May 2020 13:41:05 -0600 Subject: [PATCH 1057/1250] Spec soft-logout per MSC1466 MSC: https://github.com/matrix-org/matrix-doc/issues/1466 --- api/client-server/registration.yaml | 5 ++++- .../client_server/newsfragments/2545.feature | 1 + specification/client_server_api.rst | 22 +++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/2545.feature diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 50ce4a96..a6d5d275 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -346,8 +346,11 @@ paths: logout_devices: type: boolean description: |- - Whether the other access tokens, and their associated devices, for the user should be + Whether the other access tokens, and their associated devices, for the user should be revoked if the request succeeds. Defaults to true. + + When ``false``, the server can still take advantage of `the soft logout method <#soft-logout>`_ + for the user's remaining devices. example: true auth: description: |- diff --git a/changelogs/client_server/newsfragments/2545.feature b/changelogs/client_server/newsfragments/2545.feature new file mode 100644 index 00000000..40c066f4 --- /dev/null +++ b/changelogs/client_server/newsfragments/2545.feature @@ -0,0 +1 @@ +Add soft-logout support per `MSC1466 `_. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index fce879a2..3c99d305 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -123,6 +123,10 @@ The common error codes are: :``M_UNKNOWN_TOKEN``: The access token specified was not recognised. + An additional response parameter, ``soft_logout``, might be present on the response + for 401 HTTP status codes. See `the soft logout section <#soft-logout>`_ for more + information. + :``M_MISSING_TOKEN``: No access token was specified for the request. @@ -404,6 +408,24 @@ should pass the ``device_id`` in the request body. If the client sets the to that device. There is therefore at most one active access token assigned to each device at any one time. +Soft logout +~~~~~~~~~~~ + + + +When a requests fail due to a 401 status code per above, the server can +include an extra response parameter, ``soft_logout``, to indicate if the +device information has been retained by the server. This defaults to ``false``, +implying the server has deleted the device alongside the access token. + +When ``soft_logout`` is true, the client can acquire a new access token by +specifying the device ID it is already using to the login API. In most cases +a ``soft_logout: true`` response indicates that the user's session has expired +on the server-side and the user simply needs to provide their credentials again. + +If ``soft_logout`` is ``false``, the client will not be able to reuse the device +information it already has - the server has destroyed the session. + User-Interactive Authentication API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From bd26a41114719c59c43befbc944301d49bfa4603 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 15 May 2020 13:42:08 -0600 Subject: [PATCH 1058/1250] off by one error --- .../client_server/newsfragments/{2545.feature => 2546.feature} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelogs/client_server/newsfragments/{2545.feature => 2546.feature} (100%) diff --git a/changelogs/client_server/newsfragments/2545.feature b/changelogs/client_server/newsfragments/2546.feature similarity index 100% rename from changelogs/client_server/newsfragments/2545.feature rename to changelogs/client_server/newsfragments/2546.feature From b4beb05dde0d255d0738a11718fc0bc042d53f21 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 15 May 2020 13:44:21 -0600 Subject: [PATCH 1059/1250] Remove excess whitespace --- specification/client_server_api.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 3c99d305..4082fceb 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -411,8 +411,6 @@ each device at any one time. Soft logout ~~~~~~~~~~~ - - When a requests fail due to a 401 status code per above, the server can include an extra response parameter, ``soft_logout``, to indicate if the device information has been retained by the server. This defaults to ``false``, From 54102b8d36d31ade99ad1b8023849d1a54a5dcc3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 15 May 2020 13:50:17 -0600 Subject: [PATCH 1060/1250] Clarify wording per review suggestions --- specification/proposals_intro.rst | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index e6cebcf4..7c8e4efd 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -382,17 +382,16 @@ in some cases the MSC itself will be small enough to be considered proven. Where unclear if a MSC will require an implementation proof, ask in `#matrix-spec:matrix.org `_. -Early adoption of a MSC/idea -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Early release of a MSC/idea +~~~~~~~~~~~~~~~~~~~~~~~~~~~ To help facilitate early releases of software dependent on a spec release, implementations are required to use the following process to ensure that the official Matrix namespace is not cluttered with development or testing data. .. Note:: - Proof of concept implementations that are solely left on a branch/unreleased and for - demonstrating that a particular MSC works do not have to follow this. Note that the - ``develop`` branch adopted by some projects is still subject to this process. + Proof of concept implementations that are solely left on a branch/unreleased for + demonstrating that a particular MSC works do not have to follow this. The process for an implementation willing to be ahead of a spec release is: @@ -404,9 +403,9 @@ The process for an implementation willing to be ahead of a spec release is: `/_matrix/client/unstable/com.example/login`. Vendor prefixes throughout Matrix always use the Java package naming convention. The MSC for the feature should identify which preferred vendor prefix is to be used by early adopters. - * Unstable endpoints **do not** inherit from stable (e.g. `/r0`) APIs. Implementations - cannot assume that a particular endpoint will exist in the unstable namespace - even if the server advertises support for the feature. + * Note that unstable namespaces do not automatically inherit endpoints from stable + namespaces: for example, the fact that ``/_matrix/client/r0/sync`` exists does + not imply that ``/_matrix/client/unstable/com.example/sync`` exists. * If the client needs to be sure the server supports the feature, an unstable feature flag that MUST be vendor prefixed is to be used. This kind of flag shows up in the ``unstable_features`` section of ``/versions`` as, for example, @@ -431,7 +430,7 @@ The process for an implementation willing to be ahead of a spec release is: working as proposed. A typical example of this is an implementation of the MSC, though the implementation does not need to be shipped anywhere and can therefore avoid the forwards/backwards compatibility concerns mentioned here. -5. FCP is gone through, and assuming nothing is flagged the MSC lands. +5. The FCP process is completed, and assuming nothing is flagged the MSC lands. 6. A spec PR is written to incorporate the changes into Matrix. 7. A spec release happens. 8. Implementations switch to using stable prefixes (e.g.: ``/r0``) if the server From a2a1694c35e830cc7271cdd2e6cb242e62f037a4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 15 May 2020 14:10:06 -0600 Subject: [PATCH 1061/1250] Spec v2 send_join and send_leave endpoints MSC: https://github.com/matrix-org/matrix-doc/pull/1802 Fixes https://github.com/matrix-org/matrix-doc/issues/2541 This also adds the v2 invite endpoint to the ACL protected list as that appears to be an omission. --- .../{joins.yaml => joins-v1.yaml} | 7 +- api/server-server/joins-v2.yaml | 176 ++++++++++++++++++ .../{leaving.yaml => leaving-v1.yaml} | 7 +- api/server-server/leaving-v2.yaml | 140 ++++++++++++++ .../server_server/newsfragments/2547.new | 1 + specification/server_server_api.rst | 11 +- 6 files changed, 338 insertions(+), 4 deletions(-) rename api/server-server/{joins.yaml => joins-v1.yaml} (98%) create mode 100644 api/server-server/joins-v2.yaml rename api/server-server/{leaving.yaml => leaving-v1.yaml} (97%) create mode 100644 api/server-server/leaving-v2.yaml create mode 100644 changelogs/server_server/newsfragments/2547.new diff --git a/api/server-server/joins.yaml b/api/server-server/joins-v1.yaml similarity index 98% rename from api/server-server/joins.yaml rename to api/server-server/joins-v1.yaml index 1b5f4632..8defda20 100644 --- a/api/server-server/joins.yaml +++ b/api/server-server/joins-v1.yaml @@ -1,4 +1,5 @@ # Copyright 2018 New Vector Ltd +# Copyright 2020 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. @@ -165,6 +166,10 @@ paths: put: summary: Submit a signed join event to a resident server description: |- + .. Note:: + Servers should instead prefer to use the v2 ``/send_join`` + endpoint. + Submits a signed join event to the resident server for it to accept it into the room's graph. Note that events have a different format depending on the room version - check @@ -172,7 +177,7 @@ paths: **The request and response body here describes the common event fields in more detail and may be missing other required fields for a PDU.** - operationId: sendJoin + operationId: sendJoinV1 security: - signedRequest: [] parameters: diff --git a/api/server-server/joins-v2.yaml b/api/server-server/joins-v2.yaml new file mode 100644 index 00000000..585ab4b8 --- /dev/null +++ b/api/server-server/joins-v2.yaml @@ -0,0 +1,176 @@ +# Copyright 2018 New Vector Ltd +# Copyright 2020 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. + +swagger: '2.0' +info: + title: "Matrix Federation Join 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: + # Note: there is no v2 of make_join (yet) + "/send_join/{roomId}/{eventId}": + put: + summary: Submit a signed join event to a resident server + description: |- + .. Note:: + This API is nearly identical to the v1 API with the + exception of the response format being fixed. + + This endpoint is preferred over the v1 API as it provides + a more standarised response format. Senders which receive + a 400, 404, or other status code which indicates this endpoint + is not available should retry using the v1 API instead. + + Submits a signed join event to the resident server for it + to accept it into the room's graph. 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 body here describes the common + event fields in more detail and may be missing other required + fields for a PDU.** + operationId: sendJoinV2 + security: + - signedRequest: [] + parameters: + - in: path + name: roomId + type: string + description: The room ID that is about to be joined. + required: true + x-example: "!abc123:matrix.org" + - in: path + name: eventId + type: string + description: The event ID for the join event. + required: true + x-example: "$abc123:example.org" + - in: body + name: body + type: object + required: true + schema: + type: object + properties: + sender: + type: string + description: The user ID of the joining member. + example: "@someone:example.org" + origin: + type: string + description: The name of the joining homeserver. + example: "matrix.org" + origin_server_ts: + type: integer + format: int64 + description: A timestamp added by the joining homeserver. + example: 1234567890 + type: + type: string + description: The value ``m.room.member``. + example: "m.room.member" + state_key: + type: string + description: The user ID of the joining member. + example: "@someone:example.org" + content: + type: object + title: Membership Event Content + description: The content of the event. + example: {"membership": "join"} + properties: + membership: + type: string + description: The value ``join``. + example: "join" + required: ['membership'] + required: + - state_key + - sender + - origin + - origin_server_ts + - type + - content + example: { + "$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", + "content": { + "membership": "join" + } + } + responses: + 200: + description: |- + The full state for the room, having accepted the join event. + schema: + type: object + title: Room State + description: The state for the room. + properties: + origin: + type: string + description: The resident server's DNS name. + auth_chain: + type: array + description: |- + The auth chain. Note that events have a different format depending on + the room version - check the `room version specification`_ for precise + event formats. + items: + type: object + title: PDU + description: |- + The `PDUs <#pdus>`_ that make up the auth chain. The event format varies depending + on the room version - check the `room version specification`_ for precise event formats. + schema: + type: object + properties: [] + example: + $ref: "examples/minimal_pdu.json" + state: + type: array + description: |- + The room state. The event format varies depending on the room version - + check the `room version specification`_ for precise event formats. + items: + type: object + title: PDU + description: |- + The `PDUs <#pdus>`_ for the fully resolved state of the room. The event format varies depending + on the room version - check the `room version specification`_ for precise event formats. + schema: + type: object + properties: [] + example: + $ref: "examples/minimal_pdu.json" + required: ["auth_chain", "state", "origin"] + examples: + application/json: { + "origin": "matrix.org", + "auth_chain": [{"$ref": "examples/minimal_pdu.json"}], + "state": [{"$ref": "examples/minimal_pdu.json"}] + } diff --git a/api/server-server/leaving.yaml b/api/server-server/leaving-v1.yaml similarity index 97% rename from api/server-server/leaving.yaml rename to api/server-server/leaving-v1.yaml index e0882fe8..cd07406e 100644 --- a/api/server-server/leaving.yaml +++ b/api/server-server/leaving-v1.yaml @@ -1,4 +1,5 @@ # Copyright 2018 New Vector Ltd +# Copyright 2020 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. @@ -142,6 +143,10 @@ paths: put: summary: Submit a signed leave event to a resident server description: |- + .. Note:: + Servers should instead prefer to use the v2 ``/send_leave`` + endpoint. + Submits a signed leave event to the resident server for it to accept it into the room's graph. Note that events have a different format depending on the room version - check @@ -149,7 +154,7 @@ paths: **The request and response body here describes the common event fields in more detail and may be missing other required fields for a PDU.** - operationId: sendLeave + operationId: sendLeaveV1 security: - signedRequest: [] parameters: diff --git a/api/server-server/leaving-v2.yaml b/api/server-server/leaving-v2.yaml new file mode 100644 index 00000000..ed16773e --- /dev/null +++ b/api/server-server/leaving-v2.yaml @@ -0,0 +1,140 @@ +# Copyright 2018 New Vector Ltd +# Copyright 2020 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. + +swagger: '2.0' +info: + title: "Matrix Federation Leave 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: + # Note: there is no v2 of make_leave (yet) + "/send_leave/{roomId}/{eventId}": + put: + summary: Submit a signed leave event to a resident server + description: |- + .. Note:: + This API is nearly identical to the v1 API with the + exception of the response format being fixed. + + This endpoint is preferred over the v1 API as it provides + a more standarised response format. Senders which receive + a 400, 404, or other status code which indicates this endpoint + is not available should retry using the v1 API instead. + + Submits a signed leave event to the resident server for it + to accept it into the room's graph. 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 body here describes the common + event fields in more detail and may be missing other required + fields for a PDU.** + operationId: sendLeaveV2 + security: + - signedRequest: [] + parameters: + - in: path + name: roomId + type: string + description: The room ID that is about to be left. + required: true + x-example: "!abc123:matrix.org" + - in: path + name: eventId + type: string + description: The event ID for the leave event. + required: true + x-example: "$abc123:example.org" + - in: body + name: body + type: object + required: true + schema: + type: object + properties: + sender: + type: string + description: The user ID of the leaving member. + example: "@someone:example.org" + origin: + type: string + description: The name of the leaving homeserver. + example: "matrix.org" + origin_server_ts: + type: integer + format: int64 + description: A timestamp added by the leaving homeserver. + example: 1234567890 + type: + type: string + description: The value ``m.room.member``. + example: "m.room.member" + state_key: + type: string + description: The user ID of the leaving member. + example: "@someone:example.org" + content: + type: object + title: Membership Event Content + description: The content of the event. + example: {"membership": "leave"} + properties: + membership: + type: string + description: The value ``leave``. + example: "leave" + required: ['membership'] + depth: + type: integer + description: This field must be present but is ignored; it may be 0. + example: 12 + required: + - state_key + - sender + - origin + - origin_server_ts + - type + - depth + - content + example: { + "$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", + "content": { + "membership": "leave" + } + } + responses: + 200: + description: |- + An empty response to indicate the event was accepted into the graph by + the receiving homeserver. + schema: + type: object + title: Empty Object + description: An empty object. + examples: + application/json: {} diff --git a/changelogs/server_server/newsfragments/2547.new b/changelogs/server_server/newsfragments/2547.new new file mode 100644 index 00000000..c558fb5b --- /dev/null +++ b/changelogs/server_server/newsfragments/2547.new @@ -0,0 +1 @@ +Add new v2 ``/send_join`` and ``/send_leave`` endpoints per `MSC1802 `_. diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 655a8cfc..b0a2bc1a 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -780,7 +780,9 @@ and responds to the joining server with the full set of state for the newly-joined room. The resident server must also send the event to other servers participating in the room. -{{joins_ss_http_api}} +{{joins_v1_ss_http_api}} + +{{joins_v2_ss_http_api}} .. TODO-spec - (paul) I don't really understand why the full auth_chain events are given @@ -817,7 +819,9 @@ signs the event and replaces the ``event_id`` with it's own. This is then sent t the resident server via ``/send_leave``. The resident server will then send the event to other servers in the room. -{{leaving_ss_http_api}} +{{leaving_v1_ss_http_api}} + +{{leaving_v2_ss_http_api}} Third-party invites ------------------- @@ -1071,8 +1075,11 @@ The following endpoint prefixes MUST be protected: * ``/_matrix/federation/v1/make_join`` * ``/_matrix/federation/v1/make_leave`` * ``/_matrix/federation/v1/send_join`` +* ``/_matrix/federation/v2/send_join`` * ``/_matrix/federation/v1/send_leave`` +* ``/_matrix/federation/v2/send_leave`` * ``/_matrix/federation/v1/invite`` +* ``/_matrix/federation/v2/invite`` * ``/_matrix/federation/v1/state`` * ``/_matrix/federation/v1/state_ids`` * ``/_matrix/federation/v1/backfill`` From 19cac033058898eaf1d90b2b16651ad70ff94f3c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 15 May 2020 22:45:18 -0600 Subject: [PATCH 1062/1250] Update specification/client_server_api.rst Co-authored-by: Hubert Chathi --- specification/client_server_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 4082fceb..62550d0a 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -411,7 +411,7 @@ each device at any one time. Soft logout ~~~~~~~~~~~ -When a requests fail due to a 401 status code per above, the server can +When a request fails due to a 401 status code per above, the server can include an extra response parameter, ``soft_logout``, to indicate if the device information has been retained by the server. This defaults to ``false``, implying the server has deleted the device alongside the access token. From 28d460fb62c61f963181c890dc933b8289f4a1cc Mon Sep 17 00:00:00 2001 From: Dominic Fischer Date: Sat, 16 May 2020 21:35:26 +0100 Subject: [PATCH 1063/1250] Fix Typo --- api/client-server/admin.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client-server/admin.yaml b/api/client-server/admin.yaml index 09942a10..8794a65c 100644 --- a/api/client-server/admin.yaml +++ b/api/client-server/admin.yaml @@ -82,7 +82,7 @@ paths: devices: type: object description: |- - Each key is an identitfier for one of the user's devices. + Each key is an identifier for one of the user's devices. additionalProperties: type: object title: DeviceInfo From c3582e5fc6206f25ab06e4590d2fa54835f3d661 Mon Sep 17 00:00:00 2001 From: Dominic Fischer Date: Sat, 16 May 2020 21:41:09 +0100 Subject: [PATCH 1064/1250] Add changelog --- changelogs/client_server/newsfragments/2553.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2553.clarification diff --git a/changelogs/client_server/newsfragments/2553.clarification b/changelogs/client_server/newsfragments/2553.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/client_server/newsfragments/2553.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. From a7e7496cd6d709bc30d858d48e4f86773214df8e Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sun, 17 May 2020 22:18:00 +0200 Subject: [PATCH 1065/1250] Fix some numbers in the spec text. Odds were not written as an exponent. Special tag names count was not updated. Fixes #2550 Signed-off-by: Nicolas Werner --- changelogs/client_server/newsfragments/2554.clarification | 1 + specification/modules/end_to_end_encryption.rst | 2 +- specification/modules/tags.rst | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2554.clarification diff --git a/changelogs/client_server/newsfragments/2554.clarification b/changelogs/client_server/newsfragments/2554.clarification new file mode 100644 index 00000000..826fafd8 --- /dev/null +++ b/changelogs/client_server/newsfragments/2554.clarification @@ -0,0 +1 @@ +Fix some numbers in the specification to match their explanation text. diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 0223d9f5..7411abe4 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -513,7 +513,7 @@ received the other party's part. Thus an attacker essentially only has one attem attack the Diffie-Hellman exchange, and hence we can verify fewer bits while still achieving a high degree of security: if we verify n bits, then an attacker has a 1 in 2\ :sup:`n` chance of success. For example, if we verify 40 bits, then an attacker has -a 1 in 1,099,511,627,776 chance (or less than 1 in 1012 chance) of success. A failed +a 1 in 1,099,511,627,776 chance (or less than 1 in 10\ :sup:`12` chance) of success. A failed attack would result in a mismatched Short Authentication String, alerting users to the attack. diff --git a/specification/modules/tags.rst b/specification/modules/tags.rst index 9d0cd554..33948509 100644 --- a/specification/modules/tags.rst +++ b/specification/modules/tags.rst @@ -55,7 +55,7 @@ The tag namespace is defined as follows: display name directly). These non-namespaced tags are supported for historical reasons. New tags should use one of the defined namespaces above. -Two special names are listed in the specification: +Three special names are listed in the specification: The following tags are defined in the ``m.*`` namespace: * ``m.favourite``: The user's favourite rooms. These should be shown with higher precedence than other rooms. From ddeb695b9740a01140e215c90d1cb318d48f6795 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 18 May 2020 00:19:30 -0600 Subject: [PATCH 1066/1250] Use 'several' in place of counting --- specification/modules/tags.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/tags.rst b/specification/modules/tags.rst index 33948509..a5e23770 100644 --- a/specification/modules/tags.rst +++ b/specification/modules/tags.rst @@ -55,7 +55,7 @@ The tag namespace is defined as follows: display name directly). These non-namespaced tags are supported for historical reasons. New tags should use one of the defined namespaces above. -Three special names are listed in the specification: +Several special names are listed in the specification: The following tags are defined in the ``m.*`` namespace: * ``m.favourite``: The user's favourite rooms. These should be shown with higher precedence than other rooms. From c2d5516517559ceaa4e6bfa56024392adfa7472d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 18 May 2020 00:24:05 -0600 Subject: [PATCH 1067/1250] Clobber changelogs --- changelogs/client_server/newsfragments/2553.clarification | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/client_server/newsfragments/2553.clarification b/changelogs/client_server/newsfragments/2553.clarification index 3ccb2333..902a9c3f 100644 --- a/changelogs/client_server/newsfragments/2553.clarification +++ b/changelogs/client_server/newsfragments/2553.clarification @@ -1 +1 @@ -Fix various typos throughout the specification. +Fix various spelling errors throughout the specification. From 77d83b9ce503b9874bad98180eb233789b4bcd6a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 19 May 2020 08:05:47 -0600 Subject: [PATCH 1068/1250] Clarify that soft logout is about client state --- specification/client_server_api.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 62550d0a..11a1e3cd 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -412,17 +412,17 @@ Soft logout ~~~~~~~~~~~ When a request fails due to a 401 status code per above, the server can -include an extra response parameter, ``soft_logout``, to indicate if the -device information has been retained by the server. This defaults to ``false``, -implying the server has deleted the device alongside the access token. +include an extra response parameter, ``soft_logout``, to indicate if the client's +persisted information can be retained. This defaults to ``false``, indicating +that the server has destroyed the session. Any persisted state held by the client, +such as encryption keys and device information, will not be able to be reused. When ``soft_logout`` is true, the client can acquire a new access token by specifying the device ID it is already using to the login API. In most cases a ``soft_logout: true`` response indicates that the user's session has expired on the server-side and the user simply needs to provide their credentials again. -If ``soft_logout`` is ``false``, the client will not be able to reuse the device -information it already has - the server has destroyed the session. +In either case, the client's previously known access token will no longer function. User-Interactive Authentication API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From d419e3b38a223ab2ad56442997a6578a5341f5ae Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 19 May 2020 08:08:31 -0600 Subject: [PATCH 1069/1250] Remove extraneous spaces --- api/server-server/joins-v1.yaml | 4 ++-- api/server-server/joins-v2.yaml | 2 +- api/server-server/leaving-v1.yaml | 4 ++-- api/server-server/leaving-v2.yaml | 2 +- api/server-server/transactions.yaml | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/api/server-server/joins-v1.yaml b/api/server-server/joins-v1.yaml index 8defda20..86dd1722 100644 --- a/api/server-server/joins-v1.yaml +++ b/api/server-server/joins-v1.yaml @@ -63,7 +63,7 @@ paths: 200: description: |- A template to be used for the rest of the `Joining Rooms`_ handshake. Note that - events have a different format depending on the room version - check the + events have a different format depending on the room version - check the `room version specification`_ for precise event formats. **The response body here describes the common event fields in more detail and may be missing other required fields for a PDU.** @@ -172,7 +172,7 @@ paths: Submits a signed join event to the resident server for it to accept it into the room's graph. Note that events have - a different format depending on the room version - check + a different format depending on the room version - check the `room version specification`_ for precise event formats. **The request and response body here describes the common event fields in more detail and may be missing other required diff --git a/api/server-server/joins-v2.yaml b/api/server-server/joins-v2.yaml index 585ab4b8..d9569684 100644 --- a/api/server-server/joins-v2.yaml +++ b/api/server-server/joins-v2.yaml @@ -44,7 +44,7 @@ paths: Submits a signed join event to the resident server for it to accept it into the room's graph. Note that events have - a different format depending on the room version - check + a different format depending on the room version - check the `room version specification`_ for precise event formats. **The request and response body here describes the common event fields in more detail and may be missing other required diff --git a/api/server-server/leaving-v1.yaml b/api/server-server/leaving-v1.yaml index cd07406e..2d7785f6 100644 --- a/api/server-server/leaving-v1.yaml +++ b/api/server-server/leaving-v1.yaml @@ -54,7 +54,7 @@ paths: 200: description: |- A template to be used to call ``/send_leave``. Note that - events have a different format depending on the room version - check the + events have a different format depending on the room version - check the `room version specification`_ for precise event formats. **The response body here describes the common event fields in more detail and may be missing other required fields for a PDU.** @@ -149,7 +149,7 @@ paths: Submits a signed leave event to the resident server for it to accept it into the room's graph. Note that events have - a different format depending on the room version - check + a different format depending on the room version - check the `room version specification`_ for precise event formats. **The request and response body here describes the common event fields in more detail and may be missing other required diff --git a/api/server-server/leaving-v2.yaml b/api/server-server/leaving-v2.yaml index ed16773e..ac3111ed 100644 --- a/api/server-server/leaving-v2.yaml +++ b/api/server-server/leaving-v2.yaml @@ -44,7 +44,7 @@ paths: Submits a signed leave event to the resident server for it to accept it into the room's graph. Note that events have - a different format depending on the room version - check + a different format depending on the room version - check the `room version specification`_ for precise event formats. **The request and response body here describes the common event fields in more detail and may be missing other required diff --git a/api/server-server/transactions.yaml b/api/server-server/transactions.yaml index 9cc8be75..b34c1902 100644 --- a/api/server-server/transactions.yaml +++ b/api/server-server/transactions.yaml @@ -38,7 +38,7 @@ paths: The sending server must wait and retry for a 200 OK response before sending a transaction with a different ``txnId`` to the receiving server. - Note that events have a different format depending on the room version - check + Note that events have a different format depending on the room version - check the `room version specification`_ for precise event formats. operationId: sendTransaction security: From 7c0046ffc75ba1e6e82e6331039e0cd8c45a037f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 19 May 2020 08:09:19 -0600 Subject: [PATCH 1070/1250] describes -> describe --- api/server-server/leaving-v2.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/server-server/leaving-v2.yaml b/api/server-server/leaving-v2.yaml index ac3111ed..3e82c414 100644 --- a/api/server-server/leaving-v2.yaml +++ b/api/server-server/leaving-v2.yaml @@ -46,7 +46,7 @@ paths: to accept it into the room's graph. 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 body here describes the common + **The request and response body here describe the common event fields in more detail and may be missing other required fields for a PDU.** operationId: sendLeaveV2 From 05e83f2e7d7c09cd1518b4dc773d9baf4eeb3080 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 19 May 2020 09:54:07 -0600 Subject: [PATCH 1071/1250] Fix more describes -> describe --- api/server-server/joins-v1.yaml | 2 +- api/server-server/joins-v2.yaml | 2 +- api/server-server/leaving-v1.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/server-server/joins-v1.yaml b/api/server-server/joins-v1.yaml index 86dd1722..39287264 100644 --- a/api/server-server/joins-v1.yaml +++ b/api/server-server/joins-v1.yaml @@ -174,7 +174,7 @@ paths: to accept it into the room's graph. 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 body here describes the common + **The request and response body here describe the common event fields in more detail and may be missing other required fields for a PDU.** operationId: sendJoinV1 diff --git a/api/server-server/joins-v2.yaml b/api/server-server/joins-v2.yaml index d9569684..a98d20fd 100644 --- a/api/server-server/joins-v2.yaml +++ b/api/server-server/joins-v2.yaml @@ -46,7 +46,7 @@ paths: to accept it into the room's graph. 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 body here describes the common + **The request and response body here describe the common event fields in more detail and may be missing other required fields for a PDU.** operationId: sendJoinV2 diff --git a/api/server-server/leaving-v1.yaml b/api/server-server/leaving-v1.yaml index 2d7785f6..c92b7920 100644 --- a/api/server-server/leaving-v1.yaml +++ b/api/server-server/leaving-v1.yaml @@ -151,7 +151,7 @@ paths: to accept it into the room's graph. 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 body here describes the common + **The request and response body here describe the common event fields in more detail and may be missing other required fields for a PDU.** operationId: sendLeaveV1 From 10e4ad72ca7bd6ed36b1611e0723fcf494c34306 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 19 May 2020 11:58:28 -0600 Subject: [PATCH 1072/1250] Clarify retention of information for soft logout Co-authored-by: Hubert Chathi --- specification/client_server_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 11a1e3cd..f4cc7478 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -415,7 +415,7 @@ When a request fails due to a 401 status code per above, the server can include an extra response parameter, ``soft_logout``, to indicate if the client's persisted information can be retained. This defaults to ``false``, indicating that the server has destroyed the session. Any persisted state held by the client, -such as encryption keys and device information, will not be able to be reused. +such as encryption keys and device information, must not be reused and must be discarded. When ``soft_logout`` is true, the client can acquire a new access token by specifying the device ID it is already using to the login API. In most cases From f5ebe33a9ce858ad3bde26a35bd15437e4eb3ee5 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Tue, 19 May 2020 14:35:11 -0400 Subject: [PATCH 1073/1250] Reword how bad values are handled. --- proposals/2540-stricter-event-validation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2540-stricter-event-validation.md b/proposals/2540-stricter-event-validation.md index 3d58411d..ac28efc4 100644 --- a/proposals/2540-stricter-event-validation.md +++ b/proposals/2540-stricter-event-validation.md @@ -22,7 +22,7 @@ even support these by default. One common additional feature is handling In a future room version, homeserver implementations are to strictly enforce the JSON compliance of the Canonical JSON specification for events. Events that -do not abide by these rules should be rejected with the error code `M_NOT_JSON`. +do not abide by these rules should be treated like any other bad JSON value. The rationale for doing this in a future room version is to avoid a split brain room -- where some federated servers believe an event is valid and others reject From 9765116c47cf1045f0499bd3e190405fee8e05e0 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Wed, 20 May 2020 10:11:30 +0100 Subject: [PATCH 1074/1250] Make backfill wording clearer --- api/server-server/backfill.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/server-server/backfill.yaml b/api/server-server/backfill.yaml index d53de6c0..e98c9e90 100644 --- a/api/server-server/backfill.yaml +++ b/api/server-server/backfill.yaml @@ -32,8 +32,8 @@ paths: summary: Retrieves the events which precede the given event description: |- Retrieves a sliding-window history of previous PDUs that occurred in the given room. - Starting from the PDU ID(s) given in the ``v`` argument, the PDUs that preceded it - are retrieved, up to the total number given by the ``limit``. + Starting from the PDU ID(s) given in the ``v`` argument, the PDUs given in ``v`` and + the PDUs that preceded it are retrieved, up to the total number given by the ``limit``. operationId: backfillRoom security: - signedRequest: [] From fc91946e5a4b5ea888912420ed3ab074dfc104f9 Mon Sep 17 00:00:00 2001 From: Kegsay Date: Wed, 20 May 2020 11:07:35 +0100 Subject: [PATCH 1075/1250] Update api/server-server/backfill.yaml Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- api/server-server/backfill.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/server-server/backfill.yaml b/api/server-server/backfill.yaml index e98c9e90..4bf62663 100644 --- a/api/server-server/backfill.yaml +++ b/api/server-server/backfill.yaml @@ -33,7 +33,7 @@ paths: description: |- Retrieves a sliding-window history of previous PDUs that occurred in the given room. Starting from the PDU ID(s) given in the ``v`` argument, the PDUs given in ``v`` and - the PDUs that preceded it are retrieved, up to the total number given by the ``limit``. + the PDUs that preceded them are retrieved, up to the total number given by the ``limit``. operationId: backfillRoom security: - signedRequest: [] From 07716711f14378a08f0d45064c49ecfde8c9e66b Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 20 May 2020 08:58:32 -0400 Subject: [PATCH 1076/1250] Give more guidance on how invalid events should be handled. Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/2540-stricter-event-validation.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/proposals/2540-stricter-event-validation.md b/proposals/2540-stricter-event-validation.md index ac28efc4..31c4c39b 100644 --- a/proposals/2540-stricter-event-validation.md +++ b/proposals/2540-stricter-event-validation.md @@ -21,8 +21,10 @@ even support these by default. One common additional feature is handling ## Proposal In a future room version, homeserver implementations are to strictly enforce -the JSON compliance of the Canonical JSON specification for events. Events that -do not abide by these rules should be treated like any other bad JSON value. +the JSON compliance of the Canonical JSON specification for events. +Non-compliant events should be treated like any other malformed event, +for example by rejecting the request with an HTTP 400 error with `M_BAD_JSON`, +or by discarding the event. The rationale for doing this in a future room version is to avoid a split brain room -- where some federated servers believe an event is valid and others reject From 3875d50de80463d32b777975a94a16a99f4bffd7 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 20 May 2020 07:50:39 -0600 Subject: [PATCH 1077/1250] Add missing changelog --- changelogs/server_server/newsfragments/2559.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/server_server/newsfragments/2559.clarification diff --git a/changelogs/server_server/newsfragments/2559.clarification b/changelogs/server_server/newsfragments/2559.clarification new file mode 100644 index 00000000..cdb9cfe0 --- /dev/null +++ b/changelogs/server_server/newsfragments/2559.clarification @@ -0,0 +1 @@ +Clarify which events are targeted by backfill. From 74b627ac0b824a5fa40cf1a943a684afbf7a5516 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 20 May 2020 17:42:10 -0600 Subject: [PATCH 1078/1250] Fix the response format of the `/send` endpoint Fixes https://github.com/matrix-org/matrix-doc/issues/2236 --- api/server-server/transactions.yaml | 64 ++++++++----------- .../newsfragments/2560.clarification | 1 + 2 files changed, 28 insertions(+), 37 deletions(-) create mode 100644 changelogs/server_server/newsfragments/2560.clarification diff --git a/api/server-server/transactions.yaml b/api/server-server/transactions.yaml index b34c1902..a6348e13 100644 --- a/api/server-server/transactions.yaml +++ b/api/server-server/transactions.yaml @@ -77,43 +77,33 @@ paths: The result of processing the transaction. The server is to use this response even in the event of one or more PDUs failing to be processed. schema: - type: array - minItems: 2 - maxItems: 2 - items: - - type: integer - description: The value ``200``. - example: 200 - - type: object - title: PDU Processing Results - description: The results for the processing of each PDU in the transaction. - properties: - pdus: - type: object - description: |- - The PDUs from the original transaction. The string key represents the ID of the - PDU (event) that was processed. - additionalProperties: - type: object - title: PDU Processing Result - description: Information about how the PDU was handled. - properties: - error: - type: string - description: |- - A human readable description about what went wrong in processing this PDU. - If no error is present, the PDU can be considered successfully handled. - example: "You are not allowed to send a message to this room." - required: ['pdus'] + type: object + title: PDU Processing Results + description: The results for the processing of each PDU in the transaction. + properties: + pdus: + type: object + description: |- + The PDUs from the original transaction. The string key represents the ID of the + PDU (event) that was processed. + additionalProperties: + type: object + title: PDU Processing Result + description: Information about how the PDU was handled. + properties: + error: + type: string + description: |- + A human readable description about what went wrong in processing this PDU. + If no error is present, the PDU can be considered successfully handled. + example: "You are not allowed to send a message to this room." + required: ['pdus'] examples: - application/json: [ - 200, - { - "pdus": { - "$successful_event:example.org": {}, - "$failed_event:example.org": { - "error": "You are not allowed to send a message to this room." - } + application/json: { + "pdus": { + "$successful_event:example.org": {}, + "$failed_event:example.org": { + "error": "You are not allowed to send a message to this room." } } - ] + } diff --git a/changelogs/server_server/newsfragments/2560.clarification b/changelogs/server_server/newsfragments/2560.clarification new file mode 100644 index 00000000..c60bc6f3 --- /dev/null +++ b/changelogs/server_server/newsfragments/2560.clarification @@ -0,0 +1 @@ +Fix the response format of the ``/send`` endpoint. From 04e8244dbc3ffb7d805bd6c97bf7271c9a472162 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 20 May 2020 17:44:40 -0600 Subject: [PATCH 1079/1250] Clarify various bits of wording Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- specification/proposals_intro.rst | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 7c8e4efd..2e6f4389 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -390,17 +390,15 @@ are required to use the following process to ensure that the official Matrix nam is not cluttered with development or testing data. .. Note:: - Proof of concept implementations that are solely left on a branch/unreleased for - demonstrating that a particular MSC works do not have to follow this. - -The process for an implementation willing to be ahead of a spec release is: + Unreleased implementations (including proofs-of-concept demonstrating that a + particular MSC works) do not have to follow this process. 1. Have an idea for a feature. 2. Implement the feature using unstable endpoints, vendor prefixes, and unstable feature flags as appropriate. * When using unstable endpoints, they MUST include a vendor prefix. For example: - `/_matrix/client/unstable/com.example/login`. Vendor prefixes throughout Matrix + ``/_matrix/client/unstable/com.example/login``. Vendor prefixes throughout Matrix always use the Java package naming convention. The MSC for the feature should identify which preferred vendor prefix is to be used by early adopters. * Note that unstable namespaces do not automatically inherit endpoints from stable From 8220de58bddeb7653dd917cf2831f543698dc50a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 20 May 2020 17:48:13 -0600 Subject: [PATCH 1080/1250] Drop loudly and instead encourage --- specification/proposals_intro.rst | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 2e6f4389..6d8dc8a9 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -436,7 +436,7 @@ is not cluttered with development or testing data. specification version, but does have the feature flag, unstable prefixes should still be used. 9. A transition period of about 2 months starts immediately after the spec release, - before implementations start to loudly encourage other implementations to switch + before implementations start to encourage other implementations to switch to stable endpoints. For example, a server implementation should start asking client implementations to support the stable endpoints 2 months after the spec release, if they haven't already. The same applies in the reverse: if clients @@ -444,9 +444,6 @@ is not cluttered with development or testing data. supporting the new spec release, some noise should be raised in the general direction of the implementation. - * Please be considerate when being noisy to implementations. A gentle reminder - in their issue tracker is generally good enough. - .. Note:: MSCs MUST still describe what the stable endpoints/feature looks like with a note towards the bottom for what the unstable feature flag/prefixes are. For example, From 1388742a52876f9b13d5f05631baf5ae3959825e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 20 May 2020 18:00:27 -0600 Subject: [PATCH 1081/1250] Mention that we use OpenAPI 3's response code format See comments of https://github.com/matrix-org/matrix-doc/pull/2238 --- api/openapi_extensions.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/api/openapi_extensions.md b/api/openapi_extensions.md index 339452ba..fced21fc 100644 --- a/api/openapi_extensions.md +++ b/api/openapi_extensions.md @@ -43,3 +43,11 @@ doesn't work, as in the following example: properties: ... ``` + +## OpenAPI 3's "2xx" format for response codes + + + +In some cases, the schema will have HTTP response code definitions like +`2xx`, `3xx`, and `4xx`. These indicate that a response code within those +ranges (`2xx` = `200` to `299`) is valid for the schema. From b11cf560b54ddc7a73c03443a05cde41f7a98302 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 15 May 2020 17:24:27 -0600 Subject: [PATCH 1082/1250] Add spec for new alias handling (client-server) MSC: https://github.com/matrix-org/matrix-doc/pull/2432 This commit does not deal with areas which will be covered by the room version specifications (namely the redaction algorithm). It feels a bit overly cruel to completely obliterate all mentions of `m.room.aliases` from the spec as client/server developers may encounter the event type in the wild. To ensure that CTRL+F still works, a brief mention that they do nothing has been put in place, leaving no other references (except the redaction algorithm - see previous paragraph). --- api/client-server/directory.yaml | 82 ++++++++++++++++++- api/client-server/room_state.yaml | 24 ++++++ event-schemas/examples/m.room.aliases | 8 -- event-schemas/examples/m.room.canonical_alias | 6 +- event-schemas/schema/m.room.aliases | 24 ------ event-schemas/schema/m.room.canonical_alias | 22 +++-- specification/client_server_api.rst | 31 ++++--- specification/modules/instant_messaging.rst | 10 +-- 8 files changed, 144 insertions(+), 63 deletions(-) delete mode 100644 event-schemas/examples/m.room.aliases delete mode 100644 event-schemas/schema/m.room.aliases diff --git a/api/client-server/directory.yaml b/api/client-server/directory.yaml index 2c7c8386..67bdf236 100644 --- a/api/client-server/directory.yaml +++ b/api/client-server/directory.yaml @@ -19,7 +19,7 @@ host: localhost:8008 schemes: - https - http -basePath: /_matrix/client/%CLIENT_MAJOR_VERSION%/directory +basePath: /_matrix/client/%CLIENT_MAJOR_VERSION% consumes: - application/json produces: @@ -27,7 +27,7 @@ produces: securityDefinitions: $ref: definitions/security.yaml paths: - "/room/{roomAlias}": + "/directory/room/{roomAlias}": put: summary: Create a new mapping from room alias to room ID. operationId: setRoomAlias @@ -129,7 +129,16 @@ paths: description: |- Remove a mapping of room alias to room ID. - Servers may choose to implement additional access control checks here, for instance that room aliases can only be deleted by their creator or a server administrator. + Servers may choose to implement additional access control checks here, for instance that + room aliases can only be deleted by their creator or a server administrator. + + .. Note:: + Servers may choose to update the ``alt_aliases`` for the ``m.room.canonical_alias`` + state event in the room when an alias is removed. Servers which choose to update the + canonical alias event are recommended to, in addition to their other relevant permission + checks, delete the alias and return a successful response even if the user does not + have permission to update the ``m.room.canonical_alias`` event. + operationId: deleteRoomAlias security: - accessToken: [] @@ -159,3 +168,70 @@ paths: "$ref": "definitions/errors/error.yaml" tags: - Room directory + "/rooms/{roomId}/aliases": + get: + summary: Get a list of local aliases on a given room. + description: |- + Get a list of aliases maintained by the local server for the + given room. + + This endpoint can be called by users who are in the room (external + users receive an ``M_FORBIDDEN`` error response). If the room's + ``m.room.history_visibility`` maps to ``world_readable``, any + user can call this endpoint. + + Servers may choose to implement additional access control checks here, + such as allowing server administrators to view aliases regardless of + membership. + + .. Note:: + Clients are not recommended to display this list of aliases prominently + as they are not curated, unlike those listed in the ``m.room.canonical_alias`` + state event. + + operationId: getLocalAliases + security: + - accessToken: [] + parameters: + - in: path + type: string + name: roomId + description: The room ID to find local aliases of. + required: true + x-example: "!abc123:example.org" + responses: + 200: + description: |- + The list of local aliases for the room. + examples: + application/json: { + "aliases": [ + "#somewhere:example.com", + "#another:example.com", + "#hat_trick:example.com" + ] + } + schema: + type: object + properties: + aliases: + type: array + description: The server's local aliases on the room. Can be empty. + items: + type: string + required: ['aliases'] + 403: + description: The user is not permitted to retrieve the list of local aliases for the room. + examples: + application/json: { + "errcode": "M_FORBIDDEN", + "error": "You are not a member of the room." + } + schema: + "$ref": "definitions/errors/error.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" + tags: + - Room directory diff --git a/api/client-server/room_state.yaml b/api/client-server/room_state.yaml index 640e2009..20b9c1fd 100644 --- a/api/client-server/room_state.yaml +++ b/api/client-server/room_state.yaml @@ -45,6 +45,12 @@ paths: The body of the request should be the content object of the event; the fields in this object will vary depending on the type of event. See `Room Events`_ for the ``m.`` event specification. + + If the event type being sent is ``m.room.canonical_alias`` servers + SHOULD ensure that any new aliases being listed in the event are valid + per their grammar/syntax and that they point to the room ID where the + state event is to be sent. Servers do not validate aliases which are + being removed or are already present in the state event. operationId: setRoomStateWithKey security: - accessToken: [] @@ -104,5 +110,23 @@ paths: "errcode": "M_FORBIDDEN", "error": "You do not have permission to send the event." } + 400: + description: |- + The sender's request is malformed. + + Some example error codes include: + + * ``M_INVALID_PARAMETER``: One or more aliases within the ``m.room.canonical_alias`` + event have invalid syntax. + + * ``M_BAD_ALIAS``: One or more aliases within the ``m.room.canonical_alias`` event + do not point to the room ID for which the state event is to be sent to. + schema: + $ref: "definitions/errors/error.yaml" + examples: + application/json: { + "errcode": "M_BAD_ALIAS", + "error": "The alias '#hello:example.org' does not point to this room." + } tags: - Room participation diff --git a/event-schemas/examples/m.room.aliases b/event-schemas/examples/m.room.aliases deleted file mode 100644 index 3e20332f..00000000 --- a/event-schemas/examples/m.room.aliases +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$ref": "core/state_event.json", - "state_key": "example.org", - "type": "m.room.aliases", - "content": { - "aliases": ["#somewhere:example.org", "#another:example.org"] - } -} diff --git a/event-schemas/examples/m.room.canonical_alias b/event-schemas/examples/m.room.canonical_alias index 06c3226c..698c11b8 100644 --- a/event-schemas/examples/m.room.canonical_alias +++ b/event-schemas/examples/m.room.canonical_alias @@ -3,6 +3,10 @@ "type": "m.room.canonical_alias", "state_key": "", "content": { - "alias": "#somewhere:localhost" + "alias": "#somewhere:localhost", + "alt_aliases": [ + "#somewhere:example.org", + "#myroom:example.com" + ] } } diff --git a/event-schemas/schema/m.room.aliases b/event-schemas/schema/m.room.aliases deleted file mode 100644 index 348d490d..00000000 --- a/event-schemas/schema/m.room.aliases +++ /dev/null @@ -1,24 +0,0 @@ ---- -allOf: - - $ref: core-event-schema/state_event.yaml -description: 'This event is sent by a homeserver directly to inform of changes to the list of aliases it knows about for that room. The ``state_key`` for this event is set to the homeserver which owns the room alias. The entire set of known aliases for the room is the union of all the ``m.room.aliases`` events, one for each homeserver. Clients **should** check the validity of any room alias given in this list before presenting it to the user as trusted fact. The lists given by this event should be considered simply as advice on which aliases might exist, for which the client can perform the lookup to confirm whether it receives the correct room ID.' -properties: - content: - properties: - aliases: - description: A list of room aliases. - items: - type: string - type: array - required: - - aliases - type: object - state_key: - description: The homeserver domain which owns these room aliases. - type: string - type: - enum: - - m.room.aliases - type: string -title: Informs the room about what room aliases it has been given. -type: object diff --git a/event-schemas/schema/m.room.canonical_alias b/event-schemas/schema/m.room.canonical_alias index 5e8e0524..f227871a 100644 --- a/event-schemas/schema/m.room.canonical_alias +++ b/event-schemas/schema/m.room.canonical_alias @@ -3,21 +3,25 @@ allOf: - $ref: core-event-schema/state_event.yaml description: |- This event is used to inform the room about which alias should be - considered the canonical one. This could be for display purposes or as - suggestion to users which alias to use to advertise the room. - - A room with an ``m.room.canonical_alias`` event with an absent, null, or - empty ``alias`` field should be treated the same as a room with no - ``m.room.canonical_alias`` event. + considered the canonical one, and which other aliases point to the room. + This could be for display purposes or as suggestion to users which alias + to use to advertise and access the room. properties: content: properties: alias: - description: The canonical alias. + description: | + The canonical alias for the room. If not present, null, or empty the + room should be considered to have no canonical alias. type: string + alt_aliases: + description: | + Alternative aliases the room advertises. This list can have aliases + despite the ``alias`` field being null, empty, or otherwise not present. + type: array + items: + type: string type: object - required: - - alias state_key: description: A zero-length string. pattern: '^$' diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index fce879a2..fda2c106 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1594,8 +1594,6 @@ Room Events This specification outlines several standard event types, all of which are prefixed with ``m.`` -{{m_room_aliases_event}} - {{m_room_canonical_alias_event}} {{m_room_create_event}} @@ -1608,6 +1606,15 @@ prefixed with ``m.`` {{m_room_redaction_event}} +Historical events ++++++++++++++++++ + +Some events within the ``m.`` namespace might appear in rooms, however they +serve no significant meaning in this version of the specification. They are: + +* ``m.room.aliases`` + +Previous versions of the specification have more information on these events. Syncing ~~~~~~~ @@ -1813,6 +1820,8 @@ one of the following event types: - ``m.room.aliases`` allows key ``aliases``. - ``m.room.history_visibility`` allows key ``history_visibility``. +.. TODO: Room v6 changes how redaction works in MSC2432 (no special meaning for aliases) + The server should add the event causing the redaction to the ``unsigned`` property of the redacted event, under the ``redacted_because`` key. When a client receives a redaction event it should change the redacted event in the @@ -1871,15 +1880,15 @@ send update requests to other servers. However, homeservers MUST handle ``GET`` requests to resolve aliases on other servers; they should do this using the federation API if necessary. -Rooms store a *partial* list of room aliases via the ``m.room.aliases`` state -event. This alias list is partial because it cannot guarantee that the alias -list is in any way accurate or up-to-date, as room aliases can point to -different room IDs over time. Crucially, the aliases in this event are -**purely informational** and SHOULD NOT be treated as accurate. They SHOULD -be checked before they are used or shared with another user. If a room -appears to have a room alias of ``#alias:example.com``, this SHOULD be checked -to make sure that the room's ID matches the ``room_id`` returned from the -request. +Rooms do not store a list of all aliases present on a room, though members +of the room with relevant permissions may publish preferred aliases through +the ``m.room.canonical_alias`` state event. The aliases in the state event +should point to the room ID they are published within, however room aliases +can and do drift to other room IDs over time. Clients SHOULD NOT treat the +aliases as accurate. They SHOULD be checked before they are used or shared +with another user. If a room appears to have a room alias of ``#alias:example.com``, +this SHOULD be checked to make sure that the room's ID matches the ``room_id`` +returned from the request. {{directory_cs_http_api}} diff --git a/specification/modules/instant_messaging.rst b/specification/modules/instant_messaging.rst index 679eabdc..705fd2d9 100644 --- a/specification/modules/instant_messaging.rst +++ b/specification/modules/instant_messaging.rst @@ -275,13 +275,9 @@ choose a name: 1. If the room has an `m.room.name`_ state event with a non-empty ``name`` field, use the name given by that field. -#. If the room has an `m.room.canonical_alias`_ state event with a non-empty - ``alias`` field, use the alias given by that field as the name. - -#. If neither of the above conditions are met, the client can optionally guess - an alias from the ``m.room.alias`` events in the room. This is a temporary - measure while clients do not promote canonical aliases as prominently. This - step may be removed in a future version of the specification. +#. If the room has an `m.room.canonical_alias`_ state event with a valid + ``alias`` field, use the alias given by that field as the name. Note that + clients should avoid using ``alt_aliases`` when calculating the room name. #. If none of the above conditions are met, a name should be composed based on the members of the room. Clients should consider `m.room.member`_ events From 2b6086d87c269f4d246b2a9dc22fd7de1f5e792e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 20 May 2020 20:15:09 -0600 Subject: [PATCH 1083/1250] Add changelog entries It's a bit awkward that this shows up as a backwards compatible change, but it's also not breaking. --- changelogs/client_server/newsfragments/2562.feature | 1 + changelogs/client_server/newsfragments/2562.new | 1 + 2 files changed, 2 insertions(+) create mode 100644 changelogs/client_server/newsfragments/2562.feature create mode 100644 changelogs/client_server/newsfragments/2562.new diff --git a/changelogs/client_server/newsfragments/2562.feature b/changelogs/client_server/newsfragments/2562.feature new file mode 100644 index 00000000..556018da --- /dev/null +++ b/changelogs/client_server/newsfragments/2562.feature @@ -0,0 +1 @@ +Replaced legacy room alias handling with a more sustainable solution per `MSC2432 `_. diff --git a/changelogs/client_server/newsfragments/2562.new b/changelogs/client_server/newsfragments/2562.new new file mode 100644 index 00000000..c7b3e4ca --- /dev/null +++ b/changelogs/client_server/newsfragments/2562.new @@ -0,0 +1 @@ +Added ``/rooms/{roomId}/aliases`` for retrieving local aliases for a room. From 0300a3cab4a77a5757c9e6acd065261f4eb03954 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 20 May 2020 20:45:19 -0600 Subject: [PATCH 1084/1250] Move redaction algorithm into room version specification We stick it in a client section of v1 as the earliest version to define the algorithm is v1, and the client-server spec tells clients to use this algorithm. --- specification/client_server_api.rst | 34 +---------------- specification/rooms/v1.rst | 59 +++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 40 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index fce879a2..8a94b711 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1779,39 +1779,7 @@ redacted include a ``redacted_because`` key whose value is the event that caused it to be redacted, which may include a reason. -Upon receipt of a redaction event, the server should strip off any keys not in -the following list: - -- ``event_id`` -- ``type`` -- ``room_id`` -- ``sender`` -- ``state_key`` -- ``content`` -- ``hashes`` -- ``signatures`` -- ``depth`` -- ``prev_events`` -- ``prev_state`` -- ``auth_events`` -- ``origin`` -- ``origin_server_ts`` -- ``membership`` - -.. Note: - Some of the keys, such as ``hashes``, will appear on the federation-formatted - event and therefore the client may not be aware of them. - -The content object should also be stripped of all keys, unless it is one of -one of the following event types: - -- ``m.room.member`` allows key ``membership``. -- ``m.room.create`` allows key ``creator``. -- ``m.room.join_rules`` allows key ``join_rule``. -- ``m.room.power_levels`` allows keys ``ban``, ``events``, ``events_default``, - ``kick``, ``redact``, ``state_default``, ``users``, ``users_default``. -- ``m.room.aliases`` allows key ``aliases``. -- ``m.room.history_visibility`` allows key ``history_visibility``. +The exact algorithm to apply against an event is defined in the `room version specification`_. The server should add the event causing the redaction to the ``unsigned`` property of the redacted event, under the ``redacted_because`` key. When a diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index 10eee54d..23d8a833 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -1,4 +1,5 @@ .. Copyright 2017,2019 New Vector Ltd +.. Copyright 2020 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. @@ -21,13 +22,57 @@ blocks for other room versions. .. contents:: Table of Contents .. sectnum:: +Client considerations +--------------------- + +Clients may need to consider some algorithms performed by the server for their own +implementation. + +Redactions +~~~~~~~~~~ + +Upon receipt of a redaction event, the server should strip off any keys not in +the following list: + +- ``event_id`` +- ``type`` +- ``room_id`` +- ``sender`` +- ``state_key`` +- ``content`` +- ``hashes`` +- ``signatures`` +- ``depth`` +- ``prev_events`` +- ``prev_state`` +- ``auth_events`` +- ``origin`` +- ``origin_server_ts`` +- ``membership`` + +.. Note: + Some of the keys, such as ``hashes``, will appear on the federation-formatted + event and therefore the client may not be aware of them. + +The content object should also be stripped of all keys, unless it is one of +one of the following event types: + +- ``m.room.member`` allows key ``membership``. +- ``m.room.create`` allows key ``creator``. +- ``m.room.join_rules`` allows key ``join_rule``. +- ``m.room.power_levels`` allows keys ``ban``, ``events``, ``events_default``, + ``kick``, ``redact``, ``state_default``, ``users``, ``users_default``. +- ``m.room.aliases`` allows key ``aliases``. +- ``m.room.history_visibility`` allows key ``history_visibility``. + 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. + intricacies contained here. The section above regarding client considerations + is the resource that Client-Server API use cases should reference. The algorithms defined here should only apply to version 1 rooms. Other algorithms @@ -112,7 +157,7 @@ The types of state events that affect authorization are: .. NOTE:: Power levels are inferred from defaults when not explicitly supplied. - For example, mentions of the ``sender``'s power level can also refer + For example, mentions of the ``sender``'s power level can also refer to the default power level for users in the room. The rules are as follows: @@ -250,7 +295,7 @@ The rules are as follows: #. If there is no previous ``m.room.power_levels`` event in the room, allow. #. For the keys ``users_default``, ``events_default``, - ``state_default``, ``ban``, ``redact``, ``kick``, ``invite`` check if they + ``state_default``, ``ban``, ``redact``, ``kick``, ``invite`` check if they were added, changed or removed. For each found alteration: i. If the current value is higher than the ``sender``'s current power level, @@ -258,13 +303,13 @@ The rules are as follows: #. If the new value is higher than the ``sender``'s current power level, reject. - - #. For each entry being added, changed or removed in both the ``events`` and + + #. For each entry being added, changed or removed in both the ``events`` and ``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. From be353115594b3572fc07c8f8b5d40e57b6c161fb Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 20 May 2020 20:28:27 -0600 Subject: [PATCH 1085/1250] s/should/must for redaction algorithm This feels like it was a mistake some time ago considering the redaction algorithm is used in very strict algorithms like event signing. --- specification/rooms/v1.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index 23d8a833..9282c1f3 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -31,7 +31,7 @@ implementation. Redactions ~~~~~~~~~~ -Upon receipt of a redaction event, the server should strip off any keys not in +Upon receipt of a redaction event, the server must strip off any keys not in the following list: - ``event_id`` @@ -54,7 +54,7 @@ the following list: Some of the keys, such as ``hashes``, will appear on the federation-formatted event and therefore the client may not be aware of them. -The content object should also be stripped of all keys, unless it is one of +The content object must also be stripped of all keys, unless it is one of one of the following event types: - ``m.room.member`` allows key ``membership``. From a1324aa9dca7e9ca01acde43cc5db3c7f95ad718 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 20 May 2020 20:44:08 -0600 Subject: [PATCH 1086/1250] Move MSC2432 (alias handling) to v6 --- specification/index.rst | 1 + specification/rooms/v6.rst | 59 ++++++++++++++++++++++++++++++++++++++ specification/targets.yaml | 4 +++ 3 files changed, 64 insertions(+) create mode 100644 specification/rooms/v6.rst diff --git a/specification/index.rst b/specification/index.rst index 728383ab..aa8a4641 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -550,6 +550,7 @@ The available room versions are: * `Version 3 `_ - **Stable**. Introduces events whose IDs are the event's hash. * `Version 4 `_ - **Stable**. Builds on v3 by using URL-safe base64 for event IDs. * `Version 5 `_ - **Stable**. Introduces enforcement of signing key validity periods. +* `Version 6 `_ - **Stable**. Alters several authorization rules for events. Specification Versions ---------------------- diff --git a/specification/rooms/v6.rst b/specification/rooms/v6.rst new file mode 100644 index 00000000..de0ab889 --- /dev/null +++ b/specification/rooms/v6.rst @@ -0,0 +1,59 @@ +.. Copyright 2020 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. + +Room Version 6 +============== + +This room version builds on `version 5 `_ while changing various +authorization rules performed on events. + +.. contents:: Table of Contents +.. sectnum:: + + +Client considerations +--------------------- + +The redaction algorithm has changed from `room version 1 `_ to remove +all rules against events of type ``m.room.aliases``. Room versions 2, 3, 4, and +5 all use v1's redaction algorithm. The algorithm is otherwise unchanged. + + +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 6 makes the following alterations to algorithms described in `room version 5 `_. + +Redactions +~~~~~~~~~~ + +As mentioned in the client considerations portion of this specification, all +special meaning has been removed for events of type ``m.room.aliases``. The +algorithm is otherwise unchanged. + +Authorization rules for events +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Like redactions, all rules relating specifically to events of type ``m.room.aliases`` +are removed. They must still pass authorization checks relating to state events. + +The remaining rules are the same as in `room version 3 `_ +(the last inherited room version to specify the authorization rules). diff --git a/specification/targets.yaml b/specification/targets.yaml index 4e0b068d..5f0e32cc 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -45,6 +45,10 @@ targets: files: - rooms/v5.rst version_label: v5 + rooms@v6: # this is translated to be rooms/v6.html + files: + - rooms/v6.rst + version_label: v6 appendices: files: - appendices.rst From 74c51b05a434ddcfb3b8dc63ebfeda56c29456ba Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 20 May 2020 22:13:55 -0600 Subject: [PATCH 1087/1250] Incorporate MSC2209 (`notifications` auth rules) MSC: https://github.com/matrix-org/matrix-doc/pull/2209 The changes are slightly difficult to word without dumping the text in and playing a game of spot the difference, so we now use our pre-existing pygments support to render a representation of the difference. The difference is shown in markdown-like format instead of RST for ease of understanding. It's also not rendered HTML for largely complexity reasons. --- scripts/css/pygments.css | 83 ++++++++++++++++++++++++++++++++++++++ scripts/gendoc.py | 1 + specification/rooms/v6.rst | 32 +++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 scripts/css/pygments.css diff --git a/scripts/css/pygments.css b/scripts/css/pygments.css new file mode 100644 index 00000000..a212151a --- /dev/null +++ b/scripts/css/pygments.css @@ -0,0 +1,83 @@ +/* +Original styles generated from: + pygmentize -f html -S colorful -a pre.code > ./scripts/css/pygments.css + +Rules for which we don't want the syntax highlighter to kick in are commented +out at the bottom. + +Windows users: if you regenerate this file, you'll need to re-save it as utf-8 +to make docutils happy. +*/ + +/* DIFFS */ +pre.code .gd { color: #A00000 } /* Generic.Deleted */ +pre.code .gi { color: #00A000 } /* Generic.Inserted */ + +/* UNUSED */ +/*pre.code .hll { background-color: #ffffcc }*/ +/*pre.code { background: #ffffff; }*/ +/*pre.code .c { color: #888888 } !* Comment *!*/ +/*pre.code .err { color: #FF0000; background-color: #FFAAAA } !* Error *!*/ +/*pre.code .k { color: #008800; font-weight: bold } !* Keyword *!*/ +/*pre.code .o { color: #333333 } !* Operator *!*/ +/*pre.code .ch { color: #888888 } !* Comment.Hashbang *!*/ +/*pre.code .cm { color: #888888 } !* Comment.Multiline *!*/ +/*pre.code .cp { color: #557799 } !* Comment.Preproc *!*/ +/*pre.code .cpf { color: #888888 } !* Comment.PreprocFile *!*/ +/*pre.code .c1 { color: #888888 } !* Comment.Single *!*/ +/*pre.code .cs { color: #cc0000; font-weight: bold } !* Comment.Special *!*/ +/*pre.code .ge { font-style: italic } !* Generic.Emph *!*/ +/*pre.code .gr { color: #FF0000 } !* Generic.Error *!*/ +/*pre.code .gh { color: #000080; font-weight: bold } !* Generic.Heading *!*/ +/*pre.code .go { color: #888888 } !* Generic.Output *!*/ +/*pre.code .gp { color: #c65d09; font-weight: bold } !* Generic.Prompt *!*/ +/*pre.code .gs { font-weight: bold } !* Generic.Strong *!*/ +/*pre.code .gu { color: #800080; font-weight: bold } !* Generic.Subheading *!*/ +/*pre.code .gt { color: #0044DD } !* Generic.Traceback *!*/ +/*pre.code .kc { color: #008800; font-weight: bold } !* Keyword.Constant *!*/ +/*pre.code .kd { color: #008800; font-weight: bold } !* Keyword.Declaration *!*/ +/*pre.code .kn { color: #008800; font-weight: bold } !* Keyword.Namespace *!*/ +/*pre.code .kp { color: #003388; font-weight: bold } !* Keyword.Pseudo *!*/ +/*pre.code .kr { color: #008800; font-weight: bold } !* Keyword.Reserved *!*/ +/*pre.code .kt { color: #333399; font-weight: bold } !* Keyword.Type *!*/ +/*pre.code .m { color: #6600EE; font-weight: bold } !* Literal.Number *!*/ +/*pre.code .s { background-color: #fff0f0 } !* Literal.String *!*/ +/*pre.code .na { color: #0000CC } !* Name.Attribute *!*/ +/*pre.code .nb { color: #007020 } !* Name.Builtin *!*/ +/*pre.code .nc { color: #BB0066; font-weight: bold } !* Name.Class *!*/ +/*pre.code .no { color: #003366; font-weight: bold } !* Name.Constant *!*/ +/*pre.code .nd { color: #555555; font-weight: bold } !* Name.Decorator *!*/ +/*pre.code .ni { color: #880000; font-weight: bold } !* Name.Entity *!*/ +/*pre.code .ne { color: #FF0000; font-weight: bold } !* Name.Exception *!*/ +/*pre.code .nf { color: #0066BB; font-weight: bold } !* Name.Function *!*/ +/*pre.code .nl { color: #997700; font-weight: bold } !* Name.Label *!*/ +/*pre.code .nn { color: #0e84b5; font-weight: bold } !* Name.Namespace *!*/ +/*pre.code .nt { color: #007700 } !* Name.Tag *!*/ +/*pre.code .nv { color: #996633 } !* Name.Variable *!*/ +/*pre.code .ow { color: #000000; font-weight: bold } !* Operator.Word *!*/ +/*pre.code .w { color: #bbbbbb } !* Text.Whitespace *!*/ +/*pre.code .mb { color: #6600EE; font-weight: bold } !* Literal.Number.Bin *!*/ +/*pre.code .mf { color: #6600EE; font-weight: bold } !* Literal.Number.Float *!*/ +/*pre.code .mh { color: #005588; font-weight: bold } !* Literal.Number.Hex *!*/ +/*pre.code .mi { color: #0000DD; font-weight: bold } !* Literal.Number.Integer *!*/ +/*pre.code .mo { color: #4400EE; font-weight: bold } !* Literal.Number.Oct *!*/ +/*pre.code .sa { background-color: #fff0f0 } !* Literal.String.Affix *!*/ +/*pre.code .sb { background-color: #fff0f0 } !* Literal.String.Backtick *!*/ +/*pre.code .sc { color: #0044DD } !* Literal.String.Char *!*/ +/*pre.code .dl { background-color: #fff0f0 } !* Literal.String.Delimiter *!*/ +/*pre.code .sd { color: #DD4422 } !* Literal.String.Doc *!*/ +/*pre.code .s2 { background-color: #fff0f0 } !* Literal.String.Double *!*/ +/*pre.code .se { color: #666666; font-weight: bold; background-color: #fff0f0 } !* Literal.String.Escape *!*/ +/*pre.code .sh { background-color: #fff0f0 } !* Literal.String.Heredoc *!*/ +/*pre.code .si { background-color: #eeeeee } !* Literal.String.Interpol *!*/ +/*pre.code .sx { color: #DD2200; background-color: #fff0f0 } !* Literal.String.Other *!*/ +/*pre.code .sr { color: #000000; background-color: #fff0ff } !* Literal.String.Regex *!*/ +/*pre.code .s1 { background-color: #fff0f0 } !* Literal.String.Single *!*/ +/*pre.code .ss { color: #AA6600 } !* Literal.String.Symbol *!*/ +/*pre.code .bp { color: #007020 } !* Name.Builtin.Pseudo *!*/ +/*pre.code .fm { color: #0066BB; font-weight: bold } !* Name.Function.Magic *!*/ +/*pre.code .vc { color: #336699 } !* Name.Variable.Class *!*/ +/*pre.code .vg { color: #dd7700; font-weight: bold } !* Name.Variable.Global *!*/ +/*pre.code .vi { color: #3333BB } !* Name.Variable.Instance *!*/ +/*pre.code .vm { color: #996633 } !* Name.Variable.Magic *!*/ +/*pre.code .il { color: #0000DD; font-weight: bold } !* Literal.Number.Integer.Long *!*/ diff --git a/scripts/gendoc.py b/scripts/gendoc.py index 72e3047c..7e68ccd7 100755 --- a/scripts/gendoc.py +++ b/scripts/gendoc.py @@ -273,6 +273,7 @@ def rst2html(i, o, stylesheets): writer_name="html", settings_overrides={ "stylesheet_path": stylesheets, + "syntax_highlight": "short", }, ) diff --git a/specification/rooms/v6.rst b/specification/rooms/v6.rst index de0ab889..e165f771 100644 --- a/specification/rooms/v6.rst +++ b/specification/rooms/v6.rst @@ -55,5 +55,37 @@ Authorization rules for events Like redactions, all rules relating specifically to events of type ``m.room.aliases`` are removed. They must still pass authorization checks relating to state events. +Additionally, the authorization rules for events of type ``m.room.power_levels`` +now include the content key ``notifications``. This new rule takes the place of the +rule which checks the ``events`` and ``users`` keys. + +For completeness, the changes to the auth rules can be represented as follows: + +.. code:: diff + + ... + + -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.power_levels`: + + ... + + - * For each entry being added, changed or removed in both the `events` and `users` keys: + + * For each entry being added, changed or removed in the `events`, `users`, and `notifications` keys: + + i. If the current value is higher than the `sender`'s current power level, reject. + + ii. If the new value is higher than the `sender`'s current power level, reject. + + ... + + The remaining rules are the same as in `room version 3 `_ (the last inherited room version to specify the authorization rules). From 66ab480967c7dc1b2ad4f3750b94f837d1eda9ef Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 20 May 2020 21:58:58 -0600 Subject: [PATCH 1088/1250] Incorporate MSC2540 (Canonical JSON validation) MSC: https://github.com/matrix-org/matrix-doc/pull/2540 --- specification/appendices/signing_json.rst | 11 +++++++++++ specification/rooms/v1.rst | 6 ++++++ specification/rooms/v6.rst | 9 +++++++++ 3 files changed, 26 insertions(+) diff --git a/specification/appendices/signing_json.rst b/specification/appendices/signing_json.rst index 8036950e..fbeb0010 100644 --- a/specification/appendices/signing_json.rst +++ b/specification/appendices/signing_json.rst @@ -39,6 +39,17 @@ range where they can be accurately represented using IEEE double precision floating point numbers since a number of JSON libraries represent all numbers using this representation. +.. WARNING:: + Events in room versions 1, 2, 3, 4, and 5 might not be fully compliant with + these restrictions. Servers SHOULD be capable of handling JSON which is considered + invalid by these restrictions where possible. + + The most notable consideration is that integers might not be in the range + specified above. + +.. Note:: + Float values are not permitted by this encoding. + .. code:: python import json diff --git a/specification/rooms/v1.rst b/specification/rooms/v1.rst index 9282c1f3..a71bdfb4 100644 --- a/specification/rooms/v1.rst +++ b/specification/rooms/v1.rst @@ -352,6 +352,12 @@ Events in version 1 rooms have the following structure: {{definition_ss_pdu}} +Canonical JSON +~~~~~~~~~~~~~~ + +Servers MUST NOT strictly enforce the JSON format specified in the +`appendices <../appendices.html#canonical-json>`_ for the reasons described there. + .. _`auth events selection`: ../server_server/%SERVER_RELEASE_LABEL%.html#auth-events-selection .. _`Signing Events`: ../server_server/%SERVER_RELEASE_LABEL%.html#signing-events diff --git a/specification/rooms/v6.rst b/specification/rooms/v6.rst index e165f771..b1acccd2 100644 --- a/specification/rooms/v6.rst +++ b/specification/rooms/v6.rst @@ -89,3 +89,12 @@ For completeness, the changes to the auth rules can be represented as follows: The remaining rules are the same as in `room version 3 `_ (the last inherited room version to specify the authorization rules). + +Canonical JSON +~~~~~~~~~~~~~~ + +Servers MUST strictly enforce the JSON format specified in the +`appendices <../appendices.html#canonical-json>`_. This translates to a 400 ``M_BAD_JSON`` error +on most endpoints, or discarding of events over federation. For example, the federation API's +``/send`` endpoint would discard the event whereas the Client Server API's ``/send/{eventType}`` +endpoint would return a ``M_BAD_JSON`` error. From 98416bf94898395ae5f1b81bfcf8f659a1e76d8b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 20 May 2020 22:16:16 -0600 Subject: [PATCH 1089/1250] Add changelog for client-server API --- changelogs/client_server/newsfragments/2563.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2563.clarification diff --git a/changelogs/client_server/newsfragments/2563.clarification b/changelogs/client_server/newsfragments/2563.clarification new file mode 100644 index 00000000..a8805f4a --- /dev/null +++ b/changelogs/client_server/newsfragments/2563.clarification @@ -0,0 +1 @@ +Move redaction algorithm into the room version specifications. From 915e698c2300f62c694560f3c216df267247bf48 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 21 May 2020 16:48:27 -0400 Subject: [PATCH 1090/1250] clarify which key --- proposals/2399-reporting-no-key-sent.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2399-reporting-no-key-sent.md b/proposals/2399-reporting-no-key-sent.md index 9655574f..05f5dd64 100644 --- a/proposals/2399-reporting-no-key-sent.md +++ b/proposals/2399-reporting-no-key-sent.md @@ -31,7 +31,7 @@ the properties: - `algorithm`: Required. The encryption algorithm that the key is for. - `session_id`: Required if `code` is not `m.no_olm`. The ID of the session. - `sender_key`: Required. The key of the session creator. -- `code`: Required. A machine-readable code for why the key was not sent. +- `code`: Required. A machine-readable code for why the megolm key was not sent. Possible values are: - `m.blacklisted`: the user/device was blacklisted - `m.unverified`: the user/devices is unverified From 64b1ea332319f98f5380fd504305bdc8614ddc73 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 22 May 2020 15:00:44 -0400 Subject: [PATCH 1091/1250] clarify which key again --- proposals/2399-reporting-no-key-sent.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2399-reporting-no-key-sent.md b/proposals/2399-reporting-no-key-sent.md index 05f5dd64..14fa5e2b 100644 --- a/proposals/2399-reporting-no-key-sent.md +++ b/proposals/2399-reporting-no-key-sent.md @@ -30,7 +30,7 @@ the properties: session belongs to. - `algorithm`: Required. The encryption algorithm that the key is for. - `session_id`: Required if `code` is not `m.no_olm`. The ID of the session. -- `sender_key`: Required. The key of the session creator. +- `sender_key`: Required. The unpadded base64-encoded device curve25519 key of the session creator. - `code`: Required. A machine-readable code for why the megolm key was not sent. Possible values are: - `m.blacklisted`: the user/device was blacklisted From 40ec1ae1a998b273c3b2b6600df6bd433d01d820 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 22 May 2020 15:01:32 -0400 Subject: [PATCH 1092/1250] clarification --- proposals/2399-reporting-no-key-sent.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2399-reporting-no-key-sent.md b/proposals/2399-reporting-no-key-sent.md index 14fa5e2b..2550fdbf 100644 --- a/proposals/2399-reporting-no-key-sent.md +++ b/proposals/2399-reporting-no-key-sent.md @@ -47,7 +47,7 @@ the properties: receiving client should only use this string if it does not understand the `code`. -An `m.room_key.withheld` event should only be sent once per session; the +An `m.room_key.withheld` event should only be sent once per session per target; the recipient of the event should assume that the event applies to all messages in that session. If a sender unblocks a recipient, it may re-use the existing session for which the recipient was previously informed that it was blocked, in From 5b38c04e1921261dfe5eb7169068c1ef86a9cd33 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 22 May 2020 15:50:32 -0400 Subject: [PATCH 1093/1250] make definition of signatures fields more consistent --- api/client-server/definitions/device_keys.yaml | 5 +---- api/server-server/definitions/keys.yaml | 18 ++++++------------ api/server-server/third_party_invite.yaml | 12 ++++++------ api/server-server/user_keys.yaml | 8 +++++--- 4 files changed, 18 insertions(+), 25 deletions(-) diff --git a/api/client-server/definitions/device_keys.yaml b/api/client-server/definitions/device_keys.yaml index 41504aba..ce770c09 100644 --- a/api/client-server/definitions/device_keys.yaml +++ b/api/client-server/definitions/device_keys.yaml @@ -47,16 +47,13 @@ properties: "ed25519:JLAFKJWSCS": "lEuiRJBit0IG6nUf5pUzWTUEsRVVe/HJkoKuEww9ULI" signatures: type: object + title: Signatures description: |- Signatures for the device key object. A map from user ID, to a map from ``:`` to the signature. The signature is calculated using the process described at `Signing JSON`_. - additionalProperties: - type: object - additionalProperties: - type: string example: "@alice:example.com": "ed25519:JLAFKJWSCS": "dSO80A01XiigH3uBiDVx/EjzaoycHcjq9lfQX0uWsqxl2giMIiSPR8a4d291W1ihKJL/a+myXS367WT6NAIcBA" diff --git a/api/server-server/definitions/keys.yaml b/api/server-server/definitions/keys.yaml index 1e025a52..7e300402 100644 --- a/api/server-server/definitions/keys.yaml +++ b/api/server-server/definitions/keys.yaml @@ -75,18 +75,12 @@ properties: required: ["expired_ts", "key"] signatures: type: object - description: Digital signatures for this object signed using the ``verify_keys``. - additionalProperties: - type: object - title: Signed Server - example: { - "example.org": { - "ad25519:abc123": "VGhpcyBzaG91bGQgYWN0dWFsbHkgYmUgYSBzaWduYXR1cmU" - } - } - additionalProperties: - type: string - name: Encoded Signature Verification Key + description: |- + Digital signatures for this object signed using the ``verify_keys``. + + The signature is calculated using the process described at `Signing + JSON`_. + title: Signatures valid_until_ts: type: integer format: int64 diff --git a/api/server-server/third_party_invite.yaml b/api/server-server/third_party_invite.yaml index 0b7aac5b..8897bdcf 100644 --- a/api/server-server/third_party_invite.yaml +++ b/api/server-server/third_party_invite.yaml @@ -102,12 +102,12 @@ paths: properties: signatures: type: object - description: The server signatures for this event. - additionalProperties: - type: object - title: Server Signatures - additionalProperties: - type: string + title: Signatures + description: |- + The server signatures for this event. + + The signature is calculated using the process + described at `Signing JSON`_. example: { "magic.forest": { "ed25519:3": "fQpGIW1Snz+pwLZu6sTy2aHy/DYWWTspTJRPyNp0PKkymfIsNffysMl6ObMMFdIJhk6g6pwlIqZ54rxo8SLmAg" diff --git a/api/server-server/user_keys.yaml b/api/server-server/user_keys.yaml index 93237d80..9224d508 100644 --- a/api/server-server/user_keys.yaml +++ b/api/server-server/user_keys.yaml @@ -88,10 +88,12 @@ paths: description: The key, encoded using unpadded base64. signatures: type: object + title: Signatures description: |- - Signature for the device. Mapped from user ID to signature object. - additionalProperties: - type: string + Signature of the key object. + + The signature is calculated using the process described at `Signing + JSON`_. required: ['key', 'signatures'] example: { "@alice:example.com": { From 6a8ba9b1d6372f9a71d6b8554947548556e84c8e Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 22 May 2020 16:10:16 -0400 Subject: [PATCH 1094/1250] improve description of key object in CS and include a link in Fed --- api/server-server/user_keys.yaml | 2 +- .../modules/end_to_end_encryption.rst | 20 ++++++++++++++++--- specification/server_server_api.rst | 1 + 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/api/server-server/user_keys.yaml b/api/server-server/user_keys.yaml index 9224d508..166f1ff0 100644 --- a/api/server-server/user_keys.yaml +++ b/api/server-server/user_keys.yaml @@ -73,7 +73,7 @@ paths: One-time keys for the queried devices. A map from user ID, to a map from devices to a map from ``:`` to the key object. - See the Client-Server Key Algorithms section for more information on + See the `Client-Server Key Algorithms`_ section for more information on the Key Object format. additionalProperties: type: object diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 7411abe4..8bc46de8 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -83,9 +83,23 @@ Base64`_. Example: "JGLn/yafz74HB2AbPLYJWIVGnKAtqECOBf11yyXac2Y" The name ``signed_curve25519`` also corresponds to the Curve25519 algorithm, -but keys using this algorithm are objects with the properties ``key`` (giving -the Base64-encoded 32-byte Curve25519 public key), and ``signatures`` (giving a -signature for the key object, as described in `Signing JSON`_). Example: +but a key using this algorithm is represented by an object with a the following +properties: + +``KeyObject`` + +========== ================ ===================================================== +Parameter Type Description +========== ================ ===================================================== +key string **Required.** The unpadded Base64-encoded 32-byte + Curve25519 public key. +signatures Signatures **Required.** Signatures of the key object. + + The signature is calculated using the process described + at `Signing JSON`_. +========== ================ ===================================================== + +Example: .. code:: json diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index b0a2bc1a..00ddeffc 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -1257,3 +1257,4 @@ issue. .. _`Device Management module`: ../client_server/%CLIENT_RELEASE_LABEL%.html#device-management .. _`End-to-End Encryption module`: ../client_server/%CLIENT_RELEASE_LABEL%.html#end-to-end-encryption .. _`room version specification`: ../index.html#room-versions +.. _`Client-Server Key Algorithms`: ../client_server/%CLIENT_RELEASE_LABEL%.html#key-algorithms From 5270ed0c0ae6d1d35375c4aa2832cfa2391c2544 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 24 May 2020 14:24:49 +0300 Subject: [PATCH 1095/1250] Fix typo in read markers module Signed-off-by: Tulir Asokan --- specification/modules/read_markers.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/modules/read_markers.rst b/specification/modules/read_markers.rst index a77f2013..be06d037 100644 --- a/specification/modules/read_markers.rst +++ b/specification/modules/read_markers.rst @@ -47,7 +47,7 @@ The read markers API can additionally update the user's read receipt (``m.read`` location in the same operation as setting the fully read marker location. This is because read receipts and read markers are commonly updated at the same time, and therefore the client might wish to save an extra HTTP call. Providing an -``m.read`` location performs the same task as a request to ``/receipts/m.read/$event:example.org``. +``m.read`` location performs the same task as a request to ``/receipt/m.read/$event:example.org``. {{read_markers_cs_http_api}} @@ -56,7 +56,7 @@ Server behaviour The server MUST prevent clients from setting ``m.fully_read`` directly in room account data. The server must additionally ensure that it treats the presence of ``m.read`` in the ``/read_markers`` request the same as how it -would for a request to ``/receipts/m.read/$event:example.org``. +would for a request to ``/receipt/m.read/$event:example.org``. Upon updating the ``m.fully_read`` event due to a request to ``/read_markers``, the server MUST send the updated account data event through to the client via From bdd8f03fef638cb07cf0d38a21ad211ecf0d7ce1 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 24 May 2020 11:13:58 -0600 Subject: [PATCH 1096/1250] Add changelog --- changelogs/client_server/newsfragments/2569.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2569.clarification diff --git a/changelogs/client_server/newsfragments/2569.clarification b/changelogs/client_server/newsfragments/2569.clarification new file mode 100644 index 00000000..902a9c3f --- /dev/null +++ b/changelogs/client_server/newsfragments/2569.clarification @@ -0,0 +1 @@ +Fix various spelling errors throughout the specification. From 93f68866c5635078e84eaf8bcf55c8eb274c57f8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 May 2020 08:06:57 -0600 Subject: [PATCH 1097/1250] Fix spec generation not using titles on pseudo objects --- scripts/templating/matrix_templates/units.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index 9d2c69f2..5a7ff94e 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -213,6 +213,7 @@ def get_json_schema_object_fields(obj, enforce_title=False): res = process_data_type(additionalProps) tables = res["tables"] val_title = res["title"] + gen_title = "{%s: %s}" % (key_type, val_title) if res.get("enum_desc") and val_title != "enum": # A map to enum needs another table with enum description tables.append(TypeTable( @@ -220,7 +221,7 @@ def get_json_schema_object_fields(obj, enforce_title=False): rows=[TypeTableRow(key="(mapped value)", title="enum", desc=res["desc"])] )) return { - "title": "{%s: %s}" % (key_type, val_title), + "title": obj_title if obj_title else gen_title, "tables": tables, } From 36ed6e94a2bd2c5e591fdd87cb15acdae53ca03a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 May 2020 08:08:10 -0600 Subject: [PATCH 1098/1250] Re-introduce signature schemas --- api/client-server/definitions/device_keys.yaml | 4 ++++ api/client-server/definitions/third_party_signed.yaml | 4 ++++ api/server-server/definitions/keys.yaml | 4 ++++ api/server-server/third_party_invite.yaml | 4 ++++ api/server-server/user_keys.yaml | 4 ++++ event-schemas/schema/m.room.member | 4 ++++ 6 files changed, 24 insertions(+) diff --git a/api/client-server/definitions/device_keys.yaml b/api/client-server/definitions/device_keys.yaml index ce770c09..4f7cffe7 100644 --- a/api/client-server/definitions/device_keys.yaml +++ b/api/client-server/definitions/device_keys.yaml @@ -54,6 +54,10 @@ properties: The signature is calculated using the process described at `Signing JSON`_. + additionalProperties: + type: object + additionalProperties: + type: string example: "@alice:example.com": "ed25519:JLAFKJWSCS": "dSO80A01XiigH3uBiDVx/EjzaoycHcjq9lfQX0uWsqxl2giMIiSPR8a4d291W1ihKJL/a+myXS367WT6NAIcBA" diff --git a/api/client-server/definitions/third_party_signed.yaml b/api/client-server/definitions/third_party_signed.yaml index c9c761a1..7ce1a1d1 100644 --- a/api/client-server/definitions/third_party_signed.yaml +++ b/api/client-server/definitions/third_party_signed.yaml @@ -33,6 +33,10 @@ properties: type: object description: A signatures object containing a signature of the entire signed object. title: Signatures + additionalProperties: + type: object + additionalProperties: + type: string example: { "example.org": { "ed25519:0": "some9signature" diff --git a/api/server-server/definitions/keys.yaml b/api/server-server/definitions/keys.yaml index 7e300402..306d4d00 100644 --- a/api/server-server/definitions/keys.yaml +++ b/api/server-server/definitions/keys.yaml @@ -81,6 +81,10 @@ properties: The signature is calculated using the process described at `Signing JSON`_. title: Signatures + additionalProperties: + type: object + additionalProperties: + type: string valid_until_ts: type: integer format: int64 diff --git a/api/server-server/third_party_invite.yaml b/api/server-server/third_party_invite.yaml index 8897bdcf..fbd2a9d9 100644 --- a/api/server-server/third_party_invite.yaml +++ b/api/server-server/third_party_invite.yaml @@ -103,6 +103,10 @@ paths: signatures: type: object title: Signatures + additionalProperties: + type: object + additionalProperties: + type: string description: |- The server signatures for this event. diff --git a/api/server-server/user_keys.yaml b/api/server-server/user_keys.yaml index 166f1ff0..6ed51af0 100644 --- a/api/server-server/user_keys.yaml +++ b/api/server-server/user_keys.yaml @@ -89,6 +89,10 @@ paths: signatures: type: object title: Signatures + additionalProperties: + type: object + additionalProperties: + type: string description: |- Signature of the key object. diff --git a/event-schemas/schema/m.room.member b/event-schemas/schema/m.room.member index 1033c098..bff2002e 100644 --- a/event-schemas/schema/m.room.member +++ b/event-schemas/schema/m.room.member @@ -82,6 +82,10 @@ properties: description: 'A single signature from the verifying server, in the format specified by the Signing Events section of the server-server API.' title: Signatures type: object + additionalProperties: + type: object + additionalProperties: + type: string token: description: The token property of the containing third_party_invite object. type: string From 730d164df7fd23fb908f27bda4511f76b769cd36 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 May 2020 08:15:56 -0600 Subject: [PATCH 1099/1250] Add changelogs --- changelogs/client_server/newsfragments/2566.clarification | 1 + changelogs/server_server/newsfragments/2566.clarification | 1 + 2 files changed, 2 insertions(+) create mode 100644 changelogs/client_server/newsfragments/2566.clarification create mode 100644 changelogs/server_server/newsfragments/2566.clarification diff --git a/changelogs/client_server/newsfragments/2566.clarification b/changelogs/client_server/newsfragments/2566.clarification new file mode 100644 index 00000000..15e29b2f --- /dev/null +++ b/changelogs/client_server/newsfragments/2566.clarification @@ -0,0 +1 @@ +Clarify signature object structures for encryption. diff --git a/changelogs/server_server/newsfragments/2566.clarification b/changelogs/server_server/newsfragments/2566.clarification new file mode 100644 index 00000000..15e29b2f --- /dev/null +++ b/changelogs/server_server/newsfragments/2566.clarification @@ -0,0 +1 @@ +Clarify signature object structures for encryption. From b876ac5893dddf4a6b6b4b8152ce0ea5c2d2f482 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 May 2020 08:27:55 -0600 Subject: [PATCH 1100/1250] Clarify which server names to sign requests with Fixes https://github.com/matrix-org/matrix-doc/issues/2512 --- changelogs/server_server/newsfragments/2570.clarification | 1 + specification/server_server_api.rst | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 changelogs/server_server/newsfragments/2570.clarification diff --git a/changelogs/server_server/newsfragments/2570.clarification b/changelogs/server_server/newsfragments/2570.clarification new file mode 100644 index 00000000..3fac40bf --- /dev/null +++ b/changelogs/server_server/newsfragments/2570.clarification @@ -0,0 +1 @@ +Clarify the server names to use when signing requests. diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index b0a2bc1a..ca147665 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -291,6 +291,11 @@ Step 1 sign JSON: } } +The server names in the JSON above are the server names involved. Delegation from +the `server name resolution section <#resolving-server-names>`_ above do not affect +these - the server names from before delegation would take place are used. This +same condition applies throughout the request signing process. + Step 2 add Authorization header: .. code:: From 200212ffd741be53beec8fea1de1100826d44c66 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 May 2020 08:33:08 -0600 Subject: [PATCH 1101/1250] Clarify that a creation event and member event are needed for createRoom Fixes https://github.com/matrix-org/matrix-doc/issues/2494 --- api/client-server/create_room.yaml | 16 +++++++++++----- .../newsfragments/2571.clarification | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2571.clarification diff --git a/api/client-server/create_room.yaml b/api/client-server/create_room.yaml index 2487707e..446d8aef 100644 --- a/api/client-server/create_room.yaml +++ b/api/client-server/create_room.yaml @@ -38,20 +38,26 @@ paths: the new room, including checking power levels for each event. It MUST apply the events implied by the request in the following order: - 0. A default ``m.room.power_levels`` event, giving the room creator + 1. The ``m.room.create`` event itself. Must be the first event in the + room. + + 2. An ``m.room.member`` event for the creator to join the room. This is + needed so the remaining events can be sent. + + 3. A default ``m.room.power_levels`` event, giving the room creator (and not other members) permission to send state events. Overridden by the ``power_level_content_override`` parameter. - 1. Events set by the ``preset``. Currently these are the ``m.room.join_rules``, + 4. Events set by the ``preset``. Currently these are the ``m.room.join_rules``, ``m.room.history_visibility``, and ``m.room.guest_access`` state events. - 2. Events listed in ``initial_state``, in the order that they are + 5. Events listed in ``initial_state``, in the order that they are listed. - 3. Events implied by ``name`` and ``topic`` (``m.room.name`` and ``m.room.topic`` + 6. Events implied by ``name`` and ``topic`` (``m.room.name`` and ``m.room.topic`` state events). - 4. Invite events implied by ``invite`` and ``invite_3pid`` (``m.room.member`` with + 7. Invite events implied by ``invite`` and ``invite_3pid`` (``m.room.member`` with ``membership: invite`` and ``m.room.third_party_invite``). The available presets do the following with respect to room state: diff --git a/changelogs/client_server/newsfragments/2571.clarification b/changelogs/client_server/newsfragments/2571.clarification new file mode 100644 index 00000000..e9437f3c --- /dev/null +++ b/changelogs/client_server/newsfragments/2571.clarification @@ -0,0 +1 @@ +Clarify which events are created as part of ``/createRoom``. From ac187904bbf334ea2a6b31abf4059f5eb3d27637 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 May 2020 08:35:26 -0600 Subject: [PATCH 1102/1250] Update MSC1779 to forward link to matrix.org/foundation --- proposals/1779-open-governance.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/proposals/1779-open-governance.md b/proposals/1779-open-governance.md index bfe86eb8..d9a53c51 100644 --- a/proposals/1779-open-governance.md +++ b/proposals/1779-open-governance.md @@ -1,4 +1,11 @@ -# Proposal for Open Governance of Matrix.org +# Proposal for Open Governance of Matrix.org + +---- + +**For updated information on the Foundation, please see https://matrix.org/foundation/**. +This MSC exists for historical reference. + +---- This whole document is the proposed constitution proposal for Matrix.org, and will form the basis of the first full Articles of Association (AoA) for [The @@ -446,7 +453,7 @@ a high-level mission lock aligned with the above: The foundation was then converted into a Community Interest Company, formalising its non-profit status under the approval of the independent [Community Interest -Companies Regulator](https://www.gov.uk/government/organisations/office-of-the-regulator-of-community-interest-companies), +Companies Regulator](https://www.gov.uk/government/organisations/office-of-the-regulator-of-community-interest-companies), which took effect Jan 2019. We are currently planning to release r0 of the Matrix Spec at the end of Jan 2019, and From e8548f3c3b92e92990657571af61dea1efc95b25 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 May 2020 09:42:54 -0600 Subject: [PATCH 1103/1250] Remove claim that profile info is exclusively managed by the server Fixes https://github.com/matrix-org/matrix-doc/issues/2496 --- changelogs/client_server/newsfragments/2574.clarification | 1 + event-schemas/schema/m.room.member | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2574.clarification diff --git a/changelogs/client_server/newsfragments/2574.clarification b/changelogs/client_server/newsfragments/2574.clarification new file mode 100644 index 00000000..d771d374 --- /dev/null +++ b/changelogs/client_server/newsfragments/2574.clarification @@ -0,0 +1 @@ +Remove claims that the homeserver is exclusively responsible for profile information in membership events. diff --git a/event-schemas/schema/m.room.member b/event-schemas/schema/m.room.member index 1033c098..dabd1b08 100644 --- a/event-schemas/schema/m.room.member +++ b/event-schemas/schema/m.room.member @@ -48,10 +48,10 @@ properties: content: properties: avatar_url: - description: 'The avatar URL for this user, if any. This is added by the homeserver.' + description: 'The avatar URL for this user, if any.' type: string displayname: - description: 'The display name for this user, if any. This is added by the homeserver.' + description: 'The display name for this user, if any.' type: - "string" - "null" From 06b0c1762a879f4db86b09261c69cfc1066c4231 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 May 2020 09:55:32 -0600 Subject: [PATCH 1104/1250] Move the send_join response to its own definition Both APIs need clarification, so dedupe the changes. We should also probably deprecate some of this stuff so we can eventually remove it. --- .../definitions/send_join_response.yaml | 55 +++++++++++++++++++ api/server-server/joins-v1.yaml | 42 +------------- api/server-server/joins-v2.yaml | 42 +------------- 3 files changed, 57 insertions(+), 82 deletions(-) create mode 100644 api/server-server/definitions/send_join_response.yaml diff --git a/api/server-server/definitions/send_join_response.yaml b/api/server-server/definitions/send_join_response.yaml new file mode 100644 index 00000000..96ceaefc --- /dev/null +++ b/api/server-server/definitions/send_join_response.yaml @@ -0,0 +1,55 @@ +# Copyright 2018 New Vector Ltd +# Copyright 2020 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: Room State +description: The state for the room. +properties: + origin: + type: string + description: The resident server's DNS name. + auth_chain: + type: array + description: |- + The auth chain. Note that events have a different format depending on + the room version - check the `room version specification`_ for precise + event formats. + items: + type: object + title: PDU + description: |- + The `PDUs <#pdus>`_ that make up the auth chain. The event format varies depending + on the room version - check the `room version specification`_ for precise event formats. + schema: + type: object + properties: [] + example: + $ref: "../examples/minimal_pdu.json" + state: + type: array + description: |- + The room state. The event format varies depending on the room version - + check the `room version specification`_ for precise event formats. + items: + type: object + title: PDU + description: |- + The `PDUs <#pdus>`_ for the fully resolved state of the room. The event format varies depending + on the room version - check the `room version specification`_ for precise event formats. + schema: + type: object + properties: [] + example: + $ref: "../examples/minimal_pdu.json" +required: ["auth_chain", "state", "origin"] diff --git a/api/server-server/joins-v1.yaml b/api/server-server/joins-v1.yaml index 39287264..18c88db0 100644 --- a/api/server-server/joins-v1.yaml +++ b/api/server-server/joins-v1.yaml @@ -262,47 +262,7 @@ paths: - type: integer description: The value ``200``. example: 200 - - type: object - title: Room State - description: The state for the room. - properties: - origin: - type: string - description: The resident server's DNS name. - auth_chain: - type: array - description: |- - The auth chain. Note that events have a different format depending on - the room version - check the `room version specification`_ for precise - event formats. - items: - type: object - title: PDU - description: |- - The `PDUs <#pdus>`_ that make up the auth chain. The event format varies depending - on the room version - check the `room version specification`_ for precise event formats. - schema: - type: object - properties: [] - example: - $ref: "examples/minimal_pdu.json" - state: - type: array - description: |- - The room state. The event format varies depending on the room version - - check the `room version specification`_ for precise event formats. - items: - type: object - title: PDU - description: |- - The `PDUs <#pdus>`_ for the fully resolved state of the room. The event format varies depending - on the room version - check the `room version specification`_ for precise event formats. - schema: - type: object - properties: [] - example: - $ref: "examples/minimal_pdu.json" - required: ["auth_chain", "state", "origin"] + - $ref: "./definitions/send_join_response.yaml" examples: application/json: [ 200, diff --git a/api/server-server/joins-v2.yaml b/api/server-server/joins-v2.yaml index a98d20fd..b5a1544c 100644 --- a/api/server-server/joins-v2.yaml +++ b/api/server-server/joins-v2.yaml @@ -127,47 +127,7 @@ paths: description: |- The full state for the room, having accepted the join event. schema: - type: object - title: Room State - description: The state for the room. - properties: - origin: - type: string - description: The resident server's DNS name. - auth_chain: - type: array - description: |- - The auth chain. Note that events have a different format depending on - the room version - check the `room version specification`_ for precise - event formats. - items: - type: object - title: PDU - description: |- - The `PDUs <#pdus>`_ that make up the auth chain. The event format varies depending - on the room version - check the `room version specification`_ for precise event formats. - schema: - type: object - properties: [] - example: - $ref: "examples/minimal_pdu.json" - state: - type: array - description: |- - The room state. The event format varies depending on the room version - - check the `room version specification`_ for precise event formats. - items: - type: object - title: PDU - description: |- - The `PDUs <#pdus>`_ for the fully resolved state of the room. The event format varies depending - on the room version - check the `room version specification`_ for precise event formats. - schema: - type: object - properties: [] - example: - $ref: "examples/minimal_pdu.json" - required: ["auth_chain", "state", "origin"] + $ref: "./definitions/send_join_response.yaml" examples: application/json: { "origin": "matrix.org", From c72d30513e961c9bcd94b80bd99b8a343f2b8ecf Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Mon, 25 May 2020 19:08:17 +0200 Subject: [PATCH 1105/1250] c2s: Add required: true to request bodies --- api/client-server/administrative_contact.yaml | 5 +++++ api/client-server/create_room.yaml | 1 + api/client-server/device_management.yaml | 2 ++ api/client-server/joining.yaml | 2 ++ api/client-server/keys.yaml | 3 +++ api/client-server/login.yaml | 1 + api/client-server/redaction.yaml | 1 + api/client-server/registration.yaml | 3 +++ api/client-server/search.yaml | 1 + 9 files changed, 19 insertions(+) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index fc231b60..cebfb274 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -108,6 +108,7 @@ paths: parameters: - in: body name: body + required: true schema: type: object properties: @@ -195,6 +196,7 @@ paths: parameters: - in: body name: body + required: true schema: type: object properties: @@ -247,6 +249,7 @@ paths: parameters: - in: body name: body + required: true schema: type: object properties: @@ -299,6 +302,7 @@ paths: parameters: - in: body name: body + required: true schema: type: object properties: @@ -363,6 +367,7 @@ paths: parameters: - in: body name: body + required: true schema: type: object properties: diff --git a/api/client-server/create_room.yaml b/api/client-server/create_room.yaml index 2487707e..2be8532d 100644 --- a/api/client-server/create_room.yaml +++ b/api/client-server/create_room.yaml @@ -74,6 +74,7 @@ paths: - in: body name: body description: The desired room configuration. + required: true schema: type: object example: { diff --git a/api/client-server/device_management.yaml b/api/client-server/device_management.yaml index 75ee9e44..8039d71f 100644 --- a/api/client-server/device_management.yaml +++ b/api/client-server/device_management.yaml @@ -152,6 +152,7 @@ paths: x-example: "QBUAZIFURK" - in: body name: body + required: true schema: type: object properties: @@ -190,6 +191,7 @@ paths: parameters: - in: body name: body + required: true schema: type: object properties: diff --git a/api/client-server/joining.yaml b/api/client-server/joining.yaml index 4da86022..c5781806 100644 --- a/api/client-server/joining.yaml +++ b/api/client-server/joining.yaml @@ -53,6 +53,7 @@ paths: x-example: "!d41d8cd:matrix.org" - in: body name: third_party_signed + required: true description: |- If supplied, the homeserver must verify that it matches a pending ``m.room.third_party_invite`` event in the room, and perform @@ -134,6 +135,7 @@ paths: x-example: ["matrix.org", "elsewhere.ca"] - in: body name: third_party_signed + required: true schema: type: object properties: diff --git a/api/client-server/keys.yaml b/api/client-server/keys.yaml index 8c4a65f7..429d47ef 100644 --- a/api/client-server/keys.yaml +++ b/api/client-server/keys.yaml @@ -41,6 +41,7 @@ paths: name: keys description: |- The keys to be published + required: true schema: type: object properties: @@ -133,6 +134,7 @@ paths: name: query description: |- Query defining the keys to be downloaded + required: true schema: type: object properties: @@ -250,6 +252,7 @@ paths: name: query description: |- Query defining the keys to be claimed + required: true schema: type: object properties: diff --git a/api/client-server/login.yaml b/api/client-server/login.yaml index f6c92638..fac9361c 100644 --- a/api/client-server/login.yaml +++ b/api/client-server/login.yaml @@ -82,6 +82,7 @@ paths: parameters: - in: body name: body + required: true schema: type: object example: { diff --git a/api/client-server/redaction.yaml b/api/client-server/redaction.yaml index 907b1d16..811773d6 100644 --- a/api/client-server/redaction.yaml +++ b/api/client-server/redaction.yaml @@ -65,6 +65,7 @@ paths: x-example: "37" - in: body name: body + required: true schema: type: object example: { diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 8114299e..f57bd88c 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -84,6 +84,7 @@ paths: description: The kind of account to register. Defaults to ``user``. - in: body name: body + required: true schema: type: object properties: @@ -336,6 +337,7 @@ paths: parameters: - in: body name: body + required: true schema: type: object properties: @@ -507,6 +509,7 @@ paths: parameters: - in: body name: body + required: true schema: type: object properties: diff --git a/api/client-server/search.yaml b/api/client-server/search.yaml index 4fe72d5b..2d30ebef 100644 --- a/api/client-server/search.yaml +++ b/api/client-server/search.yaml @@ -45,6 +45,7 @@ paths: x-example: "YWxsCgpOb25lLDM1ODcwOA" - in: body name: body + required: true schema: type: object example: { From 67d46fa881169ee6cea9d20028189d1869c5c83b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 May 2020 10:59:41 -0600 Subject: [PATCH 1106/1250] Clarify the auth_chain and state for send_join Fixes https://github.com/matrix-org/matrix-doc/issues/2467 Fixes https://github.com/matrix-org/matrix-doc/issues/2464 This is based on looking at Synapse, not actually testing it. Within the send_join handling functions, an "event context" is acquired [here](https://github.com/matrix-org/synapse/blob/d14c4d6b6d02e8c55a6647ce0f0b3b44356d6173/synapse/handlers/federation.py#L1472) which then later uses the previous state (populated [here](https://github.com/matrix-org/synapse/blob/d14c4d6b6d02e8c55a6647ce0f0b3b44356d6173/synapse/state/__init__.py#L286-L289) in the event context) [here](https://github.com/matrix-org/synapse/blob/d14c4d6b6d02e8c55a6647ce0f0b3b44356d6173/synapse/handlers/federation.py#L1494-L1501) to return a response. Within the event context, the previous state IDs are populated [here](https://github.com/matrix-org/synapse/blob/d14c4d6b6d02e8c55a6647ce0f0b3b44356d6173/synapse/state/__init__.py#L351). --- .../definitions/send_join_response.yaml | 13 ++++++++----- .../server_server/newsfragments/2575.clarification | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 changelogs/server_server/newsfragments/2575.clarification diff --git a/api/server-server/definitions/send_join_response.yaml b/api/server-server/definitions/send_join_response.yaml index 96ceaefc..2837556b 100644 --- a/api/server-server/definitions/send_join_response.yaml +++ b/api/server-server/definitions/send_join_response.yaml @@ -22,9 +22,10 @@ properties: auth_chain: type: array description: |- - The auth chain. Note that events have a different format depending on - the room version - check the `room version specification`_ for precise - event formats. + The auth chain for the entire current room state prior to the join event. + + Note that events have a different format depending on the room version - check the + `room version specification`_ for precise event formats. items: type: object title: PDU @@ -39,8 +40,10 @@ properties: state: type: array description: |- - The room state. The event format varies depending on the room version - - check the `room version specification`_ for precise event formats. + The resolved current room state prior to the join event. + + The event format varies depending on the room version - check the `room version specification`_ + for precise event formats. items: type: object title: PDU diff --git a/changelogs/server_server/newsfragments/2575.clarification b/changelogs/server_server/newsfragments/2575.clarification new file mode 100644 index 00000000..5eb18394 --- /dev/null +++ b/changelogs/server_server/newsfragments/2575.clarification @@ -0,0 +1 @@ +Clarify the state/auth chain requirements for ``/send_join``. From e9998c53350442cc145dc7d05b7d77b18cd6abe7 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 May 2020 12:21:27 -0600 Subject: [PATCH 1107/1250] Clarify that server names are at least 1 character Fixes https://github.com/matrix-org/matrix-doc/issues/2460 --- specification/appendices/identifier_grammar.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/appendices/identifier_grammar.rst b/specification/appendices/identifier_grammar.rst index 4cce1f90..95c22fb1 100644 --- a/specification/appendices/identifier_grammar.rst +++ b/specification/appendices/identifier_grammar.rst @@ -45,7 +45,7 @@ following grammar:: IPv6char = DIGIT / %x41-46 / %x61-66 / ":" / "." ; 0-9, A-F, a-f, :, . - dns-name = *255dns-char + dns-name = 1*255dns-char dns-char = DIGIT / ALPHA / "-" / "." From 669377888ee6cf831f9ce0de2d1fa1b1457a1f90 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 25 May 2020 12:24:29 -0600 Subject: [PATCH 1108/1250] Fix more typos throughout the specification Fixes https://github.com/matrix-org/matrix-doc/issues/2193 --- api/server-server/keys_server.yaml | 2 +- changelogs/server_server/newsfragments/2577.clarification | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelogs/server_server/newsfragments/2577.clarification diff --git a/api/server-server/keys_server.yaml b/api/server-server/keys_server.yaml index 465bb294..81b98b1e 100644 --- a/api/server-server/keys_server.yaml +++ b/api/server-server/keys_server.yaml @@ -34,7 +34,7 @@ paths: Intermediate notary servers should cache a response for half of its lifetime to avoid serving a stale response. Originating servers should avoid returning responses that expire in less than an hour to avoid - repeated reqests for a certificate that is about to expire. Requesting + repeated requests for a certificate that is about to expire. Requesting servers should limit how frequently they query for certificates to avoid flooding a server with requests. diff --git a/changelogs/server_server/newsfragments/2577.clarification b/changelogs/server_server/newsfragments/2577.clarification new file mode 100644 index 00000000..902a9c3f --- /dev/null +++ b/changelogs/server_server/newsfragments/2577.clarification @@ -0,0 +1 @@ +Fix various spelling errors throughout the specification. From d4c19a0e808e39dbcc92a7af1193cbb1daae803f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 26 May 2020 12:36:18 -0600 Subject: [PATCH 1109/1250] Federation Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- specification/rooms/v6.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/rooms/v6.rst b/specification/rooms/v6.rst index b1acccd2..e5378d0e 100644 --- a/specification/rooms/v6.rst +++ b/specification/rooms/v6.rst @@ -95,6 +95,6 @@ Canonical JSON Servers MUST strictly enforce the JSON format specified in the `appendices <../appendices.html#canonical-json>`_. This translates to a 400 ``M_BAD_JSON`` error -on most endpoints, or discarding of events over federation. For example, the federation API's +on most endpoints, or discarding of events over federation. For example, the Federation API's ``/send`` endpoint would discard the event whereas the Client Server API's ``/send/{eventType}`` endpoint would return a ``M_BAD_JSON`` error. From bea6b321a59fb06d255bb2d02862613ca54fe732 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 26 May 2020 12:37:52 -0600 Subject: [PATCH 1110/1250] Change the nots order Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- api/client-server/directory.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client-server/directory.yaml b/api/client-server/directory.yaml index 67bdf236..7a08faf2 100644 --- a/api/client-server/directory.yaml +++ b/api/client-server/directory.yaml @@ -185,7 +185,7 @@ paths: membership. .. Note:: - Clients are not recommended to display this list of aliases prominently + Clients are recommended not to display this list of aliases prominently as they are not curated, unlike those listed in the ``m.room.canonical_alias`` state event. From a5cb9c655c083e38989215e6e405599def15f9f7 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 26 May 2020 12:38:40 -0600 Subject: [PATCH 1111/1250] It's important to say who Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- api/client-server/registration.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index a6d5d275..bab9139c 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -346,7 +346,7 @@ paths: logout_devices: type: boolean description: |- - Whether the other access tokens, and their associated devices, for the user should be + Whether the user's other access tokens, and their associated devices, should be revoked if the request succeeds. Defaults to true. When ``false``, the server can still take advantage of `the soft logout method <#soft-logout>`_ From 47c531adff5cea38dd4621a943257e6052a4997a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 26 May 2020 12:46:50 -0600 Subject: [PATCH 1112/1250] Clarify exactly which servers Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- specification/server_server_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index ca147665..3d591ca8 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -291,7 +291,7 @@ Step 1 sign JSON: } } -The server names in the JSON above are the server names involved. Delegation from +The server names in the JSON above are the server names for each homeserver involved. Delegation from the `server name resolution section <#resolving-server-names>`_ above do not affect these - the server names from before delegation would take place are used. This same condition applies throughout the request signing process. From 4b64d804374eea4d48185772a5599f9c0201dd8f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 26 May 2020 13:04:04 -0600 Subject: [PATCH 1113/1250] Remove v6 TODO To avoid the conflict, hopefully. --- specification/client_server_api.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index fda2c106..6060388b 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1820,8 +1820,6 @@ one of the following event types: - ``m.room.aliases`` allows key ``aliases``. - ``m.room.history_visibility`` allows key ``history_visibility``. -.. TODO: Room v6 changes how redaction works in MSC2432 (no special meaning for aliases) - The server should add the event causing the redaction to the ``unsigned`` property of the redacted event, under the ``redacted_because`` key. When a client receives a redaction event it should change the redacted event in the From 19a97c62e241347a3507d51c7bb617b6922aff5a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 27 May 2020 07:19:31 -0600 Subject: [PATCH 1114/1250] Client-Server r0.6.1 --- changelogs/client_server.rst | 37 +++++++++++++++++++ .../newsfragments/2245.clarification | 1 - .../newsfragments/2351.clarification | 1 - .../newsfragments/2369.clarification | 1 - .../newsfragments/2381.clarification | 1 - .../newsfragments/2415.clarification | 1 - .../newsfragments/2430.clarification | 1 - .../client_server/newsfragments/2434.feature | 1 - .../newsfragments/2453.clarification | 1 - .../newsfragments/2492.clarification | 1 - .../newsfragments/2519.clarification | 1 - .../client_server/newsfragments/2523.feature | 1 - .../newsfragments/2524.clarification | 1 - .../newsfragments/2525.clarification | 1 - .../client_server/newsfragments/2532.feature | 1 - .../client_server/newsfragments/2546.feature | 1 - .../newsfragments/2553.clarification | 1 - .../newsfragments/2554.clarification | 1 - .../client_server/newsfragments/2562.feature | 1 - .../client_server/newsfragments/2562.new | 1 - .../newsfragments/2563.clarification | 1 - .../newsfragments/2566.clarification | 1 - .../newsfragments/2569.clarification | 1 - .../newsfragments/2571.clarification | 1 - .../newsfragments/2574.clarification | 1 - specification/client_server_api.rst | 1 + 26 files changed, 38 insertions(+), 24 deletions(-) delete mode 100644 changelogs/client_server/newsfragments/2245.clarification delete mode 100644 changelogs/client_server/newsfragments/2351.clarification delete mode 100644 changelogs/client_server/newsfragments/2369.clarification delete mode 100644 changelogs/client_server/newsfragments/2381.clarification delete mode 100644 changelogs/client_server/newsfragments/2415.clarification delete mode 100644 changelogs/client_server/newsfragments/2430.clarification delete mode 100644 changelogs/client_server/newsfragments/2434.feature delete mode 100644 changelogs/client_server/newsfragments/2453.clarification delete mode 100644 changelogs/client_server/newsfragments/2492.clarification delete mode 100644 changelogs/client_server/newsfragments/2519.clarification delete mode 100644 changelogs/client_server/newsfragments/2523.feature delete mode 100644 changelogs/client_server/newsfragments/2524.clarification delete mode 100644 changelogs/client_server/newsfragments/2525.clarification delete mode 100644 changelogs/client_server/newsfragments/2532.feature delete mode 100644 changelogs/client_server/newsfragments/2546.feature delete mode 100644 changelogs/client_server/newsfragments/2553.clarification delete mode 100644 changelogs/client_server/newsfragments/2554.clarification delete mode 100644 changelogs/client_server/newsfragments/2562.feature delete mode 100644 changelogs/client_server/newsfragments/2562.new delete mode 100644 changelogs/client_server/newsfragments/2563.clarification delete mode 100644 changelogs/client_server/newsfragments/2566.clarification delete mode 100644 changelogs/client_server/newsfragments/2569.clarification delete mode 100644 changelogs/client_server/newsfragments/2571.clarification delete mode 100644 changelogs/client_server/newsfragments/2574.clarification diff --git a/changelogs/client_server.rst b/changelogs/client_server.rst index bc12da5c..6f8aee1c 100644 --- a/changelogs/client_server.rst +++ b/changelogs/client_server.rst @@ -1,3 +1,40 @@ +r0.6.1 +====== + +New Endpoints +------------- + +- Added ``/rooms/{roomId}/aliases`` for retrieving local aliases for a room. (`#2562 `_) + + +Backwards Compatible Changes +---------------------------- + +- Added data structures for defining moderation policies in rooms per `MSC2313 `_. (`#2434 `_) +- Optionally invalidate other access tokens during password modification per `MSC2457 `_. (`#2523 `_) +- Add User-Interactive Authentication for SSO-backed homeserver per `MSC2454 `_. (`#2532 `_) +- Add soft-logout support per `MSC1466 `_. (`#2546 `_) +- Replaced legacy room alias handling with a more sustainable solution per `MSC2432 `_. (`#2562 `_) + + +Spec Clarifications +------------------- + +- List available enum values for the room versions capability. (`#2245 `_) +- Fix various spelling errors throughout the specification. (`#2351 `_, `#2415 `_, `#2453 `_, `#2524 `_, `#2553 `_, `#2569 `_) +- Minor clarifications to token-based User-Interactive Authentication. (`#2369 `_) +- Minor clarification for what the user directory searches. (`#2381 `_) +- Fix key export format example to match the specification. (`#2430 `_) +- Clarify the IV data type for encrypted files. (`#2492 `_) +- Fix the ``.m.rule.contains_user_name`` default push rule to set the highlight tweak. (`#2519 `_) +- Clarify that an ``event_id`` is returned when sending events. (`#2525 `_) +- Fix some numbers in the specification to match their explanation text. (`#2554 `_) +- Move redaction algorithm into the room version specifications. (`#2563 `_) +- Clarify signature object structures for encryption. (`#2566 `_) +- Clarify which events are created as part of ``/createRoom``. (`#2571 `_) +- Remove claims that the homeserver is exclusively responsible for profile information in membership events. (`#2574 `_) + + r0.6.0 ====== diff --git a/changelogs/client_server/newsfragments/2245.clarification b/changelogs/client_server/newsfragments/2245.clarification deleted file mode 100644 index 31e5c2df..00000000 --- a/changelogs/client_server/newsfragments/2245.clarification +++ /dev/null @@ -1 +0,0 @@ -List available enum values for the room versions capability. diff --git a/changelogs/client_server/newsfragments/2351.clarification b/changelogs/client_server/newsfragments/2351.clarification deleted file mode 100644 index 902a9c3f..00000000 --- a/changelogs/client_server/newsfragments/2351.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling errors throughout the specification. diff --git a/changelogs/client_server/newsfragments/2369.clarification b/changelogs/client_server/newsfragments/2369.clarification deleted file mode 100644 index c7fd0fd9..00000000 --- a/changelogs/client_server/newsfragments/2369.clarification +++ /dev/null @@ -1 +0,0 @@ -Minor clarifications to token-based User-Interactive Authentication. diff --git a/changelogs/client_server/newsfragments/2381.clarification b/changelogs/client_server/newsfragments/2381.clarification deleted file mode 100644 index 70bd6d18..00000000 --- a/changelogs/client_server/newsfragments/2381.clarification +++ /dev/null @@ -1 +0,0 @@ -Minor clarification for what the user directory searches. diff --git a/changelogs/client_server/newsfragments/2415.clarification b/changelogs/client_server/newsfragments/2415.clarification deleted file mode 100644 index 902a9c3f..00000000 --- a/changelogs/client_server/newsfragments/2415.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling errors throughout the specification. diff --git a/changelogs/client_server/newsfragments/2430.clarification b/changelogs/client_server/newsfragments/2430.clarification deleted file mode 100644 index 56be0c1a..00000000 --- a/changelogs/client_server/newsfragments/2430.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix key export format example to match the specification. diff --git a/changelogs/client_server/newsfragments/2434.feature b/changelogs/client_server/newsfragments/2434.feature deleted file mode 100644 index 2b8f36f5..00000000 --- a/changelogs/client_server/newsfragments/2434.feature +++ /dev/null @@ -1 +0,0 @@ -Added data structures for defining moderation policies in rooms per `MSC2313 `_. diff --git a/changelogs/client_server/newsfragments/2453.clarification b/changelogs/client_server/newsfragments/2453.clarification deleted file mode 100644 index 902a9c3f..00000000 --- a/changelogs/client_server/newsfragments/2453.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling errors throughout the specification. diff --git a/changelogs/client_server/newsfragments/2492.clarification b/changelogs/client_server/newsfragments/2492.clarification deleted file mode 100644 index 88c478ec..00000000 --- a/changelogs/client_server/newsfragments/2492.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify the IV data type for encrypted files. diff --git a/changelogs/client_server/newsfragments/2519.clarification b/changelogs/client_server/newsfragments/2519.clarification deleted file mode 100644 index 4b32da1e..00000000 --- a/changelogs/client_server/newsfragments/2519.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix the ``.m.rule.contains_user_name`` default push rule to set the highlight tweak. diff --git a/changelogs/client_server/newsfragments/2523.feature b/changelogs/client_server/newsfragments/2523.feature deleted file mode 100644 index e45d1c2f..00000000 --- a/changelogs/client_server/newsfragments/2523.feature +++ /dev/null @@ -1 +0,0 @@ -Optionally invalidate other access tokens during password modification per `MSC2457 `_. diff --git a/changelogs/client_server/newsfragments/2524.clarification b/changelogs/client_server/newsfragments/2524.clarification deleted file mode 100644 index 902a9c3f..00000000 --- a/changelogs/client_server/newsfragments/2524.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling errors throughout the specification. diff --git a/changelogs/client_server/newsfragments/2525.clarification b/changelogs/client_server/newsfragments/2525.clarification deleted file mode 100644 index df1fc538..00000000 --- a/changelogs/client_server/newsfragments/2525.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify that an ``event_id`` is returned when sending events. diff --git a/changelogs/client_server/newsfragments/2532.feature b/changelogs/client_server/newsfragments/2532.feature deleted file mode 100644 index cf74a289..00000000 --- a/changelogs/client_server/newsfragments/2532.feature +++ /dev/null @@ -1 +0,0 @@ -Add User-Interactive Authentication for SSO-backed homeserver per `MSC2454 `_. diff --git a/changelogs/client_server/newsfragments/2546.feature b/changelogs/client_server/newsfragments/2546.feature deleted file mode 100644 index 40c066f4..00000000 --- a/changelogs/client_server/newsfragments/2546.feature +++ /dev/null @@ -1 +0,0 @@ -Add soft-logout support per `MSC1466 `_. diff --git a/changelogs/client_server/newsfragments/2553.clarification b/changelogs/client_server/newsfragments/2553.clarification deleted file mode 100644 index 902a9c3f..00000000 --- a/changelogs/client_server/newsfragments/2553.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling errors throughout the specification. diff --git a/changelogs/client_server/newsfragments/2554.clarification b/changelogs/client_server/newsfragments/2554.clarification deleted file mode 100644 index 826fafd8..00000000 --- a/changelogs/client_server/newsfragments/2554.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix some numbers in the specification to match their explanation text. diff --git a/changelogs/client_server/newsfragments/2562.feature b/changelogs/client_server/newsfragments/2562.feature deleted file mode 100644 index 556018da..00000000 --- a/changelogs/client_server/newsfragments/2562.feature +++ /dev/null @@ -1 +0,0 @@ -Replaced legacy room alias handling with a more sustainable solution per `MSC2432 `_. diff --git a/changelogs/client_server/newsfragments/2562.new b/changelogs/client_server/newsfragments/2562.new deleted file mode 100644 index c7b3e4ca..00000000 --- a/changelogs/client_server/newsfragments/2562.new +++ /dev/null @@ -1 +0,0 @@ -Added ``/rooms/{roomId}/aliases`` for retrieving local aliases for a room. diff --git a/changelogs/client_server/newsfragments/2563.clarification b/changelogs/client_server/newsfragments/2563.clarification deleted file mode 100644 index a8805f4a..00000000 --- a/changelogs/client_server/newsfragments/2563.clarification +++ /dev/null @@ -1 +0,0 @@ -Move redaction algorithm into the room version specifications. diff --git a/changelogs/client_server/newsfragments/2566.clarification b/changelogs/client_server/newsfragments/2566.clarification deleted file mode 100644 index 15e29b2f..00000000 --- a/changelogs/client_server/newsfragments/2566.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify signature object structures for encryption. diff --git a/changelogs/client_server/newsfragments/2569.clarification b/changelogs/client_server/newsfragments/2569.clarification deleted file mode 100644 index 902a9c3f..00000000 --- a/changelogs/client_server/newsfragments/2569.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling errors throughout the specification. diff --git a/changelogs/client_server/newsfragments/2571.clarification b/changelogs/client_server/newsfragments/2571.clarification deleted file mode 100644 index e9437f3c..00000000 --- a/changelogs/client_server/newsfragments/2571.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify which events are created as part of ``/createRoom``. diff --git a/changelogs/client_server/newsfragments/2574.clarification b/changelogs/client_server/newsfragments/2574.clarification deleted file mode 100644 index d771d374..00000000 --- a/changelogs/client_server/newsfragments/2574.clarification +++ /dev/null @@ -1 +0,0 @@ -Remove claims that the homeserver is exclusively responsible for profile information in membership events. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index ad8539cb..574999be 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -45,6 +45,7 @@ Other versions of this specification The following other versions are also available, in reverse chronological order: - `HEAD `_: Includes all changes since the latest versioned release. +- `r0.6.1 `_ - `r0.6.0 `_ - `r0.5.0 `_ - `r0.4.0 `_ From 09986af8fc2ccda4a4bbbfec3c0651663da2f84d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 27 May 2020 07:21:59 -0600 Subject: [PATCH 1115/1250] Server-Server r0.1.4 Includes a link to r0.1.3 because we forgot --- changelogs/server_server.rst | 31 +++++++++++++++++++ .../server_server/newsfragments/2035.new | 1 - .../newsfragments/2392.clarification | 1 - .../server_server/newsfragments/2470.removal | 1 - .../newsfragments/2510.clarification | 1 - .../newsfragments/2527.clarification | 1 - .../newsfragments/2538.clarification | 1 - .../server_server/newsfragments/2547.new | 1 - .../newsfragments/2559.clarification | 1 - .../newsfragments/2560.clarification | 1 - .../newsfragments/2566.clarification | 1 - .../newsfragments/2570.clarification | 1 - .../newsfragments/2575.clarification | 1 - .../newsfragments/2577.clarification | 1 - specification/server_server_api.rst | 2 ++ 15 files changed, 33 insertions(+), 13 deletions(-) delete mode 100644 changelogs/server_server/newsfragments/2035.new delete mode 100644 changelogs/server_server/newsfragments/2392.clarification delete mode 100644 changelogs/server_server/newsfragments/2470.removal delete mode 100644 changelogs/server_server/newsfragments/2510.clarification delete mode 100644 changelogs/server_server/newsfragments/2527.clarification delete mode 100644 changelogs/server_server/newsfragments/2538.clarification delete mode 100644 changelogs/server_server/newsfragments/2547.new delete mode 100644 changelogs/server_server/newsfragments/2559.clarification delete mode 100644 changelogs/server_server/newsfragments/2560.clarification delete mode 100644 changelogs/server_server/newsfragments/2566.clarification delete mode 100644 changelogs/server_server/newsfragments/2570.clarification delete mode 100644 changelogs/server_server/newsfragments/2575.clarification delete mode 100644 changelogs/server_server/newsfragments/2577.clarification diff --git a/changelogs/server_server.rst b/changelogs/server_server.rst index 22da543c..ee4a3c1c 100644 --- a/changelogs/server_server.rst +++ b/changelogs/server_server.rst @@ -1,3 +1,34 @@ +r0.1.4 +====== + +New Endpoints +------------- + +- Add new ``POST /publicRooms`` endpoint for filtering the room directory. (`#2035 `_) +- Add new v2 ``/send_join`` and ``/send_leave`` endpoints per `MSC1802 `_. (`#2547 `_) + + +Removed Endpoints +----------------- + +- Remove the unused ``query_auth`` API per `MSC2451 `_. (`#2470 `_) + + +Spec Clarifications +------------------- + +- Move auth event selection to a more obvious location. (`#2392 `_) +- Fix typo in Request Authentication python example. (`#2510 `_) +- Clarify which fields are required on the key server endpoints. (`#2527 `_) +- Clarify the limits of ``prev_events`` and ``auth_events`` for PDUs. (`#2538 `_) +- Clarify which events are targeted by backfill. (`#2559 `_) +- Fix the response format of the ``/send`` endpoint. (`#2560 `_) +- Clarify signature object structures for encryption. (`#2566 `_) +- Clarify the server names to use when signing requests. (`#2570 `_) +- Clarify the state/auth chain requirements for ``/send_join``. (`#2575 `_) +- Fix various spelling errors throughout the specification. (`#2577 `_) + + r0.1.3 ====== diff --git a/changelogs/server_server/newsfragments/2035.new b/changelogs/server_server/newsfragments/2035.new deleted file mode 100644 index 6794c4ea..00000000 --- a/changelogs/server_server/newsfragments/2035.new +++ /dev/null @@ -1 +0,0 @@ -Add new ``POST /publicRooms`` endpoint for filtering the room directory. diff --git a/changelogs/server_server/newsfragments/2392.clarification b/changelogs/server_server/newsfragments/2392.clarification deleted file mode 100644 index b09420e4..00000000 --- a/changelogs/server_server/newsfragments/2392.clarification +++ /dev/null @@ -1 +0,0 @@ -Move auth event selection to a more obvious location. diff --git a/changelogs/server_server/newsfragments/2470.removal b/changelogs/server_server/newsfragments/2470.removal deleted file mode 100644 index 51cdadd4..00000000 --- a/changelogs/server_server/newsfragments/2470.removal +++ /dev/null @@ -1 +0,0 @@ -Remove the unused ``query_auth`` API per `MSC2451 `_. diff --git a/changelogs/server_server/newsfragments/2510.clarification b/changelogs/server_server/newsfragments/2510.clarification deleted file mode 100644 index 9c96c5a5..00000000 --- a/changelogs/server_server/newsfragments/2510.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix typo in Request Authentication python example. diff --git a/changelogs/server_server/newsfragments/2527.clarification b/changelogs/server_server/newsfragments/2527.clarification deleted file mode 100644 index 329d5da2..00000000 --- a/changelogs/server_server/newsfragments/2527.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify which fields are required on the key server endpoints. diff --git a/changelogs/server_server/newsfragments/2538.clarification b/changelogs/server_server/newsfragments/2538.clarification deleted file mode 100644 index 4b709a8d..00000000 --- a/changelogs/server_server/newsfragments/2538.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify the limits of ``prev_events`` and ``auth_events`` for PDUs. diff --git a/changelogs/server_server/newsfragments/2547.new b/changelogs/server_server/newsfragments/2547.new deleted file mode 100644 index c558fb5b..00000000 --- a/changelogs/server_server/newsfragments/2547.new +++ /dev/null @@ -1 +0,0 @@ -Add new v2 ``/send_join`` and ``/send_leave`` endpoints per `MSC1802 `_. diff --git a/changelogs/server_server/newsfragments/2559.clarification b/changelogs/server_server/newsfragments/2559.clarification deleted file mode 100644 index cdb9cfe0..00000000 --- a/changelogs/server_server/newsfragments/2559.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify which events are targeted by backfill. diff --git a/changelogs/server_server/newsfragments/2560.clarification b/changelogs/server_server/newsfragments/2560.clarification deleted file mode 100644 index c60bc6f3..00000000 --- a/changelogs/server_server/newsfragments/2560.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix the response format of the ``/send`` endpoint. diff --git a/changelogs/server_server/newsfragments/2566.clarification b/changelogs/server_server/newsfragments/2566.clarification deleted file mode 100644 index 15e29b2f..00000000 --- a/changelogs/server_server/newsfragments/2566.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify signature object structures for encryption. diff --git a/changelogs/server_server/newsfragments/2570.clarification b/changelogs/server_server/newsfragments/2570.clarification deleted file mode 100644 index 3fac40bf..00000000 --- a/changelogs/server_server/newsfragments/2570.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify the server names to use when signing requests. diff --git a/changelogs/server_server/newsfragments/2575.clarification b/changelogs/server_server/newsfragments/2575.clarification deleted file mode 100644 index 5eb18394..00000000 --- a/changelogs/server_server/newsfragments/2575.clarification +++ /dev/null @@ -1 +0,0 @@ -Clarify the state/auth chain requirements for ``/send_join``. diff --git a/changelogs/server_server/newsfragments/2577.clarification b/changelogs/server_server/newsfragments/2577.clarification deleted file mode 100644 index 902a9c3f..00000000 --- a/changelogs/server_server/newsfragments/2577.clarification +++ /dev/null @@ -1 +0,0 @@ -Fix various spelling errors throughout the specification. diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 61d4375d..9deb267c 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -80,6 +80,8 @@ Other versions of this specification The following other versions are also available, in reverse chronological order: - `HEAD `_: Includes all changes since the latest versioned release. +- `r0.1.4 `_ +- `r0.1.3 `_ - `r0.1.2 `_ - `r0.1.1 `_ - `r0.1.0 `_ From 6cfb94562e1fcc99c2837d1ef2a1f5eac904b82e Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Mon, 25 May 2020 20:40:00 +0200 Subject: [PATCH 1116/1250] c2s: clean up $ref objects * Most of the changes: align to the $ref object definition (https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03#section-3) that says that any attribute other than $ref be ignored. * Remove extraneous leading ./ in $ref paths * Fix an apparent typo in registration.yaml: /account/password/msisdn/requestToken used a file from ../identity/* instead of its c2s namesake. --- api/client-server/administrative_contact.yaml | 13 ++++---- api/client-server/device_management.yaml | 12 ++++--- api/client-server/login.yaml | 16 ++++----- api/client-server/registration.yaml | 33 ++++++++++--------- api/client-server/search.yaml | 3 +- api/client-server/wellknown.yaml | 1 - 6 files changed, 42 insertions(+), 36 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index cebfb274..72565b68 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -201,10 +201,11 @@ paths: type: object properties: auth: - description: |- - Additional authentication information for the - user-interactive authentication API. - $ref: "definitions/auth_data.yaml" + allOf: + - description: |- + Additional authentication information for the + user-interactive authentication API. + - $ref: "definitions/auth_data.yaml" client_secret: type: string description: The client secret used in the session with the homeserver. @@ -432,7 +433,7 @@ paths: name: body required: true schema: - $ref: "./definitions/request_email_validation.yaml" + $ref: "definitions/request_email_validation.yaml" responses: 200: description: |- @@ -482,7 +483,7 @@ paths: name: body required: true schema: - $ref: "./definitions/request_msisdn_validation.yaml" + $ref: "definitions/request_msisdn_validation.yaml" responses: 200: description: An SMS message was sent to the given phone number. diff --git a/api/client-server/device_management.yaml b/api/client-server/device_management.yaml index 8039d71f..094084bf 100644 --- a/api/client-server/device_management.yaml +++ b/api/client-server/device_management.yaml @@ -83,7 +83,7 @@ paths: schema: type: object allOf: - - $ref: "definitions/client_device.yaml" + - $ref: "definitions/client_device.yaml" examples: application/json: { "device_id": "QBUAZIFURK", @@ -158,9 +158,10 @@ paths: properties: auth: description: |- - Additional authentication information for the - user-interactive authentication API. - "$ref": "definitions/auth_data.yaml" + Additional authentication information for the + user-interactive authentication API. + allOf: + - "$ref": "definitions/auth_data.yaml" responses: 200: description: |- @@ -203,10 +204,11 @@ paths: description: A list of device IDs. example: ["QBUAZIFURK", "AUIECTSRND"] auth: + allOf: + - "$ref": "definitions/auth_data.yaml" description: |- Additional authentication information for the user-interactive authentication API. - "$ref": "definitions/auth_data.yaml" required: - devices responses: diff --git a/api/client-server/login.yaml b/api/client-server/login.yaml index fac9361c..d37d135d 100644 --- a/api/client-server/login.yaml +++ b/api/client-server/login.yaml @@ -100,7 +100,6 @@ paths: enum: ["m.login.password", "m.login.token"] description: The login type being used. identifier: - description: Identification information for the user. "$ref": "definitions/user_identifier.yaml" user: type: string @@ -176,13 +175,14 @@ paths: ID of the logged-in device. Will be the same as the corresponding parameter in the request, if one was specified. well_known: - type: object - description: |- - Optional client configuration provided by the server. If present, - clients SHOULD use the provided object to reconfigure themselves, - optionally validating the URLs within. This object takes the same - form as the one returned from .well-known autodiscovery. - "$ref": "definitions/wellknown/full.yaml" + allOf: + - type: object + description: |- + Optional client configuration provided by the server. If present, + clients SHOULD use the provided object to reconfigure themselves, + optionally validating the URLs within. This object takes the same + form as the one returned from .well-known autodiscovery. + - "$ref": "definitions/wellknown/full.yaml" 400: description: |- Part of the request was invalid. For example, the login type may not be recognised. diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index f57bd88c..cf1a2f23 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -89,13 +89,14 @@ paths: type: object properties: auth: - description: |- - Additional authentication information for the - user-interactive authentication API. Note that this - information is *not* used to define how the registered user - should be authenticated, but is instead used to - authenticate the ``register`` call itself. - "$ref": "definitions/auth_data.yaml" + allOf: + - description: |- + Additional authentication information for the + user-interactive authentication API. Note that this + information is *not* used to define how the registered user + should be authenticated, but is instead used to + authenticate the ``register`` call itself. + - "$ref": "definitions/auth_data.yaml" username: type: string description: |- @@ -228,7 +229,7 @@ paths: name: body required: true schema: - $ref: "./definitions/request_email_validation.yaml" + $ref: "definitions/request_email_validation.yaml" responses: 200: description: |- @@ -278,7 +279,7 @@ paths: name: body required: true schema: - $ref: "./definitions/request_msisdn_validation.yaml" + $ref: "definitions/request_msisdn_validation.yaml" responses: 200: description: |- @@ -346,9 +347,10 @@ paths: description: The new password for the account. example: "ihatebananas" auth: - description: |- - Additional authentication information for the user-interactive authentication API. - "$ref": "definitions/auth_data.yaml" + allOf: + - description: |- + Additional authentication information for the user-interactive authentication API. + - "$ref": "definitions/auth_data.yaml" required: ["new_password"] responses: 200: @@ -397,7 +399,7 @@ paths: name: body required: true schema: - $ref: "./definitions/request_email_validation.yaml" + $ref: "definitions/request_email_validation.yaml" responses: 200: description: An email was sent to the given address. @@ -455,7 +457,7 @@ paths: name: body required: true schema: - $ref: "../identity/definitions/request_msisdn_validation.yaml" + $ref: "definitions/request_msisdn_validation.yaml" responses: 200: description: An SMS message was sent to the given phone number. @@ -516,7 +518,8 @@ paths: auth: description: |- Additional authentication information for the user-interactive authentication API. - "$ref": "definitions/auth_data.yaml" + allOf: + - $ref: "definitions/auth_data.yaml" id_server: type: string description: |- diff --git a/api/client-server/search.yaml b/api/client-server/search.yaml index 2d30ebef..27e06727 100644 --- a/api/client-server/search.yaml +++ b/api/client-server/search.yaml @@ -96,7 +96,8 @@ paths: # for now :/ description: |- This takes a `filter`_. - $ref: "definitions/room_event_filter.yaml" + allOf: + - $ref: "definitions/room_event_filter.yaml" order_by: title: "Ordering" type: string diff --git a/api/client-server/wellknown.yaml b/api/client-server/wellknown.yaml index b63bd041..3d1c0ae0 100644 --- a/api/client-server/wellknown.yaml +++ b/api/client-server/wellknown.yaml @@ -39,7 +39,6 @@ paths: 200: description: Server discovery information. schema: - type: object "$ref": "definitions/wellknown/full.yaml" 404: description: No server discovery information available. From 67a8176903e8361310c32a7b0559f3adc504012d Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Thu, 28 May 2020 13:54:36 +0200 Subject: [PATCH 1117/1250] Clarify officially that we use multiple API files This is not something endorsed by the OpenAPI spec, just our practice. --- api/openapi_extensions.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/api/openapi_extensions.md b/api/openapi_extensions.md index 339452ba..c614793d 100644 --- a/api/openapi_extensions.md +++ b/api/openapi_extensions.md @@ -6,6 +6,19 @@ across the specification. The defined extensions are listed below. Extensions should not break parsers, however if extra functionality is required, aware parsers should be able to take advantage of the added syntax. +## Using multiple files to describe API + +To ease API design and management, the API definition is split across several +files. Each of these files is self-contained valid OpenAPI (except +client-server files that become valid OpenAPI after substituting +`%CLIENT_MAJOR_VERSION%` with `unstable` or an API release). + +There is no single root file in the source tree as OpenAPI requires; this file +can be generated by `dump_swagger.py` (also doing the substitution mentioned +above). The script does not convert the extensions described further in this +document (`oneOf` and parameter exploding) so there can be minor +interoperability issues with tooling that expects compliant Swagger. + ## Extensible Query Parameters From b789f3e10b4f4b5e162c705af222bb740f881b5b Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Thu, 28 May 2020 13:56:29 +0200 Subject: [PATCH 1118/1250] dump-swagger.py: fix a typo in the help string --- scripts/dump-swagger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dump-swagger.py b/scripts/dump-swagger.py index 0b9f8486..232ca8ad 100755 --- a/scripts/dump-swagger.py +++ b/scripts/dump-swagger.py @@ -43,7 +43,7 @@ parser = argparse.ArgumentParser( parser.add_argument( "--client_release", "-c", metavar="LABEL", default="unstable", - help="""The client-server release version to gneerate for. Default: + help="""The client-server release version to generate for. Default: %(default)s""", ) parser.add_argument( From f299f60e1777183270f3bccae2f6e213fe64179f Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sat, 29 Sep 2018 15:59:55 +0900 Subject: [PATCH 1119/1250] Use public_rooms_response.yaml instead of replicating the same definition Signed-off-by: Alexey Rusakov --- api/client-server/list_public_rooms.yaml | 93 +----------------------- 1 file changed, 1 insertion(+), 92 deletions(-) diff --git a/api/client-server/list_public_rooms.yaml b/api/client-server/list_public_rooms.yaml index 43239b5c..222b412a 100644 --- a/api/client-server/list_public_rooms.yaml +++ b/api/client-server/list_public_rooms.yaml @@ -218,97 +218,6 @@ paths: 200: description: A list of the rooms on the server. schema: - type: object - description: A list of the rooms on the server. - required: ["chunk"] - properties: - chunk: - title: "PublicRoomsChunks" - type: array - description: |- - A paginated chunk of public rooms. - items: - type: object - title: "PublicRoomsChunk" - required: - - room_id - - num_joined_members - - world_readable - - guest_can_join - properties: - aliases: - type: array - description: |- - Aliases of the room. May be empty. - items: - type: string - canonical_alias: - type: string - description: |- - The canonical alias of the room, if any. - name: - type: string - description: |- - The name of the room, if any. - num_joined_members: - type: integer - description: |- - The number of members joined to the room. - room_id: - type: string - description: |- - The ID of the room. - topic: - type: string - description: |- - The topic of the room, if any. - world_readable: - type: boolean - description: |- - Whether the room may be viewed by guest users without joining. - guest_can_join: - type: boolean - description: |- - Whether guest users may join the room and participate in it. - If they can, they will be subject to ordinary power level - rules like any other user. - avatar_url: - type: string - description: The URL for the room's avatar, if one is set. - next_batch: - type: string - description: |- - A pagination token for the response. The absence of this token - means there are no more results to fetch and the client should - stop paginating. - prev_batch: - type: string - description: |- - A pagination token that allows fetching previous results. The - absence of this token means there are no results before this - batch, i.e. this is the first batch. - total_room_count_estimate: - type: integer - description: |- - An estimate on the total number of public rooms, if the - server has an estimate. - examples: - application/json: { - "chunk": [ - { - "aliases": ["#murrays:cheese.bar"], - "avatar_url": "mxc://bleeker.street/CHEDDARandBRIE", - "guest_can_join": false, - "name": "CHEESE", - "num_joined_members": 37, - "room_id": "!ol19s:bleecker.street", - "topic": "Tasty tasty cheese", - "world_readable": true - } - ], - "next_batch": "p190q", - "prev_batch": "p1902", - "total_room_count_estimate": 115 - } + $ref: "definitions/public_rooms_response.yaml" tags: - Room discovery From 040a91f42d724b157e49407d19f5f30e21a01865 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Thu, 28 May 2020 14:11:47 +0200 Subject: [PATCH 1120/1250] api/: More cleanup in descriptions (and a fix in one example). --- api/application-service/transactions.yaml | 3 +-- api/client-server/device_management.yaml | 6 +++--- api/client-server/kicking.yaml | 3 ++- api/client-server/presence.yaml | 2 +- api/client-server/profile.yaml | 4 ++-- api/client-server/room_upgrades.yaml | 1 - api/server-server/public_rooms.yaml | 2 +- 7 files changed, 10 insertions(+), 11 deletions(-) diff --git a/api/application-service/transactions.yaml b/api/application-service/transactions.yaml index 09f15276..a557325c 100644 --- a/api/application-service/transactions.yaml +++ b/api/application-service/transactions.yaml @@ -50,7 +50,7 @@ paths: x-example: "35" - in: body name: body - description: A list of events. + description: Transaction information schema: type: object example: { @@ -59,7 +59,6 @@ paths: {"$ref": "../../event-schemas/examples/m.room.message$m.text"} ] } - description: Transaction information properties: events: type: array diff --git a/api/client-server/device_management.yaml b/api/client-server/device_management.yaml index 094084bf..c42ebbd7 100644 --- a/api/client-server/device_management.yaml +++ b/api/client-server/device_management.yaml @@ -119,9 +119,9 @@ paths: display_name: type: string description: |- - The new display name for this device. If not given, the - display name is unchanged. - example: My other phone + The new display name for this device. If not given, the + display name is unchanged. + example: { "display_name": "My other phone" } responses: 200: description: The device was successfully updated. diff --git a/api/client-server/kicking.yaml b/api/client-server/kicking.yaml index 7fbee38b..fd3f1698 100644 --- a/api/client-server/kicking.yaml +++ b/api/client-server/kicking.yaml @@ -77,7 +77,8 @@ paths: type: object 403: description: |- - You do not have permission to kick the user from the room. A meaningful ``errcode`` and description error text will be returned. Example reasons for rejections are: + You do not have permission to kick the user from the room. A meaningful ``errcode`` and + description error text will be returned. Example reasons for rejections are: - The kicker is not currently in the room. - The kickee is not currently in the room. diff --git a/api/client-server/presence.yaml b/api/client-server/presence.yaml index 874ac59b..b3a8bb02 100644 --- a/api/client-server/presence.yaml +++ b/api/client-server/presence.yaml @@ -62,7 +62,7 @@ paths: description: The new presence state. status_msg: type: string - description: "The status message to attach to this state." + description: The status message to attach to this state. required: ["presence"] responses: 200: diff --git a/api/client-server/profile.yaml b/api/client-server/profile.yaml index c8dc4056..db998e6c 100644 --- a/api/client-server/profile.yaml +++ b/api/client-server/profile.yaml @@ -45,7 +45,7 @@ paths: x-example: "@alice:example.com" - in: body name: displayName - description: The display name info. + description: The new display name information. required: true schema: type: object @@ -119,7 +119,7 @@ paths: x-example: "@alice:example.com" - in: body name: avatar_url - description: The avatar url info. + description: The new avatar information. required: true schema: type: object diff --git a/api/client-server/room_upgrades.yaml b/api/client-server/room_upgrades.yaml index 3aaaadcb..97ef611e 100644 --- a/api/client-server/room_upgrades.yaml +++ b/api/client-server/room_upgrades.yaml @@ -45,7 +45,6 @@ paths: - in: body name: body required: true - description: The request body schema: type: object properties: diff --git a/api/server-server/public_rooms.yaml b/api/server-server/public_rooms.yaml index 0216f0c3..5324eac3 100644 --- a/api/server-server/public_rooms.yaml +++ b/api/server-server/public_rooms.yaml @@ -86,7 +86,7 @@ paths: name: body required: true description: |- - Options for which rooms to return. + Options for which rooms to return, or empty object to use defaults. schema: type: object properties: From 48af2e5b47c2dcf6d4ffdcfd9e90e66de7e64990 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Thu, 28 May 2020 14:17:01 +0200 Subject: [PATCH 1121/1250] joining.yaml: put descriptions next to their properties Fixing the problem described in https://github.com/matrix-org/matrix-doc/pull/2518#issuecomment-621684187 --- api/client-server/joining.yaml | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/api/client-server/joining.yaml b/api/client-server/joining.yaml index c5781806..5f14f528 100644 --- a/api/client-server/joining.yaml +++ b/api/client-server/joining.yaml @@ -54,15 +54,16 @@ paths: - in: body name: third_party_signed required: true - description: |- - If supplied, the homeserver must verify that it matches a pending - ``m.room.third_party_invite`` event in the room, and perform - key validity checking if required by the event. schema: type: object properties: third_party_signed: - $ref: "definitions/third_party_signed.yaml" + allOf: + - $ref: "definitions/third_party_signed.yaml" + description: |- + If supplied, the homeserver must verify that it matches a pending + ``m.room.third_party_invite`` event in the room, and perform + key validity checking if required by the event. responses: 200: description: |- @@ -110,10 +111,6 @@ paths: After a user has joined a room, the room will appear as an entry in the response of the |/initialSync|_ and |/sync|_ APIs. - - If a ``third_party_signed`` was supplied, the homeserver must verify - that it matches a pending ``m.room.third_party_invite`` event in the - room, and perform key validity checking if required by the event. operationId: joinRoom security: - accessToken: [] @@ -140,7 +137,12 @@ paths: type: object properties: third_party_signed: - $ref: "definitions/third_party_signed.yaml" + allOf: + - $ref: "definitions/third_party_signed.yaml" + description: |- + If a ``third_party_signed`` was supplied, the homeserver must verify + that it matches a pending ``m.room.third_party_invite`` event in the + room, and perform key validity checking if required by the event. responses: 200: description: |- From 3b5340539dd25c2190593f7bceea37b351111824 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Thu, 28 May 2020 14:40:29 +0200 Subject: [PATCH 1122/1250] c2s: Make allOf and description siblings throughout the PR The overall mess with allOf will be addressed separately; this PR just puts $ref under allOf to fix the glaring misuse of $ref objects. --- api/client-server/administrative_contact.yaml | 6 +++--- api/client-server/login.yaml | 11 +++++------ api/client-server/registration.yaml | 8 ++++---- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 72565b68..f8cdf5a0 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -201,10 +201,10 @@ paths: type: object properties: auth: + description: |- + Additional authentication information for the + user-interactive authentication API. allOf: - - description: |- - Additional authentication information for the - user-interactive authentication API. - $ref: "definitions/auth_data.yaml" client_secret: type: string diff --git a/api/client-server/login.yaml b/api/client-server/login.yaml index d37d135d..a959b312 100644 --- a/api/client-server/login.yaml +++ b/api/client-server/login.yaml @@ -175,13 +175,12 @@ paths: ID of the logged-in device. Will be the same as the corresponding parameter in the request, if one was specified. well_known: + description: |- + Optional client configuration provided by the server. If present, + clients SHOULD use the provided object to reconfigure themselves, + optionally validating the URLs within. This object takes the same + form as the one returned from .well-known autodiscovery. allOf: - - type: object - description: |- - Optional client configuration provided by the server. If present, - clients SHOULD use the provided object to reconfigure themselves, - optionally validating the URLs within. This object takes the same - form as the one returned from .well-known autodiscovery. - "$ref": "definitions/wellknown/full.yaml" 400: description: |- diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index cf1a2f23..c535bb99 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -89,13 +89,13 @@ paths: type: object properties: auth: - allOf: - - description: |- + description: |- Additional authentication information for the user-interactive authentication API. Note that this information is *not* used to define how the registered user should be authenticated, but is instead used to authenticate the ``register`` call itself. + allOf: - "$ref": "definitions/auth_data.yaml" username: type: string @@ -347,9 +347,9 @@ paths: description: The new password for the account. example: "ihatebananas" auth: - allOf: - - description: |- + description: |- Additional authentication information for the user-interactive authentication API. + allOf: - "$ref": "definitions/auth_data.yaml" required: ["new_password"] responses: From 3fc5540755b21ff36499e74137cd31f1b9413e63 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 29 May 2020 07:00:38 -0600 Subject: [PATCH 1123/1250] Fix r0.1.4 changelog reference --- changelogs/server_server.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/server_server.rst b/changelogs/server_server.rst index ee4a3c1c..367fb092 100644 --- a/changelogs/server_server.rst +++ b/changelogs/server_server.rst @@ -4,7 +4,7 @@ r0.1.4 New Endpoints ------------- -- Add new ``POST /publicRooms`` endpoint for filtering the room directory. (`#2035 `_) +- Add new ``POST /publicRooms`` endpoint for filtering the room directory. (`#2305 `_) - Add new v2 ``/send_join`` and ``/send_leave`` endpoints per `MSC1802 `_. (`#2547 `_) From ffea5d5e610f429b558e07df3f3d00f1b74a9aeb Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 31 May 2020 21:36:47 -0600 Subject: [PATCH 1124/1250] Document top-level UnsignedData objects --- scripts/templating/matrix_templates/units.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/templating/matrix_templates/units.py b/scripts/templating/matrix_templates/units.py index 5a7ff94e..ff614e34 100644 --- a/scripts/templating/matrix_templates/units.py +++ b/scripts/templating/matrix_templates/units.py @@ -910,6 +910,13 @@ class MatrixUnits(Units): Units.prop(json_schema, "properties/content") ) + # Include UnsignedData if it is present on the object + unsigned = Units.prop(json_schema, "properties/unsigned") + if unsigned: + tbls = get_tables_for_schema(unsigned) + for tbl in tbls: + schema["content_fields"].append(tbl) + # grab msgtype if it is the right kind of event msgtype = Units.prop( json_schema, "properties/content/properties/msgtype/enum" From 1c1e3517782484df5947a4686974f5a5782883c9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 31 May 2020 21:37:18 -0600 Subject: [PATCH 1125/1250] Move m.room.member's unsigned data to the top level --- event-schemas/schema/m.room.member | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/event-schemas/schema/m.room.member b/event-schemas/schema/m.room.member index 1ccf5ab3..7fe23f40 100644 --- a/event-schemas/schema/m.room.member +++ b/event-schemas/schema/m.room.member @@ -100,16 +100,6 @@ properties: - signed title: Invite type: object - unsigned: - type: object - title: UnsignedData - description: Contains optional extra information about the event. - properties: - invite_room_state: - description: 'A subset of the state of the room at the time of the invite, if ``membership`` is ``invite``. Note that this state is informational, and SHOULD NOT be trusted; once the client has joined the room, it SHOULD fetch the live state from the server and discard the invite_room_state. Also, clients must not rely on any particular state being present here; they SHOULD behave properly (with possibly a degraded but not a broken experience) in the absence of any particular events here. If they are set on the room, at least the state for ``m.room.avatar``, ``m.room.canonical_alias``, ``m.room.join_rules``, and ``m.room.name`` SHOULD be included.' - items: - $ref: "stripped_state.yaml" - type: array required: - membership title: EventContent @@ -124,5 +114,15 @@ properties: enum: - m.room.member type: string + unsigned: + type: object + title: UnsignedData + description: Contains optional extra information about the event. + properties: + invite_room_state: + description: 'A subset of the state of the room at the time of the invite, if ``membership`` is ``invite``. Note that this state is informational, and SHOULD NOT be trusted; once the client has joined the room, it SHOULD fetch the live state from the server and discard the invite_room_state. Also, clients must not rely on any particular state being present here; they SHOULD behave properly (with possibly a degraded but not a broken experience) in the absence of any particular events here. If they are set on the room, at least the state for ``m.room.avatar``, ``m.room.canonical_alias``, ``m.room.join_rules``, and ``m.room.name`` SHOULD be included.' + items: + $ref: "stripped_state.yaml" + type: array title: The current membership state of a user in the room. type: object From 33d738e6650037824e52ace02407dd120c0ef803 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 31 May 2020 21:41:29 -0600 Subject: [PATCH 1126/1250] Document the m.room.member unsigned object in full --- .../core-event-schema/sync_room_event.yaml | 19 +---------- .../core-event-schema/unsigned_prop.yaml | 32 +++++++++++++++++++ event-schemas/schema/m.room.member | 18 +++++------ 3 files changed, 42 insertions(+), 27 deletions(-) create mode 100644 event-schemas/schema/core-event-schema/unsigned_prop.yaml diff --git a/event-schemas/schema/core-event-schema/sync_room_event.yaml b/event-schemas/schema/core-event-schema/sync_room_event.yaml index 8006148f..fef13ad0 100644 --- a/event-schemas/schema/core-event-schema/sync_room_event.yaml +++ b/event-schemas/schema/core-event-schema/sync_room_event.yaml @@ -34,24 +34,7 @@ properties: type: integer format: int64 unsigned: - description: Contains optional extra information about the event. - properties: - age: - description: The time in milliseconds that has elapsed since the event was - sent. This field is generated by the local homeserver, and may be incorrect - if the local time on at least one of the two servers is out of sync, which can - cause the age to either be negative or greater than it actually is. - type: integer - redacted_because: - description: Optional. The event that redacted this event, if any. - title: Event - type: object - transaction_id: - description: The client-supplied transaction ID, if the client being given - the event is the same one which sent it. - type: string - title: UnsignedData - type: object + $ref: unsigned_prop.yaml required: - event_id - sender diff --git a/event-schemas/schema/core-event-schema/unsigned_prop.yaml b/event-schemas/schema/core-event-schema/unsigned_prop.yaml new file mode 100644 index 00000000..39cfb267 --- /dev/null +++ b/event-schemas/schema/core-event-schema/unsigned_prop.yaml @@ -0,0 +1,32 @@ +# Copyright 2020 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. + +title: UnsignedData +type: object +description: Contains optional extra information about the event. +properties: + age: + description: The time in milliseconds that has elapsed since the event was + sent. This field is generated by the local homeserver, and may be incorrect + if the local time on at least one of the two servers is out of sync, which can + cause the age to either be negative or greater than it actually is. + type: integer + redacted_because: + description: Optional. The event that redacted this event, if any. + title: Event + type: object + transaction_id: + description: The client-supplied transaction ID, if the client being given + the event is the same one which sent it. + type: string diff --git a/event-schemas/schema/m.room.member b/event-schemas/schema/m.room.member index 7fe23f40..36490c6b 100644 --- a/event-schemas/schema/m.room.member +++ b/event-schemas/schema/m.room.member @@ -115,14 +115,14 @@ properties: - m.room.member type: string unsigned: - type: object - title: UnsignedData - description: Contains optional extra information about the event. - properties: - invite_room_state: - description: 'A subset of the state of the room at the time of the invite, if ``membership`` is ``invite``. Note that this state is informational, and SHOULD NOT be trusted; once the client has joined the room, it SHOULD fetch the live state from the server and discard the invite_room_state. Also, clients must not rely on any particular state being present here; they SHOULD behave properly (with possibly a degraded but not a broken experience) in the absence of any particular events here. If they are set on the room, at least the state for ``m.room.avatar``, ``m.room.canonical_alias``, ``m.room.join_rules``, and ``m.room.name`` SHOULD be included.' - items: - $ref: "stripped_state.yaml" - type: array + allOf: + - $ref: "core-event-schema/unsigned_prop.yaml" + - type: object + properties: + invite_room_state: + description: 'A subset of the state of the room at the time of the invite, if ``membership`` is ``invite``. Note that this state is informational, and SHOULD NOT be trusted; once the client has joined the room, it SHOULD fetch the live state from the server and discard the invite_room_state. Also, clients must not rely on any particular state being present here; they SHOULD behave properly (with possibly a degraded but not a broken experience) in the absence of any particular events here. If they are set on the room, at least the state for ``m.room.avatar``, ``m.room.canonical_alias``, ``m.room.join_rules``, and ``m.room.name`` SHOULD be included.' + items: + $ref: "stripped_state.yaml" + type: array title: The current membership state of a user in the room. type: object From 0f9ffdf01ade1e680c503525cf0c0dbc04505f55 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 31 May 2020 21:43:27 -0600 Subject: [PATCH 1127/1250] Make server ACL example inherit from state events --- event-schemas/examples/m.room.server_acl | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/event-schemas/examples/m.room.server_acl b/event-schemas/examples/m.room.server_acl index 86da2093..06586f79 100644 --- a/event-schemas/examples/m.room.server_acl +++ b/event-schemas/examples/m.room.server_acl @@ -1,14 +1,10 @@ { - "age": 242352, + "$ref": "core/state_event.json", + "type": "m.room.server_acl", + "state_key": "", "content": { "allow_ip_literals": false, "allow": ["*"], "deny": ["*.evil.com", "evil.com"] - }, - "state_key": "", - "origin_server_ts": 1431961217939, - "event_id": "$WLGTSEFSEF:localhost", - "type": "m.room.server_acl", - "room_id": "!Cuyf34gef24t:localhost", - "sender": "@example:localhost" + } } From 33309fb68ece8264245ff2ab40bfd171b5610de0 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 31 May 2020 21:46:15 -0600 Subject: [PATCH 1128/1250] Add changelog --- changelogs/client_server/newsfragments/2591.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2591.clarification diff --git a/changelogs/client_server/newsfragments/2591.clarification b/changelogs/client_server/newsfragments/2591.clarification new file mode 100644 index 00000000..7473f453 --- /dev/null +++ b/changelogs/client_server/newsfragments/2591.clarification @@ -0,0 +1 @@ +Fix issues with ``age`` and ``unsigned`` being shown in the wrong places. From bda05a0d4450e4465e7e10f8e2c599f2e03ad24f Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Mon, 1 Jun 2020 09:50:18 +0200 Subject: [PATCH 1129/1250] capabilities.yaml: drop an extraneous title AvailableRoomVersions sticks itself as a property type, preempting the mention of RoomVersionStability in the generated text. --- api/client-server/capabilities.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/api/client-server/capabilities.yaml b/api/client-server/capabilities.yaml index 0d6b0677..a50908f7 100644 --- a/api/client-server/capabilities.yaml +++ b/api/client-server/capabilities.yaml @@ -96,7 +96,6 @@ paths: example: "1" available: type: object - title: AvailableRoomVersions description: |- A detailed description of the room versions the server supports. additionalProperties: From c02ca21a94e93570dcfad0b50d25c6681a1013b3 Mon Sep 17 00:00:00 2001 From: Dominic Fischer Date: Mon, 1 Jun 2020 17:32:10 +0100 Subject: [PATCH 1130/1250] Fix Typo --- specification/modules/end_to_end_encryption.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 8bc46de8..a357944b 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -587,7 +587,7 @@ The process between Alice and Bob verifying each other would be: the same for Bob's device keys and key IDs concurrently with Alice. #. When the other device receives the ``m.key.verification.mac`` message, the device calculates the HMAC of its copies of the other device's keys given in the message, - as well as the HMAC of the comma-seperated, sorted, list of key IDs in the message. + as well as the HMAC of the comma-separated, sorted, list of key IDs in the message. The device compares these with the HMAC values given in the message, and if everything matches then the device keys are verified. From 9535540161c2d8c2caf91603716914faec2b8d87 Mon Sep 17 00:00:00 2001 From: Dominic Fischer Date: Mon, 1 Jun 2020 17:35:36 +0100 Subject: [PATCH 1131/1250] Add changelog --- changelogs/client_server/newsfragments/2594.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2594.clarification diff --git a/changelogs/client_server/newsfragments/2594.clarification b/changelogs/client_server/newsfragments/2594.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/client_server/newsfragments/2594.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. From 07856ec7a26c79d553517ada3175846211934ad7 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 1 Jun 2020 21:03:36 -0400 Subject: [PATCH 1132/1250] initial spec of SSSS --- specification/modules/secrets.rst | 305 ++++++++++++++++++++++++++++++ specification/targets.yaml | 1 + 2 files changed, 306 insertions(+) create mode 100644 specification/modules/secrets.rst diff --git a/specification/modules/secrets.rst b/specification/modules/secrets.rst new file mode 100644 index 00000000..69a1af70 --- /dev/null +++ b/specification/modules/secrets.rst @@ -0,0 +1,305 @@ +.. Copyright 2020 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. + +Secrets +======= + +Clients may have secret information that they wish to be made available to +other authorised clients, but that the server should not be able to see, so the +information must be encrypted as it passes through the server. This can be done +either asynchronously, by storing encrypted data on the server for later +retrieval, or synchronously, by sending messages to each other. + +Each secret has an identifier that is used by clients to refer to the secret +when storing, fetching, requesting, or sharing the secret. Secrets are plain +strings; structured data can be stored by encoding it as a string. + +Storage +------- + +When secrets are stored on the server, they are stored in the user's +`account-data <#module-account-data>`_, using an event type equal to the +secret's identifier. The keys that secrets are encrypted with are described by +data that is also stored in the user's account-data. Users can have multiple +keys, allowing them to control what sets of secrets clients can access, +depending on what keys are given to them. + +Key storage +~~~~~~~~~~~ + +Each key has an ID, and the description of the key is stored in the user's +account_data using the event type ``m.secret_storage.key.[key ID]``. The +contents of the account data for the key will include an ``algorithm`` +property, which indicates the encryption algorithm used, as well as a ``name`` +property, which is a human-readable name. Other properties depend on the +encryption algorithm, and are described below. + +A key can be marked as the "default" key by setting the user's account_data +with event type ``m.secret_storage.default_key`` to an object that has the ID +of the key as its ``key`` property. The default key will be used to encrypt +all secrets that the user would expect to be available on all their clients. +Unless the user specifies otherwise, clients will try to use the default key to +decrypt secrets. + +Secret storage +~~~~~~~~~~~~~~ + +Encrypted data is stored in the user's account_data using the event type +defined by the feature that uses the data. The account_data will have an +``encrypted`` property that is a map from key ID to an object. The algorithm +from the ``m.secret_storage.key.[key ID]`` data for the given key defines how +the other properties are interpreted, though it's expected that most encryption +schemes would have ``ciphertext`` and ``mac`` properties, where the +``ciphertext`` property is the unpadded base64-encoded ciphertext, and the +``mac`` is used to ensure the integrity of the data. + +Example: + +Some secret is encrypted using keys with ID ``key_id_1`` and ``key_id_2``: + +``org.example.some.secret``: + +.. code:: json + + { + "encrypted": { + "key_id_1": { + "ciphertext": "base64+encoded+encrypted+data", + "mac": "base64+encoded+mac", + // ... other properties according to algorithm property in + // m.secret_storage.key.key_id_1 + }, + "key_id_2": { + // ... + } + } + } + +and the key descriptions for the keys would be: + +``m.secret_storage.key.key_id_1``: + +.. code:: json + + { + "name": "Some key", + "algorithm": "m.secret_storage.v1.aes-hmac-sha2", + // ... other properties according to algorithm + } + +``m.secret_storage.key.key_id_2``: + +.. code:: json + + { + "name": "Some other key", + "algorithm": "m.secret_storage.v1.aes-hmac-sha2", + // ... other properties according to algorithm + } + +Key representation +++++++++++++++++++ + +When a user is given a raw key for ``m.secret_storage.v1.aes-hmac-sha2``, +it will be presented as a string constructed as follows: + +1. The key is prepended by the two bytes ``0x8b`` and ``0x01`` +2. All the bytes in the string above, including the two header bytes, are + XORed together to form a parity byte. This parity byte is appended to the byte + string. +3. The byte string is encoded using base58, using the same `mapping as is used + for Bitcoin addresses + `_, + that is, using the alphabet + ``123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz``. +4. A space should be added after every 4th character. + +When decoding a raw key, the process should be reversed, with the exception +that whitespace is insignificant in the user's input. + +Passphrase +++++++++++ + +A user may wish to use a chosen passphrase rather than a randomly generated +key. In this case, information on how to generate the key from a passphrase +will be stored in the ``passphrase`` property of the ``m.secret_storage.key.[key +ID]`` account-data. The ``passphrase`` property has an ``algorithm`` property +that indicates how to generate the key from the passphrase. Other properties of +the ``passphrase`` property are defined by the ``algorithm`` specified. + +``m.pbkdf2`` +<<<<<<<<<<<< + +For the ``m.pbkdf2`` algorithm, the ``passphrase`` property has the following +properties: + +============ =========== ======================================================== +Parameter Type Description +============ =========== ======================================================== +algorithm string Required. Must be ``m.pbkdf2`` +salt string Required. The salt used in PBKDF2. +iterations integer Required. The number of iterations to use in PBKDF2. +bits integer Optional. The number of bits to generate for the key. + Defaults to 256. +============ =========== ======================================================== + +The key is generated using PBKDF2 with SHA-512 as the hash, using the salt +given in the ``salt`` parameter, and the number of iterations given in the +``iterations`` parameter. + +Example: + +.. code:: json + + { + "passphrase": { + "algorithm": "m.pbkdf2", + "salt": "MmMsAlty", + "iterations": 100000, + "bits": 256 + }, + ... + } + +``m.secret_storage.v1.aes-hmac-sha2`` ++++++++++++++++++++++++++++++++++++++ + +Secrets encrypted using the ``m.secret_storage.v1.aes-hmac-sha2`` algorithm are +encrypted using AES-CTR-256, and authenticated using HMAC-SHA-256. The secret is +encrypted as follows: + +1. Given the secret storage key, generate 64 bytes by performing an HKDF with + SHA-256 as the hash, a salt of 32 bytes of 0, and with the secret name as + the info. The first 32 bytes are used as the AES key, and the next 32 bytes + are used as the MAC key +2. Generate 16 random bytes, set bit 63 to 0 (in order to work around + differences in AES-CTR implementations), and use this as the AES + initialization vector. This becomes the ``iv`` property, encoded using base64. +3. Encrypt the data using AES-CTR-256 using the AES key generated above. This + encrypted data, encoded using base64, becomes the ``ciphertext`` property. +4. Pass the raw encrypted data (prior to base64 encoding) through HMAC-SHA-256 + using the MAC key generated above. The resulting MAC is base64-encoded and + becomes the ``mac`` property. + +For the purposes of allowing clients to check whether a user has correctly +entered the key, clients should: + +1. encrypt and MAC a message consisting of 32 bytes of 0 as described above, + using the empty string as the info parameter to the HKDF in step 1. +2. store the ``iv`` and ``mac`` in the ``m.secret_storage.key.[key ID]`` + account-data. + +For example, the ``m.secret_storage.key.key_id`` for a key using this algorithm +could look like: + +.. code:: json + + { + "name": "m.default", + "algorithm": "m.secret_storage.v1.aes-hmac-sha2", + "iv": "random+data", + "mac": "mac+of+encrypted+zeros" + } + +and data encrypted using this algorithm could look like this: + +.. code:: json + + { + "encrypted": { + "key_id": { + "iv": "16+bytes+base64", + "ciphertext": "base64+encoded+encrypted+data", + "mac": "base64+encoded+mac" + } + } + } + +Sharing +------- + +To request a secret from other devices, a client sends an ``m.secret.requests`` +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 ``m.secret.request`` event with ``action`` set +to ``request_cancellation`` to all devices other than the one that it received +the secret from. Clients should ignore ``m.secret.send`` events received from +devices that it did not send an ``m.secret.request`` event to. + +Clients must ensure that they only share secrets with other devices that are +allowed to see them. For example, clients should only share secrets with the +user’s own devices that are verified and may prompt the user to confirm sharing +the secret. + +Event definitions +~~~~~~~~~~~~~~~~~ + +``m.secret.request`` +++++++++++++++++++++ + +Sent by a client to request a secret from another device or to cancel a +previous request. It is sent as an unencrypted to-device event. + +.. table:: + :widths: auto + + ===================== =========== ===================================================== + Parameter Type Description + ===================== =========== ===================================================== + name string Required if ``action`` is ``request``. The name of + the secret that is being requested. + action enum Required. One of ["request", "request_cancellation"]. + requesting_device_id string Required. The ID of the device requesting the secret. + request_id string Required. A random string uniquely identifying (with + respect to the requester and the target) the target + for a secret. If the secret is requested from + multiple devices at the same time, the same ID may + be used for every target. The same ID is also used + in order to cancel a previous request. + ===================== =========== ===================================================== + +Example: + +.. code:: json + + { + "name": "org.example.some.secret", + "action": "request", + "requesting_device_id": "ABCDEFG", + "request_id": "randomly_generated_id_9573" + } + +``m.secret.send`` ++++++++++++++++++ + +Sent by a client to share a secret with another device, in response to an +``m.secret.request`` event. It must be encrypted as an ``m.room.encrypted`` event, +then sent as a to-device event. + +============ =========== ======================================================== +Parameter Type Description +============ =========== ======================================================== +request_id string Required. The ID of the request that this a response to. +secret string Required. The contents of the secret. +============ =========== ======================================================== + +Example: + +.. code:: json + + { + "request_id": "randomly_generated_id_9573", + "secret": "ThisIsASecretDon'tTellAnyone" + } diff --git a/specification/targets.yaml b/specification/targets.yaml index 4e0b068d..fa08a1ce 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -70,6 +70,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/send_to_device.rst - modules/device_management.rst - modules/end_to_end_encryption.rst + - modules/secrets.rst - modules/history_visibility.rst - modules/push.rst - modules/third_party_invites.rst From df695167e8cdbb0b25e9ddd37c707d43a601213d Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 1 Jun 2020 21:17:37 -0400 Subject: [PATCH 1133/1250] Add changelog. --- changelogs/client_server/newsfragments/2597.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2597.feature diff --git a/changelogs/client_server/newsfragments/2597.feature b/changelogs/client_server/newsfragments/2597.feature new file mode 100644 index 00000000..299d295f --- /dev/null +++ b/changelogs/client_server/newsfragments/2597.feature @@ -0,0 +1 @@ +Document Secure Secret Storage and Sharing. From 40c50c80ea4a8c26dfd20d766c995e11ee7837e1 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 1 Jun 2020 22:34:45 -0400 Subject: [PATCH 1134/1250] Apply suggestions from code review Co-authored-by: Travis Ralston --- api/client-server/key_backup.yaml | 2 +- specification/modules/end_to_end_encryption.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/client-server/key_backup.yaml b/api/client-server/key_backup.yaml index 1a79db31..ffdafcf4 100644 --- a/api/client-server/key_backup.yaml +++ b/api/client-server/key_backup.yaml @@ -1,4 +1,4 @@ -# Copyright 2019 The Matrix.org Foundation C.I.C. +# Copyright 2019-2020 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. diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 8f26477a..79228596 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -785,7 +785,7 @@ To create a backup, a client will call `POST encrypted through the backup's ``auth_data``; other clients can discover the backup by calling `GET /_matrix/client/r0/room_keys/version/{version}`_, setting ``{version}`` to the empty string. Keys are encrypted according to the -backups ``auth_data`` and added to the backup by calling `PUT +backup's ``auth_data`` and added to the backup by calling `PUT /_matrix/client/r0/room_keys/keys`_ or one of its variants, and can be retrieved by calling `GET /_matrix/client/r0/room_keys/keys`_ or one of its variants. Keys can only be written to the most recently created version of the From 8532cfd706a199d44bdc7358b8c88c2c7d643aef Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 1 Jun 2020 20:35:22 -0600 Subject: [PATCH 1135/1250] Clarify which transaction ID --- event-schemas/schema/core-event-schema/unsigned_prop.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/event-schemas/schema/core-event-schema/unsigned_prop.yaml b/event-schemas/schema/core-event-schema/unsigned_prop.yaml index 39cfb267..9571c33b 100644 --- a/event-schemas/schema/core-event-schema/unsigned_prop.yaml +++ b/event-schemas/schema/core-event-schema/unsigned_prop.yaml @@ -27,6 +27,8 @@ properties: title: Event type: object transaction_id: - description: The client-supplied transaction ID, if the client being given - the event is the same one which sent it. + description: | + The client-supplied transaction ID, for example, provided via + ``PUT /_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId}``, + if the client being given the event is the same one which sent it. type: string From d9a1de1d30e431ee96f98b92907410e0edaf9405 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 2 Jun 2020 08:13:07 -0600 Subject: [PATCH 1136/1250] Fix typos and clarify the user ID in login sections --- api/client-server/login.yaml | 2 +- api/client-server/logout.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/client-server/login.yaml b/api/client-server/login.yaml index f6c92638..f122f209 100644 --- a/api/client-server/login.yaml +++ b/api/client-server/login.yaml @@ -154,7 +154,7 @@ paths: properties: user_id: type: string - description: The fully-qualified Matrix ID that has been registered. + description: The fully-qualified Matrix ID for the account. access_token: type: string description: |- diff --git a/api/client-server/logout.yaml b/api/client-server/logout.yaml index 75a3ec87..eb84a739 100644 --- a/api/client-server/logout.yaml +++ b/api/client-server/logout.yaml @@ -39,7 +39,7 @@ paths: - accessToken: [] responses: 200: - description: The access token used in the request was succesfully invalidated. + description: The access token used in the request was successfully invalidated. schema: type: object properties: {} @@ -64,7 +64,7 @@ paths: - accessToken: [] responses: 200: - description: The user's access tokens were succesfully invalidated. + description: The user's access tokens were successfully invalidated. schema: type: object properties: {} From bcce6b9a7c51ac7e5ad0bcf4178528e4158d7f1b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 2 Jun 2020 08:21:20 -0600 Subject: [PATCH 1137/1250] changelog --- changelogs/client_server/newsfragments/2599.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2599.clarification diff --git a/changelogs/client_server/newsfragments/2599.clarification b/changelogs/client_server/newsfragments/2599.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/client_server/newsfragments/2599.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. From a36284810d7243061099402bc1fd3fa4ca7c9170 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 2 Jun 2020 16:25:31 -0400 Subject: [PATCH 1138/1250] more clarifications and fixes --- api/client-server/key_backup.yaml | 56 +++++++++++++++++++ .../modules/end_to_end_encryption.rst | 30 +++++----- 2 files changed, 72 insertions(+), 14 deletions(-) diff --git a/api/client-server/key_backup.yaml b/api/client-server/key_backup.yaml index ffdafcf4..34dce118 100644 --- a/api/client-server/key_backup.yaml +++ b/api/client-server/key_backup.yaml @@ -77,6 +77,10 @@ paths: example: "1" required: - version + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" tags: - End-to-end encryption get: @@ -144,6 +148,10 @@ paths: } schema: "$ref": "definitions/errors/error.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" tags: - End-to-end encryption "/room_keys/version/{version}": @@ -222,6 +230,10 @@ paths: } schema: "$ref": "definitions/errors/error.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" tags: - End-to-end encryption put: @@ -305,6 +317,10 @@ paths: } schema: "$ref": "definitions/errors/error.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" tags: - End-to-end encryption delete: @@ -345,6 +361,10 @@ paths: } schema: "$ref": "definitions/errors/error.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" tags: - End-to-end encryption "/room_keys/keys/{roomId}/{sessionId}": @@ -412,6 +432,10 @@ paths: } schema: "$ref": "definitions/errors/error.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" tags: - End-to-end encryption get: @@ -455,6 +479,10 @@ paths: } schema: "$ref": "definitions/errors/error.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" delete: summary: Delete a key from the backup description: |- @@ -511,6 +539,10 @@ paths: } schema: "$ref": "definitions/errors/error.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" "/room_keys/keys/{roomId}": put: summary: Store several keys in the backup for a given room. @@ -595,6 +627,10 @@ paths: } schema: "$ref": "definitions/errors/error.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" tags: - End-to-end encryption get: @@ -650,6 +686,10 @@ paths: } schema: "$ref": "definitions/errors/error.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" delete: summary: Delete a key from the backup description: |- @@ -700,6 +740,10 @@ paths: } schema: "$ref": "definitions/errors/error.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" "/room_keys/keys": put: summary: Store several keys in the backup. @@ -784,6 +828,10 @@ paths: } schema: "$ref": "definitions/errors/error.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" tags: - End-to-end encryption get: @@ -838,6 +886,10 @@ paths: } schema: "$ref": "definitions/errors/error.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" delete: summary: Delete a key from the backup description: |- @@ -882,3 +934,7 @@ paths: } schema: "$ref": "definitions/errors/error.yaml" + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/errors/rate_limited.yaml" diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 79228596..eec40159 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -783,13 +783,12 @@ decrypt the session keys. To create a backup, a client will call `POST /_matrix/client/r0/room_keys/version`_ and define how the keys are to be encrypted through the backup's ``auth_data``; other clients can discover the -backup by calling `GET /_matrix/client/r0/room_keys/version/{version}`_, -setting ``{version}`` to the empty string. Keys are encrypted according to the -backup's ``auth_data`` and added to the backup by calling `PUT -/_matrix/client/r0/room_keys/keys`_ or one of its variants, and can be -retrieved by calling `GET /_matrix/client/r0/room_keys/keys`_ or one of its -variants. Keys can only be written to the most recently created version of the -backup. Backups can also be deleted using `DELETE +backup by calling `GET /_matrix/client/r0/room_keys/version`_. Keys are +encrypted according to the backup's ``auth_data`` and added to the backup by +calling `PUT /_matrix/client/r0/room_keys/keys`_ or one of its variants, and +can be retrieved by calling `GET /_matrix/client/r0/room_keys/keys`_ or one of +its variants. Keys can only be written to the most recently created version of +the backup. Backups can also be deleted using `DELETE /_matrix/client/r0/room_keys/version/{version}`_, or individual keys can be deleted using `DELETE /_matrix/client/r0/room_keys/keys`_ or one of its variants. @@ -823,7 +822,10 @@ follows: together to form a parity byte. This parity byte is appended to the byte string. 3. The byte string is encoded using base58, using the same `mapping as is used - for Bitcoin addresses `_. + for Bitcoin addresses + `_, + that is, using the alphabet + ``123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz``. 4. A space should be added after every 4th character. When reading in a recovery key, clients must disregard whitespace, and perform @@ -844,7 +846,7 @@ following format: ========== =========== ====================================================== Parameter Type Description ========== =========== ====================================================== - public_key string Required. The curve25519 public key used to encrypt + 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 @@ -860,19 +862,19 @@ The ``session_data`` field in the backups is constructed as follows: =============================== ======== ========================================= Parameter Type Description =============================== ======== ========================================= - algorithm string Required. The end-to-end message + 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 + forwarding_curve25519_key_chain [string] **Required.** Chain of Curve25519 keys through which this session was forwarded, via `m.forwarded_room_key`_ events. - sender_key string Required. Unpadded base64-encoded + sender_key string **Required.** Unpadded base64-encoded device curve25519 key. - sender_claimed_keys {string: Required. A map from algorithm name + sender_claimed_keys {string: **Required.** A map from algorithm name string} (``ed25519``) to the identity key for the sending device. - session_key string Required. Unpadded base64-encoded + session_key string **Required.** Unpadded base64-encoded session key in `session-sharing format `_. =============================== ======== ========================================= From 7fc811d4bdf276d54c3571416628616466ae10ca Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 2 Jun 2020 15:10:18 -0600 Subject: [PATCH 1139/1250] Update event-schemas/schema/core-event-schema/unsigned_prop.yaml Co-authored-by: Hubert Chathi --- event-schemas/schema/core-event-schema/unsigned_prop.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event-schemas/schema/core-event-schema/unsigned_prop.yaml b/event-schemas/schema/core-event-schema/unsigned_prop.yaml index 9571c33b..36c37230 100644 --- a/event-schemas/schema/core-event-schema/unsigned_prop.yaml +++ b/event-schemas/schema/core-event-schema/unsigned_prop.yaml @@ -23,7 +23,7 @@ properties: cause the age to either be negative or greater than it actually is. type: integer redacted_because: - description: Optional. The event that redacted this event, if any. + description: The event that redacted this event, if any. title: Event type: object transaction_id: From f8e4bdfbaf1bdda634e45a81347fe09f96e3e676 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 2 Jun 2020 17:31:15 -0400 Subject: [PATCH 1140/1250] credit David Wong --- proposals/xxxx-sas-v2.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/xxxx-sas-v2.md b/proposals/xxxx-sas-v2.md index e4e4e320..d9d37471 100644 --- a/proposals/xxxx-sas-v2.md +++ b/proposals/xxxx-sas-v2.md @@ -11,6 +11,9 @@ generation of the SAS string by including it in the info parameter of the HKDF. Thus if an attacker sends them different public keys, the info parameters will be different, and so the key generated by the HKDF will be different. +Thanks to [David Wong](https://twitter.com/cryptodavidw) for identifying the +issue, disclosing responsibly, and for helping to design the fix. + ## Proposal A new `key_agreement_protocol`, `curve25519-hkdf-sha256` is introduced, and From ea02029f89765e64e0032bbe29112dfc41c2ec4e Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Thu, 4 Jun 2020 11:05:36 +0200 Subject: [PATCH 1141/1250] Add a changelog --- changelogs/client_server/newsfragments/2592.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2592.clarification diff --git a/changelogs/client_server/newsfragments/2592.clarification b/changelogs/client_server/newsfragments/2592.clarification new file mode 100644 index 00000000..fb770404 --- /dev/null +++ b/changelogs/client_server/newsfragments/2592.clarification @@ -0,0 +1 @@ +c2s: fix disconnected data structure in the documentation on server capabilities. From f632f4a20f524b6ca697164ab9acbd832d07d68f Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Thu, 4 Jun 2020 17:36:40 +0100 Subject: [PATCH 1142/1250] Clarify link to OpenID Connect specification (#2605) OpenID Connect and OpenID are different things. This seems to be talking about the former. --- api/client-server/openid.yaml | 2 +- changelogs/client_server/newsfragments/2605.clarification | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelogs/client_server/newsfragments/2605.clarification diff --git a/api/client-server/openid.yaml b/api/client-server/openid.yaml index 01fdf68f..98a2449e 100644 --- a/api/client-server/openid.yaml +++ b/api/client-server/openid.yaml @@ -62,7 +62,7 @@ paths: 200: description: |- OpenID token information. This response is nearly compatible with the - response documented in the `OpenID 1.0 Specification `_ + response documented in the `OpenID Connect 1.0 Specification `_ with the only difference being the lack of an ``id_token``. Instead, the Matrix homeserver's name is provided. examples: diff --git a/changelogs/client_server/newsfragments/2605.clarification b/changelogs/client_server/newsfragments/2605.clarification new file mode 100644 index 00000000..e3d1fe98 --- /dev/null +++ b/changelogs/client_server/newsfragments/2605.clarification @@ -0,0 +1 @@ +Clarify link to OpenID Connect specification. From 7c6636a520bd4b05364c223b50c43a18f57a3745 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 4 Jun 2020 22:58:12 +0100 Subject: [PATCH 1143/1250] Remove `m.login.token` and `m.login.oauth2` UIA types AFAIK these have never been implemented. oauth2 lacks enough info to be sensibly implemented, and `m.login.token` just doesn't make sense. --- specification/client_server_api.rst | 75 +++-------------------------- 1 file changed, 6 insertions(+), 69 deletions(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 574999be..50680d04 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -431,13 +431,12 @@ User-Interactive Authentication API Overview <<<<<<<< -Some API endpoints require authentication that -interacts with the user. The homeserver may provide many different ways of -authenticating, such as user/password auth, login via a social network (OAuth2), -login by confirming a token sent to their email address, etc. This specification -does not define how homeservers should authorise their users but instead -defines the standard interface which implementations should follow so that ANY -client can login to ANY homeserver. +Some API endpoints require authentication that interacts with the user. The +homeserver may provide many different ways of authenticating, such as +user/password auth, login via a single-sign-on server (SSO), etc. This +specification does not define how homeservers should authorise their users but +instead defines the standard interface which implementations should follow so +that ANY client can login to ANY homeserver. The process takes the form of one or more 'stages'. At each stage the client submits a set of data for a given authentication type and awaits a response @@ -663,11 +662,9 @@ Authentication types This specification defines the following auth types: - ``m.login.password`` - ``m.login.recaptcha`` - - ``m.login.oauth2`` - ``m.login.sso`` - ``m.login.email.identity`` - ``m.login.msisdn`` - - ``m.login.token`` - ``m.login.dummy`` Password-based @@ -744,66 +741,6 @@ To use this authentication type, clients should submit an auth dict as follows: "session": "" } -Token-based -<<<<<<<<<<< -:Type: - ``m.login.token`` -:Description: - The client submits a login token. - -To use this authentication type, clients should submit an auth dict as follows: - -.. code:: json - - { - "type": "m.login.token", - "token": "", - "txn_id": "", - "session": "" - } - - -A client may receive a login ``token`` via some external service, such as email -or SMS. Note that a login token is separate from an access token, the latter -providing general authentication to various API endpoints. - -Additionally, the server must encode the user ID in the ``token``; there is -therefore no need for the client to submit a separate username. - -The ``txn_id`` should be a random string generated by the client for the -request. The same ``txn_id`` should be used if retrying the request. The -``txn_id`` may be used by the server to disallow other devices from using the -token, thus providing "single use" tokens while still allowing the device to -retry the request. This would be done by tying the token to the ``txn_id`` -server side, as well as potentially invalidating the token completely once the -device has successfully logged in (e.g. when we receive a request from the -newly provisioned access_token). - - -OAuth2-based -<<<<<<<<<<<< -:Type: - ``m.login.oauth2`` -:Description: - Authentication is supported via OAuth2 URLs. This login consists of multiple - requests. -:Parameters: - ``uri``: Authorization Request URI OR service selection URI. Both contain an - encoded ``redirect URI``. - -The homeserver acts as a 'confidential' client for the purposes of OAuth2. If -the uri is a ``service selection URI``, it MUST point to a webpage which prompts -the user to choose which service to authorize with. On selection of a service, -this MUST link through to an ``Authorization Request URI``. If there is only one -service which the homeserver accepts when logging in, this indirection can be -skipped and the "uri" key can be the ``Authorization Request URI``. - -The client then visits the ``Authorization Request URI``, which then shows the -OAuth2 Allow/Deny prompt. Hitting 'Allow' redirects to the ``redirect URI`` with -the auth code. Homeservers can choose any path for the ``redirect URI``. Once -the OAuth flow has completed, the client retries the request with the session -only, as above. - Single Sign-On <<<<<<<<<<<<<< :Type: From d9f9706fdb59457a5d14918c97188f927de4dce4 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 4 Jun 2020 22:59:44 +0100 Subject: [PATCH 1144/1250] changelog --- changelogs/client_server/newsfragments/2609.removal | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2609.removal diff --git a/changelogs/client_server/newsfragments/2609.removal b/changelogs/client_server/newsfragments/2609.removal new file mode 100644 index 00000000..878372c3 --- /dev/null +++ b/changelogs/client_server/newsfragments/2609.removal @@ -0,0 +1 @@ +Remove unimplemented `m.login.oauth2` and `m.login.token` user-interactive authentication mechanisms. \ No newline at end of file From 7549b86192600d085b35dc0b145c2511e0616167 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 5 Jun 2020 10:15:55 +0100 Subject: [PATCH 1145/1250] Proposal to remove `m.login.oauth2` --- proposals/2610-remove-oauth2-auth-type.md | 35 +++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 proposals/2610-remove-oauth2-auth-type.md diff --git a/proposals/2610-remove-oauth2-auth-type.md b/proposals/2610-remove-oauth2-auth-type.md new file mode 100644 index 00000000..e2437a48 --- /dev/null +++ b/proposals/2610-remove-oauth2-auth-type.md @@ -0,0 +1,35 @@ +# MSC2610: Remove `m.login.oauth2` User-Interactive Authentication type from the specification + +The client-server API specification +[defines](https://matrix.org/docs/spec/client_server/r0.6.1#authentication-types) +a number of "authentication types" for use with the User-Interactive +Authentication protocol. + +Of these, `m.login.oauth2` is underspecified and of no +real use. This MSC proposes removing them. + +## Proposal + +The definition of +[OAuth2-based](https://matrix.org/docs/spec/client_server/r0.6.1#oauth2-based) +authentication is incomplete. [OAuth2](https://oauth.net/2/) is best considered +as a framework for implementing authentication protocols rather than a protocol +in its own right, and this section says nothing about the grant types, flows +and scopes which a compliant implemenation should understand. + +A better candidate for OAuth2-based authentication of matrix clients is via +[OpenID Connect](https://openid.net/connect/), but this has already been +implemented in Matrix via the `m.login.sso` authentication type. + +The `m.login.oauth2` section is therefore unimplementable in its current form, +and redundant. It should be removed from the specification to reduce confusion. + +## Alternatives + +It would be possible to extend the definition so that it is complete: as +mentioned above, a likely implemenation would be based on OpenID +Connect. Matrix clients could then follow the standardised OpenID Connect flow +rather than the matrix-specific `m.login.sso` flow. However, this would require +significant design work, and development in both clients and servers, which +currently feels hard to justify when a working solution exists via +`m.login.sso`. From 1e049481fe56596883c5f0c75b4e2ad2ea6091fe Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 5 Jun 2020 10:52:37 +0100 Subject: [PATCH 1146/1250] Proposal to remove `m.login.token` ui auth type --- proposals/2611-remove-login-auth-type.md | 40 ++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 proposals/2611-remove-login-auth-type.md diff --git a/proposals/2611-remove-login-auth-type.md b/proposals/2611-remove-login-auth-type.md new file mode 100644 index 00000000..052a09f5 --- /dev/null +++ b/proposals/2611-remove-login-auth-type.md @@ -0,0 +1,40 @@ +# MSC2611: Remove `m.login.token` User-Interactive Authentication type from the specification + +The client-server API specification +[defines](https://matrix.org/docs/spec/client_server/r0.6.1#authentication-types) +a number of "authentication types" for use with the User-Interactive +Authentication protocol. + +Of these, `m.login.token` is unused and confusing. This MSC proposes removing it. + +## Proposal + +The definition of +[token-based](https://matrix.org/docs/spec/client_server/r0.6.1#token-based) +authentication is unclear about how this authentication type should be used. It +suggests "via some external service, such as email or SMS", but in practice +those validation mechanisms have their own token-submission mechanisms (for +example, the +`submit_url` field of the responses from +[`/account/password/email/requestToken`](https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-account-password-email-requesttoken) +and +[`/account/password/msisdn/requestToken`](https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-account-password-msisdn-requesttoken) +respectively). Additionally, the specification requires that "the server must +encode the user ID in the token", which seems at odds with any token which can +be sent to a user over SMS. + +Additional confusion stems from the presence of an `m.login.token` [login +type](https://matrix.org/docs/spec/client_server/r0.6.1#login), which is used +quite differently: it forms part of the single-sign-on login flow. For clarity: +this proposal does not suggest making any changes to the `m.login.token` login +type. + +In practice, we are not aware of any implementations of the `m.login.token` +authentication type, and the inconsistency adds unnecessary confusion to the +specification. + +## Potential Issues + +It's possible that somebody has found a use for this mechanism. However, that +would necessarily entail some custom development of clients and servers, so is +not materially affected by the removal from the specification. From 97809c5eae6aa3d22ab4e1c56462d865fe1a0671 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Fri, 5 Jun 2020 12:38:10 +0200 Subject: [PATCH 1147/1250] Update changelogs/client_server/newsfragments/2592.clarification Co-authored-by: Travis Ralston --- changelogs/client_server/newsfragments/2592.clarification | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/client_server/newsfragments/2592.clarification b/changelogs/client_server/newsfragments/2592.clarification index fb770404..7414e00c 100644 --- a/changelogs/client_server/newsfragments/2592.clarification +++ b/changelogs/client_server/newsfragments/2592.clarification @@ -1 +1 @@ -c2s: fix disconnected data structure in the documentation on server capabilities. +Fix definitions for room version capabilities. From da740bfbca85920d7ddf93d319f3780f02cc9044 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Fri, 5 Jun 2020 17:32:13 +0100 Subject: [PATCH 1148/1250] Clarifications to SSO login/UIA (#2608) including a bunch of text about security --- CONTRIBUTING.rst | 2 +- .../newsfragments/2608.clarification | 1 + specification/client_server_api.rst | 32 +- specification/modules/sso_login.rst | 328 +++++++++++++++--- 4 files changed, 291 insertions(+), 72 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2608.clarification diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index fc5b146f..2d26e8a8 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -13,7 +13,7 @@ https://github.com/matrix-org/matrix-doc/blob/master/meta/documentation_style.rs Python code within the ``matrix-doc`` project should follow the same style as synapse, which is documented at -https://github.com/matrix-org/synapse/tree/master/docs/code_style.rst. +https://github.com/matrix-org/synapse/tree/master/docs/code_style.md. Matrix-doc workflows -------------------- diff --git a/changelogs/client_server/newsfragments/2608.clarification b/changelogs/client_server/newsfragments/2608.clarification new file mode 100644 index 00000000..da704fc5 --- /dev/null +++ b/changelogs/client_server/newsfragments/2608.clarification @@ -0,0 +1 @@ +Clarify the behaviour of SSO login and UI-Auth. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 574999be..27cbe8c5 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1,4 +1,4 @@ -.. Copyright 2016 OpenMarket Ltd +.. Copyright 2016-2020 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. @@ -425,6 +425,8 @@ on the server-side and the user simply needs to provide their credentials again. In either case, the client's previously known access token will no longer function. +.. _`user-interactive authentication`: + User-Interactive Authentication API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -813,28 +815,8 @@ Single Sign-On provider. A client wanting to complete authentication using SSO should use the -`Fallback`_ authentication flow by opening a browser window for -``/_matrix/client/r0/auth/m.login.sso/fallback/web?session=<...>`` with the -session parameter set to the session ID provided by the server. - -The homeserver should return a page which asks for the user's confirmation -before proceeding. For example, the page could say words to the effect of: - - A client is trying to remove a device/add an email address/take over your - account. To confirm this action, re-authenticate with single sign-on. If you - did not expect this, your account may be compromised! - -Once the user has confirmed they should be redirected to the single sign-on -provider's login page. Once the provider has validated the user, the browser is -redirected back to the homeserver. - -The homeserver then validates the response from the single sign-on provider and -updates the user-interactive authentication session to mark the single sign-on -stage has been completed. The browser is shown the fallback authentication -completion page. - -Once the flow has completed, the client retries the request with the session -only, as above. +`Fallback`_ mechanism. See `SSO during User-Interactive Authentication`_ for +more information. Email-based (identity / homeserver) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -940,6 +922,8 @@ should open is:: Where ``auth type`` is the type name of the stage it is attempting and ``session ID`` is the ID of the session given by the homeserver. +.. _`user-interactive authentication fallback completion`: + This MUST return an HTML page which can perform this authentication stage. This page must use the following JavaScript when the authentication has been completed: @@ -1157,7 +1141,7 @@ with ``403 Forbidden`` and an error code of ``M_FORBIDDEN``. If the homeserver advertises ``m.login.sso`` as a viable flow, and the client supports it, the client should redirect the user to the ``/redirect`` endpoint -for `Single Sign-On <#sso-client-login>`_. After authentication is complete, the +for `client login via SSO`_. After authentication is complete, the client will need to submit a ``/login`` request matching ``m.login.token``. {{login_cs_http_api}} diff --git a/specification/modules/sso_login.rst b/specification/modules/sso_login.rst index 6dd4a332..986bed94 100644 --- a/specification/modules/sso_login.rst +++ b/specification/modules/sso_login.rst @@ -1,4 +1,4 @@ -.. Copyright 2019 New Vector Ltd +.. Copyright 2019-2020 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. @@ -12,34 +12,98 @@ .. See the License for the specific language governing permissions and .. limitations under the License. -SSO client login -================ +SSO client login/authentication +=============================== .. _module:sso_login: Single Sign-On (SSO) is a generic term which refers to protocols which allow users to log into applications via a single web-based authentication portal. -Examples include "Central Authentication Service" (CAS) and SAML. +Examples include OpenID Connect, "Central Authentication Service" (CAS) and SAML. -An overview of the process, as used in Matrix, is as follows: +This module allows a Matrix homeserver to delegate user authentication to an +external authentication server supporting one of these protocols. In this +process, there are three systems involved: -1. The Matrix client instructs the user's browser to navigate to the - |/login/sso/redirect|_ endpoint on the user's homeserver. + * A Matrix client, using the APIs defined this specification, which is seeking + to authenticate a user to a Matrix homeserver. + + * A Matrix homeserver, implementing the APIs defined in this specification, but + which is delegating user authentication to the authentication server. + + * An "authentication server", which is responsible for authenticating the + user. + +This specification is concerned only with communication between the Matrix +client and the homeserver, and is independent of the SSO protocol used to +communicate with the authentication server. Different Matrix homeserver +implementations might support different SSO protocols. + +Clients and homeservers implementing the SSO flow will need to consider both login_ +and `user-interactive authentication`_. The flow is +similar in both cases, but there are slight differences. + +Typically, SSO systems require a single "callback" URI to be configured at the +authentication server. Once the user is authenticated, their browser is +redirected to that URI. It is up to the Matrix homeserver implementation to +implement a suitable endpoint. For example, for CAS authentication the +homeserver should provide a means for the administrator to configure where the +CAS server is and the REST endpoints which consume the ticket. + +Client login via SSO +--------------------- + +An overview of the process is as follows: + +0. The Matrix client calls |GET /login|_ to find the supported login + types, and the homeserver includes a flow with ``"type": "m.login.sso"`` in the + response. + +1. To initiate the ``m.login.sso`` login type, the Matrix client instructs the + user's browser to navigate to the |/login/sso/redirect|_ endpoint on the + user's homeserver. 2. The homeserver responds with an HTTP redirect to the SSO user interface, which the browser follows. -3. The SSO system authenticates the user. +3. The authentication server and the homeserver interact to verify the user's + identity and other authentication information, potentially using a number of + redirects. -4. The SSO server and the homeserver interact to verify the user's identity - and other authentication information, potentially using a number of redirects. - -5. The browser is directed to the ``redirectUrl`` provided by the client with +4. The browser is directed to the ``redirectUrl`` provided by the client with a ``loginToken`` query parameter for the client to log in with. +5. The client exchanges the login token for an access token by calling the + |/login|_ endpoint with a ``type`` of ``m.login.token``. + +For native applications, typically steps 1 to 4 are carried out by opening an +embedded web view. + +These steps are illustrated as follows:: + + Matrix Client Matrix Homeserver Auth Server + | | | + |-------------(0) GET /login----------->| | + |<-------------login types--------------| | + | | | + | Webview | | + | | | | + |----->| | | + | |--(1) GET /login/sso/redirect-->| | + | |<---------(2) 302---------------| | + | | | | + | |<========(3) Authentication process================>| + | | | | + | |<--(4) redirect to redirectUrl--| | + |<-----| | | + | | | + |---(5) POST /login with login token--->| | + |<-------------access token-------------| | + + .. Note:: In the older `r0.4.0 version `_ - of this specification it was possible to authenticate via CAS when the server + of this specification it was possible to authenticate via CAS when the homeserver provides a ``m.login.cas`` login flow. This specification deprecates the use of ``m.login.cas`` to instead prefer ``m.login.sso``, which is the same process with the only change being which redirect endpoint to use: for ``m.login.cas``, use @@ -47,40 +111,65 @@ An overview of the process, as used in Matrix, is as follows: The endpoints are otherwise the same. Client behaviour ----------------- +~~~~~~~~~~~~~~~~ The client starts the process by instructing the browser to navigate to |/login/sso/redirect|_ with an appropriate ``redirectUrl``. Once authentication is successful, the browser will be redirected to that ``redirectUrl``. -.. TODO-spec +{{sso_login_redirect_cs_http_api}} - Should we recommend some sort of CSRF protection here (specifically, we - should guard against people accidentally logging in by sending them a link - to ``/login/sso/redirect``. +Security considerations ++++++++++++++++++++++++ - Maybe we should recommend that the ``redirectUrl`` should contain a CSRF - token which the client should then check before sending the login token to - ``/login``? +1. CSRF attacks via manipulation of parameters on the ``redirectUrl`` -{{sso_login_redirect_cs_http_api}} + Clients should validate any requests to the ``redirectUrl``. In particular, it + may be possible for attackers to falsify any query parameters, leading to + cross-site request forgery (CSRF) attacks. + + For example, consider a web-based client at ``https://client.example.com``, + which wants to initiate SSO login on the homeserver at ``server.example.org``. + It does this by storing the homeserver name in a query parameter for the + ``redirectUrl``: it redirects to + ``https://server.example.org/login/sso/redirect?redirectUrl=https://client.example.com?hs=server.example.org``. + + An attacker could trick a victim into following a link to + ``https://server.example.org/login/sso/redirect?redirectUrl=https://client.example.com?hs=evil.com``, + which would result in the client sending a login token for the victim's + account to the attacker-controlled site ``evil.com``. + + To guard against this, clients MUST NOT store state (such as the address of + the homeserver being logged into) anywhere it can be modified by external + processes. + + Instead, the state could be stored in `localStorage + `_ or + in a cookie. + +2. For added security, clients SHOULD include a unique identifier in the + ``redirectUrl`` and reject any callbacks that do not contain a recognised + identifier, to guard against unsolicited login attempts and replay attacks. Server behaviour ----------------- +~~~~~~~~~~~~~~~~ + +Redirecting to the Authentication server +++++++++++++++++++++++++++++++++++++++++ -The URI for the SSO system to be used should be configured on the server by the -server administrator. The server is expected to set up any endpoints required to -interact with that SSO system. For example, for CAS authentication the homeserver -should provide a means for the administrator to configure where the CAS server is -and the REST endpoints which consume the ticket. A good reference for how CAS could -be implemented is available in the older `r0.4.0 version `_ -of this specification. +The server should handle +``/_matrix/client/%CLIENT_MAJOR_VERSION%/login/sso/redirect`` as follows: -Handling the redirect endpoint -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +#. It should build a suitable request for the SSO system. -When responding to the ``/login/sso/redirect`` endpoint, the server must -generate a URI for the SSO login page with any appropriate parameters. +#. It should store enough state that the flow can be securely resumed after the + SSO process completes. One way to do this is by storing a cookie which is + stored in the user's browser, by adding a ``Set-Cookie`` header to the response. + +#. It should redirect the user's browser to the SSO login page with the + appropriate parameters. + +See also the "Security considerations" below. .. TODO-spec: @@ -89,24 +178,169 @@ generate a URI for the SSO login page with any appropriate parameters. endpoint, and to give more meaningful errors in the case of faulty/poorly-configured clients. -Handling the authentication endpoint -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Handling the callback from the Authentication server +++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Note that there will normally be a single callback URI which is used for both login +and user-interactive authentication: it is up to the homeserver implementation +to distinguish which is taking place. + +The homeserver should validate the response from the SSO system: this may +require additional calls to the authentication server, and/or may require +checking a signature on the response. + +The homeserver then proceeds as follows: + +#. The homeserver MUST map the user details received from the authentication + server to a valid `Matrix user identifier <../appendices.html#user-identifiers>`_. + The guidance in `Mapping from other character sets + <../appendices.html#mapping-from-other-character-sets>`_ may be useful. + +#. If the generated user identifier represents a new user, it should be + registered as a new user. + +#. The homeserver should generate a short-term login token. This is an opaque + token, suitable for use with the ``m.login.token`` type of the |/login|_ + API. The lifetime of this token SHOULD be limited to around five + seconds. + +#. The homeserver adds a query parameter of ``loginToken``, with the value of + the generated login token, to the ``redirectUrl`` given in the + ``/_matrix/client/%CLIENT_MAJOR_VERSION%/login/sso/redirect`` + request. (Note: ``redirectURL`` may or may not include existing query + parameters. If it already includes one or more ``loginToken`` parameters, + they should be removed before adding the new one.) + +#. The homeserver redirects the user's browser to the URI thus built. + +Security considerations +~~~~~~~~~~~~~~~~~~~~~~~ + +1. Homeservers should ensure that login tokens are not sent to malicious + clients. + + For example, consider a homeserver at ``server.example.org``. An attacker tricks + a victim into following a link to + ``https://server.example.org/login/sso/redirect?redirectUrl=https://evil.com``, + resulting in a login token being sent to the attacker-controlled site + ``evil.com``. This is a form of cross-site request forgery (CSRF). + + To mitigate this, Homeservers SHOULD confirm with the user that they are + happy to grant access to their matrix account to the site named in the + ``redirectUrl``. This can be done either *before* redirecting to the SSO + login page when handling the + ``/_matrix/client/%CLIENT_MAJOR_VERSION%/login/sso/redirect`` endpoint, or + *after* login when handling the callback from the authentication server. (If + the check is performed before redirecting, it is particularly important that + the homeserver guards against unsolicited authentication attempts as below). + + It may be appropriate to whitelist a set of known-trusted client URLs in + this process. In particular, the homeserver's own `login fallback`_ + implementation could be excluded. + +2. For added security, homeservers SHOULD guard against unsolicited + authentication attempts by tracking pending requests. One way to do this is + to set a cookie when handling + ``/_matrix/client/%CLIENT_MAJOR_VERSION%/login/sso/redirect``, which is + checked and cleared when handling the callback from the authentication + server. + +SSO during User-Interactive Authentication +------------------------------------------ + +`User-interactive authentication`_ is used by client-server +endpoints which require additional confirmation of the user's identity (beyond +holding an access token). Typically this means that the user must re-enter +their password, but for homeservers which delegate to an SSO server, this means +redirecting to the authentication server during user-interactive auth. + +The implemementation of this is based on the `Fallback`_ mechanism for +user-interactive auth. + +Client behaviour +---------------- + +Clients do not need to take any particular additional steps beyond ensuring +that the fallback mechanism has been implemented, and treating the +``m.login.sso`` authentication type the same as any other unknown type +(i.e. they should open a browser window for +``/_matrix/client/%CLIENT_MAJOR_VERSION%/auth/m.login.sso/fallback/web?session=``. +Once the flow has completed, the client retries the request with the session +only.) + +Server behaviour +---------------- + +Redirecting to the Authentication server +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The server should handle +``/_matrix/client/%CLIENT_MAJOR_VERSION%/auth/m.login.sso/fallback/web`` in +much the same way as +``/_matrix/client/%CLIENT_MAJOR_VERSION%/login/sso/redirect``, which is to say: + +#. It should build a suitable request for the SSO system. + +#. It should store enough state that the flow can be securely resumed after the + SSO process completes. One way to do this is by storing a cookie which is + stored in the user's browser, by adding a ``Set-Cookie`` header to the response. + +#. It should redirect the user's browser to the SSO login page with the + appropriate parameters. + +See also the "Security considerations" below. + +Handling the callback from the Authentication server +++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Note that there will normally be a single callback URI which is used for both login +and user-interactive authentication: it is up to the homeserver implementation +to distinguish which is taking place. + +The homeserver should validate the response from the SSO system: this may +require additional calls to the authentication server, and/or may require +checking a signature on the response. + +The homeserver then returns the `user-interactive authentication fallback +completion`_ page to the user's browser. + +Security considerations ++++++++++++++++++++++++ + +1. Confirming the operation + + The homeserver SHOULD confirm that the user is happy for the operation to go + ahead. The goal of the user-interactive authentication operation is to guard + against a compromised ``access_token`` being used to take over the user's + account. Simply redirecting the user to the SSO system is insufficient, + since they may not realise what is being asked of them, or the SSO system + may even confirm the authentication automatically. + + For example, the homeserver might serve a page with words to the effect of: + + A client is trying to remove a device from your account. To confirm this + action, re-authenticate with single sign-on. If you did not expect this, your + account may be compromised! -Once the homeserver has verified the user's identity with the SSO system, it -MUST map the user ID to a valid `Matrix user identifier <../index.html#user-identifiers>`_. -The guidance in `Mapping from other character sets -<../index.html#mapping-from-other-character-sets>`_ may be useful. + This confirmation could take place before redirecting to the SSO + authentication page (when handling the + ``/_matrix/client/%CLIENT_MAJOR_VERSION%/auth/m.login.sso/fallback/web`` + endpoint), or *after* authentication when handling the callback from the + authentication server. (If the check is performed before redirecting, it is + particularly important that the homeserver guards against unsolicited + authentication attempts as below). -If the generated user identifier represents a new user, it should be registered -as a new user. +2. For added security, homeservers SHOULD guard against unsolicited + authentication attempts by tracking pending requests. One way to do this is + to set a cookie when handling + ``/_matrix/client/%CLIENT_MAJOR_VERSION%/auth/m.login.sso/fallback/web``, + which is checked and cleared when handling the callback from the + authentication server. -Finally, the server should generate a short-term login token. The generated -token should be a macaroon, suitable for use with the ``m.login.token`` type of -the |/login|_ API, and `token-based interactive login <#token-based>`_. The -lifetime of this token SHOULD be limited to around five seconds. This token is -given to the client via the ``loginToken`` query parameter previously mentioned. +.. |GET /login| replace:: ``GET /login`` +.. _GET /login: #get-matrix-client-%CLIENT_MAJOR_VERSION%-login .. |/login| replace:: ``/login`` .. _/login: #post-matrix-client-%CLIENT_MAJOR_VERSION%-login .. |/login/sso/redirect| replace:: ``/login/sso/redirect`` From 4aa778cdee0527fd1d7ec362762c2399617d76a6 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Wed, 10 Jun 2020 13:40:12 +0100 Subject: [PATCH 1149/1250] Put the MSC number in the proposal template (#2622) this seems to be our convention. --- proposals/0000-proposal-template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/0000-proposal-template.md b/proposals/0000-proposal-template.md index e50aed8b..8acbef85 100644 --- a/proposals/0000-proposal-template.md +++ b/proposals/0000-proposal-template.md @@ -1,4 +1,4 @@ -# Example: Proposal to adopt a template for MSCs +# MSC0000: Template for new MSCs *Note: Text written in italics represents notes about the section or proposal process. This document serves as an example of what a proposal could look like (in this case, a proposal to have a template) From d3b41941aa2228f675f5100428c7390d10ba63ce Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Wed, 10 Jun 2020 21:16:54 +0200 Subject: [PATCH 1150/1250] key_backup.yaml: make body parameters required Along the same lines as c72d3051. --- api/client-server/key_backup.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/api/client-server/key_backup.yaml b/api/client-server/key_backup.yaml index 34dce118..603d1c8c 100644 --- a/api/client-server/key_backup.yaml +++ b/api/client-server/key_backup.yaml @@ -39,6 +39,7 @@ paths: - in: body name: version description: "The backup configuration." + required: true schema: type: object properties: @@ -257,6 +258,7 @@ paths: - in: body name: version description: "The backup configuration" + required: true schema: type: object properties: @@ -398,6 +400,7 @@ paths: - in: body name: data description: "The key data." + required: true schema: "$ref": "definitions/key_backup_data.yaml" responses: @@ -568,6 +571,7 @@ paths: - in: body description: "The backup data" name: backupData + required: true schema: type: object properties: @@ -763,6 +767,7 @@ paths: - in: body description: "The backup data" name: backupData + required: true schema: type: object properties: From d261084f5ba863e03c18ad47271d30052af76b4b Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 10 Jun 2020 17:31:21 -0400 Subject: [PATCH 1151/1250] apply changes from review --- .../client_server/newsfragments/2597.feature | 2 +- specification/modules/secrets.rst | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/changelogs/client_server/newsfragments/2597.feature b/changelogs/client_server/newsfragments/2597.feature index 299d295f..833006a9 100644 --- a/changelogs/client_server/newsfragments/2597.feature +++ b/changelogs/client_server/newsfragments/2597.feature @@ -1 +1 @@ -Document Secure Secret Storage and Sharing. +Document Secure Secret Storage and Sharing (MSC1946/2472). diff --git a/specification/modules/secrets.rst b/specification/modules/secrets.rst index 69a1af70..cb6b6a9e 100644 --- a/specification/modules/secrets.rst +++ b/specification/modules/secrets.rst @@ -123,7 +123,7 @@ it will be presented as a string constructed as follows: `_, that is, using the alphabet ``123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz``. -4. A space should be added after every 4th character. +4. The string is formatted into groups of four characters separated by spaces. When decoding a raw key, the process should be reversed, with the exception that whitespace is insignificant in the user's input. @@ -147,9 +147,9 @@ properties: ============ =========== ======================================================== Parameter Type Description ============ =========== ======================================================== -algorithm string Required. Must be ``m.pbkdf2`` -salt string Required. The salt used in PBKDF2. -iterations integer Required. The number of iterations to use in PBKDF2. +algorithm string **Required.** Must be ``m.pbkdf2`` +salt string **Required.** The salt used in PBKDF2. +iterations integer **Required.** The number of iterations to use in PBKDF2. bits integer Optional. The number of bits to generate for the key. Defaults to 256. ============ =========== ======================================================== @@ -260,9 +260,9 @@ previous request. It is sent as an unencrypted to-device event. ===================== =========== ===================================================== name string Required if ``action`` is ``request``. The name of the secret that is being requested. - action enum Required. One of ["request", "request_cancellation"]. - requesting_device_id string Required. The ID of the device requesting the secret. - request_id string Required. A random string uniquely identifying (with + action enum **Required.** One of ["request", "request_cancellation"]. + requesting_device_id string **Required.** The ID of the device requesting the secret. + request_id string **Required.** A random string uniquely identifying (with respect to the requester and the target) the target for a secret. If the secret is requested from multiple devices at the same time, the same ID may @@ -291,8 +291,8 @@ then sent as a to-device event. ============ =========== ======================================================== Parameter Type Description ============ =========== ======================================================== -request_id string Required. The ID of the request that this a response to. -secret string Required. The contents of the secret. +request_id string **Required.** The ID of the request that this a response to. +secret string **Required.** The contents of the secret. ============ =========== ======================================================== Example: From 57f0c8346facacded144996726b0f4fc0ee7d539 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Wed, 10 Jun 2020 18:14:24 +0200 Subject: [PATCH 1152/1250] message_pagination.yaml: more $ref cleanup --- api/client-server/message_pagination.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/api/client-server/message_pagination.yaml b/api/client-server/message_pagination.yaml index 22828219..425240e3 100644 --- a/api/client-server/message_pagination.yaml +++ b/api/client-server/message_pagination.yaml @@ -111,8 +111,6 @@ paths: for ``dir=f`` in chronological order, so that events start at the ``from`` point. items: - type: object - title: RoomEvent "$ref": "definitions/event-schemas/schema/core-event-schema/room_event.yaml" state: type: array @@ -126,8 +124,6 @@ paths: sent to the client in prior calls to this endpoint, assuming the membership of those members has not changed. items: - type: object - title: RoomStateEvent $ref: "definitions/event-schemas/schema/core-event-schema/state_event.yaml" examples: application/json: { From ac982410b94f749e8ad87d7cfc548f17fc221a43 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Thu, 11 Jun 2020 11:18:29 +0100 Subject: [PATCH 1153/1250] Apply suggestions from code review Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- proposals/2610-remove-oauth2-auth-type.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/2610-remove-oauth2-auth-type.md b/proposals/2610-remove-oauth2-auth-type.md index e2437a48..05b5677c 100644 --- a/proposals/2610-remove-oauth2-auth-type.md +++ b/proposals/2610-remove-oauth2-auth-type.md @@ -15,7 +15,7 @@ The definition of authentication is incomplete. [OAuth2](https://oauth.net/2/) is best considered as a framework for implementing authentication protocols rather than a protocol in its own right, and this section says nothing about the grant types, flows -and scopes which a compliant implemenation should understand. +and scopes which a compliant implementation should understand. A better candidate for OAuth2-based authentication of matrix clients is via [OpenID Connect](https://openid.net/connect/), but this has already been @@ -27,7 +27,7 @@ and redundant. It should be removed from the specification to reduce confusion. ## Alternatives It would be possible to extend the definition so that it is complete: as -mentioned above, a likely implemenation would be based on OpenID +mentioned above, a likely implementation would be based on OpenID Connect. Matrix clients could then follow the standardised OpenID Connect flow rather than the matrix-specific `m.login.sso` flow. However, this would require significant design work, and development in both clients and servers, which From e3d12d6769a1747145c46f0e82d7eba2ad23e4e4 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Thu, 11 Jun 2020 18:01:02 +0200 Subject: [PATCH 1154/1250] Remove room_id from /sync examples Signed-off-by: Nicolas Werner --- api/client-server/sync.yaml | 3 --- changelogs/client_server/newsfragments/2629.clarification | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2629.clarification diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index bf804792..1bbe7549 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -379,7 +379,6 @@ paths: "state": { "events": [ { - "room_id": "!726s6s6q:example.com", "$ref": "definitions/event-schemas/examples/m.room.member" } ] @@ -387,11 +386,9 @@ paths: "timeline": { "events": [ { - "room_id": "!726s6s6q:example.com", "$ref": "definitions/event-schemas/examples/m.room.member" }, { - "room_id": "!726s6s6q:example.com", "$ref": "definitions/event-schemas/examples/m.room.message$m.text" } ], diff --git a/changelogs/client_server/newsfragments/2629.clarification b/changelogs/client_server/newsfragments/2629.clarification new file mode 100644 index 00000000..07fc430e --- /dev/null +++ b/changelogs/client_server/newsfragments/2629.clarification @@ -0,0 +1 @@ +Remove ``room_id`` from ``/sync`` examples. From 269e83c2335f3166e6a7929c93835bc2e5289703 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 11 Jun 2020 16:14:32 -0400 Subject: [PATCH 1155/1250] more clarifications --- specification/modules/secrets.rst | 172 ++++++++++++++++++++---------- 1 file changed, 114 insertions(+), 58 deletions(-) diff --git a/specification/modules/secrets.rst b/specification/modules/secrets.rst index cb6b6a9e..bc5386bf 100644 --- a/specification/modules/secrets.rst +++ b/specification/modules/secrets.rst @@ -42,8 +42,24 @@ Each key has an ID, and the description of the key is stored in the user's account_data using the event type ``m.secret_storage.key.[key ID]``. The contents of the account data for the key will include an ``algorithm`` property, which indicates the encryption algorithm used, as well as a ``name`` -property, which is a human-readable name. Other properties depend on the -encryption algorithm, and are described below. +property, which is a human-readable name. Key descriptions may also have a +``passphrase`` property for generating the key from a user-entered +passphrase, as described in `deriving keys from passphrases`_. + +``KeyDescription`` + +============ =========== ======================================================= +Parameter Type Description +============ =========== ======================================================= +name string **Required.** The name of the key. +algorithm string **Required.** The encryption algorithm to be used for + this key. Currently, only + ``m.secret_storage.v1.aes-hmac-sha2`` is supported. +passphrase string See `deriving keys from passphrases`_ section for a + description of this property. +============ =========== ======================================================= + +Other properties depend on the encryption algorithm, and are described below. A key can be marked as the "default" key by setting the user's account_data with event type ``m.secret_storage.default_key`` to an object that has the ID @@ -64,6 +80,18 @@ schemes would have ``ciphertext`` and ``mac`` properties, where the ``ciphertext`` property is the unpadded base64-encoded ciphertext, and the ``mac`` is used to ensure the integrity of the data. +``Secret`` + +============ =========== ======================================================= +Parameter Type Description +============ =========== ======================================================= +encrypted {string: **Required.** Map from key ID the encrypted data. The + object} exact format for the encrypted data is dependent on the + key algorithm. See the definition of + ``AesHmacSha2EncryptedData`` in the + `m.secret_storage.v1.aes-hmac-sha2`_ section. +============ =========== ======================================================= + Example: Some secret is encrypted using keys with ID ``key_id_1`` and ``key_id_2``: @@ -108,6 +136,88 @@ and the key descriptions for the keys would be: // ... other properties according to algorithm } +``m.secret_storage.v1.aes-hmac-sha2`` ++++++++++++++++++++++++++++++++++++++ + +Secrets encrypted using the ``m.secret_storage.v1.aes-hmac-sha2`` algorithm are +encrypted using AES-CTR-256, and authenticated using HMAC-SHA-256. The secret is +encrypted as follows: + +1. Given the secret storage key, generate 64 bytes by performing an HKDF with + SHA-256 as the hash, a salt of 32 bytes of 0, and with the secret name as + the info. The first 32 bytes are used as the AES key, and the next 32 bytes + are used as the MAC key +2. Generate 16 random bytes, set bit 63 to 0 (in order to work around + differences in AES-CTR implementations), and use this as the AES + initialization vector. This becomes the ``iv`` property, encoded using base64. +3. Encrypt the data using AES-CTR-256 using the AES key generated above. This + encrypted data, encoded using base64, becomes the ``ciphertext`` property. +4. Pass the raw encrypted data (prior to base64 encoding) through HMAC-SHA-256 + using the MAC key generated above. The resulting MAC is base64-encoded and + becomes the ``mac`` property. + +``AesHmacSha2EncryptedData`` + +============ =========== ======================================================= +Parameter Type Description +============ =========== ======================================================= +iv String **Required.** The 16-byte initialization vector, + encoded as base64. +ciphertext String **Required.** The AES-CTR-encrypted data, encoded as + base64. +mac String **Required.** The MAC, encoded as base64. +============ =========== ======================================================= + +For the purposes of allowing clients to check whether a user has correctly +entered the key, clients should: + +1. encrypt and MAC a message consisting of 32 bytes of 0 as described above, + using the empty string as the info parameter to the HKDF in step 1. +2. store the ``iv`` and ``mac`` in the ``m.secret_storage.key.[key ID]`` + account-data. + +``AesHmacSha2KeyDescription`` + +============ =========== ======================================================= +Parameter Type Description +============ =========== ======================================================= +name string **Required.** The name of the key. +algorithm string **Required.** The encryption algorithm to be used for + this key. Currently, only + ``m.secret_storage.v1.aes-hmac-sha2`` is supported. +passphrase string See `deriving keys from passphrases`_ section for a + description of this property. +iv String The 16-byte initialization vector, encoded as base64. +mac String The MAC of the result of encrypting 32 bytes of 0, + encoded as base64. +============ =========== ======================================================= + +For example, the ``m.secret_storage.key.key_id`` for a key using this algorithm +could look like: + +.. code:: json + + { + "name": "m.default", + "algorithm": "m.secret_storage.v1.aes-hmac-sha2", + "iv": "random+data", + "mac": "mac+of+encrypted+zeros" + } + +and data encrypted using this algorithm could look like this: + +.. code:: json + + { + "encrypted": { + "key_id": { + "iv": "16+bytes+base64", + "ciphertext": "base64+encoded+encrypted+data", + "mac": "base64+encoded+mac" + } + } + } + Key representation ++++++++++++++++++ @@ -128,8 +238,8 @@ it will be presented as a string constructed as follows: When decoding a raw key, the process should be reversed, with the exception that whitespace is insignificant in the user's input. -Passphrase -++++++++++ +Deriving keys from passphrases +++++++++++++++++++++++++++++++ A user may wish to use a chosen passphrase rather than a randomly generated key. In this case, information on how to generate the key from a passphrase @@ -172,60 +282,6 @@ Example: ... } -``m.secret_storage.v1.aes-hmac-sha2`` -+++++++++++++++++++++++++++++++++++++ - -Secrets encrypted using the ``m.secret_storage.v1.aes-hmac-sha2`` algorithm are -encrypted using AES-CTR-256, and authenticated using HMAC-SHA-256. The secret is -encrypted as follows: - -1. Given the secret storage key, generate 64 bytes by performing an HKDF with - SHA-256 as the hash, a salt of 32 bytes of 0, and with the secret name as - the info. The first 32 bytes are used as the AES key, and the next 32 bytes - are used as the MAC key -2. Generate 16 random bytes, set bit 63 to 0 (in order to work around - differences in AES-CTR implementations), and use this as the AES - initialization vector. This becomes the ``iv`` property, encoded using base64. -3. Encrypt the data using AES-CTR-256 using the AES key generated above. This - encrypted data, encoded using base64, becomes the ``ciphertext`` property. -4. Pass the raw encrypted data (prior to base64 encoding) through HMAC-SHA-256 - using the MAC key generated above. The resulting MAC is base64-encoded and - becomes the ``mac`` property. - -For the purposes of allowing clients to check whether a user has correctly -entered the key, clients should: - -1. encrypt and MAC a message consisting of 32 bytes of 0 as described above, - using the empty string as the info parameter to the HKDF in step 1. -2. store the ``iv`` and ``mac`` in the ``m.secret_storage.key.[key ID]`` - account-data. - -For example, the ``m.secret_storage.key.key_id`` for a key using this algorithm -could look like: - -.. code:: json - - { - "name": "m.default", - "algorithm": "m.secret_storage.v1.aes-hmac-sha2", - "iv": "random+data", - "mac": "mac+of+encrypted+zeros" - } - -and data encrypted using this algorithm could look like this: - -.. code:: json - - { - "encrypted": { - "key_id": { - "iv": "16+bytes+base64", - "ciphertext": "base64+encoded+encrypted+data", - "mac": "base64+encoded+mac" - } - } - } - Sharing ------- From 0fbb1b9bf9c18c7705263a0364663f3f1bd1aec2 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 11 Jun 2020 16:25:07 -0400 Subject: [PATCH 1156/1250] add information on fixed implementations --- proposals/xxxx-sas-v2.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/proposals/xxxx-sas-v2.md b/proposals/xxxx-sas-v2.md index d9d37471..d57f5119 100644 --- a/proposals/xxxx-sas-v2.md +++ b/proposals/xxxx-sas-v2.md @@ -42,3 +42,14 @@ addition of `|` as delimiter between the fields. The `key_agreement_protocol` `curve25519` is deprecated and may be removed in the future. It will no longer be mandatory for clients to support, and new implementations are discouraged from implementing it. + +## Implementation + +This has been implemented in: + +- Riot Web 1.6.3 (matrix-js-sdk 6.2.0) +- Riot Android 0.9.12 (matrix-android-sdk 0.9.35) +- RiotX 0.21 +- Riot iOS 0.11.5 (matrix-ios-sdk 0.16.5) +- matrix-weechat and pantalaimon (matrix-nio 0.12.0) +- FluffyChat (famedlysdk) From d9dc3dc1801a7dfde7d45680c3d1191b9985abf1 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 11 Jun 2020 16:30:47 -0400 Subject: [PATCH 1157/1250] rename to match MSC number --- proposals/{xxxx-sas-v2.md => 2630-sas-check-public-keys.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename proposals/{xxxx-sas-v2.md => 2630-sas-check-public-keys.md} (100%) diff --git a/proposals/xxxx-sas-v2.md b/proposals/2630-sas-check-public-keys.md similarity index 100% rename from proposals/xxxx-sas-v2.md rename to proposals/2630-sas-check-public-keys.md From 1961a215e8eae5c41e1cc19301c18454b45153c6 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 11 Jun 2020 16:36:25 -0400 Subject: [PATCH 1158/1250] Fix the title --- proposals/2630-sas-check-public-keys.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2630-sas-check-public-keys.md b/proposals/2630-sas-check-public-keys.md index d57f5119..080fe795 100644 --- a/proposals/2630-sas-check-public-keys.md +++ b/proposals/2630-sas-check-public-keys.md @@ -1,4 +1,4 @@ -# checking public keys in SAS verification +# MSC2630: Checking public keys in SAS verification The current SAS protocol does not ensure that the two users correctly received each other's public keys. An attacker could send Alice and Bob public keys From 6ca3996bef5f94a6e72e850cf33f0d091418db3d Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 11 Jun 2020 16:39:08 -0400 Subject: [PATCH 1159/1250] FluffyChat doesn't include any verification yet --- proposals/2630-sas-check-public-keys.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2630-sas-check-public-keys.md b/proposals/2630-sas-check-public-keys.md index 080fe795..e42a2528 100644 --- a/proposals/2630-sas-check-public-keys.md +++ b/proposals/2630-sas-check-public-keys.md @@ -52,4 +52,4 @@ This has been implemented in: - RiotX 0.21 - Riot iOS 0.11.5 (matrix-ios-sdk 0.16.5) - matrix-weechat and pantalaimon (matrix-nio 0.12.0) -- FluffyChat (famedlysdk) +- famedlysdk From 9b7a883b50a612dd2c577b1db7887f544547c502 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Mon, 15 Jun 2020 20:34:47 +0100 Subject: [PATCH 1160/1250] MSCXXXX: Ability for clients to request homeservers to resync device lists --- proposals/XXXX-client-request-device-list.md | 107 +++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 proposals/XXXX-client-request-device-list.md diff --git a/proposals/XXXX-client-request-device-list.md b/proposals/XXXX-client-request-device-list.md new file mode 100644 index 00000000..b36cfbc6 --- /dev/null +++ b/proposals/XXXX-client-request-device-list.md @@ -0,0 +1,107 @@ +# MSCXXXX: Ability for clients to request homeservers to resync device lists + +With the recent roll out of cross-signing, +[some](https://github.com/matrix-org/synapse/issues/7418) +[bugs](https://github.com/matrix-org/synapse/issues/7504) in Synapse were +reported around the way it was handling failures when processing device list +updates started hitting users, causing local copies of remote device lists to +grow stale. + +Remote device lists growing stale can happen as soon as a homeserver +implementation implements processing of device list updates improperly, or +without the proper retry mechanisms. It can also happen if a homeserver was down +for enough time to miss out on device list updates. + +The main consequence of this situation is rendering it impossible for impacted +users to use cross-signing/end-to-end encryption for some remote devices, or +even to use it at all. + +When fixing this issue, it is currently quite difficult for a homeserver to +figure out which users it should resync the device lists of. However, it is much +easier for clients to see if a device list is likely out of date (e.g. if it has +cross-signing keys but no signatures), and almost trivial for users to do so +(e.g. if someone tells me "I've enabled cross-signing" but I can't see their +cross-signing keys, then I know something has gone wrong). + +In the current situation, the best answer we can give to a user seeing stale +device lists is to ask their server admin to get their instance to somehow (the +details on how to do it depend on the implementation) resync the device list(s) +for the impacted user(s), which isn't an acceptable solution. + +For clarity, "resync" here means for a homeserver to ask the latest version of a +user's device list to their homeserver, using the [`GET +/_matrix/federation/v1/user/devices/{userId}`](https://matrix.org/docs/spec/server_server/latest#get-matrix-federation-v1-user-devices-userid) +federation endpoint. "device list update" here describes both a +`m.device_list_update` EDU and a `m.signing_key_update` one. + +The proposal descibed here fixes this issue by adding a new endpoint to the +client-server API, allowing clients to request homeservers to resync device +lists. Clients could then either expose a button a user can use when necessary, +or call this endpoint on specific actions, or both. + +## Proposal + +This proposal adds the following endpoint to the client-server API: + +### `GET /_matrix/client/r0/user/{userId}/devices` + +In this request, `{userId}` is the full Matrix ID of the user to retrieve the +device list for. + +The homeserver responds to a request to this endpoint with a 202 Accepted +response code and an empty body (`{}`). + +Upon request to this client-side endpoint, the homeserver would send a request +to [`GET +/_matrix/federation/v1/user/devices/{userId}`](https://matrix.org/docs/spec/server_server/latest#get-matrix-federation-v1-user-devices-userid) +on the target user's homeserver to retrieve the device list. + +If the request to the aforementioned federation endpoint succeeds (i.e. the +destination responds with a 200 response code and a device list for the target +user), then the homeserver would include the updated device list in sync +responses in order to relay it to clients. + +If the request to the aforementioned federation endpoint fails (i.e. the +destination responds with a non-200 response code or times out), then the +homeserver should relay this error to clients, but should also schedule retries +for this request in case the destination starts working again. In case one of +these retries succeeds (i.e. the destination responds with a 200 response code +and a device list for the target user), the homeserver would include the updated +device list in sync responses. + +Clients can then make requests to this endpoint, either upon an explicit +request from the user (e.g. clicking a button) or while performing other actions +(e.g. creating an encrypted 1:1 chat, processing an invite in a group chat, +sending a verification request, etc.). + +XXX: I'm unsure whether the spec should be mandating when a client uses this +endpoint or whether this is left as an implementation detail. + + +## Alternatives + +An alternative to this proposal is to let homeservers figure out when a good +time to resync a device list is. However, it can be difficult for it to do so, +especially as it can't see some of the actions a resync would be most useful for +(e.g. sending a verification request, which are encrypted in encrypted rooms). +It therefore makes more sense to do this on the client-side, and it also adds +the ability for the user to figure out when a device list needs to be resynced. + +Another approach would be to have the homeserver directly relay the response to +the client in the response to a `GET /_matrix/client/r0/user/{userId}/devices` +request. This approach has been dropped in order to stay consistent in how we +relay device list updates to users. + + +## Security considerations + +This could provide a way for users to flood remote homeservers with federated +device list requests. However, this can be easily mitigated with rate-limiting +and a short-lived cache on the homeserver. + + +## Unstable prefix + +Until this MSC is merged and included in a stable release of the spec, +implementations should use the route +`GET /_matrix/unstable/org.matrix.mscXXXX/user/{userId}/devices`. From f1e3118317c3c4b36c014b73e0909c0d67d1300f Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Mon, 15 Jun 2020 20:35:58 +0100 Subject: [PATCH 1161/1250] Revert "MSCXXXX: Ability for clients to request homeservers to resync device lists" This reverts commit 79dc04515e562847774e2f722fb14401bfb90583. --- proposals/XXXX-client-request-device-list.md | 107 ------------------- 1 file changed, 107 deletions(-) delete mode 100644 proposals/XXXX-client-request-device-list.md diff --git a/proposals/XXXX-client-request-device-list.md b/proposals/XXXX-client-request-device-list.md deleted file mode 100644 index b36cfbc6..00000000 --- a/proposals/XXXX-client-request-device-list.md +++ /dev/null @@ -1,107 +0,0 @@ -# MSCXXXX: Ability for clients to request homeservers to resync device lists - -With the recent roll out of cross-signing, -[some](https://github.com/matrix-org/synapse/issues/7418) -[bugs](https://github.com/matrix-org/synapse/issues/7504) in Synapse were -reported around the way it was handling failures when processing device list -updates started hitting users, causing local copies of remote device lists to -grow stale. - -Remote device lists growing stale can happen as soon as a homeserver -implementation implements processing of device list updates improperly, or -without the proper retry mechanisms. It can also happen if a homeserver was down -for enough time to miss out on device list updates. - -The main consequence of this situation is rendering it impossible for impacted -users to use cross-signing/end-to-end encryption for some remote devices, or -even to use it at all. - -When fixing this issue, it is currently quite difficult for a homeserver to -figure out which users it should resync the device lists of. However, it is much -easier for clients to see if a device list is likely out of date (e.g. if it has -cross-signing keys but no signatures), and almost trivial for users to do so -(e.g. if someone tells me "I've enabled cross-signing" but I can't see their -cross-signing keys, then I know something has gone wrong). - -In the current situation, the best answer we can give to a user seeing stale -device lists is to ask their server admin to get their instance to somehow (the -details on how to do it depend on the implementation) resync the device list(s) -for the impacted user(s), which isn't an acceptable solution. - -For clarity, "resync" here means for a homeserver to ask the latest version of a -user's device list to their homeserver, using the [`GET -/_matrix/federation/v1/user/devices/{userId}`](https://matrix.org/docs/spec/server_server/latest#get-matrix-federation-v1-user-devices-userid) -federation endpoint. "device list update" here describes both a -`m.device_list_update` EDU and a `m.signing_key_update` one. - -The proposal descibed here fixes this issue by adding a new endpoint to the -client-server API, allowing clients to request homeservers to resync device -lists. Clients could then either expose a button a user can use when necessary, -or call this endpoint on specific actions, or both. - -## Proposal - -This proposal adds the following endpoint to the client-server API: - -### `GET /_matrix/client/r0/user/{userId}/devices` - -In this request, `{userId}` is the full Matrix ID of the user to retrieve the -device list for. - -The homeserver responds to a request to this endpoint with a 202 Accepted -response code and an empty body (`{}`). - -Upon request to this client-side endpoint, the homeserver would send a request -to [`GET -/_matrix/federation/v1/user/devices/{userId}`](https://matrix.org/docs/spec/server_server/latest#get-matrix-federation-v1-user-devices-userid) -on the target user's homeserver to retrieve the device list. - -If the request to the aforementioned federation endpoint succeeds (i.e. the -destination responds with a 200 response code and a device list for the target -user), then the homeserver would include the updated device list in sync -responses in order to relay it to clients. - -If the request to the aforementioned federation endpoint fails (i.e. the -destination responds with a non-200 response code or times out), then the -homeserver should relay this error to clients, but should also schedule retries -for this request in case the destination starts working again. In case one of -these retries succeeds (i.e. the destination responds with a 200 response code -and a device list for the target user), the homeserver would include the updated -device list in sync responses. - -Clients can then make requests to this endpoint, either upon an explicit -request from the user (e.g. clicking a button) or while performing other actions -(e.g. creating an encrypted 1:1 chat, processing an invite in a group chat, -sending a verification request, etc.). - -XXX: I'm unsure whether the spec should be mandating when a client uses this -endpoint or whether this is left as an implementation detail. - - -## Alternatives - -An alternative to this proposal is to let homeservers figure out when a good -time to resync a device list is. However, it can be difficult for it to do so, -especially as it can't see some of the actions a resync would be most useful for -(e.g. sending a verification request, which are encrypted in encrypted rooms). -It therefore makes more sense to do this on the client-side, and it also adds -the ability for the user to figure out when a device list needs to be resynced. - -Another approach would be to have the homeserver directly relay the response to -the client in the response to a `GET /_matrix/client/r0/user/{userId}/devices` -request. This approach has been dropped in order to stay consistent in how we -relay device list updates to users. - - -## Security considerations - -This could provide a way for users to flood remote homeservers with federated -device list requests. However, this can be easily mitigated with rate-limiting -and a short-lived cache on the homeserver. - - -## Unstable prefix - -Until this MSC is merged and included in a stable release of the spec, -implementations should use the route -`GET /_matrix/unstable/org.matrix.mscXXXX/user/{userId}/devices`. From 5cb4b086c7acdfd616099252c3d4c0dffeb0a09c Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 16 Jun 2020 16:56:31 +0100 Subject: [PATCH 1162/1250] Clarifications to the push module (#2634) * Minor clarifications to the push spec * move conditions before defaults --- .../newsfragments/2634.clarification | 1 + specification/modules/push.rst | 132 ++++++++---------- 2 files changed, 62 insertions(+), 71 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2634.clarification diff --git a/changelogs/client_server/newsfragments/2634.clarification b/changelogs/client_server/newsfragments/2634.clarification new file mode 100644 index 00000000..64d9f142 --- /dev/null +++ b/changelogs/client_server/newsfragments/2634.clarification @@ -0,0 +1 @@ +Minor clarifications to the "Push Notifications" module. diff --git a/specification/modules/push.rst b/specification/modules/push.rst index ebf1aef2..37b149bc 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -33,13 +33,13 @@ Push Notifications Matrix | | | | | | Client/Server API + | | | | | | | +--------------------+ +-------------------+ - | +--+-+ | - | | <-------------------------------------------+ - +---+ | - | | Provider Push Protocol - +----+ - - Mobile Device or Client + | +--+-+ | + | | <-------------------------------------------+ + +---+ | + | | Provider Push Protocol + +----+ + + Mobile Device or Client This module adds support for push notifications. Homeservers send notifications @@ -135,8 +135,9 @@ There are different "kinds" of push rules and each rule has an associated priority. Every push rule MUST have a ``kind`` and ``rule_id``. The ``rule_id`` is a unique string within the kind of rule and its' scope: ``rule_ids`` do not need to be unique between rules of the same kind on different devices. Rules may -have extra keys depending on the value of ``kind``. The different kinds of rule -in descending order of priority are: +have extra keys depending on the value of ``kind``. + +The different ``kind``\ s of rule, in the order that they are checked, are: Override Rules ``override`` The highest priority rules are user-configured overrides. @@ -156,15 +157,6 @@ Underride rules ``underride`` These are identical to ``override`` rules, but have a lower priority than ``content``, ``room`` and ``sender`` rules. -This means that the full list of rule kinds, in descending priority order, is -as follows: - -* Global Override -* Global Content -* Global Room -* Global Sender -* Global Underride - Rules with the same ``kind`` can specify an ordering priority. This determines which rule is selected in the event of multiple matches. For example, a rule matching "tea" and a separate rule matching "time" would both match the sentence @@ -224,6 +216,55 @@ Tweaks are passed transparently through the homeserver so client applications and Push Gateways may agree on additional tweaks. For example, a tweak may be added to specify how to flash the notification light on a mobile device. +Conditions +++++++++++ + +``override`` and ``underride`` rules MAY have a list of 'conditions'. +All conditions must hold true for an event in order for the rule to match. +A rule with no conditions always matches. The following conditions are defined: + +``event_match`` + This is a glob pattern match on a field of the event. Parameters: + + * ``key``: The dot-separated field of the event to match, e.g. ``content.body`` + * ``pattern``: The glob-style pattern to match against. Patterns with no + special glob characters should be treated as having asterisks + prepended and appended when testing the condition. + +``contains_display_name`` + This matches unencrypted messages where ``content.body`` contains the owner's + display name in that room. This is a separate rule because display names may + change and as such it would be hard to maintain a rule that matched the user's + display name. This condition has no parameters. + +``room_member_count`` + This matches the current number of members in the room. Parameters: + + * ``is``: A decimal integer optionally prefixed by one of, ``==``, ``<``, + ``>``, ``>=`` or ``<=``. A prefix of ``<`` matches rooms where the member + count is strictly less than the given number and so forth. If no prefix is + present, this parameter defaults to ``==``. + +``sender_notification_permission`` + This takes into account the current power levels in the room, ensuring the + sender of the event has high enough power to trigger the notification. + + Parameters: + + * ``key``: A string that determines the power level the sender must have to trigger + notifications of a given type, such as ``room``. Refer to the `m.room.power_levels`_ + event schema for information about what the defaults are and how to interpret the event. + The ``key`` is used to look up the power level required to send a notification type + from the ``notifications`` object in the power level event content. + +Unrecognised conditions MUST NOT match any events, effectively making the push +rule disabled. + +``room``, ``sender`` and ``content`` rules do not have conditions in the same +way, but instead have predefined conditions. In the cases of ``room`` and +``sender`` rules, the ``rule_id`` of the rule determines its behaviour. + + Predefined Rules ++++++++++++++++ Homeservers can specify "server-default rules" which operate at a lower priority @@ -237,7 +278,7 @@ Default Override Rules ``.m.rule.master`` `````````````````` -Matches all events, this can be enabled to turn off all push notifications +Matches all events. This can be enabled to turn off all push notifications other than those generated by override rules set by the user. By default this rule is disabled. @@ -257,9 +298,7 @@ Definition ``.m.rule.suppress_notices`` ```````````````````````````` -Matches messages with a ``msgtype`` of ``notice``. This should be an -``override`` rule so that it takes priority over ``content`` / ``sender`` / -``room`` rules. +Matches messages with a ``msgtype`` of ``notice``. Definition: @@ -650,55 +689,6 @@ Definition: ] } - -Conditions -++++++++++ - -Override, Underride and Default Rules MAY have a list of 'conditions'. -All conditions must hold true for an event in order to apply the ``action`` for -the event. A rule with no conditions always matches. Room, Sender, User and -Content rules do not have conditions in the same way, but instead have -predefined conditions. These conditions can be configured using the parameters -outlined below. In the cases of room and sender rules, the ``rule_id`` of the -rule determines its behaviour. The following conditions are defined: - -``event_match`` - This is a glob pattern match on a field of the event. Parameters: - - * ``key``: The dot-separated field of the event to match, e.g. ``content.body`` - * ``pattern``: The glob-style pattern to match against. Patterns with no - special glob characters should be treated as having asterisks - prepended and appended when testing the condition. - -``contains_display_name`` - This matches unencrypted messages where ``content.body`` contains the owner's - display name in that room. This is a separate rule because display names may - change and as such it would be hard to maintain a rule that matched the user's - display name. This condition has no parameters. - -``room_member_count`` - This matches the current number of members in the room. Parameters: - - * ``is``: A decimal integer optionally prefixed by one of, ``==``, ``<``, - ``>``, ``>=`` or ``<=``. A prefix of ``<`` matches rooms where the member - count is strictly less than the given number and so forth. If no prefix is - present, this parameter defaults to ``==``. - -``sender_notification_permission`` - This takes into account the current power levels in the room, ensuring the - sender of the event has high enough power to trigger the notification. - - Parameters: - - * ``key``: A string that determines the power level the sender must have to trigger - notifications of a given type, such as ``room``. Refer to the `m.room.power_levels`_ - event schema for information about what the defaults are and how to interpret the event. - The ``key`` is used to look up the power level required to send a notification type - from the ``notifications`` object in the power level event content. - -Unrecognised conditions MUST NOT match any events, effectively making the push -rule disabled. - Push Rules: API ~~~~~~~~~~~~~~~ From af6e1157d90dc8976e4f3892a5c1abb9fb0ecdf7 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 16 Jun 2020 14:23:10 -0400 Subject: [PATCH 1163/1250] version is required when getting keys. Also add some full stops. --- api/client-server/key_backup.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/api/client-server/key_backup.yaml b/api/client-server/key_backup.yaml index 34dce118..a0baccc3 100644 --- a/api/client-server/key_backup.yaml +++ b/api/client-server/key_backup.yaml @@ -130,7 +130,7 @@ paths: example: "anopaquestring" version: type: string - description: The backup version + description: The backup version. example: "1" required: - algorithm @@ -212,7 +212,7 @@ paths: example: "anopaquestring" version: type: string - description: The backup version + description: The backup version. example: "1" required: - algorithm @@ -450,7 +450,7 @@ paths: type: string name: version description: |- - The backup from which to retrieve the key + The backup from which to retrieve the key. required: true x-example: "1" - in: path @@ -645,7 +645,7 @@ paths: type: string name: version description: |- - The backup from which to retrieve the key + The backup from which to retrieve the key. required: true x-example: "1" - in: path @@ -702,7 +702,7 @@ paths: type: string name: version description: |- - The backup from which to delete the key + The backup from which to delete the key. required: true x-example: "1" - in: path @@ -846,8 +846,8 @@ paths: type: string name: version description: |- - The backup from which to retrieve the keys. If omitted, the keys are - retrieved from the current backup. + The backup from which to retrieve the keys. + required: true x-example: "1" responses: 200: From 24427242f7f78f7b633e43f7c5b1818c2fe2ad4f Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 16 Jun 2020 17:00:29 -0400 Subject: [PATCH 1164/1250] fix more mistakes in key backup spec, and factor out room key backups --- .../definitions/room_key_backup.yaml | 38 ++++++++++ api/client-server/key_backup.yaml | 75 +++++++------------ 2 files changed, 65 insertions(+), 48 deletions(-) create mode 100644 api/client-server/definitions/room_key_backup.yaml diff --git a/api/client-server/definitions/room_key_backup.yaml b/api/client-server/definitions/room_key_backup.yaml new file mode 100644 index 00000000..5c70850f --- /dev/null +++ b/api/client-server/definitions/room_key_backup.yaml @@ -0,0 +1,38 @@ +# Copyright 2020 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: RoomKeyBackup +description: "The backed up keys for a room." +properties: + sessions: + type: object + description: "A map of session IDs to key data." + additionalProperties: + allOf: + - $ref: "key_backup_data.yaml" + example: { + "sessionid1": { + "first_message_index": 1, + "forwarded_count": 0, + "is_verified": true, + "session_data": { + "ephemeral": "base64+ephemeral+key", + "ciphertext": "base64+ciphertext+of+JSON+data", + "mac": "base64+mac+of+ciphertext" + } + } + } +required: + - sessions diff --git a/api/client-server/key_backup.yaml b/api/client-server/key_backup.yaml index a0baccc3..31c66a25 100644 --- a/api/client-server/key_backup.yaml +++ b/api/client-server/key_backup.yaml @@ -569,22 +569,7 @@ paths: description: "The backup data" name: backupData schema: - type: object - properties: - sessions: - type: object - description: |- - A map of session IDs to key data. - additionalProperties: - allOf: - - $ref: "definitions/key_backup_data.yaml" - example: { - "sessionid1": { - "ephemeral": "base64+ephemeral+key", - "ciphertext": "base64+ciphertext+of+JSON+data", - "mac": "base64+mac+of+ciphertext" - } - } + $ref: "definitions/room_key_backup.yaml" responses: 200: description: The update succeeded @@ -661,21 +646,7 @@ paths: ``sessions`` property will be returned (``{"sessions": {}}``). schema: type: object - properties: - sessions: - type: object - description: |- - A map of session IDs to key data. - additionalProperties: - allOf: - - $ref: "definitions/key_backup_data.yaml" - example: { - "sessionid1": { - "ephemeral": "base64+ephemeral+key", - "ciphertext": "base64+ciphertext+of+JSON+data", - "mac": "base64+mac+of+ciphertext" - } - } + $ref: "definitions/room_key_backup.yaml" 404: description: |- The backup was not found. @@ -761,7 +732,7 @@ paths: required: true x-example: "1" - in: body - description: "The backup data" + description: "The backup data." name: backupData schema: type: object @@ -769,23 +740,28 @@ paths: rooms: type: object description: |- - A map of room IDs to session IDs to key data. + A map of room IDs to room key backup data. additionalProperties: - type: object - additionalProperties: - allOf: - - $ref: "definitions/key_backup_data.yaml" + allOf: + - $ref: "definitions/room_key_backup.yaml" example: { "!room:example.org": { "sessions": { "sessionid1": { - "ephemeral": "base64+ephemeral+key", - "ciphertext": "base64+ciphertext+of+JSON+data", - "mac": "base64+mac+of+ciphertext" + "first_message_index": 1, + "forwarded_count": 0, + "is_verified": true, + "session_data": { + "ephemeral": "base64+ephemeral+key", + "ciphertext": "base64+ciphertext+of+JSON+data", + "mac": "base64+mac+of+ciphertext" + } } } } } + required: + - rooms responses: 200: description: The update succeeded @@ -860,19 +836,22 @@ paths: rooms: type: object description: |- - A map of room IDs to session IDs to key data. + A map of room IDs to room key backup data. additionalProperties: - type: object - additionalProperties: - allOf: - - $ref: "definitions/key_backup_data.yaml" + allOf: + - $ref: "definitions/room_key_backup.yaml" example: { "!room:example.org": { "sessions": { "sessionid1": { - "ephemeral": "base64+ephemeral+key", - "ciphertext": "base64+ciphertext+of+JSON+data", - "mac": "base64+mac+of+ciphertext" + "first_message_index": 1, + "forwarded_count": 0, + "is_verified": true, + "session_data": { + "ephemeral": "base64+ephemeral+key", + "ciphertext": "base64+ciphertext+of+JSON+data", + "mac": "base64+mac+of+ciphertext" + } } } } From b44ebaa32e2e81b6b875bd66a82233d26e18e063 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 16 Jun 2020 17:06:36 -0400 Subject: [PATCH 1165/1250] add changelog --- changelogs/client_server/2639.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/2639.clarification diff --git a/changelogs/client_server/2639.clarification b/changelogs/client_server/2639.clarification new file mode 100644 index 00000000..7d7032ba --- /dev/null +++ b/changelogs/client_server/2639.clarification @@ -0,0 +1 @@ +Fixed some errors in the key backup spec. \ No newline at end of file From c76d53c11a953bb84ac3aac467d2544e561e9ff9 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Thu, 18 Jun 2020 11:03:43 +0200 Subject: [PATCH 1166/1250] Apply suggestions from code review --- api/client-server/content-repo.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/api/client-server/content-repo.yaml b/api/client-server/content-repo.yaml index 5fd1f12d..71c35f01 100644 --- a/api/client-server/content-repo.yaml +++ b/api/client-server/content-repo.yaml @@ -165,8 +165,9 @@ paths: get: summary: Download content from the content repository overriding the file name description: |- - This is the same as the download endpoint above, except permitting - a desired file name. + This will download content from the content repository (same as + the previous endpoint) but replace the target file name with the one + provided by the caller. operationId: getContentOverrideName produces: ["*/*"] parameters: @@ -236,6 +237,7 @@ paths: get: summary: Download a thumbnail of content from the content repository description: |- + Download a thumbnail of content from the content repository. See the `thumbnailing <#thumbnails>`_ section for more information. operationId: getContentThumbnail produces: ["image/jpeg", "image/png"] From 049275c33bcddebc106ed5de463cc2f82cea05ea Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Fri, 19 Jun 2020 19:45:52 +0200 Subject: [PATCH 1167/1250] Consistently use the title UnsignedData for the unsigned object --- api/client-server/definitions/event.yaml | 2 +- api/server-server/definitions/unsigned_pdu_base.yaml | 2 +- api/server-server/invites-v1.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/client-server/definitions/event.yaml b/api/client-server/definitions/event.yaml index a53b6af7..7d5808b1 100644 --- a/api/client-server/definitions/event.yaml +++ b/api/client-server/definitions/event.yaml @@ -59,7 +59,7 @@ properties: description: Optional. The event that redacted this event, if any. title: Event type: object - title: Unsigned + title: UnsignedData type: object title: Event type: object diff --git a/api/server-server/definitions/unsigned_pdu_base.yaml b/api/server-server/definitions/unsigned_pdu_base.yaml index f1485b55..c97e74de 100644 --- a/api/server-server/definitions/unsigned_pdu_base.yaml +++ b/api/server-server/definitions/unsigned_pdu_base.yaml @@ -115,7 +115,7 @@ properties: example: "$def456:matrix.org" unsigned: type: object - title: Example Unsigned Data + title: UnsignedData description: |- Additional data added by the origin server but not covered by the ``signatures``. More keys than those defined here may be used. diff --git a/api/server-server/invites-v1.yaml b/api/server-server/invites-v1.yaml index 8e1c861d..c62d8e3d 100644 --- a/api/server-server/invites-v1.yaml +++ b/api/server-server/invites-v1.yaml @@ -70,7 +70,7 @@ paths: properties: unsigned: type: object - title: Unsigned Event Content + title: UnsignedData description: |- Information included alongside the event that is not signed. May include more than what is listed here. From 763e5654cc00e97345169a9da7791eebeec4dcb8 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Fri, 19 Jun 2020 20:09:39 +0200 Subject: [PATCH 1168/1250] Make event's title fields UpperCamelCase and distinguish /sync ones --- api/server-server/definitions/invite_event.yaml | 2 +- changelogs/client_server/newsfragments/2647.clarification | 1 + event-schemas/schema/core-event-schema/room_event.yaml | 2 +- event-schemas/schema/core-event-schema/state_event.yaml | 2 +- event-schemas/schema/core-event-schema/sync_room_event.yaml | 2 +- event-schemas/schema/core-event-schema/sync_state_event.yaml | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2647.clarification diff --git a/api/server-server/definitions/invite_event.yaml b/api/server-server/definitions/invite_event.yaml index 674ef2c9..dd2efdd6 100644 --- a/api/server-server/definitions/invite_event.yaml +++ b/api/server-server/definitions/invite_event.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. type: object -title: Invite Event +title: InviteEvent description: |- An invite event. Note that events have a different format depending on the room version - check the `room version specification`_ for precise event formats. diff --git a/changelogs/client_server/newsfragments/2647.clarification b/changelogs/client_server/newsfragments/2647.clarification new file mode 100644 index 00000000..a79ec474 --- /dev/null +++ b/changelogs/client_server/newsfragments/2647.clarification @@ -0,0 +1 @@ +Improve consistency and clarity of event schema ``title``s. diff --git a/event-schemas/schema/core-event-schema/room_event.yaml b/event-schemas/schema/core-event-schema/room_event.yaml index 231d5c65..6a74acdc 100644 --- a/event-schemas/schema/core-event-schema/room_event.yaml +++ b/event-schemas/schema/core-event-schema/room_event.yaml @@ -9,5 +9,5 @@ properties: type: string required: - room_id -title: Room Event +title: RoomEvent type: object diff --git a/event-schemas/schema/core-event-schema/state_event.yaml b/event-schemas/schema/core-event-schema/state_event.yaml index 816f925f..d2ff5243 100644 --- a/event-schemas/schema/core-event-schema/state_event.yaml +++ b/event-schemas/schema/core-event-schema/state_event.yaml @@ -2,5 +2,5 @@ allOf: - $ref: room_event.yaml - $ref: sync_state_event.yaml description: State Events have the following fields. -title: State Event +title: StateEvent type: object diff --git a/event-schemas/schema/core-event-schema/sync_room_event.yaml b/event-schemas/schema/core-event-schema/sync_room_event.yaml index fef13ad0..7ad7191b 100644 --- a/event-schemas/schema/core-event-schema/sync_room_event.yaml +++ b/event-schemas/schema/core-event-schema/sync_room_event.yaml @@ -39,5 +39,5 @@ required: - event_id - sender - origin_server_ts -title: Room Event +title: SyncRoomEvent type: object diff --git a/event-schemas/schema/core-event-schema/sync_state_event.yaml b/event-schemas/schema/core-event-schema/sync_state_event.yaml index 1b6ce9b2..dc48f941 100644 --- a/event-schemas/schema/core-event-schema/sync_state_event.yaml +++ b/event-schemas/schema/core-event-schema/sync_state_event.yaml @@ -35,5 +35,5 @@ properties: type: string required: - state_key -title: State Event +title: SyncStateEvent type: object From 8e2ba5ad2ac3af0ea75b7be7f6d7370f67960f79 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 23 Jun 2020 16:20:51 -0400 Subject: [PATCH 1169/1250] remove nonexistent field in verification and fix types in secret storage --- event-schemas/schema/m.key.verification.accept | 5 ----- specification/modules/secrets.rst | 12 ++++++------ 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/event-schemas/schema/m.key.verification.accept b/event-schemas/schema/m.key.verification.accept index ad54488e..3f579cc4 100644 --- a/event-schemas/schema/m.key.verification.accept +++ b/event-schemas/schema/m.key.verification.accept @@ -13,11 +13,6 @@ properties: description: |- An opaque identifier for the verification process. Must be the same as the one used for the ``m.key.verification.start`` message. - method: - type: string - enum: ["m.sas.v1"] - description: |- - The verification method to use. key_agreement_protocol: type: string description: |- diff --git a/specification/modules/secrets.rst b/specification/modules/secrets.rst index bc5386bf..2e8e3886 100644 --- a/specification/modules/secrets.rst +++ b/specification/modules/secrets.rst @@ -161,11 +161,11 @@ encrypted as follows: ============ =========== ======================================================= Parameter Type Description ============ =========== ======================================================= -iv String **Required.** The 16-byte initialization vector, +iv string **Required.** The 16-byte initialization vector, encoded as base64. -ciphertext String **Required.** The AES-CTR-encrypted data, encoded as +ciphertext string **Required.** The AES-CTR-encrypted data, encoded as base64. -mac String **Required.** The MAC, encoded as base64. +mac string **Required.** The MAC, encoded as base64. ============ =========== ======================================================= For the purposes of allowing clients to check whether a user has correctly @@ -185,10 +185,10 @@ name string **Required.** The name of the key. algorithm string **Required.** The encryption algorithm to be used for this key. Currently, only ``m.secret_storage.v1.aes-hmac-sha2`` is supported. -passphrase string See `deriving keys from passphrases`_ section for a +passphrase object See `deriving keys from passphrases`_ section for a description of this property. -iv String The 16-byte initialization vector, encoded as base64. -mac String The MAC of the result of encrypting 32 bytes of 0, +iv string The 16-byte initialization vector, encoded as base64. +mac string The MAC of the result of encrypting 32 bytes of 0, encoded as base64. ============ =========== ======================================================= From 72ad26ec927b5b19ff7d80cb350423ebc9820bcc Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 23 Jun 2020 16:24:32 -0400 Subject: [PATCH 1170/1250] fix changelog --- changelogs/client_server/newsfragments/2647.clarification | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/client_server/newsfragments/2647.clarification b/changelogs/client_server/newsfragments/2647.clarification index a79ec474..a0c5e7cc 100644 --- a/changelogs/client_server/newsfragments/2647.clarification +++ b/changelogs/client_server/newsfragments/2647.clarification @@ -1 +1 @@ -Improve consistency and clarity of event schema ``title``s. +Improve consistency and clarity of event schema ``title``\ s. From 3e3eafc6ce34a12eeef656f38e5402497c16b3de Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 23 Jun 2020 16:34:48 -0400 Subject: [PATCH 1171/1250] add changelog --- changelogs/client_server/newsfragments/2653.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2653.clarification diff --git a/changelogs/client_server/newsfragments/2653.clarification b/changelogs/client_server/newsfragments/2653.clarification new file mode 100644 index 00000000..4476d8b3 --- /dev/null +++ b/changelogs/client_server/newsfragments/2653.clarification @@ -0,0 +1 @@ +Fix some errors in the end-to-end encryption spec. From 782aed738340b459db35a4fc68c7893cdc381de2 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Sun, 28 Jun 2020 12:00:32 -0400 Subject: [PATCH 1172/1250] Add proposal for accepting query parameters to the login fallback endpoint. (#2604) --- proposals/2604-login-fallback-device-info.md | 39 ++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 proposals/2604-login-fallback-device-info.md diff --git a/proposals/2604-login-fallback-device-info.md b/proposals/2604-login-fallback-device-info.md new file mode 100644 index 00000000..c4ab3ac0 --- /dev/null +++ b/proposals/2604-login-fallback-device-info.md @@ -0,0 +1,39 @@ +# Parameters for Login Fallback + +The [login fallback](https://matrix.org/docs/spec/client_server/r0.6.1#login-fallback) +API can be used by clients to support logins that they do not recognize. It is +expected to be loaded in a web view and calls a JavaScript function +(`window.onLogin`) when the login process is complete. + +Since the login fallback page does the full login process there is no +opportunity for the application to provide a device ID (to re-authenticate +an expired session in the [case of soft-logout](https://matrix.org/docs/spec/client_server/r0.6.1#soft-logout)) +or an [initial device display name](https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-login) +(in the case of an initial login). This causes a few issues: + +* It can make it difficult for a user to manage their sessions (as additional + sessions get created for each soft-logout). +* Cross-signing information gets reset when a new device ID is returned from the + login process. This results in users needing to re-validate their device. + +## Proposal + +The login fallback page will accept query parameters for non-credential related +parameters of the login endpoint. These will be forwarded by the login fallback +API to the login API throughout the login process. Currently the following +parameters should be accepted: + +* `device_id` +* `initial_device_display_name` + + +## Potential issues + +There are no backwards compatibility concerns: if a client provides the query +parameters to a homeserver that does not check for them than the current +behavior will occur. + + +## Security considerations + +None. From fee59be2b37f9dab171a0885533120bfd0d5a140 Mon Sep 17 00:00:00 2001 From: "Olivier Wilkinson (reivilibre)" Date: Fri, 3 Jul 2020 14:03:31 +0100 Subject: [PATCH 1173/1250] Start MSC2663 proposal Signed-off-by: Olivier Wilkinson (reivilibre) --- proposals/2663-define-nonexistent-push-rule-enable.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 proposals/2663-define-nonexistent-push-rule-enable.md diff --git a/proposals/2663-define-nonexistent-push-rule-enable.md b/proposals/2663-define-nonexistent-push-rule-enable.md new file mode 100644 index 00000000..5cbb93f4 --- /dev/null +++ b/proposals/2663-define-nonexistent-push-rule-enable.md @@ -0,0 +1,2 @@ +# MSC2663 + From f8ff2ad6a9a20f670d07bd83bafac0c1452dc988 Mon Sep 17 00:00:00 2001 From: Aaron Raimist Date: Mon, 6 Jul 2020 05:19:41 -0500 Subject: [PATCH 1174/1250] Reword "UI Authorization" to "User-Interactive Authentication" (#2667) Signed-off-by: Aaron Raimist --- api/client-server/logout.yaml | 11 ++++++----- changelogs/client_server/2667.clarification | 1 + specification/client_server_api.rst | 3 +-- 3 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 changelogs/client_server/2667.clarification diff --git a/api/client-server/logout.yaml b/api/client-server/logout.yaml index eb84a739..747a57b9 100644 --- a/api/client-server/logout.yaml +++ b/api/client-server/logout.yaml @@ -54,11 +54,12 @@ paths: for the user are also deleted. `Device keys <#device-keys>`_ for the device are deleted alongside the device. - This endpoint does not require UI authorization because UI authorization is - designed to protect against attacks where the someone gets hold of a single access - token then takes over the account. This endpoint invalidates all access tokens for - the user, including the token used in the request, and therefore the attacker is - unable to take over the account in this way. + This endpoint does not use the `User-Interactive Authentication API`_ because + User-Interactive Authentication is designed to protect against attacks where the + someone gets hold of a single access token then takes over the account. This + endpoint invalidates all access tokens for the user, including the token used in + the request, and therefore the attacker is unable to take over the account in + this way. operationId: logout_all security: - accessToken: [] diff --git a/changelogs/client_server/2667.clarification b/changelogs/client_server/2667.clarification new file mode 100644 index 00000000..0eb9ad3c --- /dev/null +++ b/changelogs/client_server/2667.clarification @@ -0,0 +1 @@ +Reword "UI Authorization" to "User-Interactive Authentication" to be more clear. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 27cbe8c5..edac25ad 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1090,8 +1090,7 @@ Login A client can obtain access tokens using the ``/login`` API. -Note that this endpoint does `not` currently use the user-interactive -authentication API. +Note that this endpoint does `not` currently use the `User-Interactive Authentication API`_. For a simple username/password login, clients should submit a ``/login`` request as follows: From 90a37cdb3092204dc7a1f5860f764f649818d3e2 Mon Sep 17 00:00:00 2001 From: "Olivier Wilkinson (reivilibre)" Date: Mon, 6 Jul 2020 12:36:08 +0100 Subject: [PATCH 1175/1250] Write MSC2663 --- ...663-define-nonexistent-push-rule-enable.md | 2 - .../2663-errors-nonexistent-push-rules.md | 44 +++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) delete mode 100644 proposals/2663-define-nonexistent-push-rule-enable.md create mode 100644 proposals/2663-errors-nonexistent-push-rules.md diff --git a/proposals/2663-define-nonexistent-push-rule-enable.md b/proposals/2663-define-nonexistent-push-rule-enable.md deleted file mode 100644 index 5cbb93f4..00000000 --- a/proposals/2663-define-nonexistent-push-rule-enable.md +++ /dev/null @@ -1,2 +0,0 @@ -# MSC2663 - diff --git a/proposals/2663-errors-nonexistent-push-rules.md b/proposals/2663-errors-nonexistent-push-rules.md new file mode 100644 index 00000000..ba0a5446 --- /dev/null +++ b/proposals/2663-errors-nonexistent-push-rules.md @@ -0,0 +1,44 @@ +# MSC2663: Errors for dealing with inexistent push rules + +This MSC proposes that homeservers respond with a HTTP 404 ('Not Found') status +code and an `errcode` of `M_NOT_FOUND` when a client attempts to read or write +the `enabled` status or `actions` of a non-existent push rule. + +## Background + +The current revision of the Client-Server specification does not make clear what +a homeserver implementation is meant to do when getting or setting the `enabled` +or `actions` properties of a supposed push rule that does not exist. + +## Motivation + +This change is considered minor and the proposed error code is deemed +unsurprising as it matches the remainder of the specification. + +## Proposal + +The following endpoints of the Client-Server specification are affected: + +- `GET /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}` +- `DELETE /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}` +- `PUT /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}` +- `GET /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}/enabled` +- `PUT /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}/enabled` +- `GET /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}/actions` +- `PUT /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}/actions` + +The affected endpoints will have the following response status code added: + +**Status code 404:** + +The push rule does not exist. + +**Example** +```json +{ + "errcode": "M_NOT_FOUND" +} +``` + +This error response is to be returned when the push rule represented by +`{scope}/{kind}/{ruleId}` does not exist. From 2e72da2343d69d42417f095486ccd99b686597b9 Mon Sep 17 00:00:00 2001 From: "Olivier Wilkinson (reivilibre)" Date: Mon, 6 Jul 2020 13:14:06 +0100 Subject: [PATCH 1176/1250] Fix spec bug concerning the type of a push rule's array of actions Signed-off-by: Olivier Wilkinson (reivilibre) --- api/client-server/pushrules.yaml | 26 ++++++++++++------- .../newsfragments/2669.clarification | 1 + 2 files changed, 18 insertions(+), 9 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2669.clarification diff --git a/api/client-server/pushrules.yaml b/api/client-server/pushrules.yaml index 32c3c9a1..47580f3a 100644 --- a/api/client-server/pushrules.yaml +++ b/api/client-server/pushrules.yaml @@ -412,9 +412,9 @@ paths: description: |- The action(s) to perform when the conditions for this rule are met. items: - type: string - enum: ["notify", "dont_notify", "coalesce", "set_tweak"] - # TODO: type: object e.g. {"set_sound":"beeroclock.wav"} :/ + type: + - string + - object conditions: type: array description: |- @@ -592,7 +592,10 @@ paths: description: The actions for this push rule. examples: application/json: { - "actions": ["notify"] + "actions": [ + "notify", + {"set_tweak": "sound", "value": "bing"} + ] } schema: type: object @@ -601,7 +604,9 @@ paths: type: array description: The action(s) to perform for this rule. items: - type: string + type: + - string + - object required: ["actions"] tags: - Push notifications @@ -648,12 +653,15 @@ paths: type: array description: The action(s) to perform for this rule. items: - type: string - enum: ["notify", "dont_notify", "coalesce", "set_tweak"] - # TODO: type: object e.g. {"set_sound":"beeroclock.wav"} :/ + type: + - string + - object required: ["actions"] example: { - "actions": ["notify"] + "actions": [ + "notify", + {"set_tweak": "highlight"} + ] } responses: 200: diff --git a/changelogs/client_server/newsfragments/2669.clarification b/changelogs/client_server/newsfragments/2669.clarification new file mode 100644 index 00000000..0e219bfc --- /dev/null +++ b/changelogs/client_server/newsfragments/2669.clarification @@ -0,0 +1 @@ +Fix types of push rules' actions; they can be objects as well as strings. From 868ca45729689a70d2a1be0e43e919b4cfce6157 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Mon, 6 Jul 2020 15:15:29 +0100 Subject: [PATCH 1177/1250] move changelogs to the right directory (#2671) looks like these ended up in the wrong place. --- changelogs/client_server/{ => newsfragments}/2387.new | 0 changelogs/client_server/{ => newsfragments}/2639.clarification | 0 changelogs/client_server/{ => newsfragments}/2667.clarification | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename changelogs/client_server/{ => newsfragments}/2387.new (100%) rename changelogs/client_server/{ => newsfragments}/2639.clarification (100%) rename changelogs/client_server/{ => newsfragments}/2667.clarification (100%) diff --git a/changelogs/client_server/2387.new b/changelogs/client_server/newsfragments/2387.new similarity index 100% rename from changelogs/client_server/2387.new rename to changelogs/client_server/newsfragments/2387.new diff --git a/changelogs/client_server/2639.clarification b/changelogs/client_server/newsfragments/2639.clarification similarity index 100% rename from changelogs/client_server/2639.clarification rename to changelogs/client_server/newsfragments/2639.clarification diff --git a/changelogs/client_server/2667.clarification b/changelogs/client_server/newsfragments/2667.clarification similarity index 100% rename from changelogs/client_server/2667.clarification rename to changelogs/client_server/newsfragments/2667.clarification From 0f13ebe3ed173064ecb33b8f4fea5d7296dee74b Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 13 Jul 2020 15:59:09 -0400 Subject: [PATCH 1178/1250] document new key agreement method and deprecate old method --- .../schema/m.key.verification.start$m.sas.v1 | 2 +- .../modules/end_to_end_encryption.rst | 25 +++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/event-schemas/schema/m.key.verification.start$m.sas.v1 b/event-schemas/schema/m.key.verification.start$m.sas.v1 index daf6fa39..06f22d40 100644 --- a/event-schemas/schema/m.key.verification.start$m.sas.v1 +++ b/event-schemas/schema/m.key.verification.start$m.sas.v1 @@ -27,7 +27,7 @@ properties: type: array description: |- The key agreement protocols the sending device understands. Must - include at least ``curve25519``. + include at least ``curve25519-hkdf-sha256``. items: type: string hashes: diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index d3b6070d..53ce2775 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -674,8 +674,27 @@ HKDF calculation In all of the SAS methods, HKDF is as defined in `RFC 5869 `_ and uses the previously agreed-upon hash function for the hash function. The shared -secret is supplied as the input keying material. No salt is used, and the info -parameter is the concatenation of: +secret is supplied as the input keying material. No salt is used. When the +``key_agreement_protocol`` is ``curve25519-hkdf-sha256``, the info parameter is +the concatenation of: + + * The string ``MATRIX_KEY_VERIFICATION_SAS|``. + * The Matrix ID of the user who sent the ``m.key.verification.start`` message, + followed by ``|``. + * The Device ID of the device which sent the ``m.key.verification.start`` + message, followed by ``|``. + * The public key from the ``m.key.verification.key`` message sent by the device + which sent the ``m.key.verification.start`` message, followed by ``|``. + * The Matrix ID of the user who sent the ``m.key.verification.accept`` message, + followed by ``|``. + * The Device ID of the device which sent the ``m.key.verification.accept`` + message, followed by ``|``. + * The public key from the ``m.key.verification.key`` message sent by the device + which sent the ``m.key.verification.accept`` message, followed by ``|``. + * The ``transaction_id`` being used. + +When the ``key_agreement_protocol`` is the deprecated method ``curve25519``, +the info parameter is the concatenation of: * The string ``MATRIX_KEY_VERIFICATION_SAS``. * The Matrix ID of the user who sent the ``m.key.verification.start`` message. @@ -684,6 +703,8 @@ parameter is the concatenation of: * The Device ID of the device which sent the ``m.key.verification.accept`` message. * The ``transaction_id`` being used. +New implementations are discouraged from implementing the ``curve25519`` method. + .. admonition:: Rationale HKDF is used over the plain shared secret as it results in a harder attack From 793dae1ecee7695a3bcb0e01558bdd2726cc58ec Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 13 Jul 2020 16:03:12 -0400 Subject: [PATCH 1179/1250] add changelog --- changelogs/client_server/newsfragments/2687.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2687.feature diff --git a/changelogs/client_server/newsfragments/2687.feature b/changelogs/client_server/newsfragments/2687.feature new file mode 100644 index 00000000..f70cfdee --- /dev/null +++ b/changelogs/client_server/newsfragments/2687.feature @@ -0,0 +1 @@ +Document new key agreement method for SAS verification, and deprecate old method (MSC2630). From adc867dc9957f994633a01312b71f8cd6f842950 Mon Sep 17 00:00:00 2001 From: Michael Albert Date: Wed, 15 Jul 2020 21:40:09 +0200 Subject: [PATCH 1180/1250] Fix E2EE for guests --- proposals/2689-fix-e2ee-for-guests.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 proposals/2689-fix-e2ee-for-guests.md diff --git a/proposals/2689-fix-e2ee-for-guests.md b/proposals/2689-fix-e2ee-for-guests.md new file mode 100644 index 00000000..ad235a26 --- /dev/null +++ b/proposals/2689-fix-e2ee-for-guests.md @@ -0,0 +1,20 @@ +# MSC2689: Allow guests to operate in encrypted rooms + +MSC751 suggested to allow guests to use several endpoints in order to allow guests to use E2EE. +I found that guests are able to join encrypted rooms and read messages from other members. But when the +guest wants to send an event into the room the client receives an "guest access not allowed" error +for the `/rooms/room_id/members` endpoint. I assume the client tries to read the list of room members +to prepare the encryption of the event for the present members. Tests with a patched Synapse showed that +allowing guests to use this endpoint results in a normal behaviour and enables guests to communicate in +encrypted rooms. + + +## Proposal + +Allow guests to use the `GET /_matrix/client/r0/rooms//members` endpoint to enable them to +operate properly in encrypted rooms. + + +## Alternatives + +The list of room members could also be read from the sync. However that would not work with Lazy Loading. From 250f0e47c183eb505615b853853f0340c72dc3d2 Mon Sep 17 00:00:00 2001 From: Michael Albert Date: Wed, 15 Jul 2020 22:06:19 +0200 Subject: [PATCH 1181/1250] Fix typos --- proposals/2689-fix-e2ee-for-guests.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/2689-fix-e2ee-for-guests.md b/proposals/2689-fix-e2ee-for-guests.md index ad235a26..64323664 100644 --- a/proposals/2689-fix-e2ee-for-guests.md +++ b/proposals/2689-fix-e2ee-for-guests.md @@ -2,8 +2,8 @@ MSC751 suggested to allow guests to use several endpoints in order to allow guests to use E2EE. I found that guests are able to join encrypted rooms and read messages from other members. But when the -guest wants to send an event into the room the client receives an "guest access not allowed" error -for the `/rooms/room_id/members` endpoint. I assume the client tries to read the list of room members +guest wants to send an event into the room the client receives a "guest access not allowed" error +for the `/rooms/{room_id}/members` endpoint. I assume the client tries to read the list of room members to prepare the encryption of the event for the present members. Tests with a patched Synapse showed that allowing guests to use this endpoint results in a normal behaviour and enables guests to communicate in encrypted rooms. @@ -11,7 +11,7 @@ encrypted rooms. ## Proposal -Allow guests to use the `GET /_matrix/client/r0/rooms//members` endpoint to enable them to +Allow guests to use the `GET /_matrix/client/r0/rooms/{room_id}/members` endpoint to enable them to operate properly in encrypted rooms. From 6da06383e825a6adfd61a1d8cb0fe53fcec1f7de Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Thu, 16 Jul 2020 15:17:40 +0100 Subject: [PATCH 1182/1250] Allow `/make_join` to return a 404 (#2688) Specify that `GET /_matrix/federation/v1/make_join/{roomId}/{userId}` can return a 404 if the room is unknown. --- api/server-server/joins-v1.yaml | 10 ++++++++++ .../server_server/newsfragments/2688.clarification | 1 + 2 files changed, 11 insertions(+) create mode 100644 changelogs/server_server/newsfragments/2688.clarification diff --git a/api/server-server/joins-v1.yaml b/api/server-server/joins-v1.yaml index 18c88db0..d4fc8f24 100644 --- a/api/server-server/joins-v1.yaml +++ b/api/server-server/joins-v1.yaml @@ -162,6 +162,16 @@ paths: "error": "Your homeserver does not support the features required to join this room", "room_version": "3" } + 404: + description: |- + The room that the joining server is attempting to join is unknown + to the receiving server. + examples: + application/json: { + "errcode": "M_NOT_FOUND", + "error": "Unknown room", + } + "/send_join/{roomId}/{eventId}": put: summary: Submit a signed join event to a resident server diff --git a/changelogs/server_server/newsfragments/2688.clarification b/changelogs/server_server/newsfragments/2688.clarification new file mode 100644 index 00000000..641893d3 --- /dev/null +++ b/changelogs/server_server/newsfragments/2688.clarification @@ -0,0 +1 @@ +Specify that `GET /_matrix/federation/v1/make_join/{roomId}/{userId}` can return a 404 if the room is unknown. \ No newline at end of file From 1b74e96b7ed4beaee546d59e462223ba7b8768d6 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 16 Jul 2020 15:21:50 +0100 Subject: [PATCH 1183/1250] fix RST in changelog --- changelogs/server_server/newsfragments/2688.clarification | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/server_server/newsfragments/2688.clarification b/changelogs/server_server/newsfragments/2688.clarification index 641893d3..87e7792c 100644 --- a/changelogs/server_server/newsfragments/2688.clarification +++ b/changelogs/server_server/newsfragments/2688.clarification @@ -1 +1 @@ -Specify that `GET /_matrix/federation/v1/make_join/{roomId}/{userId}` can return a 404 if the room is unknown. \ No newline at end of file +Specify that ``GET /_matrix/federation/v1/make_join/{roomId}/{userId}`` can return a 404 if the room is unknown. \ No newline at end of file From 125614f3a4a98aac520ba773fa2ec58e10dbc704 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Thu, 16 Jul 2020 17:26:34 +0100 Subject: [PATCH 1184/1250] Make use of `highlight` tweak consistent (#2670) * remove redundant 'highlight: false' tweaks their inconsistent usage is super-confusing. * Remove redundant 'value: true' on highlight tweaks again, the inconsistency was super-confusing. * changelog --- .../newsfragments/2670.clarification | 1 + specification/modules/push.rst | 34 +++---------------- 2 files changed, 5 insertions(+), 30 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2670.clarification diff --git a/changelogs/client_server/newsfragments/2670.clarification b/changelogs/client_server/newsfragments/2670.clarification new file mode 100644 index 00000000..64d9f142 --- /dev/null +++ b/changelogs/client_server/newsfragments/2670.clarification @@ -0,0 +1 @@ +Minor clarifications to the "Push Notifications" module. diff --git a/specification/modules/push.rst b/specification/modules/push.rst index 37b149bc..ec855e6b 100644 --- a/specification/modules/push.rst +++ b/specification/modules/push.rst @@ -354,10 +354,6 @@ Definition: { "set_tweak": "sound", "value": "default" - }, - { - "set_tweak": "highlight", - "value": false } ] } @@ -448,8 +444,7 @@ Definition: "actions": [ "notify", { - "set_tweak": "highlight", - "value": true + "set_tweak": "highlight" } ] } @@ -483,8 +478,7 @@ Definition: "actions": [ "notify", { - "set_tweak": "highlight", - "value": true + "set_tweak": "highlight" } ] } @@ -546,10 +540,6 @@ Definition: { "set_tweak": "sound", "value": "ring" - }, - { - "set_tweak": "highlight", - "value": false } ] } @@ -586,10 +576,6 @@ Definition: { "set_tweak": "sound", "value": "default" - }, - { - "set_tweak": "highlight", - "value": false } ] } @@ -622,10 +608,6 @@ Definition: { "set_tweak": "sound", "value": "default" - }, - { - "set_tweak": "highlight", - "value": false } ] } @@ -650,11 +632,7 @@ Definition: } ], "actions": [ - "notify", - { - "set_tweak": "highlight", - "value": false - } + "notify" ] } @@ -681,11 +659,7 @@ Definition: } ], "actions": [ - "notify", - { - "set_tweak": "highlight", - "value": false - } + "notify" ] } From 3dd5bc42a721a369ce4aee94a66957b1916f9361 Mon Sep 17 00:00:00 2001 From: "Olivier Wilkinson (reivilibre)" Date: Fri, 17 Jul 2020 13:06:13 +0100 Subject: [PATCH 1185/1250] inexistent may or may not be a non-existent word Signed-off-by: Olivier Wilkinson (reivilibre) --- proposals/2663-errors-nonexistent-push-rules.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2663-errors-nonexistent-push-rules.md b/proposals/2663-errors-nonexistent-push-rules.md index ba0a5446..19f3e89a 100644 --- a/proposals/2663-errors-nonexistent-push-rules.md +++ b/proposals/2663-errors-nonexistent-push-rules.md @@ -1,4 +1,4 @@ -# MSC2663: Errors for dealing with inexistent push rules +# MSC2663: Errors for dealing with non-existent push rules This MSC proposes that homeservers respond with a HTTP 404 ('Not Found') status code and an `errcode` of `M_NOT_FOUND` when a client attempts to read or write From 33ed9fc2dd0a3ce790bc485c19a1aaf8b4d54c57 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 21 Jul 2020 16:19:53 -0400 Subject: [PATCH 1186/1250] apply changes from review --- changelogs/client_server/newsfragments/2687.breaking | 1 + changelogs/client_server/newsfragments/2687.feature | 1 - event-schemas/schema/m.key.verification.start$m.sas.v1 | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2687.breaking delete mode 100644 changelogs/client_server/newsfragments/2687.feature diff --git a/changelogs/client_server/newsfragments/2687.breaking b/changelogs/client_server/newsfragments/2687.breaking new file mode 100644 index 00000000..c40f7625 --- /dev/null +++ b/changelogs/client_server/newsfragments/2687.breaking @@ -0,0 +1 @@ +Document `curve25519-hkdf-sha256` key agreement method for SAS verification, and deprecate old method (MSC2630). diff --git a/changelogs/client_server/newsfragments/2687.feature b/changelogs/client_server/newsfragments/2687.feature deleted file mode 100644 index f70cfdee..00000000 --- a/changelogs/client_server/newsfragments/2687.feature +++ /dev/null @@ -1 +0,0 @@ -Document new key agreement method for SAS verification, and deprecate old method (MSC2630). diff --git a/event-schemas/schema/m.key.verification.start$m.sas.v1 b/event-schemas/schema/m.key.verification.start$m.sas.v1 index 06f22d40..f4deb3c8 100644 --- a/event-schemas/schema/m.key.verification.start$m.sas.v1 +++ b/event-schemas/schema/m.key.verification.start$m.sas.v1 @@ -26,7 +26,7 @@ properties: key_agreement_protocols: type: array description: |- - The key agreement protocols the sending device understands. Must + The key agreement protocols the sending device understands. Should include at least ``curve25519-hkdf-sha256``. items: type: string From 78f3c3dac87775b77f54c2fdb43be24b9346fcb8 Mon Sep 17 00:00:00 2001 From: Michael Albert <37796947+awesome-michael@users.noreply.github.com> Date: Fri, 24 Jul 2020 21:47:45 +0200 Subject: [PATCH 1187/1250] Update proposals/2689-fix-e2ee-for-guests.md Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- proposals/2689-fix-e2ee-for-guests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2689-fix-e2ee-for-guests.md b/proposals/2689-fix-e2ee-for-guests.md index 64323664..94413098 100644 --- a/proposals/2689-fix-e2ee-for-guests.md +++ b/proposals/2689-fix-e2ee-for-guests.md @@ -1,6 +1,6 @@ # MSC2689: Allow guests to operate in encrypted rooms -MSC751 suggested to allow guests to use several endpoints in order to allow guests to use E2EE. +[#751](https://github.com/matrix-org/matrix-doc/pull/751) granted guest users access to several endpoints in order to allow them to use E2EE. I found that guests are able to join encrypted rooms and read messages from other members. But when the guest wants to send an event into the room the client receives a "guest access not allowed" error for the `/rooms/{room_id}/members` endpoint. I assume the client tries to read the list of room members From 24d124df5097840784091401546a59a98e37b0ef Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 28 Jul 2020 10:02:11 -0600 Subject: [PATCH 1188/1250] Update changelogs/client_server/newsfragments/2609.removal --- changelogs/client_server/newsfragments/2609.removal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/client_server/newsfragments/2609.removal b/changelogs/client_server/newsfragments/2609.removal index 878372c3..deafc77d 100644 --- a/changelogs/client_server/newsfragments/2609.removal +++ b/changelogs/client_server/newsfragments/2609.removal @@ -1 +1 @@ -Remove unimplemented `m.login.oauth2` and `m.login.token` user-interactive authentication mechanisms. \ No newline at end of file +Remove unimplemented ``m.login.oauth2`` and ``m.login.token`` user-interactive authentication mechanisms. From 9a40d7bf47a2be33daca9afd819acd2769ff2bd3 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Tue, 28 Jul 2020 16:02:24 -0400 Subject: [PATCH 1189/1250] Add information from MSC2604: Parameters for Login Fallback to the spec. --- changelogs/client_server/newsfragments/2709.new | 1 + specification/client_server_api.rst | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 changelogs/client_server/newsfragments/2709.new diff --git a/changelogs/client_server/newsfragments/2709.new b/changelogs/client_server/newsfragments/2709.new new file mode 100644 index 00000000..0c6b8ea3 --- /dev/null +++ b/changelogs/client_server/newsfragments/2709.new @@ -0,0 +1 @@ +Document `MSC2604: Parameters for Login Fallback `_. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 9cf0342d..491230a0 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1096,6 +1096,12 @@ This returns an HTML and JavaScript page which can perform the entire login process. The page will attempt to call the JavaScript function ``window.onLogin`` when login has been successfully completed. +Non-credential related parameters of the login endpoint can be provided as query +parameters, for example the ``device_id`` or ``initial_device_display_name``. +These are to be forwarded to the login endpoint during the login process. + + GET /_matrix/static/client/login/?device_id=GHTYAJCE + .. _Registration: Account registration and management From e261faf70b4af2f1d45ffc1a4a761a012d526d2e Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 29 Jul 2020 07:10:14 -0400 Subject: [PATCH 1190/1250] Review comments. Co-authored-by: Travis Ralston --- changelogs/client_server/newsfragments/2709.new | 2 +- specification/client_server_api.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/changelogs/client_server/newsfragments/2709.new b/changelogs/client_server/newsfragments/2709.new index 0c6b8ea3..a6b3e2a2 100644 --- a/changelogs/client_server/newsfragments/2709.new +++ b/changelogs/client_server/newsfragments/2709.new @@ -1 +1 @@ -Document `MSC2604: Parameters for Login Fallback `_. +Add a ``device_id`` parameter to login fallback per `MSC2604 `_. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 491230a0..55a4bfbb 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1096,8 +1096,8 @@ This returns an HTML and JavaScript page which can perform the entire login process. The page will attempt to call the JavaScript function ``window.onLogin`` when login has been successfully completed. -Non-credential related parameters of the login endpoint can be provided as query -parameters, for example the ``device_id`` or ``initial_device_display_name``. +Non-credential parameters valid for the ``/login`` endpoint can be provided as query +string parameters here. For example:: These are to be forwarded to the login endpoint during the login process. GET /_matrix/static/client/login/?device_id=GHTYAJCE From 4353f346b6c2a55cd670def8a442a9c144eaf8fd Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 29 Jul 2020 09:18:21 -0400 Subject: [PATCH 1191/1250] Rename changelog file. --- changelogs/client_server/newsfragments/{2709.new => 2709.feature} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelogs/client_server/newsfragments/{2709.new => 2709.feature} (100%) diff --git a/changelogs/client_server/newsfragments/2709.new b/changelogs/client_server/newsfragments/2709.feature similarity index 100% rename from changelogs/client_server/newsfragments/2709.new rename to changelogs/client_server/newsfragments/2709.feature From 4daecd0d949ca6bf5b3b9aff8922c23d9578ac62 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 29 Jul 2020 09:19:21 -0400 Subject: [PATCH 1192/1250] Remove broken formatting. --- specification/client_server_api.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 55a4bfbb..3c5d6b54 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1098,7 +1098,6 @@ process. The page will attempt to call the JavaScript function Non-credential parameters valid for the ``/login`` endpoint can be provided as query string parameters here. For example:: -These are to be forwarded to the login endpoint during the login process. GET /_matrix/static/client/login/?device_id=GHTYAJCE From d41ad7638e4f786c7fbbb51de17aade49b771c77 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 30 Jul 2020 15:28:06 -0600 Subject: [PATCH 1193/1250] re-add note about the login process --- specification/client_server_api.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 3c5d6b54..4847d837 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1097,7 +1097,8 @@ process. The page will attempt to call the JavaScript function ``window.onLogin`` when login has been successfully completed. Non-credential parameters valid for the ``/login`` endpoint can be provided as query -string parameters here. For example:: +string parameters here. These are to be forwarded to the login endpoint during the login +process. For example:: GET /_matrix/static/client/login/?device_id=GHTYAJCE From d37f7a25b4fa90056064f4bd72248b5aba667229 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 12 Aug 2020 14:04:48 -0600 Subject: [PATCH 1194/1250] Make translations for SAS emoji available in-tree (#2728) * add a base file * Fix directory name * Added translation using Weblate (English) * Translated using Weblate (English) Currently translated at 1.6% (1 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/en_EN/ * add english files * delete english files * Added translation using Weblate (English) * Added translation using Weblate (English) * Do manual translations * Deleted translation using Weblate (English) * Deleted translation using Weblate (English) * Add a script to update the definitions with the translations * update i18n * Add a note to the spec about translations * changelog * Ensure translations end with json --- .../client_server/newsfragments/2728.feature | 1 + data-definitions/sas-emoji-v1-i18n/base.json | 66 +++ data-definitions/sas-emoji.json | 514 +++++++++++++++--- meta/releasing_a_spec.md | 2 + scripts/i18n.py | 32 ++ .../modules/end_to_end_encryption.rst | 5 + 6 files changed, 555 insertions(+), 65 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2728.feature create mode 100644 data-definitions/sas-emoji-v1-i18n/base.json create mode 100644 scripts/i18n.py diff --git a/changelogs/client_server/newsfragments/2728.feature b/changelogs/client_server/newsfragments/2728.feature new file mode 100644 index 00000000..a0393db8 --- /dev/null +++ b/changelogs/client_server/newsfragments/2728.feature @@ -0,0 +1 @@ +Added a common set of translations for SAS Emoji. diff --git a/data-definitions/sas-emoji-v1-i18n/base.json b/data-definitions/sas-emoji-v1-i18n/base.json new file mode 100644 index 00000000..68129bd6 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/base.json @@ -0,0 +1,66 @@ +{ + "Dog": "Dog", + "Cat": "Cat", + "Lion": "Lion", + "Horse": "Horse", + "Unicorn": "Unicorn", + "Pig": "Pig", + "Elephant": "Elephant", + "Rabbit": "Rabbit", + "Panda": "Panda", + "Rooster": "Rooster", + "Penguin": "Penguin", + "Turtle": "Turtle", + "Fish": "Fish", + "Octopus": "Octopus", + "Butterfly": "Butterfly", + "Flower": "Flower", + "Tree": "Tree", + "Cactus": "Cactus", + "Mushroom": "Mushroom", + "Globe": "Globe", + "Moon": "Moon", + "Cloud": "Cloud", + "Fire": "Fire", + "Banana": "Banana", + "Apple": "Apple", + "Strawberry": "Strawberry", + "Corn": "Corn", + "Pizza": "Pizza", + "Cake": "Cake", + "Heart": "Heart", + "Smiley": "Smiley", + "Robot": "Robot", + "Hat": "Hat", + "Glasses": "Glasses", + "Spanner": "Spanner", + "Santa": "Santa", + "Thumbs Up": "Thumbs Up", + "Umbrella": "Umbrella", + "Hourglass": "Hourglass", + "Clock": "Clock", + "Gift": "Gift", + "Light Bulb": "Light Bulb", + "Book": "Book", + "Pencil": "Pencil", + "Paperclip": "Paperclip", + "Scissors": "Scissors", + "Lock": "Lock", + "Key": "Key", + "Hammer": "Hammer", + "Telephone": "Telephone", + "Flag": "Flag", + "Train": "Train", + "Bicycle": "Bicycle", + "Aeroplane": "Aeroplane", + "Rocket": "Rocket", + "Trophy": "Trophy", + "Ball": "Ball", + "Guitar": "Guitar", + "Trumpet": "Trumpet", + "Bell": "Bell", + "Anchor": "Anchor", + "Headphones": "Headphones", + "Folder": "Folder", + "Pin": "Pin" +} diff --git a/data-definitions/sas-emoji.json b/data-definitions/sas-emoji.json index 060fbd49..6e9254ef 100644 --- a/data-definitions/sas-emoji.json +++ b/data-definitions/sas-emoji.json @@ -1,66 +1,450 @@ [ - {"number": 0, "emoji": "🐶", "description": "Dog", "unicode": "U+1F436"}, - {"number": 1, "emoji": "🐱", "description": "Cat", "unicode": "U+1F431"}, - {"number": 2, "emoji": "🦁", "description": "Lion", "unicode": "U+1F981"}, - {"number": 3, "emoji": "🐎", "description": "Horse", "unicode": "U+1F40E"}, - {"number": 4, "emoji": "🦄", "description": "Unicorn", "unicode": "U+1F984"}, - {"number": 5, "emoji": "🐷", "description": "Pig", "unicode": "U+1F437"}, - {"number": 6, "emoji": "🐘", "description": "Elephant", "unicode": "U+1F418"}, - {"number": 7, "emoji": "🐰", "description": "Rabbit", "unicode": "U+1F430"}, - {"number": 8, "emoji": "🐼", "description": "Panda", "unicode": "U+1F43C"}, - {"number": 9, "emoji": "🐓", "description": "Rooster", "unicode": "U+1F413"}, - {"number": 10, "emoji": "🐧", "description": "Penguin", "unicode": "U+1F427"}, - {"number": 11, "emoji": "🐢", "description": "Turtle", "unicode": "U+1F422"}, - {"number": 12, "emoji": "🐟", "description": "Fish", "unicode": "U+1F41F"}, - {"number": 13, "emoji": "🐙", "description": "Octopus", "unicode": "U+1F419"}, - {"number": 14, "emoji": "🦋", "description": "Butterfly", "unicode": "U+1F98B"}, - {"number": 15, "emoji": "🌷", "description": "Flower", "unicode": "U+1F337"}, - {"number": 16, "emoji": "🌳", "description": "Tree", "unicode": "U+1F333"}, - {"number": 17, "emoji": "🌵", "description": "Cactus", "unicode": "U+1F335"}, - {"number": 18, "emoji": "🍄", "description": "Mushroom", "unicode": "U+1F344"}, - {"number": 19, "emoji": "🌏", "description": "Globe", "unicode": "U+1F30F"}, - {"number": 20, "emoji": "🌙", "description": "Moon", "unicode": "U+1F319"}, - {"number": 21, "emoji": "☁️", "description": "Cloud", "unicode": "U+2601U+FE0F"}, - {"number": 22, "emoji": "🔥", "description": "Fire", "unicode": "U+1F525"}, - {"number": 23, "emoji": "🍌", "description": "Banana", "unicode": "U+1F34C"}, - {"number": 24, "emoji": "🍎", "description": "Apple", "unicode": "U+1F34E"}, - {"number": 25, "emoji": "🍓", "description": "Strawberry", "unicode": "U+1F353"}, - {"number": 26, "emoji": "🌽", "description": "Corn", "unicode": "U+1F33D"}, - {"number": 27, "emoji": "🍕", "description": "Pizza", "unicode": "U+1F355"}, - {"number": 28, "emoji": "🎂", "description": "Cake", "unicode": "U+1F382"}, - {"number": 29, "emoji": "❤️", "description": "Heart", "unicode": "U+2764U+FE0F"}, - {"number": 30, "emoji": "😀", "description": "Smiley", "unicode": "U+1F600"}, - {"number": 31, "emoji": "🤖", "description": "Robot", "unicode": "U+1F916"}, - {"number": 32, "emoji": "🎩", "description": "Hat", "unicode": "U+1F3A9"}, - {"number": 33, "emoji": "👓", "description": "Glasses", "unicode": "U+1F453"}, - {"number": 34, "emoji": "🔧", "description": "Spanner", "unicode": "U+1F527"}, - {"number": 35, "emoji": "🎅", "description": "Santa", "unicode": "U+1F385"}, - {"number": 36, "emoji": "👍", "description": "Thumbs Up", "unicode": "U+1F44D"}, - {"number": 37, "emoji": "☂️", "description": "Umbrella", "unicode": "U+2602U+FE0F"}, - {"number": 38, "emoji": "⌛", "description": "Hourglass", "unicode": "U+231B"}, - {"number": 39, "emoji": "⏰", "description": "Clock", "unicode": "U+23F0"}, - {"number": 40, "emoji": "🎁", "description": "Gift", "unicode": "U+1F381"}, - {"number": 41, "emoji": "💡", "description": "Light Bulb", "unicode": "U+1F4A1"}, - {"number": 42, "emoji": "📕", "description": "Book", "unicode": "U+1F4D5"}, - {"number": 43, "emoji": "✏️", "description": "Pencil", "unicode": "U+270FU+FE0F"}, - {"number": 44, "emoji": "📎", "description": "Paperclip", "unicode": "U+1F4CE"}, - {"number": 45, "emoji": "✂️", "description": "Scissors", "unicode": "U+2702U+FE0F"}, - {"number": 46, "emoji": "🔒", "description": "Lock", "unicode": "U+1F512"}, - {"number": 47, "emoji": "🔑", "description": "Key", "unicode": "U+1F511"}, - {"number": 48, "emoji": "🔨", "description": "Hammer", "unicode": "U+1F528"}, - {"number": 49, "emoji": "☎️", "description": "Telephone", "unicode": "U+260EU+FE0F"}, - {"number": 50, "emoji": "🏁", "description": "Flag", "unicode": "U+1F3C1"}, - {"number": 51, "emoji": "🚂", "description": "Train", "unicode": "U+1F682"}, - {"number": 52, "emoji": "🚲", "description": "Bicycle", "unicode": "U+1F6B2"}, - {"number": 53, "emoji": "✈️", "description": "Aeroplane", "unicode": "U+2708U+FE0F"}, - {"number": 54, "emoji": "🚀", "description": "Rocket", "unicode": "U+1F680"}, - {"number": 55, "emoji": "🏆", "description": "Trophy", "unicode": "U+1F3C6"}, - {"number": 56, "emoji": "⚽", "description": "Ball", "unicode": "U+26BD"}, - {"number": 57, "emoji": "🎸", "description": "Guitar", "unicode": "U+1F3B8"}, - {"number": 58, "emoji": "🎺", "description": "Trumpet", "unicode": "U+1F3BA"}, - {"number": 59, "emoji": "🔔", "description": "Bell", "unicode": "U+1F514"}, - {"number": 60, "emoji": "⚓", "description": "Anchor", "unicode": "U+2693"}, - {"number": 61, "emoji": "🎧", "description": "Headphones", "unicode": "U+1F3A7"}, - {"number": 62, "emoji": "📁", "description": "Folder", "unicode": "U+1F4C1"}, - {"number": 63, "emoji": "📌", "description": "Pin", "unicode": "U+1F4CC"} -] + { + "number": 0, + "emoji": "🐶", + "description": "Dog", + "unicode": "U+1F436", + "translated_descriptions": {} + }, + { + "number": 1, + "emoji": "🐱", + "description": "Cat", + "unicode": "U+1F431", + "translated_descriptions": {} + }, + { + "number": 2, + "emoji": "🦁", + "description": "Lion", + "unicode": "U+1F981", + "translated_descriptions": {} + }, + { + "number": 3, + "emoji": "🐎", + "description": "Horse", + "unicode": "U+1F40E", + "translated_descriptions": {} + }, + { + "number": 4, + "emoji": "🦄", + "description": "Unicorn", + "unicode": "U+1F984", + "translated_descriptions": {} + }, + { + "number": 5, + "emoji": "🐷", + "description": "Pig", + "unicode": "U+1F437", + "translated_descriptions": {} + }, + { + "number": 6, + "emoji": "🐘", + "description": "Elephant", + "unicode": "U+1F418", + "translated_descriptions": {} + }, + { + "number": 7, + "emoji": "🐰", + "description": "Rabbit", + "unicode": "U+1F430", + "translated_descriptions": {} + }, + { + "number": 8, + "emoji": "🐼", + "description": "Panda", + "unicode": "U+1F43C", + "translated_descriptions": {} + }, + { + "number": 9, + "emoji": "🐓", + "description": "Rooster", + "unicode": "U+1F413", + "translated_descriptions": {} + }, + { + "number": 10, + "emoji": "🐧", + "description": "Penguin", + "unicode": "U+1F427", + "translated_descriptions": {} + }, + { + "number": 11, + "emoji": "🐢", + "description": "Turtle", + "unicode": "U+1F422", + "translated_descriptions": {} + }, + { + "number": 12, + "emoji": "🐟", + "description": "Fish", + "unicode": "U+1F41F", + "translated_descriptions": {} + }, + { + "number": 13, + "emoji": "🐙", + "description": "Octopus", + "unicode": "U+1F419", + "translated_descriptions": {} + }, + { + "number": 14, + "emoji": "🦋", + "description": "Butterfly", + "unicode": "U+1F98B", + "translated_descriptions": {} + }, + { + "number": 15, + "emoji": "🌷", + "description": "Flower", + "unicode": "U+1F337", + "translated_descriptions": {} + }, + { + "number": 16, + "emoji": "🌳", + "description": "Tree", + "unicode": "U+1F333", + "translated_descriptions": {} + }, + { + "number": 17, + "emoji": "🌵", + "description": "Cactus", + "unicode": "U+1F335", + "translated_descriptions": {} + }, + { + "number": 18, + "emoji": "🍄", + "description": "Mushroom", + "unicode": "U+1F344", + "translated_descriptions": {} + }, + { + "number": 19, + "emoji": "🌏", + "description": "Globe", + "unicode": "U+1F30F", + "translated_descriptions": {} + }, + { + "number": 20, + "emoji": "🌙", + "description": "Moon", + "unicode": "U+1F319", + "translated_descriptions": {} + }, + { + "number": 21, + "emoji": "☁️", + "description": "Cloud", + "unicode": "U+2601U+FE0F", + "translated_descriptions": {} + }, + { + "number": 22, + "emoji": "🔥", + "description": "Fire", + "unicode": "U+1F525", + "translated_descriptions": {} + }, + { + "number": 23, + "emoji": "🍌", + "description": "Banana", + "unicode": "U+1F34C", + "translated_descriptions": {} + }, + { + "number": 24, + "emoji": "🍎", + "description": "Apple", + "unicode": "U+1F34E", + "translated_descriptions": {} + }, + { + "number": 25, + "emoji": "🍓", + "description": "Strawberry", + "unicode": "U+1F353", + "translated_descriptions": {} + }, + { + "number": 26, + "emoji": "🌽", + "description": "Corn", + "unicode": "U+1F33D", + "translated_descriptions": {} + }, + { + "number": 27, + "emoji": "🍕", + "description": "Pizza", + "unicode": "U+1F355", + "translated_descriptions": {} + }, + { + "number": 28, + "emoji": "🎂", + "description": "Cake", + "unicode": "U+1F382", + "translated_descriptions": {} + }, + { + "number": 29, + "emoji": "❤️", + "description": "Heart", + "unicode": "U+2764U+FE0F", + "translated_descriptions": {} + }, + { + "number": 30, + "emoji": "😀", + "description": "Smiley", + "unicode": "U+1F600", + "translated_descriptions": {} + }, + { + "number": 31, + "emoji": "🤖", + "description": "Robot", + "unicode": "U+1F916", + "translated_descriptions": {} + }, + { + "number": 32, + "emoji": "🎩", + "description": "Hat", + "unicode": "U+1F3A9", + "translated_descriptions": {} + }, + { + "number": 33, + "emoji": "👓", + "description": "Glasses", + "unicode": "U+1F453", + "translated_descriptions": {} + }, + { + "number": 34, + "emoji": "🔧", + "description": "Spanner", + "unicode": "U+1F527", + "translated_descriptions": {} + }, + { + "number": 35, + "emoji": "🎅", + "description": "Santa", + "unicode": "U+1F385", + "translated_descriptions": {} + }, + { + "number": 36, + "emoji": "👍", + "description": "Thumbs Up", + "unicode": "U+1F44D", + "translated_descriptions": {} + }, + { + "number": 37, + "emoji": "☂️", + "description": "Umbrella", + "unicode": "U+2602U+FE0F", + "translated_descriptions": {} + }, + { + "number": 38, + "emoji": "⌛", + "description": "Hourglass", + "unicode": "U+231B", + "translated_descriptions": {} + }, + { + "number": 39, + "emoji": "⏰", + "description": "Clock", + "unicode": "U+23F0", + "translated_descriptions": {} + }, + { + "number": 40, + "emoji": "🎁", + "description": "Gift", + "unicode": "U+1F381", + "translated_descriptions": {} + }, + { + "number": 41, + "emoji": "💡", + "description": "Light Bulb", + "unicode": "U+1F4A1", + "translated_descriptions": {} + }, + { + "number": 42, + "emoji": "📕", + "description": "Book", + "unicode": "U+1F4D5", + "translated_descriptions": {} + }, + { + "number": 43, + "emoji": "✏️", + "description": "Pencil", + "unicode": "U+270FU+FE0F", + "translated_descriptions": {} + }, + { + "number": 44, + "emoji": "📎", + "description": "Paperclip", + "unicode": "U+1F4CE", + "translated_descriptions": {} + }, + { + "number": 45, + "emoji": "✂️", + "description": "Scissors", + "unicode": "U+2702U+FE0F", + "translated_descriptions": {} + }, + { + "number": 46, + "emoji": "🔒", + "description": "Lock", + "unicode": "U+1F512", + "translated_descriptions": {} + }, + { + "number": 47, + "emoji": "🔑", + "description": "Key", + "unicode": "U+1F511", + "translated_descriptions": {} + }, + { + "number": 48, + "emoji": "🔨", + "description": "Hammer", + "unicode": "U+1F528", + "translated_descriptions": {} + }, + { + "number": 49, + "emoji": "☎️", + "description": "Telephone", + "unicode": "U+260EU+FE0F", + "translated_descriptions": {} + }, + { + "number": 50, + "emoji": "🏁", + "description": "Flag", + "unicode": "U+1F3C1", + "translated_descriptions": {} + }, + { + "number": 51, + "emoji": "🚂", + "description": "Train", + "unicode": "U+1F682", + "translated_descriptions": {} + }, + { + "number": 52, + "emoji": "🚲", + "description": "Bicycle", + "unicode": "U+1F6B2", + "translated_descriptions": {} + }, + { + "number": 53, + "emoji": "✈️", + "description": "Aeroplane", + "unicode": "U+2708U+FE0F", + "translated_descriptions": {} + }, + { + "number": 54, + "emoji": "🚀", + "description": "Rocket", + "unicode": "U+1F680", + "translated_descriptions": {} + }, + { + "number": 55, + "emoji": "🏆", + "description": "Trophy", + "unicode": "U+1F3C6", + "translated_descriptions": {} + }, + { + "number": 56, + "emoji": "⚽", + "description": "Ball", + "unicode": "U+26BD", + "translated_descriptions": {} + }, + { + "number": 57, + "emoji": "🎸", + "description": "Guitar", + "unicode": "U+1F3B8", + "translated_descriptions": {} + }, + { + "number": 58, + "emoji": "🎺", + "description": "Trumpet", + "unicode": "U+1F3BA", + "translated_descriptions": {} + }, + { + "number": 59, + "emoji": "🔔", + "description": "Bell", + "unicode": "U+1F514", + "translated_descriptions": {} + }, + { + "number": 60, + "emoji": "⚓", + "description": "Anchor", + "unicode": "U+2693", + "translated_descriptions": {} + }, + { + "number": 61, + "emoji": "🎧", + "description": "Headphones", + "unicode": "U+1F3A7", + "translated_descriptions": {} + }, + { + "number": 62, + "emoji": "📁", + "description": "Folder", + "unicode": "U+1F4C1", + "translated_descriptions": {} + }, + { + "number": 63, + "emoji": "📌", + "description": "Pin", + "unicode": "U+1F4CC", + "translated_descriptions": {} + } +] \ No newline at end of file diff --git a/meta/releasing_a_spec.md b/meta/releasing_a_spec.md index f186c4be..daec3662 100644 --- a/meta/releasing_a_spec.md +++ b/meta/releasing_a_spec.md @@ -19,6 +19,8 @@ The remainder of the process is as follows: 1. Having checked out the new release branch, navigate your way over to `./changelogs`. 1. Follow the release instructions provided in the README.md located there. 1. Update any version/link references across all specifications. +1. From translate.riot.im, push repository changes and merge the subsequent PR. +1. Run `./scripts/i18n.py` to ensure all translatable files are up to date. 1. Generate the specification using `./scripts/gendoc.py`, specifying all the API versions at the time of generation. For example: `./scripts/gendoc.py -c r0.4.0 -s r0.1.0 -i r0.1.0 #etc` 1. PR the changes to the matrix-org/matrix.org repository (for historic tracking). diff --git a/scripts/i18n.py b/scripts/i18n.py new file mode 100644 index 00000000..e4dce2cf --- /dev/null +++ b/scripts/i18n.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 +# +# i18n.py: Generate and merge the i18n files for the spec. + +import json +import sys +import os +import os.path + +scripts_dir = os.path.dirname(os.path.abspath(__file__)) +data_defs_dir = os.path.join(scripts_dir, "../data-definitions") + +def merge_sas_emoji_v1(): + emoji = dict() # will be populated by a read + with open(os.path.join(data_defs_dir, "sas-emoji.json"), encoding="utf8") as f: + emoji = json.load(f) + for e in emoji: + e["translated_descriptions"] = dict() + pth = os.path.join(data_defs_dir, "sas-emoji-v1-i18n") + translations = [t for t in os.listdir(pth) if os.path.isfile(os.path.join(pth, t))] + for translation in translations: + if not translation.endswith(".json") or translation == "base.json": + continue + lang = translation[:-5] # trim off the json extension + with open(os.path.join(pth, translation), encoding="utf8") as lf: + descs = json.load(lf) + for e in emoji: + e["translated_descriptions"][lang] = descs[e["description"]] + with open(os.path.join(data_defs_dir, "sas-emoji.json"), mode="w+", encoding="utf8") as o: + json.dump(emoji, o, ensure_ascii=False, indent=4) + +merge_sas_emoji_v1() diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 53ce2775..0e57636f 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -770,6 +770,11 @@ Clients SHOULD show the emoji with the descriptions from the table, or appropria translation of those descriptions. Client authors SHOULD collaborate to create a common set of translations for all languages. +.. Note:: + Known translations for the emoji are available from + https://github.com/matrix-org/matrix-doc/blob/master/data-definitions/ and can be + translated online: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1 + .. section name changed, so make sure that old links keep working .. _key-sharing: From 41fa1886dbb88a967a16845a24914f2c7a96c9fa Mon Sep 17 00:00:00 2001 From: strix aluco Date: Wed, 12 Aug 2020 20:33:53 +0000 Subject: [PATCH 1195/1250] Added translation using Weblate (Ukrainian) --- data-definitions/sas-emoji-v1-i18n/uk.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/uk.json diff --git a/data-definitions/sas-emoji-v1-i18n/uk.json b/data-definitions/sas-emoji-v1-i18n/uk.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/uk.json @@ -0,0 +1 @@ +{} From 7e6bba3256817edcce7c2f7183dc715b747b7fac Mon Sep 17 00:00:00 2001 From: reivilibre Date: Wed, 12 Aug 2020 20:46:17 +0000 Subject: [PATCH 1196/1250] Added translation using Weblate (French) --- data-definitions/sas-emoji-v1-i18n/fr.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/fr.json diff --git a/data-definitions/sas-emoji-v1-i18n/fr.json b/data-definitions/sas-emoji-v1-i18n/fr.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/fr.json @@ -0,0 +1 @@ +{} From ae44ecdafc6ea0a7e0104927c58d4068546188ee Mon Sep 17 00:00:00 2001 From: reivilibre Date: Wed, 12 Aug 2020 20:52:34 +0000 Subject: [PATCH 1197/1250] Added translation using Weblate (Japanese) --- data-definitions/sas-emoji-v1-i18n/ja.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/ja.json diff --git a/data-definitions/sas-emoji-v1-i18n/ja.json b/data-definitions/sas-emoji-v1-i18n/ja.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/ja.json @@ -0,0 +1 @@ +{} From 299492b173584335868152886b28cbde4e29c89b Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Wed, 12 Aug 2020 21:19:30 +0000 Subject: [PATCH 1198/1250] Added translation using Weblate (Spanish) --- data-definitions/sas-emoji-v1-i18n/es.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/es.json diff --git a/data-definitions/sas-emoji-v1-i18n/es.json b/data-definitions/sas-emoji-v1-i18n/es.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/es.json @@ -0,0 +1 @@ +{} From 1e401c8ae338597903b9e003d307fa944b35762f Mon Sep 17 00:00:00 2001 From: reivilibre Date: Thu, 13 Aug 2020 00:43:21 +0000 Subject: [PATCH 1199/1250] Translated using Weblate (French) Currently translated at 42.2% (27 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/fr/ --- data-definitions/sas-emoji-v1-i18n/fr.json | 30 +++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/fr.json b/data-definitions/sas-emoji-v1-i18n/fr.json index 0967ef42..b76f2cb0 100644 --- a/data-definitions/sas-emoji-v1-i18n/fr.json +++ b/data-definitions/sas-emoji-v1-i18n/fr.json @@ -1 +1,29 @@ -{} +{ + "Dog": "Chien", + "Cat": "Chat", + "Horse": "Cheval", + "Elephant": "Éléphant", + "Rabbit": "Lapin", + "Penguin": "Pinguin", + "Fish": "Poisson", + "Butterfly": "Papillon", + "Flower": "Fleur", + "Tree": "Arbre", + "Mushroom": "Champignon", + "Moon": "Lune", + "Cloud": "Nuage", + "Fire": "Feu", + "Banana": "Banane", + "Apple": "Pomme", + "Pizza": "Pizza", + "Cake": "Gâteau", + "Heart": "Cœur", + "Hat": "Châpeau", + "Glasses": "Lunettes", + "Hourglass": "Horloge", + "Book": "Livre", + "Key": "Clé", + "Telephone": "Téléphone", + "Bicycle": "Vélo", + "Aeroplane": "Avion" +} From 5daf0fbb7b82edeece98ead58e8bab4463986b50 Mon Sep 17 00:00:00 2001 From: reivilibre Date: Thu, 13 Aug 2020 00:44:31 +0000 Subject: [PATCH 1200/1250] Translated using Weblate (Japanese) Currently translated at 25.0% (16 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/ja/ --- data-definitions/sas-emoji-v1-i18n/ja.json | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/ja.json b/data-definitions/sas-emoji-v1-i18n/ja.json index 0967ef42..4180e2ae 100644 --- a/data-definitions/sas-emoji-v1-i18n/ja.json +++ b/data-definitions/sas-emoji-v1-i18n/ja.json @@ -1 +1,18 @@ -{} +{ + "Dog": "犬", + "Cat": "猫", + "Horse": "馬", + "Octopus": "たこ", + "Flower": "花", + "Tree": "木", + "Mushroom": "きのこ", + "Moon": "月", + "Apple": "リンゴ", + "Cake": "ケーキ", + "Robot": "ロボと", + "Glasses": "めがね", + "Book": "本", + "Telephone": "電話機", + "Train": "電車", + "Bicycle": "自転車" +} From c78ce90dfa14acdf710b6cd99838c3f1583b0cd4 Mon Sep 17 00:00:00 2001 From: Will Hunt Date: Thu, 13 Aug 2020 00:45:11 +0000 Subject: [PATCH 1201/1250] Translated using Weblate (Spanish) Currently translated at 31.2% (20 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/es/ --- data-definitions/sas-emoji-v1-i18n/es.json | 23 +++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/es.json b/data-definitions/sas-emoji-v1-i18n/es.json index 0967ef42..503cf13d 100644 --- a/data-definitions/sas-emoji-v1-i18n/es.json +++ b/data-definitions/sas-emoji-v1-i18n/es.json @@ -1 +1,22 @@ -{} +{ + "Dog": "Perro", + "Cat": "Gato", + "Lion": "León", + "Pig": "Cerdo", + "Fire": "Fuego", + "Apple": "Manzana", + "Clock": "Reloj", + "Gift": "Regalo", + "Book": "Libro", + "Pencil": "Lápiz", + "Key": "Llave", + "Hammer": "Martillo", + "Telephone": "Telefono", + "Train": "Tren", + "Bicycle": "Bicicleta", + "Ball": "Bola", + "Guitar": "Guitarra", + "Trumpet": "Trompeta", + "Bell": "Campana", + "Pin": "Alfiler" +} From 5b9cbfb7bfb0cf74321a1be10dd8647e8edcd834 Mon Sep 17 00:00:00 2001 From: strix aluco Date: Thu, 13 Aug 2020 00:41:18 +0000 Subject: [PATCH 1202/1250] Translated using Weblate (Ukrainian) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/uk/ --- data-definitions/sas-emoji-v1-i18n/uk.json | 67 +++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/uk.json b/data-definitions/sas-emoji-v1-i18n/uk.json index 0967ef42..1b331770 100644 --- a/data-definitions/sas-emoji-v1-i18n/uk.json +++ b/data-definitions/sas-emoji-v1-i18n/uk.json @@ -1 +1,66 @@ -{} +{ + "Dog": "Пес", + "Cat": "Кіт", + "Lion": "Лев", + "Horse": "Кінь", + "Unicorn": "Єдиноріг", + "Pig": "Свиня", + "Elephant": "Слон", + "Rabbit": "Кріль", + "Panda": "Панда", + "Rooster": "Когут", + "Penguin": "Пінгвін", + "Turtle": "Черепаха", + "Fish": "Риба", + "Octopus": "Восьминіг", + "Butterfly": "Метелик", + "Flower": "Квітка", + "Tree": "Дерево", + "Cactus": "Кактус", + "Mushroom": "Гриб", + "Globe": "Глобус", + "Moon": "Місяць", + "Cloud": "Хмара", + "Fire": "Вогонь", + "Banana": "Банан", + "Apple": "Яблуко", + "Strawberry": "Полуниця", + "Corn": "Кукурудза", + "Pizza": "Піца", + "Cake": "Пиріг", + "Heart": "Серце", + "Smiley": "Посмішка", + "Robot": "Робот", + "Hat": "Капелюх", + "Glasses": "Окуляри", + "Spanner": "Гайковий ключ", + "Santa": "Санта Клаус", + "Thumbs Up": "Великий палець вгору", + "Umbrella": "Парасолька", + "Hourglass": "Пісковий годинник", + "Clock": "Годинник", + "Gift": "Подарунок", + "Light Bulb": "Лампочка", + "Book": "Книга", + "Pencil": "Олівець", + "Paperclip": "Спиначка", + "Scissors": "Ножиці", + "Lock": "Замок", + "Key": "Ключ", + "Hammer": "Молоток", + "Telephone": "Телефон", + "Flag": "Прапор", + "Train": "Потяг", + "Bicycle": "Велосипед", + "Aeroplane": "Літак", + "Rocket": "Ракета", + "Trophy": "Приз", + "Ball": "М'яч", + "Guitar": "Гітара", + "Trumpet": "Труба", + "Bell": "Дзвін", + "Anchor": "Якір", + "Headphones": "Навушники", + "Folder": "Тека", + "Pin": "Кнопка" +} From 589b9a3f774a7c671ebc818c8ec62942554afe2a Mon Sep 17 00:00:00 2001 From: Alexey Murz Korepov Date: Thu, 13 Aug 2020 01:55:49 +0000 Subject: [PATCH 1203/1250] Added translation using Weblate (Russian) --- data-definitions/sas-emoji-v1-i18n/ru.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/ru.json diff --git a/data-definitions/sas-emoji-v1-i18n/ru.json b/data-definitions/sas-emoji-v1-i18n/ru.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/ru.json @@ -0,0 +1 @@ +{} From c5335a8922900976c143f0db75a10d38e7cbab11 Mon Sep 17 00:00:00 2001 From: aWeinzierl Date: Thu, 13 Aug 2020 07:29:44 +0000 Subject: [PATCH 1204/1250] Added translation using Weblate (German) --- data-definitions/sas-emoji-v1-i18n/de.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/de.json diff --git a/data-definitions/sas-emoji-v1-i18n/de.json b/data-definitions/sas-emoji-v1-i18n/de.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/de.json @@ -0,0 +1 @@ +{} From 05f5373a4aca732901353c6bbf7c88436f5aea99 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 13 Aug 2020 02:18:37 +0000 Subject: [PATCH 1205/1250] Translated using Weblate (French) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/fr/ --- data-definitions/sas-emoji-v1-i18n/fr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/fr.json b/data-definitions/sas-emoji-v1-i18n/fr.json index b76f2cb0..19a8ba1c 100644 --- a/data-definitions/sas-emoji-v1-i18n/fr.json +++ b/data-definitions/sas-emoji-v1-i18n/fr.json @@ -25,5 +25,6 @@ "Key": "Clé", "Telephone": "Téléphone", "Bicycle": "Vélo", - "Aeroplane": "Avion" + "Aeroplane": "Avion", + "Pig": "Cochon" } From c04bf46800e3e153f830faa9a0626348555ebe4c Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Thu, 13 Aug 2020 08:04:52 +0000 Subject: [PATCH 1206/1250] Translated using Weblate (French) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/fr/ --- data-definitions/sas-emoji-v1-i18n/fr.json | 40 ++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/data-definitions/sas-emoji-v1-i18n/fr.json b/data-definitions/sas-emoji-v1-i18n/fr.json index 19a8ba1c..f1443bb8 100644 --- a/data-definitions/sas-emoji-v1-i18n/fr.json +++ b/data-definitions/sas-emoji-v1-i18n/fr.json @@ -20,11 +20,47 @@ "Heart": "Cœur", "Hat": "Châpeau", "Glasses": "Lunettes", - "Hourglass": "Horloge", + "Hourglass": "Sablier", "Book": "Livre", "Key": "Clé", "Telephone": "Téléphone", "Bicycle": "Vélo", "Aeroplane": "Avion", - "Pig": "Cochon" + "Pig": "Cochon", + "Lion": "Lion", + "Unicorn": "Licorne", + "Panda": "Panda", + "Rooster": "Coq", + "Turtle": "Tortue", + "Octopus": "Poulpe", + "Cactus": "Cactus", + "Globe": "Globe", + "Strawberry": "Fraise", + "Corn": "Maïs", + "Smiley": "Personne souriante", + "Robot": "Robot", + "Spanner": "Clé à molette", + "Santa": "Père Noël", + "Thumbs Up": "Pouce en l'air", + "Umbrella": "Parapluie", + "Clock": "Horloge", + "Gift": "Cadeau", + "Light Bulb": "Ampoule", + "Pencil": "Crayon", + "Paperclip": "Trombone", + "Scissors": "Ciseaux", + "Lock": "Cadenas", + "Hammer": "Marteau", + "Flag": "Drapeau", + "Train": "Train", + "Rocket": "Fusée", + "Trophy": "Trophée", + "Ball": "Ballon", + "Guitar": "Guitare", + "Trumpet": "Trompette", + "Bell": "Cloche", + "Anchor": "Ancre", + "Headphones": "Casque audio", + "Folder": "Dossier", + "Pin": "Punaise" } From 7da3b3752455755079cf8939598379e2a5032c7f Mon Sep 17 00:00:00 2001 From: aWeinzierl Date: Thu, 13 Aug 2020 07:30:27 +0000 Subject: [PATCH 1207/1250] Translated using Weblate (German) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/de/ --- data-definitions/sas-emoji-v1-i18n/de.json | 67 +++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/de.json b/data-definitions/sas-emoji-v1-i18n/de.json index 0967ef42..e2b49737 100644 --- a/data-definitions/sas-emoji-v1-i18n/de.json +++ b/data-definitions/sas-emoji-v1-i18n/de.json @@ -1 +1,66 @@ -{} +{ + "Dog": "Hund", + "Cat": "Katze", + "Lion": "Löwe", + "Horse": "Pferd", + "Unicorn": "Einhorn", + "Pig": "Schwein", + "Elephant": "Elefant", + "Rabbit": "Hase", + "Panda": "Panda", + "Rooster": "Hahn", + "Penguin": "Pinguin", + "Turtle": "Schildkröte", + "Fish": "Fisch", + "Octopus": "Oktopus", + "Butterfly": "Schmetterling", + "Flower": "Blume", + "Tree": "Baum", + "Cactus": "Kaktus", + "Mushroom": "Pilz", + "Globe": "Globus", + "Moon": "Mond", + "Cloud": "Wolke", + "Fire": "Feuer", + "Banana": "Banane", + "Apple": "Apfel", + "Strawberry": "Erdbeere", + "Corn": "Korn", + "Pizza": "Pizza", + "Cake": "Kuchen", + "Heart": "Herz", + "Smiley": "Smiley", + "Robot": "Roboter", + "Hat": "Hut", + "Glasses": "Brille", + "Spanner": "Schraubenschlüssel", + "Santa": "Nikolaus", + "Thumbs Up": "Daumen Hoch", + "Umbrella": "Regenschirm", + "Hourglass": "Sanduhr", + "Clock": "Wecker", + "Gift": "Geschenk", + "Light Bulb": "Glühbirne", + "Book": "Buch", + "Pencil": "Bleistift", + "Paperclip": "Büroklammer", + "Scissors": "Schere", + "Lock": "Schloss", + "Key": "Schlüssel", + "Hammer": "Hammer", + "Telephone": "Telefon", + "Flag": "Flagge", + "Train": "Zug", + "Bicycle": "Fahrrad", + "Aeroplane": "Flugzeug", + "Rocket": "Rakete", + "Trophy": "Trophäe", + "Ball": "Ball", + "Guitar": "Gitarre", + "Trumpet": "Trompete", + "Bell": "Glocke", + "Anchor": "Anker", + "Headphones": "Kopfhörer", + "Folder": "Ordner", + "Pin": "Stecknadel" +} From 76280f215cb6eb48b27e0f8d85260f5bbb2b6a42 Mon Sep 17 00:00:00 2001 From: Alexey Murz Korepov Date: Thu, 13 Aug 2020 01:56:43 +0000 Subject: [PATCH 1208/1250] Translated using Weblate (Russian) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/ru/ --- data-definitions/sas-emoji-v1-i18n/ru.json | 67 +++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/ru.json b/data-definitions/sas-emoji-v1-i18n/ru.json index 0967ef42..99f8c220 100644 --- a/data-definitions/sas-emoji-v1-i18n/ru.json +++ b/data-definitions/sas-emoji-v1-i18n/ru.json @@ -1 +1,66 @@ -{} +{ + "Dog": "Собака", + "Cat": "Кошка", + "Lion": "Лев", + "Horse": "Лошадь", + "Unicorn": "Единорог", + "Pig": "Свинья", + "Elephant": "Слон", + "Rabbit": "Кролик", + "Panda": "Панда", + "Rooster": "Петух", + "Penguin": "Пингвин", + "Turtle": "Черепаха", + "Fish": "Рыба", + "Octopus": "Осьминог", + "Butterfly": "Бабочка", + "Flower": "Цветок", + "Tree": "Дерево", + "Cactus": "Кактус", + "Mushroom": "Гриб", + "Globe": "Глобус", + "Moon": "Луна", + "Cloud": "Облако", + "Fire": "Огонь", + "Banana": "Банан", + "Apple": "Яблоко", + "Strawberry": "Клубника", + "Corn": "Кукуруза", + "Pizza": "Пицца", + "Cake": "Торт", + "Heart": "Сердце", + "Smiley": "Улыбка", + "Robot": "Робот", + "Hat": "Шляпа", + "Glasses": "Очки", + "Spanner": "Ключ", + "Santa": "Санта", + "Thumbs Up": "Большой палец вверх", + "Umbrella": "Зонт", + "Hourglass": "Песочные часы", + "Clock": "Часы", + "Gift": "Подарок", + "Light Bulb": "Лампочка", + "Book": "Книга", + "Pencil": "Карандаш", + "Paperclip": "Скрепка", + "Scissors": "Ножницы", + "Lock": "Замок", + "Key": "Ключ", + "Hammer": "Молоток", + "Telephone": "Телефон", + "Flag": "Флаг", + "Train": "Поезд", + "Bicycle": "Велосипед", + "Aeroplane": "Самолет", + "Rocket": "Ракета", + "Trophy": "Кубок", + "Ball": "Мяч", + "Guitar": "Гитара", + "Trumpet": "Труба", + "Bell": "Колокол", + "Anchor": "Якорь", + "Headphones": "Наушники", + "Folder": "Папка", + "Pin": "Булавка" +} From f0ba7f014b1dc21baaff999e0bd710fa13baf731 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 13 Aug 2020 11:54:56 -0600 Subject: [PATCH 1209/1250] Update i18n for emoji --- data-definitions/sas-emoji.json | 576 ++++++++++++++++++++++++++++---- scripts/i18n.py | 2 +- 2 files changed, 513 insertions(+), 65 deletions(-) diff --git a/data-definitions/sas-emoji.json b/data-definitions/sas-emoji.json index 6e9254ef..093c5793 100644 --- a/data-definitions/sas-emoji.json +++ b/data-definitions/sas-emoji.json @@ -4,447 +4,895 @@ "emoji": "🐶", "description": "Dog", "unicode": "U+1F436", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Hund", + "es": "Perro", + "fr": "Chien", + "ja": "犬", + "ru": "Собака", + "uk": "Пес" + } }, { "number": 1, "emoji": "🐱", "description": "Cat", "unicode": "U+1F431", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Katze", + "es": "Gato", + "fr": "Chat", + "ja": "猫", + "ru": "Кошка", + "uk": "Кіт" + } }, { "number": 2, "emoji": "🦁", "description": "Lion", "unicode": "U+1F981", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Löwe", + "es": "León", + "fr": "Lion", + "ja": null, + "ru": "Лев", + "uk": "Лев" + } }, { "number": 3, "emoji": "🐎", "description": "Horse", "unicode": "U+1F40E", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Pferd", + "es": null, + "fr": "Cheval", + "ja": "馬", + "ru": "Лошадь", + "uk": "Кінь" + } }, { "number": 4, "emoji": "🦄", "description": "Unicorn", "unicode": "U+1F984", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Einhorn", + "es": null, + "fr": "Licorne", + "ja": null, + "ru": "Единорог", + "uk": "Єдиноріг" + } }, { "number": 5, "emoji": "🐷", "description": "Pig", "unicode": "U+1F437", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Schwein", + "es": "Cerdo", + "fr": "Cochon", + "ja": null, + "ru": "Свинья", + "uk": "Свиня" + } }, { "number": 6, "emoji": "🐘", "description": "Elephant", "unicode": "U+1F418", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Elefant", + "es": null, + "fr": "Éléphant", + "ja": null, + "ru": "Слон", + "uk": "Слон" + } }, { "number": 7, "emoji": "🐰", "description": "Rabbit", "unicode": "U+1F430", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Hase", + "es": null, + "fr": "Lapin", + "ja": null, + "ru": "Кролик", + "uk": "Кріль" + } }, { "number": 8, "emoji": "🐼", "description": "Panda", "unicode": "U+1F43C", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Panda", + "es": null, + "fr": "Panda", + "ja": null, + "ru": "Панда", + "uk": "Панда" + } }, { "number": 9, "emoji": "🐓", "description": "Rooster", "unicode": "U+1F413", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Hahn", + "es": null, + "fr": "Coq", + "ja": null, + "ru": "Петух", + "uk": "Когут" + } }, { "number": 10, "emoji": "🐧", "description": "Penguin", "unicode": "U+1F427", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Pinguin", + "es": null, + "fr": "Pinguin", + "ja": null, + "ru": "Пингвин", + "uk": "Пінгвін" + } }, { "number": 11, "emoji": "🐢", "description": "Turtle", "unicode": "U+1F422", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Schildkröte", + "es": null, + "fr": "Tortue", + "ja": null, + "ru": "Черепаха", + "uk": "Черепаха" + } }, { "number": 12, "emoji": "🐟", "description": "Fish", "unicode": "U+1F41F", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Fisch", + "es": null, + "fr": "Poisson", + "ja": null, + "ru": "Рыба", + "uk": "Риба" + } }, { "number": 13, "emoji": "🐙", "description": "Octopus", "unicode": "U+1F419", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Oktopus", + "es": null, + "fr": "Poulpe", + "ja": "たこ", + "ru": "Осьминог", + "uk": "Восьминіг" + } }, { "number": 14, "emoji": "🦋", "description": "Butterfly", "unicode": "U+1F98B", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Schmetterling", + "es": null, + "fr": "Papillon", + "ja": null, + "ru": "Бабочка", + "uk": "Метелик" + } }, { "number": 15, "emoji": "🌷", "description": "Flower", "unicode": "U+1F337", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Blume", + "es": null, + "fr": "Fleur", + "ja": "花", + "ru": "Цветок", + "uk": "Квітка" + } }, { "number": 16, "emoji": "🌳", "description": "Tree", "unicode": "U+1F333", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Baum", + "es": null, + "fr": "Arbre", + "ja": "木", + "ru": "Дерево", + "uk": "Дерево" + } }, { "number": 17, "emoji": "🌵", "description": "Cactus", "unicode": "U+1F335", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Kaktus", + "es": null, + "fr": "Cactus", + "ja": null, + "ru": "Кактус", + "uk": "Кактус" + } }, { "number": 18, "emoji": "🍄", "description": "Mushroom", "unicode": "U+1F344", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Pilz", + "es": null, + "fr": "Champignon", + "ja": "きのこ", + "ru": "Гриб", + "uk": "Гриб" + } }, { "number": 19, "emoji": "🌏", "description": "Globe", "unicode": "U+1F30F", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Globus", + "es": null, + "fr": "Globe", + "ja": null, + "ru": "Глобус", + "uk": "Глобус" + } }, { "number": 20, "emoji": "🌙", "description": "Moon", "unicode": "U+1F319", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Mond", + "es": null, + "fr": "Lune", + "ja": "月", + "ru": "Луна", + "uk": "Місяць" + } }, { "number": 21, "emoji": "☁️", "description": "Cloud", "unicode": "U+2601U+FE0F", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Wolke", + "es": null, + "fr": "Nuage", + "ja": null, + "ru": "Облако", + "uk": "Хмара" + } }, { "number": 22, "emoji": "🔥", "description": "Fire", "unicode": "U+1F525", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Feuer", + "es": "Fuego", + "fr": "Feu", + "ja": null, + "ru": "Огонь", + "uk": "Вогонь" + } }, { "number": 23, "emoji": "🍌", "description": "Banana", "unicode": "U+1F34C", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Banane", + "es": null, + "fr": "Banane", + "ja": null, + "ru": "Банан", + "uk": "Банан" + } }, { "number": 24, "emoji": "🍎", "description": "Apple", "unicode": "U+1F34E", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Apfel", + "es": "Manzana", + "fr": "Pomme", + "ja": "リンゴ", + "ru": "Яблоко", + "uk": "Яблуко" + } }, { "number": 25, "emoji": "🍓", "description": "Strawberry", "unicode": "U+1F353", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Erdbeere", + "es": null, + "fr": "Fraise", + "ja": null, + "ru": "Клубника", + "uk": "Полуниця" + } }, { "number": 26, "emoji": "🌽", "description": "Corn", "unicode": "U+1F33D", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Korn", + "es": null, + "fr": "Maïs", + "ja": null, + "ru": "Кукуруза", + "uk": "Кукурудза" + } }, { "number": 27, "emoji": "🍕", "description": "Pizza", "unicode": "U+1F355", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Pizza", + "es": null, + "fr": "Pizza", + "ja": null, + "ru": "Пицца", + "uk": "Піца" + } }, { "number": 28, "emoji": "🎂", "description": "Cake", "unicode": "U+1F382", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Kuchen", + "es": null, + "fr": "Gâteau", + "ja": "ケーキ", + "ru": "Торт", + "uk": "Пиріг" + } }, { "number": 29, "emoji": "❤️", "description": "Heart", "unicode": "U+2764U+FE0F", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Herz", + "es": null, + "fr": "Cœur", + "ja": null, + "ru": "Сердце", + "uk": "Серце" + } }, { "number": 30, "emoji": "😀", "description": "Smiley", "unicode": "U+1F600", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Smiley", + "es": null, + "fr": "Personne souriante", + "ja": null, + "ru": "Улыбка", + "uk": "Посмішка" + } }, { "number": 31, "emoji": "🤖", "description": "Robot", "unicode": "U+1F916", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Roboter", + "es": null, + "fr": "Robot", + "ja": "ロボと", + "ru": "Робот", + "uk": "Робот" + } }, { "number": 32, "emoji": "🎩", "description": "Hat", "unicode": "U+1F3A9", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Hut", + "es": null, + "fr": "Châpeau", + "ja": null, + "ru": "Шляпа", + "uk": "Капелюх" + } }, { "number": 33, "emoji": "👓", "description": "Glasses", "unicode": "U+1F453", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Brille", + "es": null, + "fr": "Lunettes", + "ja": "めがね", + "ru": "Очки", + "uk": "Окуляри" + } }, { "number": 34, "emoji": "🔧", "description": "Spanner", "unicode": "U+1F527", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Schraubenschlüssel", + "es": null, + "fr": "Clé à molette", + "ja": null, + "ru": "Ключ", + "uk": "Гайковий ключ" + } }, { "number": 35, "emoji": "🎅", "description": "Santa", "unicode": "U+1F385", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Nikolaus", + "es": null, + "fr": "Père Noël", + "ja": null, + "ru": "Санта", + "uk": "Санта Клаус" + } }, { "number": 36, "emoji": "👍", "description": "Thumbs Up", "unicode": "U+1F44D", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Daumen Hoch", + "es": null, + "fr": "Pouce en l'air", + "ja": null, + "ru": "Большой палец вверх", + "uk": "Великий палець вгору" + } }, { "number": 37, "emoji": "☂️", "description": "Umbrella", "unicode": "U+2602U+FE0F", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Regenschirm", + "es": null, + "fr": "Parapluie", + "ja": null, + "ru": "Зонт", + "uk": "Парасолька" + } }, { "number": 38, "emoji": "⌛", "description": "Hourglass", "unicode": "U+231B", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Sanduhr", + "es": null, + "fr": "Sablier", + "ja": null, + "ru": "Песочные часы", + "uk": "Пісковий годинник" + } }, { "number": 39, "emoji": "⏰", "description": "Clock", "unicode": "U+23F0", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Wecker", + "es": "Reloj", + "fr": "Horloge", + "ja": null, + "ru": "Часы", + "uk": "Годинник" + } }, { "number": 40, "emoji": "🎁", "description": "Gift", "unicode": "U+1F381", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Geschenk", + "es": "Regalo", + "fr": "Cadeau", + "ja": null, + "ru": "Подарок", + "uk": "Подарунок" + } }, { "number": 41, "emoji": "💡", "description": "Light Bulb", "unicode": "U+1F4A1", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Glühbirne", + "es": null, + "fr": "Ampoule", + "ja": null, + "ru": "Лампочка", + "uk": "Лампочка" + } }, { "number": 42, "emoji": "📕", "description": "Book", "unicode": "U+1F4D5", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Buch", + "es": "Libro", + "fr": "Livre", + "ja": "本", + "ru": "Книга", + "uk": "Книга" + } }, { "number": 43, "emoji": "✏️", "description": "Pencil", "unicode": "U+270FU+FE0F", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Bleistift", + "es": "Lápiz", + "fr": "Crayon", + "ja": null, + "ru": "Карандаш", + "uk": "Олівець" + } }, { "number": 44, "emoji": "📎", "description": "Paperclip", "unicode": "U+1F4CE", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Büroklammer", + "es": null, + "fr": "Trombone", + "ja": null, + "ru": "Скрепка", + "uk": "Спиначка" + } }, { "number": 45, "emoji": "✂️", "description": "Scissors", "unicode": "U+2702U+FE0F", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Schere", + "es": null, + "fr": "Ciseaux", + "ja": null, + "ru": "Ножницы", + "uk": "Ножиці" + } }, { "number": 46, "emoji": "🔒", "description": "Lock", "unicode": "U+1F512", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Schloss", + "es": null, + "fr": "Cadenas", + "ja": null, + "ru": "Замок", + "uk": "Замок" + } }, { "number": 47, "emoji": "🔑", "description": "Key", "unicode": "U+1F511", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Schlüssel", + "es": "Llave", + "fr": "Clé", + "ja": null, + "ru": "Ключ", + "uk": "Ключ" + } }, { "number": 48, "emoji": "🔨", "description": "Hammer", "unicode": "U+1F528", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Hammer", + "es": "Martillo", + "fr": "Marteau", + "ja": null, + "ru": "Молоток", + "uk": "Молоток" + } }, { "number": 49, "emoji": "☎️", "description": "Telephone", "unicode": "U+260EU+FE0F", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Telefon", + "es": "Telefono", + "fr": "Téléphone", + "ja": "電話機", + "ru": "Телефон", + "uk": "Телефон" + } }, { "number": 50, "emoji": "🏁", "description": "Flag", "unicode": "U+1F3C1", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Flagge", + "es": null, + "fr": "Drapeau", + "ja": null, + "ru": "Флаг", + "uk": "Прапор" + } }, { "number": 51, "emoji": "🚂", "description": "Train", "unicode": "U+1F682", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Zug", + "es": "Tren", + "fr": "Train", + "ja": "電車", + "ru": "Поезд", + "uk": "Потяг" + } }, { "number": 52, "emoji": "🚲", "description": "Bicycle", "unicode": "U+1F6B2", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Fahrrad", + "es": "Bicicleta", + "fr": "Vélo", + "ja": "自転車", + "ru": "Велосипед", + "uk": "Велосипед" + } }, { "number": 53, "emoji": "✈️", "description": "Aeroplane", "unicode": "U+2708U+FE0F", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Flugzeug", + "es": null, + "fr": "Avion", + "ja": null, + "ru": "Самолет", + "uk": "Літак" + } }, { "number": 54, "emoji": "🚀", "description": "Rocket", "unicode": "U+1F680", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Rakete", + "es": null, + "fr": "Fusée", + "ja": null, + "ru": "Ракета", + "uk": "Ракета" + } }, { "number": 55, "emoji": "🏆", "description": "Trophy", "unicode": "U+1F3C6", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Trophäe", + "es": null, + "fr": "Trophée", + "ja": null, + "ru": "Кубок", + "uk": "Приз" + } }, { "number": 56, "emoji": "⚽", "description": "Ball", "unicode": "U+26BD", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Ball", + "es": "Bola", + "fr": "Ballon", + "ja": null, + "ru": "Мяч", + "uk": "М'яч" + } }, { "number": 57, "emoji": "🎸", "description": "Guitar", "unicode": "U+1F3B8", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Gitarre", + "es": "Guitarra", + "fr": "Guitare", + "ja": null, + "ru": "Гитара", + "uk": "Гітара" + } }, { "number": 58, "emoji": "🎺", "description": "Trumpet", "unicode": "U+1F3BA", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Trompete", + "es": "Trompeta", + "fr": "Trompette", + "ja": null, + "ru": "Труба", + "uk": "Труба" + } }, { "number": 59, "emoji": "🔔", "description": "Bell", "unicode": "U+1F514", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Glocke", + "es": "Campana", + "fr": "Cloche", + "ja": null, + "ru": "Колокол", + "uk": "Дзвін" + } }, { "number": 60, "emoji": "⚓", "description": "Anchor", "unicode": "U+2693", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Anker", + "es": null, + "fr": "Ancre", + "ja": null, + "ru": "Якорь", + "uk": "Якір" + } }, { "number": 61, "emoji": "🎧", "description": "Headphones", "unicode": "U+1F3A7", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Kopfhörer", + "es": null, + "fr": "Casque audio", + "ja": null, + "ru": "Наушники", + "uk": "Навушники" + } }, { "number": 62, "emoji": "📁", "description": "Folder", "unicode": "U+1F4C1", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Ordner", + "es": null, + "fr": "Dossier", + "ja": null, + "ru": "Папка", + "uk": "Тека" + } }, { "number": 63, "emoji": "📌", "description": "Pin", "unicode": "U+1F4CC", - "translated_descriptions": {} + "translated_descriptions": { + "de": "Stecknadel", + "es": "Alfiler", + "fr": "Punaise", + "ja": null, + "ru": "Булавка", + "uk": "Кнопка" + } } ] \ No newline at end of file diff --git a/scripts/i18n.py b/scripts/i18n.py index e4dce2cf..bd9e3bbd 100644 --- a/scripts/i18n.py +++ b/scripts/i18n.py @@ -25,7 +25,7 @@ def merge_sas_emoji_v1(): with open(os.path.join(pth, translation), encoding="utf8") as lf: descs = json.load(lf) for e in emoji: - e["translated_descriptions"][lang] = descs[e["description"]] + e["translated_descriptions"][lang] = descs.get(e["description"]) with open(os.path.join(data_defs_dir, "sas-emoji.json"), mode="w+", encoding="utf8") as o: json.dump(emoji, o, ensure_ascii=False, indent=4) From ddc0d78e0ce15acbb9a32b4b812decb5fd2a5fa9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 18 Aug 2020 08:53:13 -0600 Subject: [PATCH 1210/1250] Revert "MSC2033: Adding a device_id to /account/whoami" --- proposals/2033-whoami-device-id.md | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 proposals/2033-whoami-device-id.md diff --git a/proposals/2033-whoami-device-id.md b/proposals/2033-whoami-device-id.md deleted file mode 100644 index bac804c1..00000000 --- a/proposals/2033-whoami-device-id.md +++ /dev/null @@ -1,30 +0,0 @@ -# Proposal to include device IDs in `/account/whoami` - -There are some use cases (namely using -[Pantalaimon with bots](https://github.com/matrix-org/pantalaimon/issues/14)) -which could benefit from knowing the `device_id` associated with a token. - - -## Proposal - -The `/account/whoami` endpoint receives an additional response field for the `device_id` -associated with the access token. The field is optional because appservice users may not -have a real device associated with them. Non-appservice users should always have a device -associated with them. - -Access tokens are already associated with at most 1 device, and devices are associated with -exactly 1 access token. Because of this, we do not need to worry about multiple devices -causing problems. For more information, see -https://matrix.org/docs/spec/client_server/r0.4.0.html#relationship-between-access-tokens-and-devices - -*Note*: Pantalaimon would likely require a `device_id` be returned and error requests -otherwise. This should be considered expected behaviour by Pantalaimon in the MSC author's -opinion. - - -## Tradeoffs - -We could introduce a `/device/whoami` endpoint, however that is a less superior option. Most -calls to `/device/whoami` would additionally need to call `/account/whoami` to determine the -user ID of the account. We had might as well bundle the two pieces of information into the -same request. From 9080c5f87f87e7461d0350843b2fc6c82d079d6a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 18 Aug 2020 08:53:34 -0600 Subject: [PATCH 1211/1250] Revert "Revert "MSC2033: Adding a device_id to /account/whoami"" --- proposals/2033-whoami-device-id.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 proposals/2033-whoami-device-id.md diff --git a/proposals/2033-whoami-device-id.md b/proposals/2033-whoami-device-id.md new file mode 100644 index 00000000..bac804c1 --- /dev/null +++ b/proposals/2033-whoami-device-id.md @@ -0,0 +1,30 @@ +# Proposal to include device IDs in `/account/whoami` + +There are some use cases (namely using +[Pantalaimon with bots](https://github.com/matrix-org/pantalaimon/issues/14)) +which could benefit from knowing the `device_id` associated with a token. + + +## Proposal + +The `/account/whoami` endpoint receives an additional response field for the `device_id` +associated with the access token. The field is optional because appservice users may not +have a real device associated with them. Non-appservice users should always have a device +associated with them. + +Access tokens are already associated with at most 1 device, and devices are associated with +exactly 1 access token. Because of this, we do not need to worry about multiple devices +causing problems. For more information, see +https://matrix.org/docs/spec/client_server/r0.4.0.html#relationship-between-access-tokens-and-devices + +*Note*: Pantalaimon would likely require a `device_id` be returned and error requests +otherwise. This should be considered expected behaviour by Pantalaimon in the MSC author's +opinion. + + +## Tradeoffs + +We could introduce a `/device/whoami` endpoint, however that is a less superior option. Most +calls to `/device/whoami` would additionally need to call `/account/whoami` to determine the +user ID of the account. We had might as well bundle the two pieces of information into the +same request. From c00710d91aefaf913639542fdacf91ff08c42593 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 19 Aug 2020 15:12:54 +0100 Subject: [PATCH 1212/1250] Revert "Merge pull request #1598 from matrix-org/rav/proposals/id_grammar" This reverts commit d9135ef902310b1bc796b59b0a740dc64daee011, reversing changes made to f714aaadd011ac736d779f8460202a8d95799123. People are getting confused by the fact this has been merged. --- proposals/1597-id-grammar.md | 273 ----------------------------------- 1 file changed, 273 deletions(-) delete mode 100644 proposals/1597-id-grammar.md diff --git a/proposals/1597-id-grammar.md b/proposals/1597-id-grammar.md deleted file mode 100644 index 102f652c..00000000 --- a/proposals/1597-id-grammar.md +++ /dev/null @@ -1,273 +0,0 @@ -# Grammars for identifiers in the Matrix protocol - -## Background - -Matrix uses client- or server-generated identifiers in a number of -places. Historically the grammars for these have been underspecified, which -leads to confusion about what is or is not a valid identifier with the -possibility of incompatability between implementations. - -This proposal presents tightly-specified grammars for a number of -identifiers. - -## Common Identifiers - -[Spec](https://matrix.org/docs/spec/appendices.html#common-identifier-format) - -Proposal: - -> `localpart` may not include `:`. When parsing a Common Identifier, it should -> be split at the *leftmost* `:`. - -Rationale: server names may contain multiple `:`s (think IPv6 literals), so the -first colon is the only sane place to split them. This is a Known Thing, but I -don't think we spell it out anywhere in the spec. - -## User IDs - -User IDs are -[well-specified](https://matrix.org/docs/spec/appendices.html#user-identifiers), -however we should consider dropping `/` from the list of allowed characters, -because HTTP proxies might rewrite -`/_matrix/client/r0/profile/@foo%25bar:matrix.org/displayname` to -`/_matrix/client/r0/profile/@foo/bar:matrix.org/displayname`, messing things -up. - -History: `/` was introduced with the intention of acting as a hierarchical -namespacing character, particularly with consideration to the gitter protocol -which uses it as a hierarchical separator. However, this was not as effective -as hoped because `@foo/bar:example.com` looks like the ID is partitioned into -`@foo` and `bar:example.com`. - -Proposal: - -> Remove `/` from the list of allowed characters in User IDs. - -`/` will of course be maintained under the grammar of "historical user -IDs". Sorting out that mess is a longer-term project. - -## Room IDs and Event IDs - -[Issue](https://github.com/matrix-org/matrix-doc/issues/667) -[Spec](https://matrix.org/docs/spec/appendices.html#room-ids-and-event-ids) - -These currently have similar formats, though it is likely that event ids will -be replaced with something else due to -[#1127](https://github.com/matrix-org/matrix-doc/issues/1127). - -Currently they are both specified as ``?opaque_id:domain``, without clues as to -what the opaque_id should be. - -Synapse uses: `[A-Za-z]{18}`. -[Dendrite](https://github.com/matrix-org/dendrite/blob/b71d922/src/github.com/matrix-org/dendrite/clientapi/routing/createroom.go#L125) -uses (I think) `[A-Za-z0-9]{16}` via -[json.go](https://github.com/matrix-org/util/blob/master/json.go#L185). However, -some server implementations/forks are known to generate event IDs (and possibly -room IDs) using a wide alphabet, which means that there exist rooms that -include unusual event IDs. - -Proposal: - -> The opaque_id part must not be empty, and must consist entirely of the -> characters `[0-9a-zA-Z.=_-]`. -> -> The total length (including sigil and domain) must not exceed 255 characters. -> -> This is only enforced for v2 rooms - servers and clients wishing to support -> v1 rooms should be more tolerant. - - -## Key IDs (for federation, e2e, and identity servers) - -These are always of the form `:`. - -Valid algorithms are defined at -https://matrix.org/docs/spec/client_server/unstable.html#key-algorithms, though -we should define the alphabet for future algorithms. - -Proposal: - -> Future algorithm identifiers will be assigned from the alphabet `[a-z0-9_.]` -> and will be at most 31 characters in length. - -For federation keys, -[Synapse](https://github.com/matrix-org/synapse/blob/74854a97191191b08101821753c2672efc2a65fd/synapse/config/key.py#L159) -generates key ids as `ed25519:a_[A-Za-z]{4}`, though an HS admin can configure -them manually to be anything without whitespace. - -Key IDs end up in an Authorization header which looks like `X-Matrix -origin=origin.example.com,key="keyId",sig="ABCDEF..."`. The Synapse -implementation splits on `,` and `=` without regard to quoting so this -currently precludes the use of `,` or `=` in a key ID. - -For e2e, device keys have a `tok` corresponding to the device id, whilst -one-time keys are generated by libolm, which uses a base64-encoded 32-bit int, ie -`[A-Za-z0-9+/]{6}`. - -A key ID needs to be unique over the lifetime of the server (for federation) or -the device (for e2e). However, they are used fairly widely, so making them long -is unattractive as they could significantly increase the amount of data being -transmitted. Let's limit the 'tok' part of the key to 31 characters too. - -Proposal: - -> Key IDs use the following BNF grammar: -> -> ``` -> key_id = algorithm ":" tok -> -> algorithm = 1*31 alg_chars -> -> tok = 1*31 tok_chars -> -> alg_chars = %x61-7a / %30-39 / "_" / "." -> ; a-z 0-9 _ . -> -> tok_chars = ALPHA / DIGIT / "." / "=" / "_" / "-" -> ; A-Z a-z 0-9 . = _ - -> ``` -> - -Note that enforcing this grammar will mean: - -* Making sure that synapse handles "=" characters in key IDs (easy). - -* Making libolm not put + and / characters in key IDs (easy enough, but there - will be a bunch of malformed unique keys out there in the wild. Possibly they - would just get thrown away. Servers may need to continue to tolerate `+` and - `/` in e2e keys for a while.) - -## Opaque IDs - -[Issue](https://github.com/matrix-org/matrix-doc/issues/666) - -This is a class of identifier types where nobody is really meant to parse any -part of the ID - they are just unique identifiers (with varying scopes of -uniqueness). See below for discussion on what is currently in use. - -I propose to specify the almost the same grammar for all of these, for -simplicity and consistency. - -Proposal: - -> Opaque IDs must be strings consisting entirely of the characters -> `[0-9a-zA-Z.=_-]`. Their length must not exceed 255 characters and they must -> not be empty. - -For almost all of the current implementations I have looked at (listed below), -the grammar above is a superset of the generated identifiers, and a subset of -the understood identifiers. There should therefore be no -backwards-compatibility problems with its introduction. - -The exception is transaction IDs generated by some clients. I think that we'll -just have to fix those clients and accept that old versions may not work with -future servers. - -### Call IDs - -[Spec](https://matrix.org/docs/spec/client_server/unstable.html#m-call-invite) - -These are only used within the body of `m.call.*` events, as far as I am -aware. They should be unique within the lifetime of a room. (Some -implementations currently treat them as globally unique, but that is considered -an implementation bug.) - -[matrix-js-sdk](https://github.com/matrix-org/matrix-js-sdk/blob/4d310cd4618db4e98a8e6b5eb812480102ee4dee/src/webrtc/call.js#L72) uses `c[0-9.]{32}`. -[matrix-android-sdk](https://github.com/matrix-org/matrix-android-sdk/blob/5c6f785e53632e7b6fb3f3859a90c3d85b040e7f/matrix-sdk/src/main/java/org/matrix/androidsdk/call/MXWebRtcCall.java#L221) uses `c[0-9]{13}`. - -Additional proposal: - -> Call IDs should be long enough to make clashes unlikely. - -### Media IDs - -[Spec](https://matrix.org/docs/spec/client_server/r0.3.0.html#id67) - -These are generated by the server on upload, and then embedded in `mxc://` URIs -and used in the C-S API and the S-S API. - -They must be URI-safe to be sensibly embedded in `mxc://` URIs. - -[Synapse](https://github.com/matrix-org/synapse/blob/74854a97191191b08101821753c2672efc2a65fd/synapse/rest/media/v1/media_repository.py#L153) -uses `[A-Za-z]{24}`, though it also uses `[0-9A-Za-z_-]{27}` for -[URL -previews](https://github.com/matrix-org/synapse/blob/74854a97191191b08101821753c2672efc2a65fd/synapse/rest/media/v1/preview_url_resource.py#L285). - -[matrix-media-repo](https://github.com/turt2live/matrix-media-repo/blob/539f25ee75ba6cdbb0410314b29978f4b8b1d7fe/src/github.com/turt2live/matrix-media-repo/controllers/upload_controller/upload_controller.go#L50) -uses `[A-Za-z0-9]{32}`, via [random.go](https://github.com/turt2live/matrix-media-repo/blob/539f25ee75ba6cdbb0410314b29978f4b8b1d7fe/src/github.com/turt2live/matrix-media-repo/util/random.go#L18-L27). - -### Filter IDs - -[Spec](https://matrix.org/docs/spec/client_server/unstable.html#post-matrix-client-r0-user-userid-filter) - -These are generated by the server and then used in the CS API. They are only -required to be unique for a given user. `{` is already forbidden by the spec. - -[Synapse](https://github.com/matrix-org/synapse/blob/74854a97191191b08101821753c2672efc2a65fd/synapse/storage/filtering.py#L70-L73) -uses a stringified int. - -### Auth Session IDs - -[Spec](https://matrix.org/docs/spec/client_server/r0.3.0.html#user-interactive-authentication-api) - -These are generated by the server during auth, and then used in the CS -API. However, they need to be unique for a given server. - -[Synapse](https://github.com/matrix-org/synapse/blob/74854a97191191b08101821753c2672efc2a65fd/synapse/handlers/auth.py#L494) uses `[A-Za-z]{24}`. - -### Transaction IDs (for federation) - -[Spec](https://matrix.org/docs/spec/server_server/unstable.html#put-matrix-federation-v1-send-txnid) - -Generated by sending server. Needs to be unique for a given pair of servers. - -[Synapse](https://github.com/matrix-org/synapse/blob/74854a97191191b08101821753c2672efc2a65fd/synapse/federation/transaction_queue.py#L593) uses a stringified int and accepts pretty much anything. - -### Transaction IDs (for C-S API) - -[Spec](https://matrix.org/docs/spec/client_server/unstable.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid) - -These are generated by the client. They only need to be unique within the -context of a single access_token/device. - -Synapse doesn't appear to do any sanity-checking here currently. - -[matrix-js-sdk](https://github.com/matrix-org/matrix-js-sdk/blob/c6b500bc09994ab5924ef8aab9bd10fc7ded5dae/src/base-apis.js#L123) -uses `m[0-9]{13}.[0-9]{1,}`. -[matrix-android-sdk](https://github.com/matrix-org/matrix-android-sdk/blob/088414fb187cae341690c3a01493b87d97f0169f/matrix-sdk/src/main/java/org/matrix/androidsdk/rest/model/Event.java#L503) -uses a room ID plus a timestamp, hence kinda could be anything, but certainly -will include a `!`. - -### Device IDs - -[Spec](https://matrix.org/docs/spec/client_server/unstable.html#relationship-between-access-tokens-and-devices) - -These are normally generated by the server on login. It's possible for clients -to present their own device_ids, but we're not aware of this feature being -widely used. - -They are used between users and across federation for E2E and to-device -messages. They need to be unique for a particular user. They also appear in key -IDs and must therefore be a subset of that grammar. - -[Synapse](https://github.com/matrix-org/synapse/blob/74854a97191191b08101821753c2672efc2a65fd/synapse/handlers/device.py#L89) -generates device IDs with `[A-Z]{10}`. It appears to do little sanity-checking -of client-generated device IDs currently. - -Additional proposal: - -> Device IDs must not exceed 31 characters in length. - -### Message IDs - -These are used in the server-server API for -[Send-to-device messaging](https://matrix.org/docs/spec/server_server/unstable.html#send-to-device-messaging). - -Synapse uses `[A-Za-z]{16}`, and accepts anything that fits in a postgres TEXT -field. Ref: [devicemessage.py](https://github.com/matrix-org/synapse/blob/74854a97191191b08101821753c2672efc2a65fd/synapse/handlers/devicemessage.py#L102). - - -## Room Aliases - -These are a complex topic and are discussed in [MSC -1608](https://github.com/matrix-org/matrix-doc/issues/1608). From fdbaca662f992ab4bb4e7a2172cba56c9ab42dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Fri, 14 Aug 2020 20:33:26 +0000 Subject: [PATCH 1213/1250] Added translation using Weblate (Estonian) --- data-definitions/sas-emoji-v1-i18n/et.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/et.json diff --git a/data-definitions/sas-emoji-v1-i18n/et.json b/data-definitions/sas-emoji-v1-i18n/et.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/et.json @@ -0,0 +1 @@ +{} From 7920960d336d5f2105c38ef7a21b67e210c862c2 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Sat, 15 Aug 2020 19:04:08 +0000 Subject: [PATCH 1214/1250] Added translation using Weblate (Swedish) --- data-definitions/sas-emoji-v1-i18n/sv.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/sv.json diff --git a/data-definitions/sas-emoji-v1-i18n/sv.json b/data-definitions/sas-emoji-v1-i18n/sv.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/sv.json @@ -0,0 +1 @@ +{} From 2c375ae080450f33b5f395f5c7ca855229a650bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Fri, 14 Aug 2020 20:33:48 +0000 Subject: [PATCH 1215/1250] Translated using Weblate (Estonian) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/et/ --- data-definitions/sas-emoji-v1-i18n/et.json | 67 +++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/et.json b/data-definitions/sas-emoji-v1-i18n/et.json index 0967ef42..6cf53de3 100644 --- a/data-definitions/sas-emoji-v1-i18n/et.json +++ b/data-definitions/sas-emoji-v1-i18n/et.json @@ -1 +1,66 @@ -{} +{ + "Dog": "Koer", + "Cat": "Kass", + "Lion": "Lõvi", + "Horse": "Hobune", + "Unicorn": "Ükssarvik", + "Pig": "Siga", + "Elephant": "Elevant", + "Rabbit": "Jänes", + "Panda": "Panda", + "Rooster": "Kukk", + "Penguin": "Pingviin", + "Turtle": "Kilpkonn", + "Fish": "Kala", + "Octopus": "Kaheksajalg", + "Butterfly": "Liblikas", + "Flower": "Lill", + "Tree": "Puu", + "Cactus": "Kaktus", + "Mushroom": "Seen", + "Globe": "Maakera", + "Moon": "Kuu", + "Cloud": "Pilv", + "Fire": "Tuli", + "Banana": "Banaan", + "Apple": "Õun", + "Strawberry": "Maasikas", + "Corn": "Mais", + "Pizza": "Pitsa", + "Cake": "Kook", + "Heart": "Süda", + "Smiley": "Smaili", + "Robot": "Robot", + "Hat": "Kübar", + "Glasses": "Prillid", + "Spanner": "Mutrivõti", + "Santa": "Jõuluvana", + "Thumbs Up": "Pöidlad püsti", + "Umbrella": "Vihmavari", + "Hourglass": "Liivakell", + "Clock": "Kell", + "Gift": "Kingitus", + "Light Bulb": "Lambipirn", + "Book": "Raamat", + "Pencil": "Pliiats", + "Paperclip": "Kirjaklamber", + "Scissors": "Käärid", + "Lock": "Lukk", + "Key": "Võti", + "Hammer": "Haamer", + "Telephone": "Telefon", + "Flag": "Lipp", + "Train": "Rong", + "Bicycle": "Jalgratas", + "Aeroplane": "Lennuk", + "Rocket": "Rakett", + "Trophy": "Auhind", + "Ball": "Pall", + "Guitar": "Kitarr", + "Trumpet": "Trompet", + "Bell": "Kelluke", + "Anchor": "Ankur", + "Headphones": "Kõrvaklapid", + "Folder": "Kaust", + "Pin": "Nööpnõel" +} From 8197761b2930a4a4862c6b80283b410f43d8fc40 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Sun, 16 Aug 2020 16:07:34 +0000 Subject: [PATCH 1216/1250] Added translation using Weblate (Esperanto) --- data-definitions/sas-emoji-v1-i18n/eo.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/eo.json diff --git a/data-definitions/sas-emoji-v1-i18n/eo.json b/data-definitions/sas-emoji-v1-i18n/eo.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/eo.json @@ -0,0 +1 @@ +{} From cd8f0c89916770eda3343986208eed68b276ec6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= Date: Sun, 16 Aug 2020 21:49:52 +0000 Subject: [PATCH 1217/1250] =?UTF-8?q?Added=20translation=20using=20Weblate?= =?UTF-8?q?=20(Norwegian=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data-definitions/sas-emoji-v1-i18n/nb_NO.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/nb_NO.json diff --git a/data-definitions/sas-emoji-v1-i18n/nb_NO.json b/data-definitions/sas-emoji-v1-i18n/nb_NO.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/nb_NO.json @@ -0,0 +1 @@ +{} From 46549f3f9f3203f6e7de497d8d38b43b1975c437 Mon Sep 17 00:00:00 2001 From: tusooa Date: Mon, 17 Aug 2020 01:23:16 +0000 Subject: [PATCH 1218/1250] Added translation using Weblate (Chinese (Simplified)) --- data-definitions/sas-emoji-v1-i18n/zh_Hans.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/zh_Hans.json diff --git a/data-definitions/sas-emoji-v1-i18n/zh_Hans.json b/data-definitions/sas-emoji-v1-i18n/zh_Hans.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/zh_Hans.json @@ -0,0 +1 @@ +{} From 573ea497d9ff7bb6464b898fbc4259347941f42d Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 17 Aug 2020 10:13:20 +0000 Subject: [PATCH 1219/1250] Added translation using Weblate (Dutch) --- data-definitions/sas-emoji-v1-i18n/nl.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/nl.json diff --git a/data-definitions/sas-emoji-v1-i18n/nl.json b/data-definitions/sas-emoji-v1-i18n/nl.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/nl.json @@ -0,0 +1 @@ +{} From a23b8c1fc495f6c28427e862cfd2a33d8ff379a1 Mon Sep 17 00:00:00 2001 From: Tuomas Hietala Date: Mon, 17 Aug 2020 10:51:15 +0000 Subject: [PATCH 1220/1250] Added translation using Weblate (Finnish) --- data-definitions/sas-emoji-v1-i18n/fi.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/fi.json diff --git a/data-definitions/sas-emoji-v1-i18n/fi.json b/data-definitions/sas-emoji-v1-i18n/fi.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/fi.json @@ -0,0 +1 @@ +{} From 0565766d1c04a630db2e32022d50efd13f865f86 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Sat, 15 Aug 2020 19:06:47 +0000 Subject: [PATCH 1221/1250] Translated using Weblate (Swedish) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/sv/ --- data-definitions/sas-emoji-v1-i18n/sv.json | 67 +++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/sv.json b/data-definitions/sas-emoji-v1-i18n/sv.json index 0967ef42..27c238a3 100644 --- a/data-definitions/sas-emoji-v1-i18n/sv.json +++ b/data-definitions/sas-emoji-v1-i18n/sv.json @@ -1 +1,66 @@ -{} +{ + "Dog": "Hund", + "Cat": "Katt", + "Lion": "Lejon", + "Horse": "Häst", + "Unicorn": "Enhörning", + "Pig": "Gris", + "Elephant": "Elefant", + "Rabbit": "Kanin", + "Panda": "Panda", + "Rooster": "Tupp", + "Penguin": "Pingvin", + "Turtle": "Sköldpadda", + "Fish": "Fisk", + "Octopus": "Bläckfisk", + "Butterfly": "Fjäril", + "Flower": "Blomma", + "Tree": "Träd", + "Cactus": "Kaktus", + "Mushroom": "Svamp", + "Globe": "Jordklot", + "Moon": "Måne", + "Cloud": "Moln", + "Fire": "Eld", + "Banana": "Banan", + "Apple": "Äpple", + "Strawberry": "Jordgubbe", + "Corn": "Majskolv", + "Pizza": "Pizza", + "Cake": "Tårta", + "Heart": "Hjärta", + "Smiley": "Smiley", + "Robot": "Robot", + "Hat": "Hatt", + "Glasses": "Glasögon", + "Spanner": "Skruvnyckel", + "Santa": "Tomte", + "Thumbs Up": "Tummen upp", + "Umbrella": "Paraply", + "Hourglass": "Timglas", + "Clock": "Klocka", + "Gift": "Paket", + "Light Bulb": "Lampa", + "Book": "Bok", + "Pencil": "Penna", + "Paperclip": "Gem", + "Scissors": "Sax", + "Lock": "Lås", + "Key": "Nyckel", + "Hammer": "Hammare", + "Telephone": "Telefon", + "Flag": "Flagga", + "Train": "Ånglok", + "Bicycle": "Cykel", + "Aeroplane": "Flygplan", + "Rocket": "Raket", + "Trophy": "Trofé", + "Ball": "Boll", + "Guitar": "Gitarr", + "Trumpet": "Trumpet", + "Bell": "Bjällra", + "Anchor": "Ankare", + "Headphones": "Hörlurar", + "Folder": "Mapp", + "Pin": "Häftstift" +} From a72a5ccda11d94b306f507c6cb59d4fdc3042ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 18 Aug 2020 05:44:53 +0000 Subject: [PATCH 1222/1250] Added translation using Weblate (Slovak) --- data-definitions/sas-emoji-v1-i18n/sk.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/sk.json diff --git a/data-definitions/sas-emoji-v1-i18n/sk.json b/data-definitions/sas-emoji-v1-i18n/sk.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/sk.json @@ -0,0 +1 @@ +{} From f1c8fc21961d8cc0a56be63324cb113f470ed210 Mon Sep 17 00:00:00 2001 From: tusooa Date: Mon, 17 Aug 2020 01:24:31 +0000 Subject: [PATCH 1223/1250] Translated using Weblate (Chinese (Simplified)) Currently translated at 9.4% (6 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/zh_Hans/ --- data-definitions/sas-emoji-v1-i18n/zh_Hans.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/zh_Hans.json b/data-definitions/sas-emoji-v1-i18n/zh_Hans.json index 0967ef42..e0dc6bde 100644 --- a/data-definitions/sas-emoji-v1-i18n/zh_Hans.json +++ b/data-definitions/sas-emoji-v1-i18n/zh_Hans.json @@ -1 +1,8 @@ -{} +{ + "Dog": "狗", + "Cat": "猫", + "Lion": "狮子", + "Horse": "马", + "Unicorn": "独角兽", + "Pig": "猪" +} From 0966341c278d22862d4d3ff48800cadf42a71e44 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 17 Aug 2020 10:14:35 +0000 Subject: [PATCH 1224/1250] Translated using Weblate (Dutch) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/nl/ --- data-definitions/sas-emoji-v1-i18n/nl.json | 67 +++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/nl.json b/data-definitions/sas-emoji-v1-i18n/nl.json index 0967ef42..ffaaba1f 100644 --- a/data-definitions/sas-emoji-v1-i18n/nl.json +++ b/data-definitions/sas-emoji-v1-i18n/nl.json @@ -1 +1,66 @@ -{} +{ + "Dog": "Hond", + "Cat": "Kat", + "Lion": "Leeuw", + "Horse": "Paard", + "Unicorn": "Eenhoorn", + "Pig": "Varken", + "Elephant": "Olifant", + "Rabbit": "Konijn", + "Panda": "Panda", + "Rooster": "Haan", + "Penguin": "Pinguïn", + "Turtle": "Schildpad", + "Fish": "Vis", + "Octopus": "Octopus", + "Butterfly": "Vlinder", + "Flower": "Bloem", + "Tree": "Boom", + "Cactus": "Cactus", + "Mushroom": "Paddenstoel", + "Globe": "Wereldbol", + "Moon": "Maan", + "Cloud": "Wolk", + "Fire": "Vuur", + "Banana": "Banaan", + "Apple": "Appel", + "Strawberry": "Aardbei", + "Corn": "Maïs", + "Pizza": "Pizza", + "Cake": "Taart", + "Heart": "Hart", + "Smiley": "Smiley", + "Robot": "Robot", + "Hat": "Hoed", + "Glasses": "Bril", + "Spanner": "Moersleutel", + "Santa": "Kerstman", + "Thumbs Up": "Duim omhoog", + "Umbrella": "Paraplu", + "Hourglass": "Zandloper", + "Clock": "Wekker", + "Gift": "Geschenk", + "Light Bulb": "Gloeilamp", + "Book": "Boek", + "Pencil": "Potlood", + "Paperclip": "Papierklemmetje", + "Scissors": "Schaar", + "Lock": "Slot", + "Key": "Sleutel", + "Hammer": "Hamer", + "Telephone": "Telefoon", + "Flag": "Vlag", + "Train": "Trein", + "Bicycle": "Fiets", + "Aeroplane": "Vliegtuig", + "Rocket": "Raket", + "Trophy": "Trofee", + "Ball": "Bal", + "Guitar": "Gitaar", + "Trumpet": "Trompet", + "Bell": "Bel", + "Anchor": "Anker", + "Headphones": "Koptelefoon", + "Folder": "Map", + "Pin": "Duimspijker" +} From 8eb0f9414fde7980bed56301c93a7ced4281b0e9 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Sun, 16 Aug 2020 16:07:51 +0000 Subject: [PATCH 1225/1250] Translated using Weblate (Esperanto) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/eo/ --- data-definitions/sas-emoji-v1-i18n/eo.json | 67 +++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/eo.json b/data-definitions/sas-emoji-v1-i18n/eo.json index 0967ef42..1fafa276 100644 --- a/data-definitions/sas-emoji-v1-i18n/eo.json +++ b/data-definitions/sas-emoji-v1-i18n/eo.json @@ -1 +1,66 @@ -{} +{ + "Dog": "Hundo", + "Cat": "Kato", + "Lion": "Leono", + "Horse": "Ĉevalo", + "Unicorn": "Unukorno", + "Pig": "Porko", + "Elephant": "Elefanto", + "Rabbit": "Kuniklo", + "Panda": "Pando", + "Rooster": "Virkoko", + "Penguin": "Pingveno", + "Turtle": "Testudo", + "Fish": "Fiŝo", + "Octopus": "Polpo", + "Butterfly": "Papilio", + "Flower": "Floro", + "Tree": "Arbo", + "Cactus": "Kakto", + "Mushroom": "Fungo", + "Globe": "Globo", + "Moon": "Luno", + "Cloud": "Nubo", + "Fire": "Fajro", + "Banana": "Banano", + "Apple": "Pomo", + "Strawberry": "Frago", + "Corn": "Maizo", + "Pizza": "Pico", + "Cake": "Torto", + "Heart": "Koro", + "Smiley": "Rideto", + "Robot": "Roboto", + "Hat": "Ĉapelo", + "Glasses": "Okulvitroj", + "Spanner": "Ŝraŭbŝlosilo", + "Santa": "Kristnaska viro", + "Thumbs Up": "Dikfingro supren", + "Umbrella": "Ombrelo", + "Hourglass": "Sablohorloĝo", + "Clock": "Horloĝo", + "Gift": "Donaco", + "Light Bulb": "Lampo", + "Book": "Libro", + "Pencil": "Krajono", + "Paperclip": "Paperkuntenilo", + "Scissors": "Tondilo", + "Lock": "Seruro", + "Key": "Ŝlosilo", + "Hammer": "Martelo", + "Telephone": "Telefono", + "Flag": "Flago", + "Train": "Vagonaro", + "Bicycle": "Biciklo", + "Aeroplane": "Aviadilo", + "Rocket": "Raketo", + "Trophy": "Trofeo", + "Ball": "Pilko", + "Guitar": "Gitaro", + "Trumpet": "Trumpeto", + "Bell": "Sonorilo", + "Anchor": "Ankro", + "Headphones": "Kapaŭdilo", + "Folder": "Dosierujo", + "Pin": "Pinglo" +} From dfae4c43256941201f21676196ee0fea4f0b0ea2 Mon Sep 17 00:00:00 2001 From: Tuomas Hietala Date: Mon, 17 Aug 2020 10:52:01 +0000 Subject: [PATCH 1226/1250] Translated using Weblate (Finnish) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/fi/ --- data-definitions/sas-emoji-v1-i18n/fi.json | 67 +++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/fi.json b/data-definitions/sas-emoji-v1-i18n/fi.json index 0967ef42..0975b1e2 100644 --- a/data-definitions/sas-emoji-v1-i18n/fi.json +++ b/data-definitions/sas-emoji-v1-i18n/fi.json @@ -1 +1,66 @@ -{} +{ + "Dog": "Koira", + "Cat": "Kissa", + "Lion": "Leijona", + "Horse": "Hevonen", + "Unicorn": "Yksisarvinen", + "Pig": "Sika", + "Elephant": "Norsu", + "Rabbit": "Kani", + "Panda": "Panda", + "Rooster": "Kukko", + "Penguin": "Pingviini", + "Turtle": "Kilpikonna", + "Fish": "Kala", + "Octopus": "Tursas", + "Butterfly": "Perhonen", + "Flower": "Kukka", + "Tree": "Puu", + "Cactus": "Kaktus", + "Mushroom": "Sieni", + "Globe": "Maapallo", + "Moon": "Kuu", + "Cloud": "Pilvi", + "Fire": "Tuli", + "Banana": "Banaani", + "Apple": "Omena", + "Strawberry": "Mansikka", + "Corn": "Maissi", + "Pizza": "Pizza", + "Cake": "Kakku", + "Heart": "Sydän", + "Smiley": "Hymynaama", + "Robot": "Robotti", + "Hat": "Hattu", + "Glasses": "Silmälasit", + "Spanner": "Mutteriavain", + "Santa": "Joulupukki", + "Thumbs Up": "Peukalo ylös", + "Umbrella": "Sateenvarjo", + "Hourglass": "Tiimalasi", + "Clock": "Pöytäkello", + "Gift": "Lahja", + "Light Bulb": "Hehkulamppu", + "Book": "Kirja", + "Pencil": "Lyijykynä", + "Paperclip": "Paperiliitin", + "Scissors": "Sakset", + "Lock": "Lukko", + "Key": "Avain", + "Hammer": "Vasara", + "Telephone": "Puhelin", + "Flag": "Lippu", + "Train": "Juna", + "Bicycle": "Polkupyörä", + "Aeroplane": "Lentokone", + "Rocket": "Raketti", + "Trophy": "Palkinto", + "Ball": "Pallo", + "Guitar": "Kitara", + "Trumpet": "Trumpetti", + "Bell": "Soittokello", + "Anchor": "Ankkuri", + "Headphones": "Kuulokkeet", + "Folder": "Kansio", + "Pin": "Nuppineula" +} From c52c5e5f4a1f51c31aa887ac6dc64a2b539ccf14 Mon Sep 17 00:00:00 2001 From: q-b Date: Fri, 14 Aug 2020 19:49:33 +0000 Subject: [PATCH 1227/1250] Translated using Weblate (French) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/fr/ --- data-definitions/sas-emoji-v1-i18n/fr.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data-definitions/sas-emoji-v1-i18n/fr.json b/data-definitions/sas-emoji-v1-i18n/fr.json index f1443bb8..5ef3cbe3 100644 --- a/data-definitions/sas-emoji-v1-i18n/fr.json +++ b/data-definitions/sas-emoji-v1-i18n/fr.json @@ -37,13 +37,13 @@ "Globe": "Globe", "Strawberry": "Fraise", "Corn": "Maïs", - "Smiley": "Personne souriante", + "Smiley": "Sourire", "Robot": "Robot", "Spanner": "Clé à molette", "Santa": "Père Noël", "Thumbs Up": "Pouce en l'air", "Umbrella": "Parapluie", - "Clock": "Horloge", + "Clock": "Réveil", "Gift": "Cadeau", "Light Bulb": "Ampoule", "Pencil": "Crayon", From 70e047e484445a520c34a603f954d3abbb64cddb Mon Sep 17 00:00:00 2001 From: reivilibre Date: Fri, 14 Aug 2020 19:49:01 +0000 Subject: [PATCH 1228/1250] Translated using Weblate (French) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/fr/ --- data-definitions/sas-emoji-v1-i18n/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/fr.json b/data-definitions/sas-emoji-v1-i18n/fr.json index 5ef3cbe3..7996c108 100644 --- a/data-definitions/sas-emoji-v1-i18n/fr.json +++ b/data-definitions/sas-emoji-v1-i18n/fr.json @@ -4,7 +4,7 @@ "Horse": "Cheval", "Elephant": "Éléphant", "Rabbit": "Lapin", - "Penguin": "Pinguin", + "Penguin": "Manchot", "Fish": "Poisson", "Butterfly": "Papillon", "Flower": "Fleur", From 700c63f9eaa308a47ef446527ddda8ae5180ac3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= Date: Sun, 16 Aug 2020 21:50:17 +0000 Subject: [PATCH 1229/1250] =?UTF-8?q?Translated=20using=20Weblate=20(Norwe?= =?UTF-8?q?gian=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/nb_NO/ --- data-definitions/sas-emoji-v1-i18n/nb_NO.json | 67 ++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/nb_NO.json b/data-definitions/sas-emoji-v1-i18n/nb_NO.json index 0967ef42..b8bf02d3 100644 --- a/data-definitions/sas-emoji-v1-i18n/nb_NO.json +++ b/data-definitions/sas-emoji-v1-i18n/nb_NO.json @@ -1 +1,66 @@ -{} +{ + "Dog": "Hund", + "Cat": "Katt", + "Lion": "Løve", + "Horse": "Hest", + "Unicorn": "Enhjørning", + "Pig": "Gris", + "Elephant": "Elefant", + "Rabbit": "Kanin", + "Panda": "Panda", + "Rooster": "Hane", + "Penguin": "Pingvin", + "Turtle": "Skilpadde", + "Fish": "Fisk", + "Octopus": "Blekksprut", + "Butterfly": "Sommerfugl", + "Flower": "Blomst", + "Tree": "Tre", + "Cactus": "Kaktus", + "Mushroom": "Sopp", + "Globe": "Globus", + "Moon": "Måne", + "Cloud": "Sky", + "Fire": "Flamme", + "Banana": "Banan", + "Apple": "Eple", + "Strawberry": "Jordbær", + "Corn": "Mais", + "Pizza": "Pizza", + "Cake": "Kake", + "Heart": "Hjerte", + "Smiley": "Smilefjes", + "Robot": "Robot", + "Hat": "Hatt", + "Glasses": "Briller", + "Spanner": "Fastnøkkel", + "Santa": "Julenisse", + "Thumbs Up": "Tommel Opp", + "Umbrella": "Paraply", + "Hourglass": "Timeglass", + "Clock": "Klokke", + "Gift": "Gave", + "Light Bulb": "Lyspære", + "Book": "Bok", + "Pencil": "Blyant", + "Paperclip": "BInders", + "Scissors": "Saks", + "Lock": "Lås", + "Key": "Nøkkel", + "Hammer": "Hammer", + "Telephone": "Telefon", + "Flag": "Flagg", + "Train": "Tog", + "Bicycle": "Sykkel", + "Aeroplane": "Fly", + "Rocket": "Rakett", + "Trophy": "Pokal", + "Ball": "Ball", + "Guitar": "Gitar", + "Trumpet": "Trompet", + "Bell": "Bjelle", + "Anchor": "Anker", + "Headphones": "Hodetelefoner", + "Folder": "Mappe", + "Pin": "Tegnestift" +} From 93a614c2728c919f47ea6151d2c5c0399f55789a Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 17 Aug 2020 10:29:19 +0000 Subject: [PATCH 1230/1250] Translated using Weblate (Spanish) Currently translated at 76.6% (49 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/es/ --- data-definitions/sas-emoji-v1-i18n/es.json | 31 +++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/es.json b/data-definitions/sas-emoji-v1-i18n/es.json index 503cf13d..8b899942 100644 --- a/data-definitions/sas-emoji-v1-i18n/es.json +++ b/data-definitions/sas-emoji-v1-i18n/es.json @@ -18,5 +18,34 @@ "Guitar": "Guitarra", "Trumpet": "Trompeta", "Bell": "Campana", - "Pin": "Alfiler" + "Pin": "Alfiler", + "Horse": "Caballo", + "Unicorn": "Unicornio", + "Elephant": "Elefante", + "Rabbit": "Conejo", + "Panda": "Panda", + "Rooster": "Gallo", + "Penguin": "Pingüino", + "Turtle": "Tortuga", + "Fish": "Pez", + "Octopus": "Pulpo", + "Butterfly": "Mariposa", + "Flower": "Flor", + "Tree": "Árbol", + "Cactus": "Cactus", + "Mushroom": "Seta", + "Globe": "Globo", + "Moon": "Luna", + "Cloud": "Nube", + "Banana": "Plátano", + "Strawberry": "Fresa", + "Corn": "Maíz", + "Pizza": "Pizza", + "Cake": "Tarta", + "Heart": "Corazón", + "Smiley": "Emoticono", + "Robot": "Robot", + "Hat": "Sombrero", + "Glasses": "Gafas", + "Spanner": "Llave inglesa" } From 3e3c2c704ba2b619add59ae53d0254ce51ad97d0 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 18 Aug 2020 06:05:03 +0000 Subject: [PATCH 1231/1250] Deleted translation using Weblate (Slovak) --- data-definitions/sas-emoji-v1-i18n/sk.json | 1 - 1 file changed, 1 deletion(-) delete mode 100644 data-definitions/sas-emoji-v1-i18n/sk.json diff --git a/data-definitions/sas-emoji-v1-i18n/sk.json b/data-definitions/sas-emoji-v1-i18n/sk.json deleted file mode 100644 index 0967ef42..00000000 --- a/data-definitions/sas-emoji-v1-i18n/sk.json +++ /dev/null @@ -1 +0,0 @@ -{} From aafec5887140f98c742fb9cbfb2dc25ea524364b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 18 Aug 2020 06:18:25 +0000 Subject: [PATCH 1232/1250] Added translation using Weblate (Slovak) --- data-definitions/sas-emoji-v1-i18n/sk.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/sk.json diff --git a/data-definitions/sas-emoji-v1-i18n/sk.json b/data-definitions/sas-emoji-v1-i18n/sk.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/sk.json @@ -0,0 +1 @@ +{} From 14da11eaa5422eccf37433f799df7a02d91d613a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 18 Aug 2020 15:48:59 +0000 Subject: [PATCH 1233/1250] Translated using Weblate (Slovak) Currently translated at 96.9% (62 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/sk/ --- data-definitions/sas-emoji-v1-i18n/sk.json | 67 +++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/sk.json b/data-definitions/sas-emoji-v1-i18n/sk.json index 0967ef42..f0a7176c 100644 --- a/data-definitions/sas-emoji-v1-i18n/sk.json +++ b/data-definitions/sas-emoji-v1-i18n/sk.json @@ -1 +1,66 @@ -{} +{ + "Dog": "Hlava psa", + "Cat": "Hlava mačky", + "Lion": "Hlava leva", + "Horse": "Kôň", + "Unicorn": "Hlava jednorožca", + "Pig": "Hlava prasaťa", + "Elephant": "Slon", + "Rabbit": "Hlava zajaca", + "Panda": "Hlava pandy", + "Rooster": "Kohút", + "Penguin": "Tučniak", + "Turtle": "Korytnačka", + "Fish": "Ryba", + "Octopus": "Chobotnica", + "Butterfly": "Motýľ", + "Flower": "Tulipán", + "Tree": "Listnatý strom", + "Cactus": "Kaktus", + "Mushroom": "Huba", + "Globe": "Zemeguľa", + "Moon": "Polmesiac", + "Cloud": "Oblak", + "Fire": "Oheň", + "Banana": "Banán", + "Apple": "Červené jablko", + "Strawberry": "Jahoda", + "Corn": "Kukuričný klas", + "Pizza": "Pizza", + "Cake": "Narodeninová torta", + "Heart": "červené srdce", + "Smiley": "Škeriaca sa tvár", + "Robot": "Robot", + "Hat": "Cilinder", + "Glasses": "Okuliare", + "Spanner": "Francúzsky kľúč", + "Santa": "Santa Claus", + "Thumbs Up": "Palec nahor", + "Umbrella": "Dáždnik", + "Hourglass": "Presýpacie hodiny", + "Clock": "Budík", + "Gift": "Zabalený darček", + "Light Bulb": "Žiarovka", + "Book": "Zatvorená kniha", + "Pencil": "Ceruzka", + "Paperclip": "Sponka na papier", + "Scissors": "Nožnice", + "Lock": "Zatvorená zámka", + "Key": "Kľúč", + "Hammer": "Kladivo", + "Telephone": "Telefón", + "Flag": "Kockovaná zástava", + "Train": "Rušeň", + "Bicycle": "Bicykel", + "Aeroplane": "Lietadlo", + "Rocket": "Raketa", + "Trophy": "Trofej", + "Ball": "Futbal", + "Guitar": "Gitara", + "Trumpet": "Trúbka", + "Bell": "Zvon", + "Anchor": "Kotva", + "Headphones": "Slúchadlá", + "Folder": "Fascikel", + "Pin": "Špendlík" +} From 6b64281af726d9bb8c0390a55d928eaaa1a5ae64 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 19 Aug 2020 09:43:15 -0600 Subject: [PATCH 1234/1250] Update sas-emoji.json for i18n --- data-definitions/sas-emoji.json | 704 +++++++++++++++++++++++++++----- 1 file changed, 608 insertions(+), 96 deletions(-) diff --git a/data-definitions/sas-emoji.json b/data-definitions/sas-emoji.json index 093c5793..a18d7731 100644 --- a/data-definitions/sas-emoji.json +++ b/data-definitions/sas-emoji.json @@ -6,11 +6,19 @@ "unicode": "U+1F436", "translated_descriptions": { "de": "Hund", + "eo": "Hundo", "es": "Perro", + "et": "Koer", + "fi": "Koira", "fr": "Chien", "ja": "犬", + "nb_NO": "Hund", + "nl": "Hond", "ru": "Собака", - "uk": "Пес" + "sk": "Hlava psa", + "sv": "Hund", + "uk": "Пес", + "zh_Hans": "狗" } }, { @@ -20,11 +28,19 @@ "unicode": "U+1F431", "translated_descriptions": { "de": "Katze", + "eo": "Kato", "es": "Gato", + "et": "Kass", + "fi": "Kissa", "fr": "Chat", "ja": "猫", + "nb_NO": "Katt", + "nl": "Kat", "ru": "Кошка", - "uk": "Кіт" + "sk": "Hlava mačky", + "sv": "Katt", + "uk": "Кіт", + "zh_Hans": "猫" } }, { @@ -34,11 +50,19 @@ "unicode": "U+1F981", "translated_descriptions": { "de": "Löwe", + "eo": "Leono", "es": "León", + "et": "Lõvi", + "fi": "Leijona", "fr": "Lion", "ja": null, + "nb_NO": "Løve", + "nl": "Leeuw", "ru": "Лев", - "uk": "Лев" + "sk": "Hlava leva", + "sv": "Lejon", + "uk": "Лев", + "zh_Hans": "狮子" } }, { @@ -48,11 +72,19 @@ "unicode": "U+1F40E", "translated_descriptions": { "de": "Pferd", - "es": null, + "eo": "Ĉevalo", + "es": "Caballo", + "et": "Hobune", + "fi": "Hevonen", "fr": "Cheval", "ja": "馬", + "nb_NO": "Hest", + "nl": "Paard", "ru": "Лошадь", - "uk": "Кінь" + "sk": "Kôň", + "sv": "Häst", + "uk": "Кінь", + "zh_Hans": "马" } }, { @@ -62,11 +94,19 @@ "unicode": "U+1F984", "translated_descriptions": { "de": "Einhorn", - "es": null, + "eo": "Unukorno", + "es": "Unicornio", + "et": "Ükssarvik", + "fi": "Yksisarvinen", "fr": "Licorne", "ja": null, + "nb_NO": "Enhjørning", + "nl": "Eenhoorn", "ru": "Единорог", - "uk": "Єдиноріг" + "sk": "Hlava jednorožca", + "sv": "Enhörning", + "uk": "Єдиноріг", + "zh_Hans": "独角兽" } }, { @@ -76,11 +116,19 @@ "unicode": "U+1F437", "translated_descriptions": { "de": "Schwein", + "eo": "Porko", "es": "Cerdo", + "et": "Siga", + "fi": "Sika", "fr": "Cochon", "ja": null, + "nb_NO": "Gris", + "nl": "Varken", "ru": "Свинья", - "uk": "Свиня" + "sk": "Hlava prasaťa", + "sv": "Gris", + "uk": "Свиня", + "zh_Hans": "猪" } }, { @@ -90,11 +138,19 @@ "unicode": "U+1F418", "translated_descriptions": { "de": "Elefant", - "es": null, + "eo": "Elefanto", + "es": "Elefante", + "et": "Elevant", + "fi": "Norsu", "fr": "Éléphant", "ja": null, + "nb_NO": "Elefant", + "nl": "Olifant", "ru": "Слон", - "uk": "Слон" + "sk": "Slon", + "sv": "Elefant", + "uk": "Слон", + "zh_Hans": null } }, { @@ -104,11 +160,19 @@ "unicode": "U+1F430", "translated_descriptions": { "de": "Hase", - "es": null, + "eo": "Kuniklo", + "es": "Conejo", + "et": "Jänes", + "fi": "Kani", "fr": "Lapin", "ja": null, + "nb_NO": "Kanin", + "nl": "Konijn", "ru": "Кролик", - "uk": "Кріль" + "sk": "Hlava zajaca", + "sv": "Kanin", + "uk": "Кріль", + "zh_Hans": null } }, { @@ -118,11 +182,19 @@ "unicode": "U+1F43C", "translated_descriptions": { "de": "Panda", - "es": null, + "eo": "Pando", + "es": "Panda", + "et": "Panda", + "fi": "Panda", "fr": "Panda", "ja": null, + "nb_NO": "Panda", + "nl": "Panda", "ru": "Панда", - "uk": "Панда" + "sk": "Hlava pandy", + "sv": "Panda", + "uk": "Панда", + "zh_Hans": null } }, { @@ -132,11 +204,19 @@ "unicode": "U+1F413", "translated_descriptions": { "de": "Hahn", - "es": null, + "eo": "Virkoko", + "es": "Gallo", + "et": "Kukk", + "fi": "Kukko", "fr": "Coq", "ja": null, + "nb_NO": "Hane", + "nl": "Haan", "ru": "Петух", - "uk": "Когут" + "sk": "Kohút", + "sv": "Tupp", + "uk": "Когут", + "zh_Hans": null } }, { @@ -146,11 +226,19 @@ "unicode": "U+1F427", "translated_descriptions": { "de": "Pinguin", - "es": null, - "fr": "Pinguin", + "eo": "Pingveno", + "es": "Pingüino", + "et": "Pingviin", + "fi": "Pingviini", + "fr": "Manchot", "ja": null, + "nb_NO": "Pingvin", + "nl": "Pinguïn", "ru": "Пингвин", - "uk": "Пінгвін" + "sk": "Tučniak", + "sv": "Pingvin", + "uk": "Пінгвін", + "zh_Hans": null } }, { @@ -160,11 +248,19 @@ "unicode": "U+1F422", "translated_descriptions": { "de": "Schildkröte", - "es": null, + "eo": "Testudo", + "es": "Tortuga", + "et": "Kilpkonn", + "fi": "Kilpikonna", "fr": "Tortue", "ja": null, + "nb_NO": "Skilpadde", + "nl": "Schildpad", "ru": "Черепаха", - "uk": "Черепаха" + "sk": "Korytnačka", + "sv": "Sköldpadda", + "uk": "Черепаха", + "zh_Hans": null } }, { @@ -174,11 +270,19 @@ "unicode": "U+1F41F", "translated_descriptions": { "de": "Fisch", - "es": null, + "eo": "Fiŝo", + "es": "Pez", + "et": "Kala", + "fi": "Kala", "fr": "Poisson", "ja": null, + "nb_NO": "Fisk", + "nl": "Vis", "ru": "Рыба", - "uk": "Риба" + "sk": "Ryba", + "sv": "Fisk", + "uk": "Риба", + "zh_Hans": null } }, { @@ -188,11 +292,19 @@ "unicode": "U+1F419", "translated_descriptions": { "de": "Oktopus", - "es": null, + "eo": "Polpo", + "es": "Pulpo", + "et": "Kaheksajalg", + "fi": "Tursas", "fr": "Poulpe", "ja": "たこ", + "nb_NO": "Blekksprut", + "nl": "Octopus", "ru": "Осьминог", - "uk": "Восьминіг" + "sk": "Chobotnica", + "sv": "Bläckfisk", + "uk": "Восьминіг", + "zh_Hans": null } }, { @@ -202,11 +314,19 @@ "unicode": "U+1F98B", "translated_descriptions": { "de": "Schmetterling", - "es": null, + "eo": "Papilio", + "es": "Mariposa", + "et": "Liblikas", + "fi": "Perhonen", "fr": "Papillon", "ja": null, + "nb_NO": "Sommerfugl", + "nl": "Vlinder", "ru": "Бабочка", - "uk": "Метелик" + "sk": "Motýľ", + "sv": "Fjäril", + "uk": "Метелик", + "zh_Hans": null } }, { @@ -216,11 +336,19 @@ "unicode": "U+1F337", "translated_descriptions": { "de": "Blume", - "es": null, + "eo": "Floro", + "es": "Flor", + "et": "Lill", + "fi": "Kukka", "fr": "Fleur", "ja": "花", + "nb_NO": "Blomst", + "nl": "Bloem", "ru": "Цветок", - "uk": "Квітка" + "sk": "Tulipán", + "sv": "Blomma", + "uk": "Квітка", + "zh_Hans": null } }, { @@ -230,11 +358,19 @@ "unicode": "U+1F333", "translated_descriptions": { "de": "Baum", - "es": null, + "eo": "Arbo", + "es": "Árbol", + "et": "Puu", + "fi": "Puu", "fr": "Arbre", "ja": "木", + "nb_NO": "Tre", + "nl": "Boom", "ru": "Дерево", - "uk": "Дерево" + "sk": "Listnatý strom", + "sv": "Träd", + "uk": "Дерево", + "zh_Hans": null } }, { @@ -244,11 +380,19 @@ "unicode": "U+1F335", "translated_descriptions": { "de": "Kaktus", - "es": null, + "eo": "Kakto", + "es": "Cactus", + "et": "Kaktus", + "fi": "Kaktus", "fr": "Cactus", "ja": null, + "nb_NO": "Kaktus", + "nl": "Cactus", "ru": "Кактус", - "uk": "Кактус" + "sk": "Kaktus", + "sv": "Kaktus", + "uk": "Кактус", + "zh_Hans": null } }, { @@ -258,11 +402,19 @@ "unicode": "U+1F344", "translated_descriptions": { "de": "Pilz", - "es": null, + "eo": "Fungo", + "es": "Seta", + "et": "Seen", + "fi": "Sieni", "fr": "Champignon", "ja": "きのこ", + "nb_NO": "Sopp", + "nl": "Paddenstoel", "ru": "Гриб", - "uk": "Гриб" + "sk": "Huba", + "sv": "Svamp", + "uk": "Гриб", + "zh_Hans": null } }, { @@ -272,11 +424,19 @@ "unicode": "U+1F30F", "translated_descriptions": { "de": "Globus", - "es": null, + "eo": "Globo", + "es": "Globo", + "et": "Maakera", + "fi": "Maapallo", "fr": "Globe", "ja": null, + "nb_NO": "Globus", + "nl": "Wereldbol", "ru": "Глобус", - "uk": "Глобус" + "sk": "Zemeguľa", + "sv": "Jordklot", + "uk": "Глобус", + "zh_Hans": null } }, { @@ -286,11 +446,19 @@ "unicode": "U+1F319", "translated_descriptions": { "de": "Mond", - "es": null, + "eo": "Luno", + "es": "Luna", + "et": "Kuu", + "fi": "Kuu", "fr": "Lune", "ja": "月", + "nb_NO": "Måne", + "nl": "Maan", "ru": "Луна", - "uk": "Місяць" + "sk": "Polmesiac", + "sv": "Måne", + "uk": "Місяць", + "zh_Hans": null } }, { @@ -300,11 +468,19 @@ "unicode": "U+2601U+FE0F", "translated_descriptions": { "de": "Wolke", - "es": null, + "eo": "Nubo", + "es": "Nube", + "et": "Pilv", + "fi": "Pilvi", "fr": "Nuage", "ja": null, + "nb_NO": "Sky", + "nl": "Wolk", "ru": "Облако", - "uk": "Хмара" + "sk": "Oblak", + "sv": "Moln", + "uk": "Хмара", + "zh_Hans": null } }, { @@ -314,11 +490,19 @@ "unicode": "U+1F525", "translated_descriptions": { "de": "Feuer", + "eo": "Fajro", "es": "Fuego", + "et": "Tuli", + "fi": "Tuli", "fr": "Feu", "ja": null, + "nb_NO": "Flamme", + "nl": "Vuur", "ru": "Огонь", - "uk": "Вогонь" + "sk": "Oheň", + "sv": "Eld", + "uk": "Вогонь", + "zh_Hans": null } }, { @@ -328,11 +512,19 @@ "unicode": "U+1F34C", "translated_descriptions": { "de": "Banane", - "es": null, + "eo": "Banano", + "es": "Plátano", + "et": "Banaan", + "fi": "Banaani", "fr": "Banane", "ja": null, + "nb_NO": "Banan", + "nl": "Banaan", "ru": "Банан", - "uk": "Банан" + "sk": "Banán", + "sv": "Banan", + "uk": "Банан", + "zh_Hans": null } }, { @@ -342,11 +534,19 @@ "unicode": "U+1F34E", "translated_descriptions": { "de": "Apfel", + "eo": "Pomo", "es": "Manzana", + "et": "Õun", + "fi": "Omena", "fr": "Pomme", "ja": "リンゴ", + "nb_NO": "Eple", + "nl": "Appel", "ru": "Яблоко", - "uk": "Яблуко" + "sk": "Červené jablko", + "sv": "Äpple", + "uk": "Яблуко", + "zh_Hans": null } }, { @@ -356,11 +556,19 @@ "unicode": "U+1F353", "translated_descriptions": { "de": "Erdbeere", - "es": null, + "eo": "Frago", + "es": "Fresa", + "et": "Maasikas", + "fi": "Mansikka", "fr": "Fraise", "ja": null, + "nb_NO": "Jordbær", + "nl": "Aardbei", "ru": "Клубника", - "uk": "Полуниця" + "sk": "Jahoda", + "sv": "Jordgubbe", + "uk": "Полуниця", + "zh_Hans": null } }, { @@ -370,11 +578,19 @@ "unicode": "U+1F33D", "translated_descriptions": { "de": "Korn", - "es": null, + "eo": "Maizo", + "es": "Maíz", + "et": "Mais", + "fi": "Maissi", "fr": "Maïs", "ja": null, + "nb_NO": "Mais", + "nl": "Maïs", "ru": "Кукуруза", - "uk": "Кукурудза" + "sk": "Kukuričný klas", + "sv": "Majskolv", + "uk": "Кукурудза", + "zh_Hans": null } }, { @@ -384,11 +600,19 @@ "unicode": "U+1F355", "translated_descriptions": { "de": "Pizza", - "es": null, + "eo": "Pico", + "es": "Pizza", + "et": "Pitsa", + "fi": "Pizza", "fr": "Pizza", "ja": null, + "nb_NO": "Pizza", + "nl": "Pizza", "ru": "Пицца", - "uk": "Піца" + "sk": "Pizza", + "sv": "Pizza", + "uk": "Піца", + "zh_Hans": null } }, { @@ -398,11 +622,19 @@ "unicode": "U+1F382", "translated_descriptions": { "de": "Kuchen", - "es": null, + "eo": "Torto", + "es": "Tarta", + "et": "Kook", + "fi": "Kakku", "fr": "Gâteau", "ja": "ケーキ", + "nb_NO": "Kake", + "nl": "Taart", "ru": "Торт", - "uk": "Пиріг" + "sk": "Narodeninová torta", + "sv": "Tårta", + "uk": "Пиріг", + "zh_Hans": null } }, { @@ -412,11 +644,19 @@ "unicode": "U+2764U+FE0F", "translated_descriptions": { "de": "Herz", - "es": null, + "eo": "Koro", + "es": "Corazón", + "et": "Süda", + "fi": "Sydän", "fr": "Cœur", "ja": null, + "nb_NO": "Hjerte", + "nl": "Hart", "ru": "Сердце", - "uk": "Серце" + "sk": "červené srdce", + "sv": "Hjärta", + "uk": "Серце", + "zh_Hans": null } }, { @@ -426,11 +666,19 @@ "unicode": "U+1F600", "translated_descriptions": { "de": "Smiley", - "es": null, - "fr": "Personne souriante", + "eo": "Rideto", + "es": "Emoticono", + "et": "Smaili", + "fi": "Hymynaama", + "fr": "Sourire", "ja": null, + "nb_NO": "Smilefjes", + "nl": "Smiley", "ru": "Улыбка", - "uk": "Посмішка" + "sk": "Škeriaca sa tvár", + "sv": "Smiley", + "uk": "Посмішка", + "zh_Hans": null } }, { @@ -440,11 +688,19 @@ "unicode": "U+1F916", "translated_descriptions": { "de": "Roboter", - "es": null, + "eo": "Roboto", + "es": "Robot", + "et": "Robot", + "fi": "Robotti", "fr": "Robot", "ja": "ロボと", + "nb_NO": "Robot", + "nl": "Robot", "ru": "Робот", - "uk": "Робот" + "sk": "Robot", + "sv": "Robot", + "uk": "Робот", + "zh_Hans": null } }, { @@ -454,11 +710,19 @@ "unicode": "U+1F3A9", "translated_descriptions": { "de": "Hut", - "es": null, + "eo": "Ĉapelo", + "es": "Sombrero", + "et": "Kübar", + "fi": "Hattu", "fr": "Châpeau", "ja": null, + "nb_NO": "Hatt", + "nl": "Hoed", "ru": "Шляпа", - "uk": "Капелюх" + "sk": "Cilinder", + "sv": "Hatt", + "uk": "Капелюх", + "zh_Hans": null } }, { @@ -468,11 +732,19 @@ "unicode": "U+1F453", "translated_descriptions": { "de": "Brille", - "es": null, + "eo": "Okulvitroj", + "es": "Gafas", + "et": "Prillid", + "fi": "Silmälasit", "fr": "Lunettes", "ja": "めがね", + "nb_NO": "Briller", + "nl": "Bril", "ru": "Очки", - "uk": "Окуляри" + "sk": "Okuliare", + "sv": "Glasögon", + "uk": "Окуляри", + "zh_Hans": null } }, { @@ -482,11 +754,19 @@ "unicode": "U+1F527", "translated_descriptions": { "de": "Schraubenschlüssel", - "es": null, + "eo": "Ŝraŭbŝlosilo", + "es": "Llave inglesa", + "et": "Mutrivõti", + "fi": "Mutteriavain", "fr": "Clé à molette", "ja": null, + "nb_NO": "Fastnøkkel", + "nl": "Moersleutel", "ru": "Ключ", - "uk": "Гайковий ключ" + "sk": "Francúzsky kľúč", + "sv": "Skruvnyckel", + "uk": "Гайковий ключ", + "zh_Hans": null } }, { @@ -496,11 +776,19 @@ "unicode": "U+1F385", "translated_descriptions": { "de": "Nikolaus", + "eo": "Kristnaska viro", "es": null, + "et": "Jõuluvana", + "fi": "Joulupukki", "fr": "Père Noël", "ja": null, + "nb_NO": "Julenisse", + "nl": "Kerstman", "ru": "Санта", - "uk": "Санта Клаус" + "sk": "Santa Claus", + "sv": "Tomte", + "uk": "Санта Клаус", + "zh_Hans": null } }, { @@ -510,11 +798,19 @@ "unicode": "U+1F44D", "translated_descriptions": { "de": "Daumen Hoch", + "eo": "Dikfingro supren", "es": null, + "et": "Pöidlad püsti", + "fi": "Peukalo ylös", "fr": "Pouce en l'air", "ja": null, + "nb_NO": "Tommel Opp", + "nl": "Duim omhoog", "ru": "Большой палец вверх", - "uk": "Великий палець вгору" + "sk": "Palec nahor", + "sv": "Tummen upp", + "uk": "Великий палець вгору", + "zh_Hans": null } }, { @@ -524,11 +820,19 @@ "unicode": "U+2602U+FE0F", "translated_descriptions": { "de": "Regenschirm", + "eo": "Ombrelo", "es": null, + "et": "Vihmavari", + "fi": "Sateenvarjo", "fr": "Parapluie", "ja": null, + "nb_NO": "Paraply", + "nl": "Paraplu", "ru": "Зонт", - "uk": "Парасолька" + "sk": "Dáždnik", + "sv": "Paraply", + "uk": "Парасолька", + "zh_Hans": null } }, { @@ -538,11 +842,19 @@ "unicode": "U+231B", "translated_descriptions": { "de": "Sanduhr", + "eo": "Sablohorloĝo", "es": null, + "et": "Liivakell", + "fi": "Tiimalasi", "fr": "Sablier", "ja": null, + "nb_NO": "Timeglass", + "nl": "Zandloper", "ru": "Песочные часы", - "uk": "Пісковий годинник" + "sk": "Presýpacie hodiny", + "sv": "Timglas", + "uk": "Пісковий годинник", + "zh_Hans": null } }, { @@ -552,11 +864,19 @@ "unicode": "U+23F0", "translated_descriptions": { "de": "Wecker", + "eo": "Horloĝo", "es": "Reloj", - "fr": "Horloge", + "et": "Kell", + "fi": "Pöytäkello", + "fr": "Réveil", "ja": null, + "nb_NO": "Klokke", + "nl": "Wekker", "ru": "Часы", - "uk": "Годинник" + "sk": "Budík", + "sv": "Klocka", + "uk": "Годинник", + "zh_Hans": null } }, { @@ -566,11 +886,19 @@ "unicode": "U+1F381", "translated_descriptions": { "de": "Geschenk", + "eo": "Donaco", "es": "Regalo", + "et": "Kingitus", + "fi": "Lahja", "fr": "Cadeau", "ja": null, + "nb_NO": "Gave", + "nl": "Geschenk", "ru": "Подарок", - "uk": "Подарунок" + "sk": "Zabalený darček", + "sv": "Paket", + "uk": "Подарунок", + "zh_Hans": null } }, { @@ -580,11 +908,19 @@ "unicode": "U+1F4A1", "translated_descriptions": { "de": "Glühbirne", + "eo": "Lampo", "es": null, + "et": "Lambipirn", + "fi": "Hehkulamppu", "fr": "Ampoule", "ja": null, + "nb_NO": "Lyspære", + "nl": "Gloeilamp", "ru": "Лампочка", - "uk": "Лампочка" + "sk": "Žiarovka", + "sv": "Lampa", + "uk": "Лампочка", + "zh_Hans": null } }, { @@ -594,11 +930,19 @@ "unicode": "U+1F4D5", "translated_descriptions": { "de": "Buch", + "eo": "Libro", "es": "Libro", + "et": "Raamat", + "fi": "Kirja", "fr": "Livre", "ja": "本", + "nb_NO": "Bok", + "nl": "Boek", "ru": "Книга", - "uk": "Книга" + "sk": "Zatvorená kniha", + "sv": "Bok", + "uk": "Книга", + "zh_Hans": null } }, { @@ -608,11 +952,19 @@ "unicode": "U+270FU+FE0F", "translated_descriptions": { "de": "Bleistift", + "eo": "Krajono", "es": "Lápiz", + "et": "Pliiats", + "fi": "Lyijykynä", "fr": "Crayon", "ja": null, + "nb_NO": "Blyant", + "nl": "Potlood", "ru": "Карандаш", - "uk": "Олівець" + "sk": "Ceruzka", + "sv": "Penna", + "uk": "Олівець", + "zh_Hans": null } }, { @@ -622,11 +974,19 @@ "unicode": "U+1F4CE", "translated_descriptions": { "de": "Büroklammer", + "eo": "Paperkuntenilo", "es": null, + "et": "Kirjaklamber", + "fi": "Paperiliitin", "fr": "Trombone", "ja": null, + "nb_NO": "BInders", + "nl": "Papierklemmetje", "ru": "Скрепка", - "uk": "Спиначка" + "sk": "Sponka na papier", + "sv": "Gem", + "uk": "Спиначка", + "zh_Hans": null } }, { @@ -636,11 +996,19 @@ "unicode": "U+2702U+FE0F", "translated_descriptions": { "de": "Schere", + "eo": "Tondilo", "es": null, + "et": "Käärid", + "fi": "Sakset", "fr": "Ciseaux", "ja": null, + "nb_NO": "Saks", + "nl": "Schaar", "ru": "Ножницы", - "uk": "Ножиці" + "sk": "Nožnice", + "sv": "Sax", + "uk": "Ножиці", + "zh_Hans": null } }, { @@ -650,11 +1018,19 @@ "unicode": "U+1F512", "translated_descriptions": { "de": "Schloss", + "eo": "Seruro", "es": null, + "et": "Lukk", + "fi": "Lukko", "fr": "Cadenas", "ja": null, + "nb_NO": "Lås", + "nl": "Slot", "ru": "Замок", - "uk": "Замок" + "sk": "Zatvorená zámka", + "sv": "Lås", + "uk": "Замок", + "zh_Hans": null } }, { @@ -664,11 +1040,19 @@ "unicode": "U+1F511", "translated_descriptions": { "de": "Schlüssel", + "eo": "Ŝlosilo", "es": "Llave", + "et": "Võti", + "fi": "Avain", "fr": "Clé", "ja": null, + "nb_NO": "Nøkkel", + "nl": "Sleutel", "ru": "Ключ", - "uk": "Ключ" + "sk": "Kľúč", + "sv": "Nyckel", + "uk": "Ключ", + "zh_Hans": null } }, { @@ -678,11 +1062,19 @@ "unicode": "U+1F528", "translated_descriptions": { "de": "Hammer", + "eo": "Martelo", "es": "Martillo", + "et": "Haamer", + "fi": "Vasara", "fr": "Marteau", "ja": null, + "nb_NO": "Hammer", + "nl": "Hamer", "ru": "Молоток", - "uk": "Молоток" + "sk": "Kladivo", + "sv": "Hammare", + "uk": "Молоток", + "zh_Hans": null } }, { @@ -692,11 +1084,19 @@ "unicode": "U+260EU+FE0F", "translated_descriptions": { "de": "Telefon", + "eo": "Telefono", "es": "Telefono", + "et": "Telefon", + "fi": "Puhelin", "fr": "Téléphone", "ja": "電話機", + "nb_NO": "Telefon", + "nl": "Telefoon", "ru": "Телефон", - "uk": "Телефон" + "sk": "Telefón", + "sv": "Telefon", + "uk": "Телефон", + "zh_Hans": null } }, { @@ -706,11 +1106,19 @@ "unicode": "U+1F3C1", "translated_descriptions": { "de": "Flagge", + "eo": "Flago", "es": null, + "et": "Lipp", + "fi": "Lippu", "fr": "Drapeau", "ja": null, + "nb_NO": "Flagg", + "nl": "Vlag", "ru": "Флаг", - "uk": "Прапор" + "sk": "Kockovaná zástava", + "sv": "Flagga", + "uk": "Прапор", + "zh_Hans": null } }, { @@ -720,11 +1128,19 @@ "unicode": "U+1F682", "translated_descriptions": { "de": "Zug", + "eo": "Vagonaro", "es": "Tren", + "et": "Rong", + "fi": "Juna", "fr": "Train", "ja": "電車", + "nb_NO": "Tog", + "nl": "Trein", "ru": "Поезд", - "uk": "Потяг" + "sk": "Rušeň", + "sv": "Ånglok", + "uk": "Потяг", + "zh_Hans": null } }, { @@ -734,11 +1150,19 @@ "unicode": "U+1F6B2", "translated_descriptions": { "de": "Fahrrad", + "eo": "Biciklo", "es": "Bicicleta", + "et": "Jalgratas", + "fi": "Polkupyörä", "fr": "Vélo", "ja": "自転車", + "nb_NO": "Sykkel", + "nl": "Fiets", "ru": "Велосипед", - "uk": "Велосипед" + "sk": "Bicykel", + "sv": "Cykel", + "uk": "Велосипед", + "zh_Hans": null } }, { @@ -748,11 +1172,19 @@ "unicode": "U+2708U+FE0F", "translated_descriptions": { "de": "Flugzeug", + "eo": "Aviadilo", "es": null, + "et": "Lennuk", + "fi": "Lentokone", "fr": "Avion", "ja": null, + "nb_NO": "Fly", + "nl": "Vliegtuig", "ru": "Самолет", - "uk": "Літак" + "sk": "Lietadlo", + "sv": "Flygplan", + "uk": "Літак", + "zh_Hans": null } }, { @@ -762,11 +1194,19 @@ "unicode": "U+1F680", "translated_descriptions": { "de": "Rakete", + "eo": "Raketo", "es": null, + "et": "Rakett", + "fi": "Raketti", "fr": "Fusée", "ja": null, + "nb_NO": "Rakett", + "nl": "Raket", "ru": "Ракета", - "uk": "Ракета" + "sk": "Raketa", + "sv": "Raket", + "uk": "Ракета", + "zh_Hans": null } }, { @@ -776,11 +1216,19 @@ "unicode": "U+1F3C6", "translated_descriptions": { "de": "Trophäe", + "eo": "Trofeo", "es": null, + "et": "Auhind", + "fi": "Palkinto", "fr": "Trophée", "ja": null, + "nb_NO": "Pokal", + "nl": "Trofee", "ru": "Кубок", - "uk": "Приз" + "sk": "Trofej", + "sv": "Trofé", + "uk": "Приз", + "zh_Hans": null } }, { @@ -790,11 +1238,19 @@ "unicode": "U+26BD", "translated_descriptions": { "de": "Ball", + "eo": "Pilko", "es": "Bola", + "et": "Pall", + "fi": "Pallo", "fr": "Ballon", "ja": null, + "nb_NO": "Ball", + "nl": "Bal", "ru": "Мяч", - "uk": "М'яч" + "sk": "Futbal", + "sv": "Boll", + "uk": "М'яч", + "zh_Hans": null } }, { @@ -804,11 +1260,19 @@ "unicode": "U+1F3B8", "translated_descriptions": { "de": "Gitarre", + "eo": "Gitaro", "es": "Guitarra", + "et": "Kitarr", + "fi": "Kitara", "fr": "Guitare", "ja": null, + "nb_NO": "Gitar", + "nl": "Gitaar", "ru": "Гитара", - "uk": "Гітара" + "sk": "Gitara", + "sv": "Gitarr", + "uk": "Гітара", + "zh_Hans": null } }, { @@ -818,11 +1282,19 @@ "unicode": "U+1F3BA", "translated_descriptions": { "de": "Trompete", + "eo": "Trumpeto", "es": "Trompeta", + "et": "Trompet", + "fi": "Trumpetti", "fr": "Trompette", "ja": null, + "nb_NO": "Trompet", + "nl": "Trompet", "ru": "Труба", - "uk": "Труба" + "sk": "Trúbka", + "sv": "Trumpet", + "uk": "Труба", + "zh_Hans": null } }, { @@ -832,11 +1304,19 @@ "unicode": "U+1F514", "translated_descriptions": { "de": "Glocke", + "eo": "Sonorilo", "es": "Campana", + "et": "Kelluke", + "fi": "Soittokello", "fr": "Cloche", "ja": null, + "nb_NO": "Bjelle", + "nl": "Bel", "ru": "Колокол", - "uk": "Дзвін" + "sk": "Zvon", + "sv": "Bjällra", + "uk": "Дзвін", + "zh_Hans": null } }, { @@ -846,11 +1326,19 @@ "unicode": "U+2693", "translated_descriptions": { "de": "Anker", + "eo": "Ankro", "es": null, + "et": "Ankur", + "fi": "Ankkuri", "fr": "Ancre", "ja": null, + "nb_NO": "Anker", + "nl": "Anker", "ru": "Якорь", - "uk": "Якір" + "sk": "Kotva", + "sv": "Ankare", + "uk": "Якір", + "zh_Hans": null } }, { @@ -860,11 +1348,19 @@ "unicode": "U+1F3A7", "translated_descriptions": { "de": "Kopfhörer", + "eo": "Kapaŭdilo", "es": null, + "et": "Kõrvaklapid", + "fi": "Kuulokkeet", "fr": "Casque audio", "ja": null, + "nb_NO": "Hodetelefoner", + "nl": "Koptelefoon", "ru": "Наушники", - "uk": "Навушники" + "sk": "Slúchadlá", + "sv": "Hörlurar", + "uk": "Навушники", + "zh_Hans": null } }, { @@ -874,11 +1370,19 @@ "unicode": "U+1F4C1", "translated_descriptions": { "de": "Ordner", + "eo": "Dosierujo", "es": null, + "et": "Kaust", + "fi": "Kansio", "fr": "Dossier", "ja": null, + "nb_NO": "Mappe", + "nl": "Map", "ru": "Папка", - "uk": "Тека" + "sk": "Fascikel", + "sv": "Mapp", + "uk": "Тека", + "zh_Hans": null } }, { @@ -888,11 +1392,19 @@ "unicode": "U+1F4CC", "translated_descriptions": { "de": "Stecknadel", + "eo": "Pinglo", "es": "Alfiler", + "et": "Nööpnõel", + "fi": "Nuppineula", "fr": "Punaise", "ja": null, + "nb_NO": "Tegnestift", + "nl": "Duimspijker", "ru": "Булавка", - "uk": "Кнопка" + "sk": "Špendlík", + "sv": "Häftstift", + "uk": "Кнопка", + "zh_Hans": null } } ] \ No newline at end of file From 6490fda6eee63e8083584eb42184dd172d8b6fd6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 21 Aug 2020 07:07:41 -0600 Subject: [PATCH 1235/1250] Apply suggestions from code review Co-authored-by: David Baker Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- proposals/1960-integrations-openid.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1960-integrations-openid.md b/proposals/1960-integrations-openid.md index edc34a0b..9b2c981e 100644 --- a/proposals/1960-integrations-openid.md +++ b/proposals/1960-integrations-openid.md @@ -19,7 +19,7 @@ via a common widget - it would be nice if that widget could auth the user withou their username and password into an iframe. Widgets can request OpenID credentials from the user by sending a `fromWidget` action of `get_openid` -to intiate the token exchange process. The client should respond with an acknowledgement of +to initiate the token exchange process. The client should respond with an acknowledgement of `{"state":"request"}` (or `{"state":"blocked"}` if the client/user doesn't think the widget is safe). The client should then prompt the user if the widget should be allowed to get details about the user, optionally providing a way for the user to always accept/deny the widget. If the user agrees, the @@ -31,7 +31,7 @@ the OpenID object (just like in the data for `openid_credentials`). The widget s credentials until after it has exchanged capabilities with the client, however this is not required. The widget should acknowledge the `openid_credentials` request with an empty response object. -A full sequence diagram for this flow is as follows: +A successful sequence diagram for this flow is as follows: ``` +-------+ +---------+ +---------+ From a8328404cedc54c0584b452bb44f53bbcf048f73 Mon Sep 17 00:00:00 2001 From: Marcelo Filho Date: Fri, 21 Aug 2020 14:24:58 +0000 Subject: [PATCH 1236/1250] Added translation using Weblate (Portuguese (Brazil)) --- data-definitions/sas-emoji-v1-i18n/pt_BR.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/pt_BR.json diff --git a/data-definitions/sas-emoji-v1-i18n/pt_BR.json b/data-definitions/sas-emoji-v1-i18n/pt_BR.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/pt_BR.json @@ -0,0 +1 @@ +{} From 80214998f6af8ebd6daf2806c67bf99739da2098 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 21 Aug 2020 08:34:35 -0600 Subject: [PATCH 1237/1250] Various clarifications to structure --- proposals/1960-integrations-openid.md | 52 +++++++++++++++++++-------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/proposals/1960-integrations-openid.md b/proposals/1960-integrations-openid.md index 9b2c981e..edb6470a 100644 --- a/proposals/1960-integrations-openid.md +++ b/proposals/1960-integrations-openid.md @@ -1,4 +1,4 @@ -# MSC1960: OpenID information exchange for widgets +# MSC1960: OpenID Connect information exchange for widgets With the various integrations API proposals, widgets are left with no options to verify the requesting user's ID if they need it. Widgets like the sticker picker must know who is making @@ -10,26 +10,50 @@ API proposed by [MSC1236](https://github.com/matrix-org/matrix-doc/issues/1236). ## Proposal -Room and account widgets may request a new OpenID object from the user so they can log in/register with +Room and account widgets may request new OpenID credentials from the user so they can log in/register with the backing integration manager or other application. This is largely based on the prior art available -[here (riot-web#7153)](https://github.com/vector-im/riot-web/issues/7153). The rationale for such an +[here (element-web#7153)](https://github.com/vector-im/element-web/issues/7153). The rationale for such an API is so that widgets can load things like a user's sticker packs or other information without having to rely on secret strings. For example, a room could be used to let a user create custom sticker packs via a common widget - it would be nice if that widget could auth the user without asking them to enter their username and password into an iframe. Widgets can request OpenID credentials from the user by sending a `fromWidget` action of `get_openid` -to initiate the token exchange process. The client should respond with an acknowledgement of +to initiate the token exchange process. The client responds with an acknowledgement of `{"state":"request"}` (or `{"state":"blocked"}` if the client/user doesn't think the widget is safe). -The client should then prompt the user if the widget should be allowed to get details about the user, +The client then prompts the user if the widget should be allowed to get details about the user, optionally providing a way for the user to always accept/deny the widget. If the user agrees, the client sends a `toWidget` action of `openid_credentials` with `data` holding the raw OpenID credentials -object returned from the homeserver, and a `success: true` parameter. If the user denies the widget, -just `success: false` is returned in the `data` property. To lessen the number of requests, a client may -also respond to the original `get_openid` request with a `state` of `"allowed"`, `success: true`, and -the OpenID object (just like in the data for `openid_credentials`). The widget should not request OpenID -credentials until after it has exchanged capabilities with the client, however this is not required. The -widget should acknowledge the `openid_credentials` request with an empty response object. +object returned from the homeserver, and a `success: true` parameter, similar to the following: +``` +{ + "api": "fromWidget", + "requestId": "AABBCC", + "action": "openid_credentials", + "widgetId": "DDEEFF", + "data": { + "success": true, + "access_token": "SecretTokenHere", + "token_type": "Bearer", + "matrix_server_name": "example.com", + "expires_in": 3600 + } +} +``` + +For clarity, the `data` consists of properties as returned by `/_matrix/client/r0/user/:userId/openid/request_token` +plus the `success` parameter. + +If the user denies the widget, just `success: false` is returned in the `data` property. + +To lessen the number of requests, a client can also respond to the original `get_openid` request with a +`state` of `"allowed"`, `success: true`, and the OpenID Connect credentials object (just like in the `data` for +`openid_credentials`). + +The widget should not request OpenID credentials until after it has exchanged capabilities with the client, +however this is not required to wait for the capabiltiies exchange. + +The widget acknowledges the `openid_credentials` request with an empty response object. A successful sequence diagram for this flow is as follows: @@ -67,9 +91,9 @@ Prior to this proposal, widgets could use an undocumented `scalar_token` paramet send it to the widget. Clients typically chose to send it if the widget's URL matched a whitelist for URLs the client trusts. Widgets are now not able to rely on this behaviour with this proposal, although clients may wish to still support it until adoption is complete. Widgets may wish to look into cookies and other -storage techniques to avoid continously requesting credentials. +storage techniques to avoid continously requesting credentials, regardless of how they got those credentials. -A proof of concept for this system is demonstrated [here](https://github.com/matrix-org/matrix-react-sdk/pull/2781). +An implementation of this proposal is [here](https://github.com/matrix-org/matrix-react-sdk/pull/2781). The widget is left responsible for dealing with the OpenID object it receives, likely handing it off to the integration manager it is backed by to exchange it for a long-lived Bearer token. @@ -77,7 +101,7 @@ the integration manager it is backed by to exchange it for a long-lived Bearer t ## Security considerations The user is explicitly kept in the loop to avoid automatic and silent harvesting of private information. -Clients must ask the user for permission to send OpenID information to a widget, but may optionally allow +Clients must ask the user for permission to send OpenID Connect information to a widget, but may optionally allow the user to always allow/deny the widget access. Clients are encouraged to notify the user when future requests are automatically handled due to the user's prior selection (eg: an unobtrusive popup saying "hey, your sticker picker asked for your information. [Block future requests]"). From 2e8733c368e1e9674f1e4f8ba3cd5d45fbf4ee70 Mon Sep 17 00:00:00 2001 From: Marcelo Filho Date: Fri, 21 Aug 2020 14:26:42 +0000 Subject: [PATCH 1238/1250] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/pt_BR/ --- data-definitions/sas-emoji-v1-i18n/pt_BR.json | 67 ++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/pt_BR.json b/data-definitions/sas-emoji-v1-i18n/pt_BR.json index 0967ef42..e14901fb 100644 --- a/data-definitions/sas-emoji-v1-i18n/pt_BR.json +++ b/data-definitions/sas-emoji-v1-i18n/pt_BR.json @@ -1 +1,66 @@ -{} +{ + "Dog": "Cachorro", + "Cat": "Gato", + "Lion": "Leão", + "Horse": "Cavalo", + "Unicorn": "Unicórnio", + "Pig": "Porco", + "Elephant": "Elefante", + "Rabbit": "Coelho", + "Panda": "Panda", + "Rooster": "Galo", + "Penguin": "Pinguim", + "Turtle": "Tartaruga", + "Fish": "Peixe", + "Octopus": "Polvo", + "Butterfly": "Borboleta", + "Flower": "Flor", + "Tree": "Árvore", + "Cactus": "Cacto", + "Mushroom": "Cogumelo", + "Globe": "Globo", + "Moon": "Lua", + "Cloud": "Nuvem", + "Fire": "Fogo", + "Banana": "Banana", + "Apple": "Maçã", + "Strawberry": "Morango", + "Corn": "Milho", + "Pizza": "Pizza", + "Cake": "Bolo", + "Heart": "Coração", + "Smiley": "Sorriso", + "Robot": "Robô", + "Hat": "Chapéu", + "Glasses": "Óculos", + "Spanner": "Chave inglesa", + "Santa": "Papai-noel", + "Thumbs Up": "Joinha", + "Umbrella": "Guarda-chuva", + "Hourglass": "Ampulheta", + "Clock": "Relógio", + "Gift": "Presente", + "Light Bulb": "Lâmpada", + "Book": "Livro", + "Pencil": "Lápis", + "Paperclip": "Clipe de papel", + "Scissors": "Tesoura", + "Lock": "Cadeado", + "Key": "Chave", + "Hammer": "Martelo", + "Telephone": "Telefone", + "Flag": "Bandeira", + "Train": "Trem", + "Bicycle": "Bicicleta", + "Aeroplane": "Avião", + "Rocket": "Foguete", + "Trophy": "Troféu", + "Ball": "Bola", + "Guitar": "Guitarra", + "Trumpet": "Trombeta", + "Bell": "Sino", + "Anchor": "Âncora", + "Headphones": "Fones de ouvido", + "Folder": "Pasta", + "Pin": "Alfinete" +} From 0e64c4de72613f4d88cd142267b8796d18561338 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Sat, 22 Aug 2020 15:18:33 +0000 Subject: [PATCH 1239/1250] Translated using Weblate (Swedish) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/sv/ --- data-definitions/sas-emoji-v1-i18n/sv.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/sv.json b/data-definitions/sas-emoji-v1-i18n/sv.json index 27c238a3..e2e3cd8e 100644 --- a/data-definitions/sas-emoji-v1-i18n/sv.json +++ b/data-definitions/sas-emoji-v1-i18n/sv.json @@ -50,7 +50,7 @@ "Hammer": "Hammare", "Telephone": "Telefon", "Flag": "Flagga", - "Train": "Ånglok", + "Train": "Tåg", "Bicycle": "Cykel", "Aeroplane": "Flygplan", "Rocket": "Raket", From 1e0d497f457953a2114116cf422b699f50f1643b Mon Sep 17 00:00:00 2001 From: linsui Date: Mon, 24 Aug 2020 10:35:56 +0000 Subject: [PATCH 1240/1250] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/zh_Hans/ --- .../sas-emoji-v1-i18n/zh_Hans.json | 60 ++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/zh_Hans.json b/data-definitions/sas-emoji-v1-i18n/zh_Hans.json index e0dc6bde..fb193afa 100644 --- a/data-definitions/sas-emoji-v1-i18n/zh_Hans.json +++ b/data-definitions/sas-emoji-v1-i18n/zh_Hans.json @@ -4,5 +4,63 @@ "Lion": "狮子", "Horse": "马", "Unicorn": "独角兽", - "Pig": "猪" + "Pig": "猪", + "Elephant": "大象", + "Rabbit": "兔子", + "Panda": "熊猫", + "Rooster": "公鸡", + "Penguin": "企鹅", + "Turtle": "乌龟", + "Fish": "鱼", + "Octopus": "章鱼", + "Butterfly": "蝴蝶", + "Flower": "花", + "Tree": "树", + "Cactus": "仙人掌", + "Mushroom": "蘑菇", + "Globe": "地球", + "Moon": "月亮", + "Cloud": "云", + "Fire": "火", + "Banana": "香蕉", + "Apple": "苹果", + "Strawberry": "草莓", + "Corn": "玉米", + "Pizza": "披萨", + "Cake": "蛋糕", + "Heart": "心", + "Smiley": "笑脸", + "Robot": "机器人", + "Hat": "帽子", + "Glasses": "眼镜", + "Spanner": "扳手", + "Santa": "圣诞老人", + "Thumbs Up": "赞", + "Umbrella": "伞", + "Hourglass": "沙漏", + "Clock": "时钟", + "Gift": "礼物", + "Light Bulb": "灯泡", + "Book": "书", + "Pencil": "铅笔", + "Paperclip": "回形针", + "Scissors": "剪刀", + "Lock": "锁", + "Key": "钥匙", + "Hammer": "锤子", + "Telephone": "电话", + "Flag": "旗帜", + "Train": "火车", + "Bicycle": "自行车", + "Aeroplane": "飞机", + "Rocket": "火箭", + "Trophy": "奖杯", + "Ball": "球", + "Guitar": "吉他", + "Trumpet": "喇叭", + "Bell": "铃铛", + "Anchor": "锚", + "Headphones": "耳机", + "Folder": "文件夹", + "Pin": "图钉" } From 4cb7e96b110c5f14bbe5dc9deb50e2ff5d7635aa Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 27 Aug 2020 08:13:12 -0600 Subject: [PATCH 1241/1250] Apply suggestions from code review Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- proposals/1960-integrations-openid.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/1960-integrations-openid.md b/proposals/1960-integrations-openid.md index edb6470a..6d6a7593 100644 --- a/proposals/1960-integrations-openid.md +++ b/proposals/1960-integrations-openid.md @@ -10,7 +10,7 @@ API proposed by [MSC1236](https://github.com/matrix-org/matrix-doc/issues/1236). ## Proposal -Room and account widgets may request new OpenID credentials from the user so they can log in/register with +Room and account widgets may request new OpenID Connect credentials from the user so they can log in/register with the backing integration manager or other application. This is largely based on the prior art available [here (element-web#7153)](https://github.com/vector-im/element-web/issues/7153). The rationale for such an API is so that widgets can load things like a user's sticker packs or other information without having @@ -18,12 +18,12 @@ to rely on secret strings. For example, a room could be used to let a user creat via a common widget - it would be nice if that widget could auth the user without asking them to enter their username and password into an iframe. -Widgets can request OpenID credentials from the user by sending a `fromWidget` action of `get_openid` +Widgets can request OpenID Connect credentials from the user by sending a `fromWidget` action of `get_openid` to initiate the token exchange process. The client responds with an acknowledgement of `{"state":"request"}` (or `{"state":"blocked"}` if the client/user doesn't think the widget is safe). The client then prompts the user if the widget should be allowed to get details about the user, optionally providing a way for the user to always accept/deny the widget. If the user agrees, the -client sends a `toWidget` action of `openid_credentials` with `data` holding the raw OpenID credentials +client sends a `toWidget` action of `openid_credentials` with `data` holding the raw OpenID Connect credentials object returned from the homeserver, and a `success: true` parameter, similar to the following: ``` { @@ -50,7 +50,7 @@ To lessen the number of requests, a client can also respond to the original `get `state` of `"allowed"`, `success: true`, and the OpenID Connect credentials object (just like in the `data` for `openid_credentials`). -The widget should not request OpenID credentials until after it has exchanged capabilities with the client, +The widget should not request OpenID Connect credentials until after it has exchanged capabilities with the client, however this is not required to wait for the capabiltiies exchange. The widget acknowledges the `openid_credentials` request with an empty response object. From e304109289e6ae043677b0b81a1468f51c726991 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 27 Aug 2020 08:21:41 -0600 Subject: [PATCH 1242/1250] fix widget example --- proposals/1960-integrations-openid.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1960-integrations-openid.md b/proposals/1960-integrations-openid.md index 6d6a7593..84aa3c66 100644 --- a/proposals/1960-integrations-openid.md +++ b/proposals/1960-integrations-openid.md @@ -27,7 +27,7 @@ client sends a `toWidget` action of `openid_credentials` with `data` holding the object returned from the homeserver, and a `success: true` parameter, similar to the following: ``` { - "api": "fromWidget", + "api": "toWidget", "requestId": "AABBCC", "action": "openid_credentials", "widgetId": "DDEEFF", From d6b59621a343dfc3a6eae13a1109626e6b57f830 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Wed, 26 Aug 2020 17:22:01 +0000 Subject: [PATCH 1243/1250] Translated using Weblate (Swedish) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1/sv/ --- data-definitions/sas-emoji-v1-i18n/sv.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data-definitions/sas-emoji-v1-i18n/sv.json b/data-definitions/sas-emoji-v1-i18n/sv.json index e2e3cd8e..e0df5b30 100644 --- a/data-definitions/sas-emoji-v1-i18n/sv.json +++ b/data-definitions/sas-emoji-v1-i18n/sv.json @@ -25,7 +25,7 @@ "Banana": "Banan", "Apple": "Äpple", "Strawberry": "Jordgubbe", - "Corn": "Majskolv", + "Corn": "Majs", "Pizza": "Pizza", "Cake": "Tårta", "Heart": "Hjärta", @@ -39,7 +39,7 @@ "Umbrella": "Paraply", "Hourglass": "Timglas", "Clock": "Klocka", - "Gift": "Paket", + "Gift": "Present", "Light Bulb": "Lampa", "Book": "Bok", "Pencil": "Penna", From 1c7a6a9c7fa2b47877ce8790ea5e5c588df5fa90 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 31 Aug 2020 15:16:55 -0600 Subject: [PATCH 1244/1250] Attempt to clarify how the `state` restriction works for lazy-loading --- api/client-server/sync.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/api/client-server/sync.yaml b/api/client-server/sync.yaml index 1bbe7549..35134fad 100644 --- a/api/client-server/sync.yaml +++ b/api/client-server/sync.yaml @@ -42,12 +42,15 @@ paths: full state of rooms is requested, to aid discovering the user's avatar & displayname. - Like other members, the user's own membership event is eligible + Further, like other members, the user's own membership event is eligible for being considered redundant by the server. When a sync is ``limited``, the server MUST return membership events for events in the gap (between ``since`` and the start of the returned timeline), regardless - as to whether or not they are redundant. This ensures that joins/leaves + as to whether or not they are redundant. This ensures that joins/leaves and profile changes which occur during the gap are not lost. + + Note that the default behaviour of ``state`` is to include all membership + events, alongside other state, when lazy-loading is not enabled. operationId: sync security: - accessToken: [] From 1bac9fb6e3f1a8a418dbfeb6eeda895a4fd616e7 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 31 Aug 2020 15:20:52 -0600 Subject: [PATCH 1245/1250] Changelog --- changelogs/client_server/newsfragments/2754.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2754.clarification diff --git a/changelogs/client_server/newsfragments/2754.clarification b/changelogs/client_server/newsfragments/2754.clarification new file mode 100644 index 00000000..d3f96b84 --- /dev/null +++ b/changelogs/client_server/newsfragments/2754.clarification @@ -0,0 +1 @@ +Clarify the behaviour of ``state`` for ``/sync`` with lazy-loading. From 287745955375625dcffac59de656b7e220d1920c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 2 Sep 2020 14:04:55 -0600 Subject: [PATCH 1246/1250] Add a link to the push module in the push gateway spec --- changelogs/push_gateway/newsfragments/2763.clarification | 1 + specification/push_gateway.rst | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 changelogs/push_gateway/newsfragments/2763.clarification diff --git a/changelogs/push_gateway/newsfragments/2763.clarification b/changelogs/push_gateway/newsfragments/2763.clarification new file mode 100644 index 00000000..d6886641 --- /dev/null +++ b/changelogs/push_gateway/newsfragments/2763.clarification @@ -0,0 +1 @@ +Clarify where to get information about the various parameter values for the notify endpoint. diff --git a/specification/push_gateway.rst b/specification/push_gateway.rst index cba38b6c..46c0000d 100644 --- a/specification/push_gateway.rst +++ b/specification/push_gateway.rst @@ -89,4 +89,7 @@ the event-related fields in the ``/notify`` request. When the homeserver is perf a push where the ``format`` is ``"event_id_only"``, only the ``event_id``, ``room_id``, ``counts``, and ``devices`` are required to be populated. +Note that most of the values and behaviour of this endpoint is described by the Client-Server +API's `Push Module <../client_server/%CLIENT_RELEASE_LABEL%.html#module-push>`_. + {{push_notifier_push_http_api}} From c9e8326783366d95b7d564a78d6e4ab9f97ca03f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sat, 5 Sep 2020 14:56:34 -0600 Subject: [PATCH 1247/1250] Reword following widget spec --- proposals/1960-integrations-openid.md | 175 +++++++++++++++++++------- 1 file changed, 130 insertions(+), 45 deletions(-) diff --git a/proposals/1960-integrations-openid.md b/proposals/1960-integrations-openid.md index 84aa3c66..6f33001f 100644 --- a/proposals/1960-integrations-openid.md +++ b/proposals/1960-integrations-openid.md @@ -1,61 +1,144 @@ # MSC1960: OpenID Connect information exchange for widgets -With the various integrations API proposals, widgets are left with no options to verify the -requesting user's ID if they need it. Widgets like the sticker picker must know who is making -the request and as such need a way to get accurate information about who is contacting them. +Widgets are currently left with no options to verify the user's ID, making it hard for +personalized and authenticated widgets to exist. The spec says the `$matrix_user_id` +template variable cannot be relied upon due to how easy it is to faslify, which is true. -This proposal introduces a way for widgets (room and account) to do so over the `fromWidget` -API proposed by [MSC1236](https://github.com/matrix-org/matrix-doc/issues/1236). +This MSC aims to solve the problem with verifiably accurate OpenID Connect credentials. +As of writing, the best resource to learn more about the widgets spec is the following +spec PR: https://github.com/matrix-org/matrix-doc/pull/2764 ## Proposal -Room and account widgets may request new OpenID Connect credentials from the user so they can log in/register with -the backing integration manager or other application. This is largely based on the prior art available -[here (element-web#7153)](https://github.com/vector-im/element-web/issues/7153). The rationale for such an -API is so that widgets can load things like a user's sticker packs or other information without having -to rely on secret strings. For example, a room could be used to let a user create custom sticker packs -via a common widget - it would be nice if that widget could auth the user without asking them to enter -their username and password into an iframe. - -Widgets can request OpenID Connect credentials from the user by sending a `fromWidget` action of `get_openid` -to initiate the token exchange process. The client responds with an acknowledgement of -`{"state":"request"}` (or `{"state":"blocked"}` if the client/user doesn't think the widget is safe). -The client then prompts the user if the widget should be allowed to get details about the user, -optionally providing a way for the user to always accept/deny the widget. If the user agrees, the -client sends a `toWidget` action of `openid_credentials` with `data` holding the raw OpenID Connect credentials -object returned from the homeserver, and a `success: true` parameter, similar to the following: +Typically widgets which need to accurately verify the user's identity will also have a +backend service of some kind. This backend service likely already uses the integration +manager authentication APIs introduced by [MSC1961](https://github.com/matrix-org/matrix-doc/pull/1961). + +Through using the same concepts from MSC1961, the widget can verify the user's identity +by requesting a fresh OpenID Connect credential object to pass along to its backend, like +the integration manager which might be running it. + +The protocol sequence defined here is based upon the previous discussion in the Element Web +issue tracker: https://github.com/vector-im/element-web/issues/7153 + +It is proposed that after the capabilities negotation, the widget can ask the client for +an OpenID Connect credential object so it can pass it along to its backend for validation. +The request SHOULD result in the user being prompted to confirm that the widget can have +their information. Because of this user interaction, it's not always possible for the user +to complete the approval within the 10 second suggested timeout by the widget spec. As +such, the initial request by the widget can have one of three states: + +1. The client indicates that the user is being prompted (to be followed up on). +2. The client sends over credentials for the widget to verify. +3. The client indicates the request was blocked/denied. + +The initial request from the widget looks as follows: + +```json +{ + "api": "fromWidget", + "action": "get_openid", + "requestId": "AAABBB", + "widgetId": "CCCDDD", + "data": {} +} +``` + +Which then receives a response which has a `state` field alongside potentially the credentials +to be verified. Matching the order of possible responses above, here are examples: + +```json +{ + "api": "fromWidget", + "action": "get_openid", + "requestId": "AAABBB", + "widgetId": "CCCDDD", + "data": {}, + "response": { + "state": "request" + } +} ``` + +```json +{ + "api": "fromWidget", + "action": "get_openid", + "requestId": "AAABBB", + "widgetId": "CCCDDD", + "data": {}, + "response": { + "state": "allowed", + "access_token": "s3cr3t", + "token_type": "Bearer", + "matrix_server_name": "example.org", + "expires_in": 3600 + } +} +``` + +```json +{ + "api": "fromWidget", + "action": "get_openid", + "requestId": "AAABBB", + "widgetId": "CCCDDD", + "data": {}, + "response": { + "state": "blocked" + } +} +``` + +The credential information is directly copied from the `/_matrix/client/r0/user/:userId/openid/request_token` +response. + +In the case of `state: "request"`, the user is being asked to approve the widget's attempt to +verify their identity. To ensure that future requests are quicker, clients are encouraged to +include a "remember this widget" option to make use of the immediate `state: "allowed"` or +`state: "blocked"` responses above. + +There is no timeout associated with the user making their selection. Once a user does make +a selection (allow or deny the request), the client sends a `toWidget` request to indicate the +result, using a very similar structure to the above immediate responses: + +```json { "api": "toWidget", - "requestId": "AABBCC", "action": "openid_credentials", - "widgetId": "DDEEFF", + "requestId": "EEEFFF", + "widgetId": "CCCDDD", "data": { - "success": true, - "access_token": "SecretTokenHere", + "state": "allowed", + "original_request_id": "AAABBB", + "access_token": "s3cr3t", "token_type": "Bearer", - "matrix_server_name": "example.com", + "matrix_server_name": "example.org", "expires_in": 3600 } } ``` -For clarity, the `data` consists of properties as returned by `/_matrix/client/r0/user/:userId/openid/request_token` -plus the `success` parameter. - -If the user denies the widget, just `success: false` is returned in the `data` property. - -To lessen the number of requests, a client can also respond to the original `get_openid` request with a -`state` of `"allowed"`, `success: true`, and the OpenID Connect credentials object (just like in the `data` for -`openid_credentials`). +```json +{ + "api": "toWidget", + "action": "openid_credentials", + "requestId": "EEEFFF", + "widgetId": "CCCDDD", + "data": { + "state": "blocked", + "original_request_id": "AAABBB" + } +} +``` -The widget should not request OpenID Connect credentials until after it has exchanged capabilities with the client, -however this is not required to wait for the capabiltiies exchange. +`original_request_id` is the `requestId` of the `get_openid` request which started the prompt, +for the widget's reference. -The widget acknowledges the `openid_credentials` request with an empty response object. +The widget acknowledges receipt of the credentials with an empty `response` object. -A successful sequence diagram for this flow is as follows: +A typical sequence diagram for this flow is as follows: ``` +-------+ +---------+ +---------+ @@ -63,10 +146,10 @@ A successful sequence diagram for this flow is as follows: +-------+ +---------+ +---------+ | | | | | Capabilities negotiation | - | |<-----------------------------------------| + | |----------------------------------------->| | | | | | Capabilities negotiation | - | |----------------------------------------->| + | |<-----------------------------------------| | | | | | fromWidget get_openid request | | |<-----------------------------------------| @@ -89,14 +172,16 @@ A successful sequence diagram for this flow is as follows: Prior to this proposal, widgets could use an undocumented `scalar_token` parameter if the client chose to send it to the widget. Clients typically chose to send it if the widget's URL matched a whitelist for URLs -the client trusts. Widgets are now not able to rely on this behaviour with this proposal, although clients -may wish to still support it until adoption is complete. Widgets may wish to look into cookies and other -storage techniques to avoid continously requesting credentials, regardless of how they got those credentials. +the client trusts. With the widget specification as written, widgets cannot rely on this behaviour. -An implementation of this proposal is [here](https://github.com/matrix-org/matrix-react-sdk/pull/2781). +Widgets may wish to look into cookies and other storage techniques to avoid continously requesting +credentials. Widgets should also look into [MSC1961](https://github.com/matrix-org/matrix-doc/pull/1961) +for information on how to properly verify the OpenID Connect credentials it will be receiving. The +widget is ultimately responsible for how it deals with the credentials, though the author recommends +handing it off to an integration manager's `/register` endpoint to acquire a single token string +instead. -The widget is left responsible for dealing with the OpenID object it receives, likely handing it off to -the integration manager it is backed by to exchange it for a long-lived Bearer token. +An implementation of this proposal's early draft is here: https://github.com/matrix-org/matrix-react-sdk/pull/2781 ## Security considerations From c25121974e0220db2849735fa21900142ebc7cc2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 8 Sep 2020 14:28:03 -0600 Subject: [PATCH 1248/1250] Create SECURITY.md --- SECURITY.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..3126b47a --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +# Reporting a Vulnerability + +**If you've found a security vulnerability, please report it to security@matrix.org** + +For more information on our security disclosure policy, visit https://www.matrix.org/security-disclosure-policy/ From 89a36633729d02e1c6d810a9b66ba8751562b1d1 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 8 Sep 2020 14:30:22 -0600 Subject: [PATCH 1249/1250] Delete SECURITY.md --- SECURITY.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index 3126b47a..00000000 --- a/SECURITY.md +++ /dev/null @@ -1,5 +0,0 @@ -# Reporting a Vulnerability - -**If you've found a security vulnerability, please report it to security@matrix.org** - -For more information on our security disclosure policy, visit https://www.matrix.org/security-disclosure-policy/ From 81c7893a6ef0d0151cc4061bf667194d74d88ff1 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 16 Sep 2020 14:48:20 -0600 Subject: [PATCH 1250/1250] sync translations for sas emoji --- data-definitions/sas-emoji.json | 186 +++++++++++++++++++++----------- 1 file changed, 125 insertions(+), 61 deletions(-) diff --git a/data-definitions/sas-emoji.json b/data-definitions/sas-emoji.json index a18d7731..b336728e 100644 --- a/data-definitions/sas-emoji.json +++ b/data-definitions/sas-emoji.json @@ -14,6 +14,7 @@ "ja": "犬", "nb_NO": "Hund", "nl": "Hond", + "pt_BR": "Cachorro", "ru": "Собака", "sk": "Hlava psa", "sv": "Hund", @@ -36,6 +37,7 @@ "ja": "猫", "nb_NO": "Katt", "nl": "Kat", + "pt_BR": "Gato", "ru": "Кошка", "sk": "Hlava mačky", "sv": "Katt", @@ -58,6 +60,7 @@ "ja": null, "nb_NO": "Løve", "nl": "Leeuw", + "pt_BR": "Leão", "ru": "Лев", "sk": "Hlava leva", "sv": "Lejon", @@ -80,6 +83,7 @@ "ja": "馬", "nb_NO": "Hest", "nl": "Paard", + "pt_BR": "Cavalo", "ru": "Лошадь", "sk": "Kôň", "sv": "Häst", @@ -102,6 +106,7 @@ "ja": null, "nb_NO": "Enhjørning", "nl": "Eenhoorn", + "pt_BR": "Unicórnio", "ru": "Единорог", "sk": "Hlava jednorožca", "sv": "Enhörning", @@ -124,6 +129,7 @@ "ja": null, "nb_NO": "Gris", "nl": "Varken", + "pt_BR": "Porco", "ru": "Свинья", "sk": "Hlava prasaťa", "sv": "Gris", @@ -146,11 +152,12 @@ "ja": null, "nb_NO": "Elefant", "nl": "Olifant", + "pt_BR": "Elefante", "ru": "Слон", "sk": "Slon", "sv": "Elefant", "uk": "Слон", - "zh_Hans": null + "zh_Hans": "大象" } }, { @@ -168,11 +175,12 @@ "ja": null, "nb_NO": "Kanin", "nl": "Konijn", + "pt_BR": "Coelho", "ru": "Кролик", "sk": "Hlava zajaca", "sv": "Kanin", "uk": "Кріль", - "zh_Hans": null + "zh_Hans": "兔子" } }, { @@ -190,11 +198,12 @@ "ja": null, "nb_NO": "Panda", "nl": "Panda", + "pt_BR": "Panda", "ru": "Панда", "sk": "Hlava pandy", "sv": "Panda", "uk": "Панда", - "zh_Hans": null + "zh_Hans": "熊猫" } }, { @@ -212,11 +221,12 @@ "ja": null, "nb_NO": "Hane", "nl": "Haan", + "pt_BR": "Galo", "ru": "Петух", "sk": "Kohút", "sv": "Tupp", "uk": "Когут", - "zh_Hans": null + "zh_Hans": "公鸡" } }, { @@ -234,11 +244,12 @@ "ja": null, "nb_NO": "Pingvin", "nl": "Pinguïn", + "pt_BR": "Pinguim", "ru": "Пингвин", "sk": "Tučniak", "sv": "Pingvin", "uk": "Пінгвін", - "zh_Hans": null + "zh_Hans": "企鹅" } }, { @@ -256,11 +267,12 @@ "ja": null, "nb_NO": "Skilpadde", "nl": "Schildpad", + "pt_BR": "Tartaruga", "ru": "Черепаха", "sk": "Korytnačka", "sv": "Sköldpadda", "uk": "Черепаха", - "zh_Hans": null + "zh_Hans": "乌龟" } }, { @@ -278,11 +290,12 @@ "ja": null, "nb_NO": "Fisk", "nl": "Vis", + "pt_BR": "Peixe", "ru": "Рыба", "sk": "Ryba", "sv": "Fisk", "uk": "Риба", - "zh_Hans": null + "zh_Hans": "鱼" } }, { @@ -300,11 +313,12 @@ "ja": "たこ", "nb_NO": "Blekksprut", "nl": "Octopus", + "pt_BR": "Polvo", "ru": "Осьминог", "sk": "Chobotnica", "sv": "Bläckfisk", "uk": "Восьминіг", - "zh_Hans": null + "zh_Hans": "章鱼" } }, { @@ -322,11 +336,12 @@ "ja": null, "nb_NO": "Sommerfugl", "nl": "Vlinder", + "pt_BR": "Borboleta", "ru": "Бабочка", "sk": "Motýľ", "sv": "Fjäril", "uk": "Метелик", - "zh_Hans": null + "zh_Hans": "蝴蝶" } }, { @@ -344,11 +359,12 @@ "ja": "花", "nb_NO": "Blomst", "nl": "Bloem", + "pt_BR": "Flor", "ru": "Цветок", "sk": "Tulipán", "sv": "Blomma", "uk": "Квітка", - "zh_Hans": null + "zh_Hans": "花" } }, { @@ -366,11 +382,12 @@ "ja": "木", "nb_NO": "Tre", "nl": "Boom", + "pt_BR": "Árvore", "ru": "Дерево", "sk": "Listnatý strom", "sv": "Träd", "uk": "Дерево", - "zh_Hans": null + "zh_Hans": "树" } }, { @@ -388,11 +405,12 @@ "ja": null, "nb_NO": "Kaktus", "nl": "Cactus", + "pt_BR": "Cacto", "ru": "Кактус", "sk": "Kaktus", "sv": "Kaktus", "uk": "Кактус", - "zh_Hans": null + "zh_Hans": "仙人掌" } }, { @@ -410,11 +428,12 @@ "ja": "きのこ", "nb_NO": "Sopp", "nl": "Paddenstoel", + "pt_BR": "Cogumelo", "ru": "Гриб", "sk": "Huba", "sv": "Svamp", "uk": "Гриб", - "zh_Hans": null + "zh_Hans": "蘑菇" } }, { @@ -432,11 +451,12 @@ "ja": null, "nb_NO": "Globus", "nl": "Wereldbol", + "pt_BR": "Globo", "ru": "Глобус", "sk": "Zemeguľa", "sv": "Jordklot", "uk": "Глобус", - "zh_Hans": null + "zh_Hans": "地球" } }, { @@ -454,11 +474,12 @@ "ja": "月", "nb_NO": "Måne", "nl": "Maan", + "pt_BR": "Lua", "ru": "Луна", "sk": "Polmesiac", "sv": "Måne", "uk": "Місяць", - "zh_Hans": null + "zh_Hans": "月亮" } }, { @@ -476,11 +497,12 @@ "ja": null, "nb_NO": "Sky", "nl": "Wolk", + "pt_BR": "Nuvem", "ru": "Облако", "sk": "Oblak", "sv": "Moln", "uk": "Хмара", - "zh_Hans": null + "zh_Hans": "云" } }, { @@ -498,11 +520,12 @@ "ja": null, "nb_NO": "Flamme", "nl": "Vuur", + "pt_BR": "Fogo", "ru": "Огонь", "sk": "Oheň", "sv": "Eld", "uk": "Вогонь", - "zh_Hans": null + "zh_Hans": "火" } }, { @@ -520,11 +543,12 @@ "ja": null, "nb_NO": "Banan", "nl": "Banaan", + "pt_BR": "Banana", "ru": "Банан", "sk": "Banán", "sv": "Banan", "uk": "Банан", - "zh_Hans": null + "zh_Hans": "香蕉" } }, { @@ -542,11 +566,12 @@ "ja": "リンゴ", "nb_NO": "Eple", "nl": "Appel", + "pt_BR": "Maçã", "ru": "Яблоко", "sk": "Červené jablko", "sv": "Äpple", "uk": "Яблуко", - "zh_Hans": null + "zh_Hans": "苹果" } }, { @@ -564,11 +589,12 @@ "ja": null, "nb_NO": "Jordbær", "nl": "Aardbei", + "pt_BR": "Morango", "ru": "Клубника", "sk": "Jahoda", "sv": "Jordgubbe", "uk": "Полуниця", - "zh_Hans": null + "zh_Hans": "草莓" } }, { @@ -586,11 +612,12 @@ "ja": null, "nb_NO": "Mais", "nl": "Maïs", + "pt_BR": "Milho", "ru": "Кукуруза", "sk": "Kukuričný klas", - "sv": "Majskolv", + "sv": "Majs", "uk": "Кукурудза", - "zh_Hans": null + "zh_Hans": "玉米" } }, { @@ -608,11 +635,12 @@ "ja": null, "nb_NO": "Pizza", "nl": "Pizza", + "pt_BR": "Pizza", "ru": "Пицца", "sk": "Pizza", "sv": "Pizza", "uk": "Піца", - "zh_Hans": null + "zh_Hans": "披萨" } }, { @@ -630,11 +658,12 @@ "ja": "ケーキ", "nb_NO": "Kake", "nl": "Taart", + "pt_BR": "Bolo", "ru": "Торт", "sk": "Narodeninová torta", "sv": "Tårta", "uk": "Пиріг", - "zh_Hans": null + "zh_Hans": "蛋糕" } }, { @@ -652,11 +681,12 @@ "ja": null, "nb_NO": "Hjerte", "nl": "Hart", + "pt_BR": "Coração", "ru": "Сердце", "sk": "červené srdce", "sv": "Hjärta", "uk": "Серце", - "zh_Hans": null + "zh_Hans": "心" } }, { @@ -674,11 +704,12 @@ "ja": null, "nb_NO": "Smilefjes", "nl": "Smiley", + "pt_BR": "Sorriso", "ru": "Улыбка", "sk": "Škeriaca sa tvár", "sv": "Smiley", "uk": "Посмішка", - "zh_Hans": null + "zh_Hans": "笑脸" } }, { @@ -696,11 +727,12 @@ "ja": "ロボと", "nb_NO": "Robot", "nl": "Robot", + "pt_BR": "Robô", "ru": "Робот", "sk": "Robot", "sv": "Robot", "uk": "Робот", - "zh_Hans": null + "zh_Hans": "机器人" } }, { @@ -718,11 +750,12 @@ "ja": null, "nb_NO": "Hatt", "nl": "Hoed", + "pt_BR": "Chapéu", "ru": "Шляпа", "sk": "Cilinder", "sv": "Hatt", "uk": "Капелюх", - "zh_Hans": null + "zh_Hans": "帽子" } }, { @@ -740,11 +773,12 @@ "ja": "めがね", "nb_NO": "Briller", "nl": "Bril", + "pt_BR": "Óculos", "ru": "Очки", "sk": "Okuliare", "sv": "Glasögon", "uk": "Окуляри", - "zh_Hans": null + "zh_Hans": "眼镜" } }, { @@ -762,11 +796,12 @@ "ja": null, "nb_NO": "Fastnøkkel", "nl": "Moersleutel", + "pt_BR": "Chave inglesa", "ru": "Ключ", "sk": "Francúzsky kľúč", "sv": "Skruvnyckel", "uk": "Гайковий ключ", - "zh_Hans": null + "zh_Hans": "扳手" } }, { @@ -784,11 +819,12 @@ "ja": null, "nb_NO": "Julenisse", "nl": "Kerstman", + "pt_BR": "Papai-noel", "ru": "Санта", "sk": "Santa Claus", "sv": "Tomte", "uk": "Санта Клаус", - "zh_Hans": null + "zh_Hans": "圣诞老人" } }, { @@ -806,11 +842,12 @@ "ja": null, "nb_NO": "Tommel Opp", "nl": "Duim omhoog", + "pt_BR": "Joinha", "ru": "Большой палец вверх", "sk": "Palec nahor", "sv": "Tummen upp", "uk": "Великий палець вгору", - "zh_Hans": null + "zh_Hans": "赞" } }, { @@ -828,11 +865,12 @@ "ja": null, "nb_NO": "Paraply", "nl": "Paraplu", + "pt_BR": "Guarda-chuva", "ru": "Зонт", "sk": "Dáždnik", "sv": "Paraply", "uk": "Парасолька", - "zh_Hans": null + "zh_Hans": "伞" } }, { @@ -850,11 +888,12 @@ "ja": null, "nb_NO": "Timeglass", "nl": "Zandloper", + "pt_BR": "Ampulheta", "ru": "Песочные часы", "sk": "Presýpacie hodiny", "sv": "Timglas", "uk": "Пісковий годинник", - "zh_Hans": null + "zh_Hans": "沙漏" } }, { @@ -872,11 +911,12 @@ "ja": null, "nb_NO": "Klokke", "nl": "Wekker", + "pt_BR": "Relógio", "ru": "Часы", "sk": "Budík", "sv": "Klocka", "uk": "Годинник", - "zh_Hans": null + "zh_Hans": "时钟" } }, { @@ -894,11 +934,12 @@ "ja": null, "nb_NO": "Gave", "nl": "Geschenk", + "pt_BR": "Presente", "ru": "Подарок", "sk": "Zabalený darček", - "sv": "Paket", + "sv": "Present", "uk": "Подарунок", - "zh_Hans": null + "zh_Hans": "礼物" } }, { @@ -916,11 +957,12 @@ "ja": null, "nb_NO": "Lyspære", "nl": "Gloeilamp", + "pt_BR": "Lâmpada", "ru": "Лампочка", "sk": "Žiarovka", "sv": "Lampa", "uk": "Лампочка", - "zh_Hans": null + "zh_Hans": "灯泡" } }, { @@ -938,11 +980,12 @@ "ja": "本", "nb_NO": "Bok", "nl": "Boek", + "pt_BR": "Livro", "ru": "Книга", "sk": "Zatvorená kniha", "sv": "Bok", "uk": "Книга", - "zh_Hans": null + "zh_Hans": "书" } }, { @@ -960,11 +1003,12 @@ "ja": null, "nb_NO": "Blyant", "nl": "Potlood", + "pt_BR": "Lápis", "ru": "Карандаш", "sk": "Ceruzka", "sv": "Penna", "uk": "Олівець", - "zh_Hans": null + "zh_Hans": "铅笔" } }, { @@ -982,11 +1026,12 @@ "ja": null, "nb_NO": "BInders", "nl": "Papierklemmetje", + "pt_BR": "Clipe de papel", "ru": "Скрепка", "sk": "Sponka na papier", "sv": "Gem", "uk": "Спиначка", - "zh_Hans": null + "zh_Hans": "回形针" } }, { @@ -1004,11 +1049,12 @@ "ja": null, "nb_NO": "Saks", "nl": "Schaar", + "pt_BR": "Tesoura", "ru": "Ножницы", "sk": "Nožnice", "sv": "Sax", "uk": "Ножиці", - "zh_Hans": null + "zh_Hans": "剪刀" } }, { @@ -1026,11 +1072,12 @@ "ja": null, "nb_NO": "Lås", "nl": "Slot", + "pt_BR": "Cadeado", "ru": "Замок", "sk": "Zatvorená zámka", "sv": "Lås", "uk": "Замок", - "zh_Hans": null + "zh_Hans": "锁" } }, { @@ -1048,11 +1095,12 @@ "ja": null, "nb_NO": "Nøkkel", "nl": "Sleutel", + "pt_BR": "Chave", "ru": "Ключ", "sk": "Kľúč", "sv": "Nyckel", "uk": "Ключ", - "zh_Hans": null + "zh_Hans": "钥匙" } }, { @@ -1070,11 +1118,12 @@ "ja": null, "nb_NO": "Hammer", "nl": "Hamer", + "pt_BR": "Martelo", "ru": "Молоток", "sk": "Kladivo", "sv": "Hammare", "uk": "Молоток", - "zh_Hans": null + "zh_Hans": "锤子" } }, { @@ -1092,11 +1141,12 @@ "ja": "電話機", "nb_NO": "Telefon", "nl": "Telefoon", + "pt_BR": "Telefone", "ru": "Телефон", "sk": "Telefón", "sv": "Telefon", "uk": "Телефон", - "zh_Hans": null + "zh_Hans": "电话" } }, { @@ -1114,11 +1164,12 @@ "ja": null, "nb_NO": "Flagg", "nl": "Vlag", + "pt_BR": "Bandeira", "ru": "Флаг", "sk": "Kockovaná zástava", "sv": "Flagga", "uk": "Прапор", - "zh_Hans": null + "zh_Hans": "旗帜" } }, { @@ -1136,11 +1187,12 @@ "ja": "電車", "nb_NO": "Tog", "nl": "Trein", + "pt_BR": "Trem", "ru": "Поезд", "sk": "Rušeň", - "sv": "Ånglok", + "sv": "Tåg", "uk": "Потяг", - "zh_Hans": null + "zh_Hans": "火车" } }, { @@ -1158,11 +1210,12 @@ "ja": "自転車", "nb_NO": "Sykkel", "nl": "Fiets", + "pt_BR": "Bicicleta", "ru": "Велосипед", "sk": "Bicykel", "sv": "Cykel", "uk": "Велосипед", - "zh_Hans": null + "zh_Hans": "自行车" } }, { @@ -1180,11 +1233,12 @@ "ja": null, "nb_NO": "Fly", "nl": "Vliegtuig", + "pt_BR": "Avião", "ru": "Самолет", "sk": "Lietadlo", "sv": "Flygplan", "uk": "Літак", - "zh_Hans": null + "zh_Hans": "飞机" } }, { @@ -1202,11 +1256,12 @@ "ja": null, "nb_NO": "Rakett", "nl": "Raket", + "pt_BR": "Foguete", "ru": "Ракета", "sk": "Raketa", "sv": "Raket", "uk": "Ракета", - "zh_Hans": null + "zh_Hans": "火箭" } }, { @@ -1224,11 +1279,12 @@ "ja": null, "nb_NO": "Pokal", "nl": "Trofee", + "pt_BR": "Troféu", "ru": "Кубок", "sk": "Trofej", "sv": "Trofé", "uk": "Приз", - "zh_Hans": null + "zh_Hans": "奖杯" } }, { @@ -1246,11 +1302,12 @@ "ja": null, "nb_NO": "Ball", "nl": "Bal", + "pt_BR": "Bola", "ru": "Мяч", "sk": "Futbal", "sv": "Boll", "uk": "М'яч", - "zh_Hans": null + "zh_Hans": "球" } }, { @@ -1268,11 +1325,12 @@ "ja": null, "nb_NO": "Gitar", "nl": "Gitaar", + "pt_BR": "Guitarra", "ru": "Гитара", "sk": "Gitara", "sv": "Gitarr", "uk": "Гітара", - "zh_Hans": null + "zh_Hans": "吉他" } }, { @@ -1290,11 +1348,12 @@ "ja": null, "nb_NO": "Trompet", "nl": "Trompet", + "pt_BR": "Trombeta", "ru": "Труба", "sk": "Trúbka", "sv": "Trumpet", "uk": "Труба", - "zh_Hans": null + "zh_Hans": "喇叭" } }, { @@ -1312,11 +1371,12 @@ "ja": null, "nb_NO": "Bjelle", "nl": "Bel", + "pt_BR": "Sino", "ru": "Колокол", "sk": "Zvon", "sv": "Bjällra", "uk": "Дзвін", - "zh_Hans": null + "zh_Hans": "铃铛" } }, { @@ -1334,11 +1394,12 @@ "ja": null, "nb_NO": "Anker", "nl": "Anker", + "pt_BR": "Âncora", "ru": "Якорь", "sk": "Kotva", "sv": "Ankare", "uk": "Якір", - "zh_Hans": null + "zh_Hans": "锚" } }, { @@ -1356,11 +1417,12 @@ "ja": null, "nb_NO": "Hodetelefoner", "nl": "Koptelefoon", + "pt_BR": "Fones de ouvido", "ru": "Наушники", "sk": "Slúchadlá", "sv": "Hörlurar", "uk": "Навушники", - "zh_Hans": null + "zh_Hans": "耳机" } }, { @@ -1378,11 +1440,12 @@ "ja": null, "nb_NO": "Mappe", "nl": "Map", + "pt_BR": "Pasta", "ru": "Папка", "sk": "Fascikel", "sv": "Mapp", "uk": "Тека", - "zh_Hans": null + "zh_Hans": "文件夹" } }, { @@ -1400,11 +1463,12 @@ "ja": null, "nb_NO": "Tegnestift", "nl": "Duimspijker", + "pt_BR": "Alfinete", "ru": "Булавка", "sk": "Špendlík", "sv": "Häftstift", "uk": "Кнопка", - "zh_Hans": null + "zh_Hans": "图钉" } } ] \ No newline at end of file