Compare commits

...

258 Commits
v1.5 ... main

Author SHA1 Message Date
Richard van der Hoff dac867dd6a
Rename "recovery key" to "backup decryption key" (#1819)
Also, some other editorial improvements, including factoring out our two definitions of the same key encoding algorithm.

Co-authored-by: Travis Ralston <travisr@matrix.org>
5 days ago
Kévin Commaille b0df8e7fb5
Use `patternProperties` in more places with supported formats (#1813)
Allows to have more places where the property name's type is better defined.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 week ago
Richard van der Hoff df1e799c51
Spec terms of service at registration (MSC1692) (#1812)
Spec for matrix-org/matrix-spec-proposals#1692

Co-authored-by: Hubert Chathi <hubertc@matrix.org>
1 week ago
Andrew Morgan f4b34ba962
Note that whitespace around `Authorization` param commas is allowed (#1818) 1 week ago
Kévin Commaille 98d85cf421
Add support for rendering string formats (#1814)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 weeks ago
Richard van der Hoff 48f4c4954f
Include information about additionalProperties in object tables (#1798)
Currently, if we have an object which has additionalProperties in addition to properties, that information gets lost. This PR seeks to address that.
2 weeks ago
Matthias Ahouansou eea3dfa969
Mention notifying AS for sender_localpart events (#1810)
Signed-off-by: Matthias Ahouansou <matthias@ahouansou.cz>
3 weeks ago
Kévin Commaille 2d18aac201
Use `OneTimeKeys` schema (#1800)
This was commented prior to the
port to OpenAPI 3.1 for technical reasons (#1127).
Now we can use it just fine.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
3 weeks ago
Kévin Commaille 1fc25d8d48
Do not use `title` for objects containing only `additionalProperties` or `patternProperties` (#1801)
Previously, titles would appear that do not link to a subchema definition.
It would also mean that named subschemas would appear without being clearly referenced.

Now, the type clearly shows the nesting of objects
and subschema definitions should be clearly referenced.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
3 weeks ago
Kévin Commaille 85ad0c767c
Render response headers (#1809)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
3 weeks ago
Kévin Commaille 625999a039
Deprecate authentication via a query string (#1808)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
3 weeks ago
Kévin Commaille ae70b5fcf3
Replace `set-output` with environment files in CI (#1806)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
3 weeks ago
Kévin Commaille d3eca87389
Set python version for the Towncrier CI job (#1805)
Otherwise the version might change depending on the runner.
We just use the same version as other jobs.

This removes a GitHub warning.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
3 weeks ago
Kévin Commaille d6b1d7300f
Update most CI actions (#1803)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
3 weeks ago
Kévin Commaille b0115a9613
Update typos CI action (#1804)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
3 weeks ago
Kévin Commaille a0bc6e7f83
Add anchors in `definition` shortcode (#1802)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
3 weeks ago
Kévin Commaille 7201042894
Fix anchors for schemas under `oneOf` (#1799)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
3 weeks ago
Kévin Commaille 2edfb21d5d
Add support for pattern formats for `patternProperties` (#1796)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
3 weeks ago
Kévin Commaille 26ce3929b4
Clean up unecessary `allOf`s (#1797)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
4 weeks ago
Kévin Commaille 1095179374
Upgrade version of Hugo used to build the spec in CI (#1794)
* Upgrade version of Hugo used to build the spec in CI

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Escape HTML manually in property-type partial

The behavior of `delimit` changed,
so Hugo doesn't recognize "safe" HTML passed to it anymore, so it escapes nested HTML links.

To fix that we escape the schema data manually
and consider the output of the partial as "safe".

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
4 weeks ago
Richard van der Hoff 2b5f990f60
Factor out common definition of `Tag` type (#1793)
... and remove spurious `additionalProperties: true`
1 month ago
Kévin Commaille e82829d4a2
Make resolve-allof partial recursive (#1787)
Makes it easier to use, like resolve-refs. It just needs to be called once.

Fixes an issue with m.call.* events not displaying the common fields

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
1 month ago
Richard van der Hoff 073ce659df
Define opaque identifier grammar (#1791)
Since we already have three of these, and I'm about to add a fourth, let's pull
it out to a common definition.

We could, of course, keep defining the grammar each time it's used, but
defining it in an appendix helps us be consistent for future API design.
1 month ago
Kévin Commaille f4e7b2aa97
Fix property type resolution in render-object-table (#1789)
The split was not clear between property-type and type-or-title,
so it was not obvious which partial should be called for recursion.
That resulted in an error where type-or-title was only called for objects and array items, even if it also resolves
arrays of types.

This makes the split clearer. property-type must be called for any schema,
and object-type-or-title is only called for object schemas.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 month ago
Kévin Commaille 521e555cf6
Bump minimum Hugo version in README (#1788)
To match the one in config.toml

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 month ago
Kévin Commaille a81b720151
Upgrade CI scripts dependencies (#1786)
Will allow us to benefit from future fixes in JSON Schema validation.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 month ago
Richard van der Hoff becc667672
Update github-labels.rst (#1781)
Fix formatting
1 month ago
Kévin Commaille 2678370f2c
Simplify uses of `resolve-refs` partial (#1773)
* Use the resolve-refs partial as soon as possible

Call it right after accessing the site.Data,
since it is recursing it will solve all references in the tree.
That way we don't need to wonder where to call it,
we trust the validators that the refs will be used in the right place.

* Enable strict $ref rule in OpenAPI validator

* Document use of $ref to compose examples

* Fix schema path in event-fields shortcode

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 month ago
Kévin Commaille 2ea8e0f514
Remove enum for `POST /login` `type` definition (#1776)
Since the enum is not exhaustive, improve the description of the property instead.
1 month ago
Kévin Commaille efe72d3b26
Fix security schemes in OpenAPI definitions (#1772) 1 month ago
Johannes Marbach ee1a169121
Arrange rows in .basic-info tables vertically when horizontal space is constrained (#1771)
Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com>
1 month ago
Kévin Commaille e74c7c1540
Fix Hugo warnings (#1775) 1 month ago
Travis Ralston d547154c91
Spec `?animated` on `/thumbnail` (#1757)
* Spec `?animated` on `/thumbnail`

* v3*

* v1.11
2 months ago
Johannes Marbach 8ff3623e37
Reduce whitespace on mobile viewports (#1770)
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2 months ago
Kévin Commaille eb7ac353e2
Add support for muting in VoIP calls (#1755)
As per MSC3291.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 months ago
Richard van der Hoff c25ff9e012
Formatting fixes in CONTRIBUTING.rst (#1769)
* Formatting fix in CONTRIBUTING.rst

* Fix link

* Create 1769.clarification
2 months ago
Michael Telatynski 083e6ef25d
Fix npm publishing being broken in CI (#1765)
* Fix `v` tag_name prefix sneaking into npm version

* Fix `yarn version` failing in CI due to no git global ident name

* Add changelog

* Rename 1765.misc to 1765.clarification
2 months ago
Travis Ralston bd122b35b0 Return to unstable 2 months ago
Travis Ralston 4e51970c55 Upgrade Hugo version on the historical spec 2 months ago
Travis Ralston f7452e2bad Matrix 1.10 2 months ago
Patrick Cloke 7c19d24e3a
Do not allow setting m.push_rules account data directly. (#1763)
* Do not allow setting m.push_rules account data directly.

* Newsfragment

* Update 1763.clarification

Co-authored-by: Travis Ralston <travpc@gmail.com>

* add change notice

Co-authored-by: Travis Ralston <travpc@gmail.com>

* clarify read status

Co-authored-by: Travis Ralston <travpc@gmail.com>

* Fix link for push rules.

* Refer to the error response

---------

Co-authored-by: Travis Ralston <travpc@gmail.com>
2 months ago
Travis Ralston eb22fac5dc
Break out non-JSON request/response content types as tables (#1756)
* Break out non-JSON request/response content types as tables

Currently we display this as a table like "image/png|image/jpeg" and description on a single line, but we're using a table. This breaks the join out to individual rows.

* changelog
2 months ago
Kévin Commaille 6700f5ddd1
Disable smooth scrolling (#1762)
It was not enabled before the docsy update and it messes with
the TOC highlighting during the transition.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 months ago
Will Hunt e5aa5235fe
MSC4041 - Add Retry-After header notice. (#1737) 2 months ago
Kévin Commaille 4247cff2fa
Deprecate the `font` HTML tag (#1739)
* Deprecate the `font` HTML tag

Rationale:
MSC4077 allows to deprecate HTML tags
that are deprecated in the WHATWG standard,
if they can be replaced by tags with the same feature.

`font` is deprecated and can be replaced by `span`
with the `data-mx-bg-color` and `data-mx-color` attributes.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add deprecation info box

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 months ago
Travis Ralston 15663d405e Changelog normalization for Matrix 1.10 2 months ago
Kévin Commaille 44c16918fd
Add server support discovery endpoint (#1733)
* Add server support discovery endpoint

As per MSC1929.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Fix example indentation

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Apply suggestions from code review

Co-authored-by: Travis Ralston <travpc@gmail.com>

* Fix line length

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add link to definiton of Matrix User ID

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Fix copyright

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Remove HTTP from supported protocols

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
Co-authored-by: Travis Ralston <travpc@gmail.com>
2 months ago
Kévin Commaille 575c84d431
Fix `event-group` shortcode for changes in `resolve-refs` partial (#1754)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 months ago
David Baker 848c1e0348
Spec for MSC3981 (#1746)
* Spec for MSC3981

This writes up https://github.com/matrix-org/matrix-spec-proposals/pull/3981

Hopefully this is relatively straightforward, apart from having to add
the parameters and response field in all three places. I tried to factor
these out but it seems references just aren't supported in the right
places currently (see https://github.com/matrix-org/matrix-spec/pull/1745
for my efforts). Path parameters can't be optional, so it can't be done
that way either.

* Missed schemas

* newsfile

* Actually it clearly isn't going to support markdown, is it?

* grammar

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* grammar

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Clarity

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Clarity

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Typo

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* More clarity.

Note this is counter what the MSC actually proposed to add, but
I think it's clear that this is what it meant.

---------

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
2 months ago
David Baker bb4003afa8
Factor out all the common parameters of the various /relations apis (#1745)
Contributed by @zecakeh bd54781052.

Co-authored-by: Richard van der Hoff <richard@matrix.org>
2 months ago
Kévin Commaille 38796de79a
Add support for multi-stream VoIP (#1735)
As per MSC3077.
2 months ago
Tulir Asokan 5c96f45556
Specify that appservice login and register fail on incorrect as_tokens (#1744)
Signed-off-by: Tulir Asokan <tulir@maunium.net>
2 months ago
Kévin Commaille 4d7e33ec26
Add support for `$ref` URIs containing fragments in OpenAPI definitions and JSON schemas (#1751)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 months ago
Hubert Chathi 0b43b5a343
Add some clarifications around implementation requirements for MSCs (#1718)
* clarification around implementation requirement, and mention new label

* add changelog

* fix typo

* Fix typos

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

---------

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
2 months ago
Johannes Marbach 6634f73bff
Add missing 'in' in SSO specification (#1748)
* Add missing 'in' in SSO specification

Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>

* Use standard changelog entry for typos

---------

Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
Co-authored-by: Hubert Chathi <hubert@uhoreg.ca>
2 months ago
Kévin Commaille 9068c336f4
Clarify that sdpMid and sdpMLineIndex are not required in `m.call.candidates` (#1742)
* Convert m.call.candidates schema to YAML

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Clarify that sdpMid and sdpMLineIndex are not required in `m.call.candidates`

MSC2746, merged in v1.17,
introduced the end-of-candidates candidate,
where only the `candidate` property is set to an empty string.

Besides, the [WebRTC specification](https://www.w3.org/TR/webrtc/)
says that only one of those fields is required in a normal candidate.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Link to the "End-of-candidates" section, and clarify what "empty" means

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 months ago
Kévin Commaille 9fdc7ac38f
Disambiguate uses of PublicRoomsChunk` (#1740)
* Disambiguate uses of PublicRoomsChunk

Make sure that different objects don't share the same title.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 months ago
Kévin Commaille a1210ff6d1
Clarify that extra fields of space hierarchy children are not required (#1741)
* Clarify that extra fields of space hierarchy children are not required

There is no `children_state` field,
the `room_type` is only set for spaces
and the description of `allowed_room_ids` says that the field can be omitted.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 months ago
Kévin Commaille 542a219623
Allow `/versions` to optionally accept authentication (#1728)
* Allow /versions to optionally accept authentication

According to MSC2046.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Set "Requires Authentication: Optional"

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 months ago
Kévin Commaille 4e1b364015
Document the deprecation policy of HTML tags. (#1732)
* Deprecate `strike` HTML tag

Replace it with `s` or `del`.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Remove strike deprecation and add added-in annotation

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add link to HTML standard

Co-authored-by: Hubert Chathi <hubertc@matrix.org>

* Update changelogs/client_server/newsfragments/1732.clarification

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
Co-authored-by: Hubert Chathi <hubertc@matrix.org>
Co-authored-by: Travis Ralston <travpc@gmail.com>
3 months ago
Richard van der Hoff 976ebdca2f
Update HTML templates to link to object definitions (#1724) 3 months ago
Kévin Commaille afda8b8f74
Add local user erasure requests (#1730)
* Add local user erasure requests

As per MSC4025.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add default value

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
3 months ago
reivilibre 2cb70e6e3d
Use a POST request in Federation request signing example (#1721)
* Use a POST request in Federation request signing example

Otherwise the GET request having a body is confusing, since it is not valid HTTP

* Newsfile
3 months ago
Kévin Commaille 38260aabcc
Fix typo in secrets module (#1734)
* Fix typo in secrets module

Introduced in #1695.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
3 months ago
Kévin Commaille b136b357e0
Update docsy to v0.8.0 (#1699)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
3 months ago
Cadence Ember e2dc5a3826
strike element is deprecated, s replaces it (#1629)
* strike element is deprecated, s replaces it

* Add newsfragment
3 months ago
Kévin Commaille 4cfe2fbf8d
Use `body` field as media caption (#1731)
* Use `body` field as media caption

As per MSC2530.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Use `s` HTML tag in example

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Move changed-in annotation

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
3 months ago
Sumner Evans 9a1f0ad532
sas: clarify ECDH process in step 12 (#1720)
Co-authored-by: Denis Kasak <dkasak@termina.org.uk>
3 months ago
Sumner Evans 6096a28984
sas: clarify HKDF calculation uses base64-encoded keys (#1719) 3 months ago
kegsay c4e69d8cb1
Clarify that invite->knock is not a valid transition (#1717)
This reverts https://github.com/matrix-org/matrix-spec/pull/1175

See https://github.com/matrix-org/matrix-spec/issues/1710
3 months ago
Hubert Chathi 170626da67
clarify otk and fallback key types in examples (#1715)
* clarify otk and fallback key types in examples

- remove unsigned curve25519 keys from examples because we don't use those for
  otks and fallback keys
- add missing `device_unused_fallback_key_types` property, which is required

* add changelog
3 months ago
Michael Telatynski 650e691a22
Fix npm release script (#1713)
* Fix npm release script

* Create 1713.misc
4 months ago
Sumner Evans 9a5cacda90
Clarify that the key backup MAC is implemented incorrectly (#1712)
* Clarify that the key backup MAC is implemented incorrectly

Due to a bug in libolm, all implementations of the
m.megolm_backup.v1.curve25519-aes-sha2 key backup algorithm incorrectly
pass an empty string through HMAC-SHA-256 to generate the `mac` property
of the `session_data`.

It was intended for the entire raw encrypted data to be passed through
HMAC-SHA-256, but the issue was caught too late in the process, and thus
we are stuck with this until a new key backup algorithm is introduced.

This commit clarifies the real-world behavior of all current
implementations.

Signed-off-by: Sumner Evans <sumner@beeper.com>
4 months ago
Samuel Loury 1d35e7aac6
Make clearer in the example that the fallback prefix sequence should be repeated for each line (#1690)
Signed-off-by: Samuel Loury <konubinixweb@gmail.com>
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
4 months ago
Richard van der Hoff 4a80df364a
Wording tweak in CONTRIBUTING.rst (#1697) 5 months ago
Richard van der Hoff 37ab151aad
Clarify secret storage format (#1695) 5 months ago
Andy Balaam a843cad285
Clarify that threads can be created based on replies (#1687)
Signed-off-by: Andy Balaam <andy.balaam@matrix.org>
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
5 months ago
Andy Balaam 3b2146c875
Batch receipts by thread as well as room (#1685) 6 months ago
Travis Ralston 59f8d632a3
Add step to release process to remind ourselves to reach out to Advocacy (#1680)
* Add step to release process to remind ourselves to reach out to Advocacy

* changelog
6 months ago
Travis Ralston d50929d46b Become unstable 6 months ago
Travis Ralston 0c099e3b79 Matrix 1.9 6 months ago
Hubert Chathi 62c377e19c
fallback keys should have a "fallback: true" property (#1676)
* fallback keys should have a "fallback: true" property

* add changelog
6 months ago
Andy Balaam 6fe2ff4fa7
Make clear the thread root is not in the thread (#1677)
* Make clear the thread root is not in the thread

Signed-off-by: Andy Balaam <andy.balaam@matrix.org>

* Changlog entry for thread PR 1677 - thread roots not in thread

* Fix typo

* Add formatting for code values.

Co-authored-by: Patrick Cloke <clokep@users.noreply.github.com>

* Reword main timeline ID paragraph

* Use close to the original wording for the 'recurse' part of the 'in the thread' definition

* Remove note about thread roots being displayed in a thread

* Define the thread root

---------

Signed-off-by: Andy Balaam <andy.balaam@matrix.org>
Co-authored-by: Patrick Cloke <clokep@users.noreply.github.com>
6 months ago
Travis Ralston 634b24fb25 Normalize changelog for 1.9 6 months ago
No 25a9157f0a
Add event_property_is and event_property_contains props to PushConditions (#1673)
Signed-off-by: tusooa <tusooa@kazv.moe>
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
6 months ago
Patrick Cloke 161a4a2cfb
Federation requests must be for local users. (#1672)
This is already mentioned for /user/devices, but is not mentioned for /query/profile, /user/keys/claim, or /user/keys/query.

See GHSA-mp92-3jfm-3575 for an issue found with this in Synapse.
6 months ago
Matthew Hodgson 7b72c42ba6 put the e back into erik 6 months ago
No 91724e4aef
Fix .m.rule.suppress_notices push rule not being valid JSON (#1671)
Signed-off-by: tusooa <tusooa@kazv.moe>
6 months ago
Val Lorentz 7c19500da7
server-server-api: Fix grammar in server discovery (#1665) 7 months ago
Kévin Commaille 9fe119370b
Update typos action and fix typos (#1661)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
7 months ago
Kévin Commaille 560d98ba9b
Add more CI checks for OpenAPI definitions and JSON Schemas (#1656)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
7 months ago
Kévin Commaille c71b528148
Upgrade GitHub actions (#1660)
* Upgrade most github actions

Gets rid of warning in CI complaining about those actions
using node 12.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Upgrade node version used to run scripts

Use the latest LTS

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
7 months ago
наб 7fb9e99071
annotion (#1658)
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
7 months ago
Kévin Commaille 72517c0f9c
Generate server-server OpenAPI definition (#1657)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
7 months ago
Kévin Commaille 242b62ed55
Fix `m.call.negotiate` schema and example (#1546)
* Fix m.call.negotiate schema and example

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add lifetime back

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Fix lifetime description

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
8 months ago
Kévin Commaille c3098cc55c
Remove required 'fieldname' in Protocol definition (#1646)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
8 months ago
Kévin Commaille 9a9221d8ef
Fix schemas used for account data and presence events in `GET /initialSync` (#1647)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
8 months ago
tsufeki 92cf662e3a
Fix typo in canonical JSON grammar (#1652)
Signed-off-by: Benedykt Błaszkiewicz <tsufeki@gmail.com>
8 months ago
Kévin Commaille e40d9ca186
Fix rendering of `m.receipt` event in Client-Server API (#1637)
... and other improvements

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
8 months ago
Kévin Commaille 5672bdbab7
Fix enum types in JSON schemas (#1634)
`type: enum` does not exist, as an enum can be of any type.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
8 months ago
Michael Telatynski f11c5600a2
Fix npm package release automation (#1648) 8 months ago
Kévin Commaille 99e2ff4927
Replace all mentions of Swagger by OpenAPI (#1633)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
8 months ago
Kévin Commaille df3f0af5d4
Fix schema of `m.mentions` object (#1635)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
8 months ago
Kévin Commaille 96f88e035c
Fix schema of `m.receipt` EDU (#1636)
It was missing a nesting level for the user ID -> user read receipt map.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
8 months ago
Mohit Kumar Patel 46447e0287
add "case sensitive" to `/publicRooms` (#1638) 8 months ago
Kévin Commaille 044a78730e
Clarify that an `m.room.name` event with an absent `name` field is not expected behavior (#1639)
Fixes #1632

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
8 months ago
Paarth Shah 838dec272c
Clarify that `via` is required for `m.space.parent` and `m.space.child` as per MSC1772. (#1618) 9 months ago
Patrick Cloke 5e938f2b83
Document .m.rule.suppress_edits push rule (MSC3958). (#1617) 9 months ago
heinrich5991 a1b832960c
Clarify that Unix timestamps disregard leap seconds since 1970 (#1627)
Fixes #1626.
9 months ago
Travis Ralston ca456a4f53 Reset for development 9 months ago
Travis Ralston 529cbf4ffc Matrix 1.8 changelog 9 months ago
Travis Ralston 7f8606eb6c Matrix 1.8 9 months ago
Travis Ralston 7aaeac0760 Update data-definitions
Following f65007476b
9 months ago
Weblate f65007476b Merge branch 'origin/main' into Weblate. 9 months ago
Travis Ralston 06298e4d8d Normalize changelog for Matrix 1.8
See https://github.com/matrix-org/matrix-spec/issues/1614
9 months ago
Travis Ralston 86ab57ec4f
Specify IANA-registered service name (MSC4040) (#1624)
* Specify MSC4040

* add changelog

* Fix flow of steps 4 and 5
9 months ago
Mohit Kumar Patel 4f8b8a746c
Switch to ordered list for server name resolution steps (#1623)
* Update server-server-api.md

I have updated the list of Resolving server names in step 3 from unordered list to ordered list. Because we care about its order

* Create 1567.clarification

* Delete 1567.clarification

* Create 1623.clarification

* Update 1623.clarification
9 months ago
Michael Telatynski c0babbfc13
Create @matrix-org/spec npm package containing sas-emoji.json (#1620)
* Create packages/npm @matrix-org/spec npm package containing spec-emoji

* Initial workflow script

* Add newsfragment

* Add docs

* npm publish doesn't like symlinks, yarn does :((
9 months ago
Patrick Cloke 4abea9a6ca
Add room version 11 (#1604)
* Remove duplicate words.

* Add information on room version 11.

* Note some event changes.

* Newsfragment

* Fix-up event schema.

* Apply suggestions from code review

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Fix 'new in this version'.

* Clarify creator field.

* Fix-up event format & examples.

* Move the Redactions section to the client section.

* Reference the sender instead of the creator.

* More links

* Even more links.

* Fix order of headers.

* Fix typos.

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Clarify description of creator.

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Clean-up intro paragraphs for redactions.

* Clean-up examples and language.

* Review comments.

* FIx-up markup tags.

---------

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
9 months ago
Will Hunt 1b69e03793
Add spec for MSC2449: Require users to have visibility on an event when submitting reports (#1517)
* Add MSC2249 support

* changelog

* Add a line on verification

* Changes based on review feedback

* Apply suggestions from code review

Co-authored-by: Travis Ralston <travpc@gmail.com>

* move tags field to the bottom of report_content.yaml

* fix duplicated content

now how did that happen

* fix up the 404 response schema

it wasn't displaying correctly in the rendered spec otherwise

* remove erroneous schema reference

* 1.7 -> 1.8

Co-authored-by: Travis Ralston <travpc@gmail.com>

---------

Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com>
Co-authored-by: Travis Ralston <travpc@gmail.com>
Co-authored-by: Andrew Morgan <andrew@amorgan.xyz>
9 months ago
Richard van der Hoff 05ca6c7392
Remove mention of default port with SRV records (#1615) 9 months ago
Richard van der Hoff f5035b8e02
Fix up attribution
Per request at https://github.com/matrix-org/matrix-spec/pull/1601#discussion_r1269035798
10 months ago
Martin Fischer 1a11a7b998
Use auto table-layout on desktop (#1601)
Signed-off-by: Martin Fischer <martin@push-f.com>
10 months ago
Martin Fischer 4f39ad2a24
Add comment about Docsy fork to .gitmodules (#1600) 10 months ago
Kévin Commaille 639caf057d
Fix rendered changelog with new version of towncrier (#1598)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
10 months ago
Kévin Commaille 50fe89d74b
Fix definition of response of `POST /_matrix/federation/v1/user/keys/claim` (#1559)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
10 months ago
Vladimir Panteleev 746524928c
Fix grammar in client-server-api intro (#1597) 10 months ago
Michael Telatynski 3ae6bb47d8
Update end_to_end_encryption.md (#1596) 10 months ago
Kévin Commaille 1405184765
Fix schema of custom fields in query for appservice API (#1584)
* Fix schema of custom fields in query for appservice API

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Remove ellipses

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
11 months ago
Hubert Chathi 67c9f814e0
fix description of MAC calculation (#1590) 11 months ago
Kévin Commaille bed9223610
Make sure examples types match schema in definitions (#1563)
* Make sure examples types match schema in definitions

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelogs

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add double quotes around URL

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
11 months ago
Patrick Cloke 6521411547
Allow + in Matrix IDs. (#1583) 11 months ago
Tony Garnock-Jones e9acece3ec
Cope with negative-zero, and give an example of negative-zero and a large power of ten (#1573) 11 months ago
cheb 414cc1ea52
Add missing type enum for m.reaction (#1552) 11 months ago
Richard van der Hoff 42114406af
Update link to SAS emoji data (#1593) 11 months ago
Travis Ralston 903b206e3b
Specify our usage of ABNF for grammar (#1582)
* Specify our usage of ABNF for grammar

* Create 1582.clarification

* Update meta/documentation_style.rst

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

---------

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
11 months ago
Richard van der Hoff b2ab339ba6
Bump hugo version used for the build (#1591)
Since https://github.com/matrix-org/matrix-spec/issues/1544 is fixed, we can
use a modern hugo.
11 months ago
Kévin Commaille a6eb381ebb
Fix the sidebar in recent versions of Hugo (#1551)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
11 months ago
Kévin Commaille 30845e189f
Remove unnecessary `oneOf`s in JSON schemas (#1585)
* Remove unnecessary `oneOf`s in JSON schemas

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
11 months ago
Midnight Veil b79fa06cfb
Fix headers with custom IDs via the correct syntax (#1578)
Was previously using <a name="..."> elements which just
add another anchor rather than changing the existing one.
They also use a deprecated HTML attribute and in some cases
broke the header display.

Fixes #1572.

Signed-off-by: Midnight Veil <midnightveil@fea.st>
11 months ago
Kévin Commaille 564444d43e
Render binary request and response bodies (#1579)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
11 months ago
Kévin Commaille 4a9bda9bed
Use tag name as the OpenAPI definition version (#1561)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
11 months ago
Kévin Commaille 49957be1e3
Allow `null` in `room_types` for `POST /publicRooms` endpoints (#1564)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
11 months ago
Kévin Commaille adff3faa35
Make sure version in x-changedInMatrixVersion is a string (#1562) 11 months ago
Kévin Commaille 7a142936f5
Fix level of examples in server keys definition (#1560) 11 months ago
Kévin Commaille 3c5355a278
Use Redocly CLI to validate OpenAPI definitions (#1558) 11 months ago
Kévin Commaille f4aa7c0327
Bump the version of jsonschema (#1556)
* Bump the version of jsonschema

OpenAPI 3.1 uses JSON Schema Draft 2020-12 so we need a version that
supports it.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Fix PR number

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
12 months ago
Kévin Commaille 45b6aaf07a
Upgrade Swagger data to OpenAPI 3.1 (#1310)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
12 months ago
Andrew Morgan c64a616d54
Update the changelog entry checker script to check newsfragment file extension (#1542) 12 months ago
Eric Eastwood dd6af5bfb1
Document why `/state_ids` can respond with a 404 (#1521) 12 months ago
David Robertson 48459dee9b
Only include titles in summaries (#1549)
I previously made this change for HTTP endpoints in #1446. It seems there are
other places where we have over-sized `<summary>` elements. I would like
to elimintate those too, as grumbled about in
https://github.com/matrix-org/matrix-spec/issues/1358#issuecomment-1325220859
and
https://github.com/matrix-org/matrix-spec/issues/1352#issuecomment-1439033334
12 months ago
Travis Ralston 48ee507489 Build unstable 12 months ago
Travis Ralston 8b51f1c011 Matrix 1.7 12 months ago
Travis Ralston 65d70e90b8 Tag Matrix 1.7 12 months ago
Travis Ralston fbb8a789f6
Add release checklist issue template; Document some of our timelines around releases (#1538)
* Add a spec release checklist issue template

because I'm tired of copy/paste

* Document a chunk of our release approach

This should probably go elsewhere, but here is fine for now as a SCT-referenced doc/content.

* changelog

* Brief clarifications
12 months ago
Kévin Commaille 089d209047
Mark the appservice ping response `duration_ms` field as required (#1541)
* Mark the appservice ping response duration_ms field as required

As intended in MSC2659.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 year ago
Kévin Commaille bdf574eeb2
Fix typo in VoIP module (#1540)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 year ago
Travis Ralston db0fd30744 Fix stray localhost link 1 year ago
Travis Ralston d028dc4b82 Normalize changelog for v1.7 1 year ago
Michael Kohler c6348c9f78
Remove age_ts from reference hash calculation (#1536)
* Remove age_ts from reference hash calculation

Signed-off-by: Michael Kohler <me@michaelkohler.info>

* Add newsfragment

* Fix newsfragment number

* Update changelogs/server_server/newsfragments/1536.clarification

Co-authored-by: Travis Ralston <travpc@gmail.com>

---------

Signed-off-by: Michael Kohler <me@michaelkohler.info>
Co-authored-by: Travis Ralston <travpc@gmail.com>
1 year ago
Michael Kohler c94bebc983
Add knock_restricted to m.room.join_rules enum (#1535)
* Add knock_restricted to m.room.join_rules enum

Signed-off-by: Michael Kohler <me@michaelkohler.info>

Fixes #1491

* Add changelog
1 year ago
David Baker 4fd9f39966
Add spec for MSC2746 (#1511)
* Change version field to a string

And add the notes on how the version field works.

* Add spec requiring tracks to be within streams.

* Put streams spec in its own section

* Add 'invitee' field

* Add party_id

* Remember how JSON works

* Add m.call.select_answer

* Update examples

* Add select_answer to call flow example diagram

* Add m.call.reject

* Make party_id required in other events

* Add possible ways for client to handle an invite

* Convert hangup & reject events to YAML

So we can have a bulleted list in the description for the values
of 'reason'.

* Add new reason codes to hangup & reject

* Add m.call.negotiate

* Add other sections

* Revert changes to package lock

* Typos

* Fix type of other version fields, fix anchor.

* Add newsfragment

* Fix reason in hangup/reject

* Change tense

Co-authored-by: Hubert Chathi <hubertc@matrix.org>

* Tense, typos & grammar

Co-authored-by: Hubert Chathi <hubertc@matrix.org>

* Linkify

Co-authored-by: Hubert Chathi <hubertc@matrix.org>

* Remove unnecessary parts from link

Co-authored-by: Hubert Chathi <hubertc@matrix.org>

* Capitalise

Co-authored-by: Hubert Chathi <hubertc@matrix.org>

* Fix hangup reasons

* Clarify who can answer

Co-authored-by: Hubert Chathi <hubertc@matrix.org>

* Linkify

Co-authored-by: Hubert Chathi <hubertc@matrix.org>

* Remove reference to 'this MSC'.

* Move common VoIP fields into a call event type.

* Move common voip events to the content, not the actual event

* Remove reason from reject event

I confused myself, but it's not in the MSC and it shouldn't be.

* Failure to YAML

* Fix number of room members allowed when sending voip events.

Co-authored-by: Hubert Chathi <hubertc@matrix.org>

* Add 'added in' version

Co-authored-by: Hubert Chathi <hubertc@matrix.org>

* Another added-in

Co-authored-by: Hubert Chathi <hubertc@matrix.org>

* Add missing comma

---------

Co-authored-by: Hubert Chathi <hubertc@matrix.org>
Co-authored-by: Travis Ralston <travisr@matrix.org>
1 year ago
Michael Kohler 17ebdf7c86
Fix ASCII art alignment (#1534)
* Fix ASCII art alignment

Signed-off-by: Michael Kohler <me@michaelkohler.info>

Fixes #1430

* Add changelog

---------

Co-authored-by: Travis Ralston <travpc@gmail.com>
1 year ago
Tulir Asokan 9dd9639dd7
Add spec for MSC2659: application service ping endpoint (#1516) 1 year ago
Kévin Commaille f564c07e60
Fixes and clarifications around m.reaction (#1531)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 year ago
Travis Ralston 6496d374d2
Specify MSC3882: Using an existing session to log in another (#1530)
* Specify MSC3882: Using an existing session to log in another

MSC: https://github.com/matrix-org/matrix-spec-proposals/pull/3882

* Changelog entries

* Update data/api/client-server/login.yaml

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Link to endpoint

* Copy/paste `auth` dict definition

* Move get_token API to the correct version prefix (v1, not v3)

* Apply suggestions from code review

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

---------

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
1 year ago
Richard van der Hoff cad4f78711
Update 1473.clarification
fix formatting
1 year ago
Nick Mills-Barrett 4fabef1c97
Add `allow_redirect` query parameter to relevant media endpoints (#1529)
* Add `allow_redirect` query parameter to relevant media endpoints

* Add added in version flag to `allow_redirect` params

* Add 307/308 responses to media endpoints

* Add changelogs
1 year ago
Patrick Cloke 466acdfc46
Update spec for MSC3952: intentional mentions (#1508)
See MSC3952.
1 year ago
Richard van der Hoff 9766b142f1
event_replacements: fix rationale box (#1525)
This was missing its %s
1 year ago
Richard van der Hoff c1ac9a9ad7
Update transaction ID scope (#1526) 1 year ago
Richard van der Hoff 188d568f3a
Add 'deprecated:true' to /v1/send_{join,leave} (#1518)
The words already say this is deprecated, but it was missing the flag.
1 year ago
Hubert Chathi dc5d95c242
Clarify signatures upload endpoint (#1495)
* clarify signatures upload endpoint

* add changelog
1 year ago
Kévin Commaille ade2d29210
Fix internal link to asynchronous upload enpoint (#1510)
* Fix internal link to asynchronous upload enpoint

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 year ago
Andrew Morgan 50757e61b7
Fix a list formatting error under C-S API -> `m.room.member` definition (#1509)
* Fix a list formatting error under C-S API -> m.room.member definition

* changelog
1 year ago
Patrick Cloke e1dc5f8f53
Remove the `dont_notify` and `coalesce` push rule actions. (#1501)
* Remove the `dont_notify` and `coalesce` push rule actions.

Per MSC3987, these should both be considered no-ops.

* Remove obsolete dont_notify from default rules.

* Remove obsolete dont_notify from examples.
1 year ago
Richard van der Hoff 283c5877fe
Spec asynchronous uploads (#1499)
Spec for matrix-org/matrix-spec-proposals#2246
1 year ago
Richard van der Hoff 6150f71ba1
Corrections to the response format of `/_matrix/identity/v2/store-invite` (#1486)
This has been wrong since the dawn of time.

Fixes https://github.com/matrix-org/matrix-spec/issues/495
1 year ago
Kim Brose cafb453545
Fix m.location.yaml scheme (#1507)
* Fix m.location.yaml scheme

This appears to have been mixed up while refactoring
f1f32d3a15 (diff-eb879a272497c490480df3e07215d058ace2fa0bf456447786f299995fb467ef)

* Create 1507.clarification
1 year ago
Richard van der Hoff c662976fab
Fix generation of anchors for additional properties (#1488)
but objects defined under `additionalProperties` missed out on them. This fixes
that.
1 year ago
Richard van der Hoff cdbf44eef0
Fix rendering of properties with a list of types (#1487) 1 year ago
Richard van der Hoff 1f729eef60
"MXC URI" -> "`mxc://` URI" (#1500)
* "MXC URI" -> "`mxc://` URI"

We're a bit inconsistent with this currently, and IMHO "`mxc://` URI" is more
explicit.

* Update content/client-server-api/modules/content_repo.md

Co-authored-by: Hubert Chathi <hubertc@matrix.org>

* more MXCs

---------

Co-authored-by: Hubert Chathi <hubertc@matrix.org>
1 year ago
Richard van der Hoff 715f6a301d
Spec annotations (#1475) 1 year ago
Richard van der Hoff a225025cab
Remove fictitious `token` parameter on `/keys/query` (#1485) 1 year ago
Richard van der Hoff 64c61c2de2
Properly separate Room ID and Event ID grammars (#1484) 1 year ago
Richard van der Hoff e9fc66cf77
Remove references to groups from appendices (#1483) 1 year ago
Richard van der Hoff 91b2f77e0e
Remove outdated text saying that state_default defaults to 0 (#1479)
There was substantial confusion around this, but I've done some archaeology.

Basically, this was changed back in r0.5.0 by MSC1304 and matrix-org/synapse#3397. Before that, it was indeed the case that state_default was 0 if there was no m.room.power_levels event, but that was confusing and a source of security holes, so we changed it.

matrix-org/matrix-spec-proposals#1656 changed the spec, but apparently overlooked the text in the description.

Reverts: #1478.
Fixes: #861.
1 year ago
Patrick Cloke d222fc60d6
Document MSC3758, MSC3966, MSC3873, and MSC3980. (#1464)
* Add information on MSC3758: event_property_is.

* Add information on MSC3966: event_property_contains.

* Add information on MSC3873 dotted-path escape rules.

* Newsfragment

* Update sync filter with ref to appendix.

* Escape example key.

* Fix typos.

Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com>

* Fix links.

* Clarify the appendix a bit.

* Clarify support values.

* Add MSC3980 to changelog.

---------

Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com>
1 year ago
Travis Ralston 7670a74116
Mention that `state_default` can be zero by default. (#1478)
* Mention that `state_default` can be zero by default.

* Changelog

* Update data/event-schemas/schema/m.room.power_levels.yaml

Co-authored-by: Hubert Chathi <hubertc@matrix.org>

---------

Co-authored-by: Hubert Chathi <hubertc@matrix.org>
1 year ago
Richard van der Hoff ac8d34bc81
Cleanups to github actions workflow (#1476) 1 year ago
Kim Brose a21b23dda8
Fix typo in registration.yaml (#1474) 1 year ago
Val Lorentz a847ee3b57
Remove leftover {key_id} from /_matrix/key/v2/server/ (#1473)
The parameter was removed in v1.6 (specifically in
9e45037129)
1 year ago
Richard van der Hoff d26794ee90
Clarify terminology around aggregations (#1424)
I've done my best to remove the word "bundle", because I feel like it causes
more confusion than it provides. Instead I have favoured "aggregated child
events" which I think is clearer.

Some general clarification around these parts of the spec.
1 year ago
Stuart Mumford d6f38f157d
Add a sentence about what canonical JSON is (#1468)
Signed-off-by: Stuart Mumford <stuart@cadair.com>
1 year ago
Richard van der Hoff acb631d3d6
Change the server aggregation for edits (#1440)
per matrix-org/matrix-spec-proposals#3925
1 year ago
Stuart Mumford bdc87784a1
Clarify that Persistent data unit is PDU (#1466)
Signed-off-by: Stuart Mumford <stuart@cadair.com>
1 year ago
Stuart Mumford 09e2250a8d
Spec implicit filter event limit (#1463)
Signed-off-by: Stuart Mumford <stuart@cadair.com>
1 year ago
Andrew Morgan 35f5439e00
Correct a small typo in the push rules spec (#1465 1 year ago
Patrick Cloke 53d7de2376
Define how clients process push rules (#1461)
* Move Push Rules section out from Client Behaviour.
* Clarify server vs. client behavior.
* Remove references to unencrypted content.
1 year ago
Travis Ralston a481d6aafb
Add mention of private sign off to contributing guidelines (#1462) 1 year ago
Patrick Cloke afae1083aa
Clarify what key content-specific rules match against. (#1441) 1 year ago
Alexey Rusakov b441b19cc3
More cleanup before upgrading to OpenAPI 3.1 (#1455)
* `cross_signing_key.yaml`: the parameter documentation already restricts the number of properties
 * `receipts.yaml`: use `maxProperties: 0` to say the object is empty (the comment is still there but is not really needed any more)
 
Signed-off-by: Alexey Rusakov <Kitsune.Ral@users.sf.net>
1 year ago
Andrew Morgan c0955a6aee
Add a hyphen between third and party when used as an adjective (#1447) 1 year ago
Alexey Rusakov 9ebcf5f257
OpenAPI compliance: avoid $ref siblings (#1457)
This strives to fix all remaining cases where additional attributes
(most often 'description' but not only) are provided next to $ref
by wrapping $ref in allOf; and also drops allOf in a couple of places
where $ref is the only element under it.
1 year ago
Hugh Nimmo-Smith 10844fef8c
Clarification to transaction identifier idempotent semantics (#1449) 1 year ago
David Robertson f9ea0f9d9b
Only include endpoint path in `<summary>` (#1446) 1 year ago
Richard van der Hoff a45138c3b4
Minor updates to documentation style (#1456)
i.e. has full-stops
1 year ago
Richard van der Hoff a9e9202e89
Load Inter CSS directly (#1444)
Move the load of the Inter font CSS from _variables_project.scss to head-end.html.

Empirically, this seems to fix #965
1 year ago
Kévin Commaille 427f472331
Remove overridden references to `examples/minimal_pdu.json` and add the missing `room_id` field. (#1454)
The syntax is incorrect and would require to use allOf
because a $ref can't have siblings.
However the only field not overwritten of that definition is room_id,
so we include it instead of the $ref

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 year ago
Richard van der Hoff 77d0f20226
Remove spurious 'weight: 340' (#1442) 1 year ago
Jonas Platte 71b2235868
Clarify that reply chain fallback for threads may not be present (#1439) 1 year ago
Saiprakash Shet ea47197930
Update spelling in s2s authorization (#1431)
* Issue #1231/Update spelling in s2s authorization

* Update spelling in s2s authorization.

* Apply suggestions from code review

---------

Co-authored-by: Travis Ralston <travpc@gmail.com>
1 year ago
Andrew Morgan 5c7bb2fcd5
Remove some erroneous underscores from the Client-Server spec text (#1432)
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
1 year ago
Travis Ralston 377e301c61 Fix MSC naming reference 1 year ago
Travis Ralston 49b7414080 Return to unstable 1 year ago
Travis Ralston 029e988835 Matrix 1.6 1 year ago
Travis Ralston 97e353d26b Tag Matrix 1.6 1 year ago
DeepBlueV7.X a383698be5
Improve distinction between tags and their attributes in the rich text section (#1433)
Originally the tags used to be bold, followed by a colon and separated
into two columns in a table. This at least restores the table aspect,
which makes it clear, that font is not an attribute (and similar).

This seems to have gotten lost in the transition to the new design.

Signed-off-by: Nicolas Werner <nicolas.werner@hotmail.de>
1 year ago
Andy Balaam b5566dbadb
Clarify which events will be included in Stripped State (#1409)
Signed-off-by: Andy Balaam andy.balaam@matrix.org
1 year ago
Richard van der Hoff 6b02e39308
Move `.m.rule.roomnotif` before `.m.rule.tombstone` (#1421)
See https://github.com/matrix-org/matrix-spec/issues/1406 for the reasoning on
this. TL;DR: the spec has always been wrong here.
1 year ago
Hubert Chathi ad94985754
Define hkdf-hmac-sha256.v2 MAC method for SAS verification (#1412)
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
1 year ago
Hubert Chathi e9a463d871
Send heroes for nameless rooms on send_join (#1425)
Co-authored-by: Patrick Cloke <clokep@users.noreply.github.com>
1 year ago
Travis Ralston 5c485ade2e Prepare changelogs for v1.6 1 year ago
Richard van der Hoff a7790fcbbf
Clarify room version grammar (#1422)
Apparently the SHOULD is confusing
1 year ago
Richard van der Hoff 05620913d5
Fix anchor for room-knocking heading (#1423)
Fixes #1407
1 year ago
Kévin Commaille d55af02738
Add links to the spec for the definition of 3PID `medium` (#1417)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 year ago
Kim Brose d4586eba2e
Improve formatting of definitions in the Push Notifications section (#1415)
Signed-off-by: Kim Brose <2803622+HarHarLinks@users.noreply.github.com>
1 year ago
dylhack.dev f06ffc8176
replace "<content>" with "content" (#1370)
* replace "<content>" with "content"

This parameter that's part of the content-repo openapi spec causes generators to mess up

* added changelogs

* Update changelogs/internal/newsfragments/1370.clarification

Co-authored-by: Travis Ralston <travpc@gmail.com>

Co-authored-by: Travis Ralston <travpc@gmail.com>
1 year ago
Catalan Lover fdd3d94a94
Change default room version from 9 to 10 (#1397)
* Change default room version from 9 to 10 in accordance with MSC3904

* Add changelog entry with assumed PR number.

* Fix missing comma in changelog.

Co-authored-by: Travis Ralston <travpc@gmail.com>

Co-authored-by: Travis Ralston <travpc@gmail.com>
1 year ago
Kévin Commaille eb656dfce3
Add missing `x-addedInMatrixVersion` to `servers_in_room` in `v2/send_join` (#1398)
* Add missing `x-addedInMatrixVersion` to `servers_in_room` in `v2/send_join`

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 year ago
Richard van der Hoff b8411b5159
Spec `omit_members` for `/v2/send_join` (#1393)
Per MSC3706
1 year ago
Kévin Commaille 9e45037129
Remove `keyId` from the server keys endpoints (#1350)
* Remove keyId from the server keys endpoints

It has been deprecated forever.
Besides, the OpenAPI 3 spec doesn't allow optional path parameters.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add newsfragment

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Fix broken link

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Mention MSC3938 in newfragment

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 year ago
Hubert Chathi eb2456c7d4
Improve documentation around one-time keys and key types (#1381) 1 year ago
Hubert Chathi 94465fe93b
Add spec for getting events by timestamp (#1366) 1 year ago
Richard van der Hoff 7bd48ca9c7
Stop autogenerating examples where we already have one (#1384)
If an object definition already has an example, we shouldn't try to extend that
definition by adding examples derived from the individual properties. Doing so
is confusing, and there is no way to inhibit it when it is not desired. It's
also not what the RapiDoc viewere does, so we end up with examples being
inconsistent.
1 year ago
Richard van der Hoff 966f3c443a
Fix `edu_type` on EDU examples (#1383)
The top-level `example` in `edu.yaml` was overriding the individual examples
for `edu_type`. Let's fix that by getting rid of the example in `edu.yaml`.

Fixes https://github.com/matrix-org/matrix-spec/issues/805
1 year ago
Kim Brose 05d2bc4c95
move login API definitions to the right heading (#1382)
* move login API definitions to the right heading

regressed from https://github.com/matrix-org/matrix-spec-proposals/pull/3324

* Create 1382.clarification
1 year ago
Richard van der Hoff f386c903c0
Clarify that CNAMEs are permissible for server names (#1376)
Fixes https://github.com/matrix-org/matrix-spec/issues/606.
1 year ago
Travis Ralston 8a555fb411
Add some safety to the proposals script (#1368)
* Add some safety to the proposals script

for if github's api explodes, forgets the header, or we are rate limited or something.

* changelog
1 year ago
Richard van der Hoff 9555cbe5a9
Fix incorrect default "Invite level" (#1371) 1 year ago
Hubert Chathi 5d40118116
Merge pull request #1363 from zecakeh/fix-typos
Fix various typos
1 year ago
Kévin Commaille 2e789736cc
Add newsfragment
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 year ago
Kévin Commaille 60544a362b
Reference relations were added in v1.5
According to the changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 year ago
Kévin Commaille 7af45a36fc
Fix `read_markers`
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 year ago
Kévin Commaille 6ffc5e6ed0
Fix `and` -> `an`
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 year ago
Johannes Becker e481fd011a
Add link to the unstable spec to the README (#1357) 2 years ago
Kévin Commaille 8d4a3bb912
Clarify what fields are required when deleting a pusher (#1321)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 years ago
Sumner Evans 84fbb611db
Clarify that /context always returns 'event' even if limit is zero (#1239)
Signed-off-by: Sumner Evans <me@sumnerevans.com>
2 years ago
Johannes Becker 3f3b5c39f0
Remove duplicated "Note:" from `m.room.power_levels` (#1355)
Remove duplicated "Note:"

Signed-off-by: Johannes Becker <j.becker@famedly.com>
2 years ago
David Robertson 07442876ce
Improve presentation of push rules kinds and actions (#1348) 2 years ago
Kévin Commaille 4534124742
Include examples inline instead of using a reference for invite endpoint definitions (#1349)
The OpenAPI 3 spec doesn't allow building examples by composition.
Either the whole example must be a reference, or it has to be included.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 years ago
Patrick Cloke eeb43043ad
Add standard error responses (MSC3743). (#1347) 2 years ago
Kévin Commaille dfc8a2e184
Fix `POST _matrix/federation/v1/user/keys/claim` response schema (#1351)
The syntax was not compliant with the Swagger spec.
It also lacked one level of nesting.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 years ago
Johannes Becker b2c4abf567
Clarify the power levels integer range (#1169)
Signed-off-by: Johannes Becker <j.becker@famedly.com>
2 years ago
David Baker 24b95cbb89
Merge pull request #1353 from HarHarLinks/patch-1
add missing description to m.call.answer schema
2 years ago
Kim Brose 8830314401
Create 1353.clarification 2 years ago
Kim Brose 8d378cfd51
add missing description to m.call.answer schema 2 years ago
Travis Ralston 3a84ea7cf6 Return to unstable 2 years ago

@ -0,0 +1,35 @@
---
name: [SCT] Release checklist
about: Used by the Spec Core Team to create a new release.
title: 'Matrix 1.X'
labels: 'release-blocker'
assignees: ''
---
<!-- ------------------------------------------------------------------------ -->
<!-- Please asssign the release coordinator (probably yourself) to this issue -->
<!-- ------------------------------------------------------------------------ -->
Date: **Thursday, May 25, 2023** <!-- CHANGE ME -->
Previous release: <!-- LINK TO LAST RELEASE'S CHECKLIST -->
Preflight checklist ([release steps](https://github.com/matrix-org/matrix-spec/blob/main/meta/releasing.md)):
* [ ] Ensure the social media account holders are available for the release day.
* [ ] Blog post written
* [ ] Check for release blockers that may have been missed
* [ ] Review/fix the changelog
Release checklist ([release steps](https://github.com/matrix-org/matrix-spec/blob/main/meta/releasing.md)):
* [ ] Branch stuffs
* [ ] Github release artifact
* [ ] Published to spec.matrix.org
* [ ] All links work
* [ ] Publish blog post
* [ ] Announce in #matrix-spec, client developers, HS developers, SCT office, and other rooms as warranted
* [ ] Post to Twitter/Mastodon
* [ ] Close this issue
Known release blockers:
* [ ] <!-- Issue/PR link -->

@ -10,3 +10,4 @@ au1ba7o = "au1ba7o"
[default.extend-words]
Appy = "Appy"
fo = "fo"
Iy = "Iy"

@ -10,7 +10,7 @@ jobs:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: scripts/check-newsfragments

@ -18,33 +18,72 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: "📥 Source checkout"
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: " Setup Node"
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: '14'
- name: "⚙️ npm"
working-directory: "./scripts"
run: |
npm install
node-version: '20'
- name: "🔎 Run validator"
working-directory: "./scripts"
run: |
node validator.js -s "../data/api/application-service"
node validator.js -s "../data/api/client-server"
node validator.js -s "../data/api/push-gateway"
npx @redocly/cli@latest lint data/api/*/*.yaml
check-examples:
check-event-examples:
name: "🔎 Check Event schema examples"
runs-on: ubuntu-latest
container: uhoreg/matrix-doc-build
steps:
- name: "📥 Source checkout"
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: " Setup Python"
uses: actions/setup-python@v5
with:
python-version: '3.9'
cache: 'pip'
cache-dependency-path: scripts/requirements.txt
- name: " Install dependencies"
run: |
pip install -r scripts/requirements.txt
- name: "🔎 Run validator"
run: |
python scripts/check-event-schema-examples.py
check-openapi-examples:
name: "🔎 Check OpenAPI definitions examples"
runs-on: ubuntu-latest
steps:
- name: "📥 Source checkout"
uses: actions/checkout@v4
- name: " Setup Python"
uses: actions/setup-python@v5
with:
python-version: '3.9'
cache: 'pip'
cache-dependency-path: scripts/requirements.txt
- name: " Install dependencies"
run: |
pip install -r scripts/requirements.txt
- name: "🔎 Run validator"
run: |
/env/bin/python scripts/check-event-schema-examples.py
python scripts/check-openapi-sources.py
check-schemas-examples:
name: "🔎 Check JSON Schemas inline examples"
runs-on: ubuntu-latest
steps:
- name: "📥 Source checkout"
uses: actions/checkout@v4
- name: " Setup Python"
uses: actions/setup-python@v5
with:
python-version: '3.9'
cache: 'pip'
cache-dependency-path: scripts/requirements.txt
- name: " Install dependencies"
run: |
pip install -r scripts/requirements.txt
- name: "🔎 Run validator"
run: |
python scripts/check-json-schemas.py
calculate-baseurl:
name: "⚙️ Calculate baseURL for later jobs"
runs-on: ubuntu-latest
@ -60,41 +99,60 @@ jobs:
# the asterisk matching behaviour, not the literal string.
run: |
if [ "${GITHUB_EVENT_NAME}" == "pull_request" ]; then
echo ::set-output name=baseURL::/
echo "baseURL=/" >> "$GITHUB_OUTPUT"
elif [[ "${GITHUB_REF}" == refs/tags/* ]]; then
echo ::set-output name=baseURL::"/${GITHUB_REF/refs\/tags\//}"
echo "baseURL=/${GITHUB_REF/refs\/tags\//}" >> "$GITHUB_OUTPUT"
else
echo ::set-output name=baseURL::/unstable
echo "baseURL=/unstable" >> "$GITHUB_OUTPUT"
fi
build-openapi:
name: "🐍 Build OpenAPI definitions"
runs-on: ubuntu-latest
container: "python:3.9"
needs: [calculate-baseurl]
steps:
- name: "📥 Source checkout"
uses: actions/checkout@v2
- name: "📦 Asset creation"
uses: actions/checkout@v4
- name: " Setup Python"
uses: actions/setup-python@v5
with:
python-version: '3.9'
cache: 'pip'
cache-dependency-path: scripts/requirements.txt
- name: " Install dependencies"
run: |
python3 -m venv env && . env/bin/activate
pip install -r scripts/requirements.txt
- name: "📦 Asset creation"
run: |
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
export RELEASE="${GITHUB_REF/refs\/tags\//}"
else
export RELEASE="unstable"
fi
# The output path matches the final deployment path at spec.matrix.org
scripts/dump-swagger.py \
scripts/dump-openapi.py \
--base-url "https://spec.matrix.org${{ needs.calculate-baseurl.outputs.baseURL }}" \
--api application-service \
-r "$RELEASE" \
-o spec/application-service-api/api.json
scripts/dump-swagger.py \
scripts/dump-openapi.py \
--base-url "https://spec.matrix.org${{ needs.calculate-baseurl.outputs.baseURL }}" \
--api client-server \
-r "$RELEASE" \
-o spec/client-server-api/api.json
scripts/dump-swagger.py \
scripts/dump-openapi.py \
--base-url "https://spec.matrix.org${{ needs.calculate-baseurl.outputs.baseURL }}" \
--api push-gateway \
-r "$RELEASE" \
-o spec/push-gateway-api/api.json
scripts/dump-openapi.py \
--base-url "https://spec.matrix.org${{ needs.calculate-baseurl.outputs.baseURL }}" \
--api server-server \
-r "$RELEASE" \
-o spec/server-server-api/api.json
tar -czf openapi.tar.gz spec
- name: "📤 Artifact upload"
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: openapi-artifact
path: openapi.tar.gz
@ -106,15 +164,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: "📥 Source checkout"
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: " Setup Python"
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.9'
- name: " Install towncrier"
run: "pip install 'towncrier'"
- name: "Generate changelog"
run: ./scripts/generate-changelog.sh vUNSTABLE
- name: "📤 Artifact upload"
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: changelog-artifact
path: content/changelog/vUNSTABLE.md
@ -127,23 +187,23 @@ jobs:
if: ${{ always() }}
steps:
- name: " Setup Node"
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: '14'
node-version: '20'
- name: " Setup Hugo"
uses: peaceiris/actions-hugo@c03b5dbed22245418539b65eb9a3b1d5fdd9a0a6
uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3.0.0
with:
hugo-version: '0.93.3'
hugo-version: '0.113.0'
extended: true
- name: "📥 Source checkout"
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: "⚙️ npm"
run: |
npm i
npm run get-proposals
- name: "📥 Download generated changelog"
if: "needs.generate-changelog.result == 'success'"
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: changelog-artifact
path: content/changelog
@ -154,7 +214,7 @@ jobs:
# https://spec.matrix.org/latest/client-server-api/api.json
# Works for /unstable/ and /v1.1/ as well.
- name: "📥 Spec definition download"
uses: actions/download-artifact@v2
uses: actions/download-artifact@v4
with:
name: openapi-artifact
- name: "📝 Unpack the OpenAPI definitions in the right location"
@ -164,7 +224,7 @@ jobs:
- name: "📦 Tarball creation"
run: tar -czf spec.tar.gz spec
- name: "📤 Artifact upload"
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: spec-artifact
path: spec.tar.gz
@ -175,10 +235,10 @@ jobs:
needs: [calculate-baseurl, build-spec]
steps:
- name: "📥 Source checkout"
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: "📥 Fetch built spec"
uses: actions/download-artifact@v2
uses: actions/download-artifact@v4
with:
name: spec-artifact
@ -204,16 +264,17 @@ jobs:
if: ${{ startsWith(github.ref, 'refs/tags/') }}
steps:
- name: " Setup Node"
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: '14'
node-version: '20'
- name: " Setup Hugo"
uses: peaceiris/actions-hugo@c03b5dbed22245418539b65eb9a3b1d5fdd9a0a6
uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3.0.0
with:
hugo-version: '0.93.3'
# Cannot build the spec with Hugo 0.125.0 because of https://github.com/google/docsy/issues/1930
hugo-version: '0.124.1'
extended: true
- name: "📥 Source checkout"
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: "⚙️ npm"
run: |
npm i
@ -225,7 +286,7 @@ jobs:
hugo --config config.toml,historical.toml --baseURL "/${GITHUB_REF/refs\/tags\//}" -d "spec"
- name: "📥 Spec definition download"
uses: actions/download-artifact@v2
uses: actions/download-artifact@v4
with:
name: openapi-artifact
- name: "📝 Unpack the OpenAPI definitions in the right location"
@ -235,7 +296,7 @@ jobs:
- name: "📦 Tarball creation"
run: tar -czf spec-historical.tar.gz spec
- name: "📤 Artifact upload"
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: spec-historical-artifact
path: spec-historical.tar.gz

@ -32,10 +32,10 @@ jobs:
pr_number=$(curl -H 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' "$pulls_uri" |
jq -r '.[] | .number')
echo "PR number: $pr_number"
echo "::set-output name=prnumber::$pr_number"
echo "prnumber=$pr_number" >> "$GITHUB_OUTPUT"
- name: '📥 Download artifact'
uses: dawidd6/action-download-artifact@af92a8455a59214b7b932932f2662fdefbd78126 # v2.15.0
uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe # v3.1.4
with:
workflow: main.yaml
run_id: ${{ github.event.workflow_run.id }}
@ -46,8 +46,7 @@ jobs:
- name: "📤 Deploy to Netlify"
id: netlify
# v1.2.2
uses: nwtgck/actions-netlify@f517512ae75beec8896aa7b027c1c72f01816200
uses: nwtgck/actions-netlify@4cbaf4c08f1a7bfa537d6113472ef4424e4eb654 # v3.0.0
with:
publish-dir: spec
deploy-message: "Deploy from GitHub Actions"

@ -0,0 +1,42 @@
name: Release packages
on:
release:
types: [published]
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
# Releases to npm after bumping the package.json version from 0.0.0 to $TAG.0 as the tags only contain MAJOR.MINOR
npm:
name: Publish to npm
runs-on: ubuntu-latest
if: github.event.release.prerelease == false
defaults:
run:
working-directory: packages/npm
steps:
- name: 🧮 Checkout code
uses: actions/checkout@v4
- name: 🔧 Yarn cache
uses: actions/setup-node@v4
with:
cache: "yarn"
cache-dependency-path: packages/npm/yarn.lock
registry-url: "https://registry.npmjs.org"
- name: 🔨 Install dependencies
run: "yarn install --frozen-lockfile"
# We bump the package.json version to git, we just need it for publish to do the right thing
- name: 🎖 Bump package.json version
run: "yarn version --new-version ${VERSION#v} --no-git-tag-version"
env:
VERSION: ${{ github.event.release.tag_name }}.0
- name: 🚀 Publish to npm
id: npm-publish
uses: JS-DevTools/npm-publish@19c28f1ef146469e409470805ea4279d47c3d35c # v3.1.1
with:
token: ${{ secrets.NPM_TOKEN }}
package: packages/npm
access: public
ignore-scripts: false

@ -11,9 +11,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Actions Repository
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Check spelling of proposals
uses: crate-ci/typos@9be36f97fdbe645ee9a12449fb13aca856c2516a
uses: crate-ci/typos@f2c1f08a7b3c1b96050cb786baaa2a94797bdb7d # v1.20.10
with:
config: ${{github.workspace}}/.github/_typos.toml
config: ${{github.workspace}}/.github/_typos.toml

2
.gitignore vendored

@ -2,7 +2,7 @@ node_modules
/data/msc
/env*
/resources
/scripts/swagger
/scripts/openapi
/scripts/tmp
/hugo-config.toml
/public

4
.gitmodules vendored

@ -1,4 +0,0 @@
[submodule "themes/docsy"]
path = themes/docsy
url = https://github.com/matrix-org/docsy.git
branch = master

@ -12,7 +12,7 @@ The documentation style is described at
https://github.com/matrix-org/matrix-spec/blob/main/meta/documentation_style.rst.
Matrix-spec workflows
--------------------
---------------------
Specification changes
~~~~~~~~~~~~~~~~~~~~~
@ -72,7 +72,7 @@ ask.
Adding to the changelog
~~~~~~~~~~~~~~~~~~~~~~~
All API specifications require a changelog entry. Adding to the changelog can only
All changes to the contents of this repository 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/twisted/towncrier>`_ in the
@ -117,7 +117,7 @@ license - in our case, this is Apache Software License v2 (see LICENSE).
In order to have a concrete record that your contribution is intentional
and you agree to license it under the same terms as the project's license, we've adopted the
same lightweight approach used by the `Linux Kernel <https://www.kernel.org/doc/html/latest/process/submitting-patches.html>`_,
`Docker <https://github.com/docker/docker/blob/master/CONTRIBUTING.md`_, and many other
`Docker <https://github.com/docker/docker/blob/master/CONTRIBUTING.md>`_, and many other
projects: the `Developer Certificate of Origin <http://developercertificate.org/>`_
(DCO). This is a simple declaration that you wrote
the contribution or otherwise have the right to contribute it to Matrix::
@ -167,3 +167,15 @@ include the line in your commit or pull request comment::
can't be accepted. Git makes this trivial - just use the -s flag when you do
``git commit``, having first set ``user.name`` and ``user.email`` git configs
(which you should have done anyway :)
Private sign off
~~~~~~~~~~~~~~~~
If you would like to provide your legal name privately to the Matrix.org
Foundation (instead of in a public commit or comment), you can do so by emailing
your legal name and a link to the pull request to dco@matrix.org. It helps to
include "sign off" or similar in the subject line. You will then be instructed
further.
Once private sign off is complete, doing so for future contributions will not
be required.

@ -1,6 +1,6 @@
# Matrix Specification
This repository contains the Matrix Specification, rendered at [spec.matrix.org](http://spec.matrix.org/).
This repository contains the Matrix Specification. The current release version is rendered at https://spec.matrix.org, while the latest available build of the `main` branch is at https://spec.matrix.org/unstable.
Developers looking to use Matrix should join [#matrix-dev:matrix.org](https://matrix.to/#/#matrix-dev:matrix.org)
on Matrix for help.
@ -22,7 +22,7 @@ The Matrix spec is compiled with [Hugo](https://gohugo.io/) (a static site gener
* `/data`: this can contain TOML, YAML, or JSON files. Files kept here are directly available to template code as
[data objects](https://gohugo.io/templates/data-templates/), so templates don't need to load them from a file and
parse them. This is also where our Swagger/OpenAPI definitions and schemas are.
parse them. This is also where our OpenAPI definitions and schemas are.
* `/layouts`: this contains [Hugo templates](https://gohugo.io/templates/). Some templates define the overall layout of
a page: for example, whether it has header, footer, sidebar, and so on.
@ -52,6 +52,7 @@ Additionally, the following directories may be of interest:
* `/data-definitions`: Bits of structured data consumable by Matrix implementations.
* `/meta`: Documentation relating to the spec's processes that are otherwise untracked (release instructions, etc).
* `/scripts`: Various scripts for generating the spec and validating its contents.
* `/packages`: Various packages for shipping spec files like OpenAPI bindings and data definitions.
## Authoring changes to the spec
@ -60,13 +61,12 @@ place after an MSC has been accepted, not as part of a proposal itself.
1. Install the extended version (often the OS default) of Hugo:
<https://gohugo.io/getting-started/installing>. Note that at least Hugo
v0.93.0 is required.
v0.113.0 is required.
Alternatively, use the Docker image at
https://hub.docker.com/r/klakegg/hugo/. (The "extended edition" is required
to process the SCSS.)
2. Run `npm i` to install the dependencies and fetch the docsy git submodule.
Note that this will require NodeJS to be installed.
2. Run `npm i` to install the dependencies. Note that this will require NodeJS to be installed.
3. Run `npm run get-proposals` to seed proposal data. This is merely for populating the content of the "Spec Change Proposals"
page and is not required.
4. Run `hugo serve` (or `docker run --rm -it -v $(pwd):/src -p 1313:1313
@ -86,13 +86,13 @@ steps for authoring changes to the specification and instead of `hugo serve` run
spec to `/spec`. If you'd like to serve the spec off a path instead of a domain root (eg: `/unstable`), add `--baseURL "/unstable"`
to the `hugo -d "spec"` command.
For building the swagger definitions, create a python3 virtualenv and activate it. Then run `pip install -r ./scripts/requirements.txt`
and finally `python ./scripts/dump-swagger.py` to generate it to `./scripts/swagger/api-docs.json`. To make use of the generated file,
For building the OpenAPI definitions, create a python3 virtualenv and activate it. Then run `pip install -r ./scripts/requirements.txt`
and finally `python ./scripts/dump-openapi.py` to generate it to `./scripts/openapi/api-docs.json`. To make use of the generated file,
there are a number of options:
* You can open `./scripts/swagger-preview.html` in your browser, and then open the file by clicking on `Local JSON File`.
* You can run a local HTTP server by running `./scripts/swagger-http-server.py`, and then view the documentation by
opening `./scripts/swagger-preview.html` in your browser.
* You can open `./scripts/openapi-preview.html` in your browser, and then open the file by clicking on `Local JSON File`.
* You can run a local HTTP server by running `./scripts/openapi-http-server.py`, and then view the documentation by
opening `./scripts/openapi-preview.html` in your browser.
## Issue tracking

@ -18,9 +18,6 @@ limitations under the License.
Custom SCSS for the Matrix spec
*/
@import "variables_project";
@import "variables";
/* Import the CSS classes for the syntax highlighter.
*
* This is generated with:
@ -43,10 +40,17 @@ Custom SCSS for the Matrix spec
.navbar-brand {
font-size: 1.1rem;
/* Allow the text to wrap if it is wider than the viewport */
text-align: center;
white-space: normal;
.navbar-version {
color: $secondary;
}
}
.nav-link {
font-weight: normal;
}
a {
@ -68,9 +72,8 @@ Custom SCSS for the Matrix spec
margin-top: 1rem;
}
&>.td-sidebar-nav__section > li > a.td-sidebar-link {
font-weight: $font-weight-bold;
font-size: 1.3rem;
.td-sidebar-nav__section .ul-1 ul {
padding-left: 0;
}
/* This is to make the width of the items that have sub-items (like room versions)
@ -79,12 +82,20 @@ Custom SCSS for the Matrix spec
padding-right: 0 !important;
}
a.indent-1 {
.ul-1 > li > a {
padding-left: 1rem !important;
}
a.indent-2 {
padding-left: 2rem;
.ul-2 > li > a {
padding-left: 2rem !important;
}
a.td-sidebar-link.tree-root {
color: $gray-800;
font-weight: $font-weight-bold;
font-size: 1.3rem;
margin-bottom: 0;
border-bottom: none;
}
a, a.td-sidebar-link {
@ -103,12 +114,11 @@ Custom SCSS for the Matrix spec
&.active, &active:hover {
background-color: $secondary-background;
font-weight: $font-weight-normal;
}
}
}
@media (min-width: 768px) {
@include media-breakpoint-up(md) {
@supports (position: sticky) {
.td-sidebar-nav {
/* This overrides calc(100vh - 10rem);, which gives us a blank space at the bottom of the sidebar */
@ -165,6 +175,13 @@ footer {
}
/* Remove some padding before the main content, when the sidebar is disabled */
.td-main main {
@include media-breakpoint-down(md) {
padding-top: 0;
}
}
/* Adjust the scroll margin for everything in the main content, so that
* it doesn't disappear behind the header bar */
.td-content * {
@ -286,18 +303,22 @@ footer {
}
/* Styles for sections that are rendered from data, such as HTTP APIs and event schemas */
.rendered-data {
.td-content .rendered-data {
background-color: $secondary-lightest-background;
padding: 1rem;
margin: 1rem 0;
padding: 0.85rem;
margin: 0.85rem 0;
details {
summary {
padding: .5rem 0;
p {
max-width: 80%;
h1 {
margin: 0;
/* Ensure the disclosure control is vertically centred with the header text. */
vertical-align: middle;
}
}
p {
max-width: 80%;
}
}
.deprecated-inline {
@ -336,23 +357,41 @@ footer {
}
p code, table code {
background-color: inherit;
background-color: transparent;
}
table {
/* Docsy makes all tables "responsive tables", which causes Bootstrap 4 to create
* tables with a "display" property of "block".
*
* However, for "table-layout: fixed" to be effective, an element must have a
* "display" property of "table".
*
* Thus, we override the "display" property here. This may no longer be necessary once
* Docsy updates to Bootstrap v5+: https://github.com/google/docsy/issues/470.
* For more details, see
* https://github.com/matrix-org/matrix-spec/pull/1295/files#r1010759688 */
display: table;
table-layout: fixed;
width: 100%;
@media (max-width: 800px) {
/* Docsy by default applies `overflow-x: auto;` to tables, which
* results in annoying horizontal scrolling on mobile, so we instead
* switch to a fixed table layout on a narrow browser width.
* (On a wider width the default auto table-layout provides better readability.)
*
* Docsy makes all tables "responsive tables", which causes Bootstrap 4 to create
* tables with a "display" property of "block".
* However, for "table-layout: fixed" to be effective, an element must have a
* "display" property of "table".
*
* Thus, we override the "display" property here. This may no longer be necessary once
* Docsy updates to Bootstrap v5+: https://github.com/google/docsy/issues/470.
* For more details, see
* https://github.com/matrix-org/matrix-spec/pull/1295/files#r1010759688 */
display: table;
table-layout: fixed;
width: 100%;
.col-name, .col-type, .col-status {
width: 25%;
}
.col-description {
width: 50%;
}
.col-status-description {
width: 75%;
}
}
// add some space between two tables when they are right next to each other
& + table {
@ -368,9 +407,10 @@ footer {
th, td, caption {
padding: 1rem;
border-top: 1px $table-border-color solid;
}
&.object-table, &.response-table {
&.object-table, &.response-table, &.content-type-table {
border: 1px $table-border-color solid;
caption {
@ -380,14 +420,12 @@ footer {
// ... but avoid double border between caption and table
border-bottom: 0;
}
caption, tbody tr {
background-color: $table-row-default;
background-color: $secondary-lighter-background;
}
tbody tr:nth-child(even) {
background-color: $table-row-alternate;
tbody tr {
--bs-table-striped-bg: #{$secondary-lighter-background};
}
}
@ -400,18 +438,30 @@ footer {
width: 15rem;
}
.col-name, .col-type, .col-status {
width: 25%;
}
/* Arrange rows vertically when horizontal space is constrained to avoid overflowing */
@include media-breakpoint-down(sm) {
/* Make cells full width without vertical margin */
&.basic-info th, &.basic-info td {
width: 100%;
display: inline-block;
margin-top: 0;
margin-bottom: 0;
}
.col-description {
width: 50%;
}
/* Remove border and padding between header & data cells to make them appear like a single cell */
&.basic-info td {
padding-top: 0;
border-top: none;
}
&.basic-info th {
border-bottom: none;
}
.col-status-description {
width: 75%;
/* Remove top border on all but the first header cell to prevent double borders between rows */
&.basic-info tr + tr th {
border-top: none;
}
}
}
pre {
@ -456,12 +506,18 @@ of .td-content. This applies the same style to any blockquotes that descend from
Make padding symmetrical (this selector is used in the default styles to apply padding-left: 3rem)
*/
.pl-md-5, .px-md-5 {
padding-right: 3rem;
@include media-breakpoint-up(md) {
padding-right: 3rem;
}
}
/* Adjust default styles for info banner */
.pageinfo-primary {
max-width: 80%;
@include media-breakpoint-up(lg) {
max-width: 80%;
}
margin-top: 0;
margin-right: 0;
margin-left: 0;
border: 0;
border-left: solid 5px $secondary;
@ -473,4 +529,44 @@ Make padding symmetrical (this selector is used in the default styles to apply p
background-position: left 1rem center;
background-repeat: no-repeat;
padding-left: 100px;
}
/* Adjust the styling of definition lists. */
/* Add a little spacing between the term and its definition. */
dt {
margin-bottom: 0.15rem;
}
/* _reboot.scss deliberately sets margin-left to 0. Undo this. */
dd {
margin-left: 2rem;
}
/* docsy's _code.scss does only styles <code> elements matching
* .td-content { p code, li > code, table code }.
* Copy those styles here to apply to code <elements> in definition terms too. */
.td-content {
dt code {
color: inherit;
padding: 0.2em 0.4em;
margin: 0;
font-size: 85%;
word-break: normal;
background-color: rgba($black, 0.05);
border-radius: 0.25rem; // was $border-radius, but that var isn't accessible here.
}
}
/* Style for breadcrumbs */
.td-breadcrumbs {
padding: .75rem 1rem;
background-color: #eee;
border-radius: .25rem;
margin-bottom: 1rem;
.breadcrumb {
margin: 0;
}
}

@ -20,7 +20,7 @@ $dark: #333;
$gray-100: #FBFBFB;
$secondary-background: #E5F5FB;
$secondary-lighter-background: #F4FaFC;
$secondary-lighter-background: #F4FAFC;
$secondary-lightest-background: #FBFDFD;
@ -33,20 +33,22 @@ $warning-background: #FFE0E0;
// colours for definition tables.
// the border colour matches that used for "highlight" divs
$table-border-color: rgba(black, .125);
$table-row-alternate: $secondary-lightest-background;
$table-row-default: $secondary-lighter-background;
$table-bg: $secondary-lightest-background;
/* Configure docsy to use the default system fonts instead of Google Fonts.
* See https://www.docsy.dev/docs/adding-content/lookandfeel/#fonts */
$td-enable-google-fonts: false;
/*
* Replace the default font with Inter - we load it from a local copy, which is downloaded from
* Google Fonts manually via a script:
* https://github.com/matrix-org/matrix-spec/tree/main/static/css/fonts
* Replace the default font with Inter.
*
* The $font-family-sans-serif definition here overrides the default value set by docsy:
* https://github.com/matrix-org/docsy/blob/66a4e61d2d34edc7196b9df83a7d09cd4af14b47/assets/scss/_variables.scss#L68
* and adds "Inter" to the front. */
@import url("../css/fonts/Inter.css");
$font-family-sans-serif: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
* and adds "Inter" to the front.
*
* The font itself is loaded via stylesheet link layouts/partials/hooks/head-end.html.
*/
$font-family-sans-serif: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
// Disable smooth scrolling as it makes TOC highlighting jump during the transition.
$enable-smooth-scroll: false;

@ -246,7 +246,7 @@ anyway.
In this arrangement there is now a room with both users may join but neither has
the power to invite any others. Both users now have the confidence that (at
least within the messaging system itself) their messages remain private and
cannot later be provably leaked to a third party. They can freely set the topic
cannot later be provably leaked to a third-party. They can freely set the topic
or name if they choose and add or edit any other state of the room. The update
powerlevel of each of these fixed properties should be 1, to lock out the users
from being able to alter them.

@ -1,9 +1,9 @@
======================
Third Party Identities
Third-party Identities
======================
A description of how email addresses, mobile phone numbers and other third
party identifiers can be used to authenticate and discover users in Matrix.
A description of how email addresses, mobile phone numbers and other third-party
identifiers can be used to authenticate and discover users in Matrix.
Overview
@ -15,16 +15,16 @@ and phone numbers for contacts in their address book. They want to communicate
with those contacts in Matrix without manually exchanging a Matrix User ID with
them.
Third Party IDs
Third-party IDs
---------------
[[TODO(markjh): Describe the format of a 3PID]]
Third Party ID Associations
Third-party ID Associations
---------------------------
An Associaton is a binding between a Matrix User ID and a Third Party ID (3PID).
An Associaton is a binding between a Matrix User ID and a Third-party ID (3PID).
Each 3PID can be associated with one Matrix User ID at a time.
[[TODO(markjh): JSON format of the association.]]

@ -0,0 +1 @@
Define 'Opaque Identifier Grammar'.

@ -0,0 +1 @@
Define common cryptographic key representation.

@ -0,0 +1 @@
Fix the OpenAPI definition of the security schemes.

@ -0,0 +1 @@
Clarify that appservices should be notified of events relating to the sender_localpart user.

@ -0,0 +1 @@
Add support for muting in VoIP calls, as per [MSC3291](https://github.com/matrix-org/matrix-spec-proposals/pull/3291).

@ -0,0 +1 @@
Add optional `animated` query string option to `GET /_matrix/media/v3/thumbnail`, as per [MSC2705](https://github.com/matrix-org/matrix-spec-proposals/pull/2705).

@ -0,0 +1 @@
Fix the OpenAPI definition of the security schemes.

@ -0,0 +1 @@
Clarify that the `type` of the `POST /login` request must be one of the types returned by the `GET /login` response.

@ -0,0 +1 @@
Deprecate authentication via a query string, as per [MSC4126](https://github.com/matrix-org/matrix-spec-proposals/issues/4126).

@ -0,0 +1 @@
Specify terms of services at registration, as per [MSC1692](https://github.com/matrix-org/matrix-spec-proposals/pull/1692).

@ -0,0 +1 @@
Use `patternProperties` in more places with supported formats.

@ -0,0 +1 @@
Rename "recovery key" to "backup decryption key".

@ -0,0 +1 @@
Fix the OpenAPI definition of the security schemes.

@ -0,0 +1 @@
Deprecate authentication via a query string, as per [MSC4126](https://github.com/matrix-org/matrix-spec-proposals/issues/4126).

@ -0,0 +1 @@
Fix npm release script for `@matrix-org/spec`.

@ -0,0 +1 @@
Formatting fixes in CONTRIBUTING.rst.

@ -0,0 +1 @@
Reduce whitespace on mobile viewports

@ -0,0 +1 @@
Arrange rows in `.basic-info` tables vertically when horizontal space is constrained.

@ -0,0 +1 @@
Simplify uses of `resolve-refs` partial.

@ -0,0 +1 @@
Upgrade jsonschema and python-jsonpath CI scripts dependencies.

@ -0,0 +1 @@
Solve `allOf` recursively in OpenAPI and JSON Schemas.

@ -0,0 +1 @@
Fix property type resolution in `render-object-table` partial.

@ -0,0 +1 @@
Factor out common definition of `Tag` type.

@ -0,0 +1 @@
Update the version of Hugo used to render the spec to v0.124.1.

@ -0,0 +1 @@
Add support for pattern formats for `patternProperties`.

@ -0,0 +1 @@
Clean up unnecessary `allOf`s in OpenAPI definitions.

@ -0,0 +1 @@
Show information about "Additional Properties" in object tables.

@ -0,0 +1 @@
Fix anchors for schemas under `oneOf`.

@ -0,0 +1 @@
Use reference to `OneTimeKeys` schema in OpenAPI definitions.

@ -0,0 +1 @@
Do not use the `title` of objects containing only `additionalProperties` or `patternProperties`.

@ -0,0 +1 @@
Add anchors in `definition` shortcode.

@ -0,0 +1 @@
Set python version for the Towncrier CI job.

@ -0,0 +1 @@
Replace `set-output` with environment files in CI.

@ -0,0 +1 @@
Add support for rendering string formats.

@ -22,5 +22,5 @@ r0.1.0
This is the first release of the Application Service specification. It
includes support for application services being able to interact with
homeservers and bridge third party networks, such as IRC, over to Matrix
homeservers and bridge third-party networks, such as IRC, over to Matrix
in a standard and accessible way.

@ -211,7 +211,7 @@ Backwards Compatible Changes
- Add a common standard for user, room, and group mentions in messages. (`#1547 <https://github.com/matrix-org/matrix-doc/issues/1547>`_)
- Add server ACLs as an option for controlling federation in a room. (`#1550 <https://github.com/matrix-org/matrix-doc/issues/1550>`_)
- Add new push rules for encrypted events and ``@room`` notifications. (`#1551 <https://github.com/matrix-org/matrix-doc/issues/1551>`_)
- Add third party network room directories, as provided by application services. (`#1554 <https://github.com/matrix-org/matrix-doc/issues/1554>`_)
- Add third-party network room directories, as provided by application services. (`#1554 <https://github.com/matrix-org/matrix-doc/issues/1554>`_)
- Document the ``validated_at`` and ``added_at`` fields on ``GET /acount/3pid``. (`#1567 <https://github.com/matrix-org/matrix-doc/issues/1567>`_)
- Add an ``inhibit_login`` registration option. (`#1589 <https://github.com/matrix-org/matrix-doc/issues/1589>`_)
- Recommend that servers set a Content Security Policy for the content repository. (`#1600 <https://github.com/matrix-org/matrix-doc/issues/1600>`_)
@ -554,7 +554,7 @@ Since the draft stage, the following major changes have been made:
- Push notification
- History visibility
- Search
- Invites based on third party identifiers
- Invites based on third-party identifiers
- Room tagging
- Guest access
- Client config

@ -48,7 +48,7 @@ r0.1.0
======
This is the first release of the Identity Service API. With this API, clients and
homeservers can store bindings between third party identifiers such as email addresses
homeservers can store bindings between third-party identifiers such as email addresses
and phone numbers, associating them with Matrix user IDs. Additionally, identity
servers offer the ability to invite third party users to Matrix rooms by storing
servers offer the ability to invite third-party users to Matrix rooms by storing
the invite until the identifier is bound.

@ -1,39 +1,66 @@
[tool.towncrier]
version = "unused"
filename = "../rendered.md"
issue_format = "[#{issue}](https://github.com/matrix-org/matrix-spec/issues/{issue})"
title_format = "### {name}" # Matches rendered spec, even if awkward
underlines = " " # 3 spaces intentionally to hide RST headings
# Note: The names below have the <strong> tag built-in so the rendered spec *and* the generated
# changelog can benefit from sane headings.
filename = "rendered.md"
template = "template.md.jinja"
[[tool.towncrier.type]]
directory = "breaking"
name = "<strong>Breaking Changes</strong>"
name = "Breaking Changes"
showcontent = true
[[tool.towncrier.type]]
directory = "deprecation"
name = "<strong>Deprecations</strong>"
name = "Deprecations"
showcontent = true
[[tool.towncrier.type]]
directory = "new"
name = "<strong>New Endpoints</strong>"
name = "New Endpoints"
showcontent = true
[[tool.towncrier.type]]
directory = "removal"
name = "<strong>Removed Endpoints</strong>"
name = "Removed Endpoints"
showcontent = true
[[tool.towncrier.type]]
directory = "feature"
name = "<strong>Backwards Compatible Changes</strong>"
name = "Backwards Compatible Changes"
showcontent = true
[[tool.towncrier.type]]
directory = "clarification"
name = "<strong>Spec Clarifications</strong>"
name = "Spec Clarifications"
showcontent = true
[[tool.towncrier.section]]
name = "Client-Server API"
path = "client_server"
[[tool.towncrier.section]]
name = "Server-Server API"
path = "server_server"
[[tool.towncrier.section]]
name = "Application Service API"
path = "application_service"
[[tool.towncrier.section]]
name = "Identity Service API"
path = "identity_service"
[[tool.towncrier.section]]
name = "Push Gateway API"
path = "push_gateway"
[[tool.towncrier.section]]
name = "Room Versions"
path = "room_versions"
[[tool.towncrier.section]]
name = "Appendices"
path = "appendices"
[[tool.towncrier.section]]
name = "Internal Changes/Tooling"
path = "internal"

@ -0,0 +1 @@
Fix the OpenAPI definition of the security schemes.

@ -0,0 +1 @@
Use `patternProperties` in more places with supported formats.

@ -0,0 +1 @@
Clarify that whitespace around commas is allowed in the `X-Matrix` `Authorization` header value params list.

@ -0,0 +1,24 @@
{% for section_name, section in sections.items() %}
{% if section_name %}
### {{section_name}}
{% endif %}
{% if section %}
{% for category, val in definitions.items() if category in section %}
**{{ definitions[category]['name'] }}**
{% for content, issues in section[category].items() %}
- {{ content }} (
{%- for issue in issues %}
[{{issue}}](https://github.com/matrix-org/matrix-spec/issues/{{issue|trim('#')}}){% if not loop.last %}, {% endif %}
{%- endfor %}
)
{% endfor %}
{% endfor %}
{% else %}
No significant changes.
{% endif %}
{% endfor %}

@ -7,21 +7,34 @@ canonifyURLs = true
enableRobotsTXT = true
# Hugo allows theme composition (and inheritance). The precedence is from left to right.
theme = ["docsy"]
# We disable RSS, because (a) it's useless, (b) Hugo seems to generate broken
# links to it when used with a --baseURL (for example, https://spec.matrix.org/v1.4/
# contains `<link rel="alternate" type="application/rss&#43;xml" href="/v1.4/v1.4/index.xml">`).
disableKinds = ["taxonomy", "taxonomyTerm", "RSS"]
disableKinds = ["taxonomy", "RSS"]
[languages]
[languages.en]
title = "Matrix Specification"
description = "Home of the Matrix specification for decentralised communication"
languageName ="English"
# Weight used for sorting.
weight = 1
[languages.en.params]
description = "Home of the Matrix specification for decentralised communication"
# Entries in the main menu in the header.
[menus]
[[menus.main]]
name = 'Foundation'
url = 'https://matrix.org/foundation/'
weight = 10
[[menus.main]]
name = 'FAQs'
url = 'https://matrix.org/faq'
weight = 20
[[menus.main]]
name = 'Blog'
url = 'https://matrix.org/blog/posts'
weight = 30
[markup]
[markup.goldmark]
@ -47,14 +60,14 @@ privacy_policy = "https://matrix.org/legal/privacy-notice"
[params.version]
# must be one of "unstable", "current", "historical"
# this is used to decide whether to show a banner pointing to the current release
status = "stable"
status = "unstable"
# A URL pointing to the latest, stable release of the spec. To be shown in the unstable version warning banner.
current_version_url = "https://spec.matrix.org/latest"
# The following is used when status = "stable", and is displayed in various UI elements on a released version
# of the spec. CI will set these values here automatically when a release git tag (i.e `v1.5`) is created.
major = "1"
minor = "5"
release_date = "November 17, 2022"
# major = "1"
# minor = "10"
# release_date = "March 22, 2024"
# User interface configuration
[params.ui]
@ -62,6 +75,10 @@ release_date = "November 17, 2022"
footer_about_disable = false
# Collapse HTTP API and event <details> elements
rendered_data_collapsed = false
# Hide the search entry in the sidebar
sidebar_search_disable = true
# Only show the current page's ancestors, siblings and direct descendants in the sidebar menu
sidebar_menu_compact = true
[params.links]
# End user relevant links. These will show up on left side of footer and in the community page if you have one.
@ -107,3 +124,13 @@ rendered_data_collapsed = false
X-Frame-Options = "sameorigin"
Access-Control-Allow-Origin = "*"
Access-Control-Allow-Methods = "GET"
# hugo module configuration
[module]
[module.hugoVersion]
extended = true
min = "0.113.0"
[[module.imports]]
path = "github.com/matrix-org/docsy"
disable = false

@ -357,8 +357,8 @@ servers that are in the room that can be used to join via.
HTTP GET
#matrix:example.org !aaabaa:matrix.org
| ^
| |
| ^
| |
_______V____________________|____
| example.org |
| Mappings: |
@ -372,7 +372,7 @@ servers that are in the room that can be used to join via.
Users in Matrix are identified via their Matrix user ID. However,
existing 3rd party ID namespaces can also be used in order to identify
Matrix users. A Matrix "Identity" describes both the user ID and any
other existing IDs from third party namespaces *linked* to their
other existing IDs from third-party namespaces *linked* to their
account. Matrix users can *link* third-party IDs (3PIDs) such as email
addresses, social network accounts and phone numbers to their user ID.
Linking 3PIDs creates a mapping from a 3PID to a user ID. This mapping
@ -419,9 +419,16 @@ 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".
Unless otherwise stated, timestamps are the number of milliseconds
elapsed since the unix epoch (1970-01-01 00:00:00 UTC), but not counting
leap seconds, so that each day is precisely 86,400,000 milliseconds.
This means that timestamps can repeat during leap seconds. Most
programming languages provide timestamps in that format natively, e.g.
[ECMAScript](https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-time-values-and-time-range).
Throughout the specification this may be referred to as POSIX,
[Unix](https://en.wikipedia.org/wiki/Unix_time), or just "time in
milliseconds".
## Specification Versions

@ -83,10 +83,15 @@ object.
### Canonical JSON
We define the canonical JSON encoding for a value to be the shortest
To ensure that all implementations use the same JSON encoding we define
"Canonical JSON". This should not be confused with other uses of
"Canonical JSON" outside of the specification.
We define this encoding for a value to be the shortest
UTF-8 JSON encoding with dictionary keys lexicographically sorted by
Unicode codepoint. Numbers in the JSON must be integers in the range
`[-(2**53)+1, (2**53)-1]`.
`[-(2**53)+1, (2**53)-1]`, represented without exponents or decimal
places, and negative zero `-0` MUST NOT appear.
We pick UTF-8 as the encoding as it should be available to all platforms
and JSON received from the network is likely to be already encoded using
@ -131,12 +136,12 @@ removing insignificant whitespace, fractions, exponents and redundant
character escapes.
value = false / null / true / object / array / number / string
false = %x66.61.6c.73.65
null = %x6e.75.6c.6c
false = %x66.61.6C.73.65
null = %x6E.75.6C.6C
true = %x74.72.75.65
object = %x7B [ member *( %x2C member ) ] %7D
object = %x7B [ member *( %x2C member ) ] %x7D
member = string %x3A value
array = %x5B [ value *( %x2C value ) ] %5B
array = %x5B [ value *( %x2C value ) ] %x5D
number = [ %x2D ] int
int = %x30 / ( %x31-39 *digit )
digit = %x30-39
@ -300,6 +305,21 @@ The following canonical JSON should be produced:
{"a":null}
```
Given the following JSON object:
```json
{
"a": -0,
"b": 1e10
}
```
The following canonical JSON should be produced:
```json
{"a":0,"b":10000000000}
```
### Signing Details
JSON is signed by encoding the JSON object without `signatures` or keys
@ -502,10 +522,9 @@ The sigil characters are as follows:
- `@`: User ID
- `!`: Room ID
- `$`: Event ID
- `+`: Group ID
- `#`: Room alias
User IDs, group IDs, room IDs, room aliases, and sometimes event IDs
User IDs, room IDs, room aliases, and sometimes event IDs
take the form:
&localpart:domain
@ -517,10 +536,12 @@ 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 sometimes
be represented with a `domain` component under some conditions - see the
[Event IDs](#room-ids-and-event-ids) section below for more information.
[Event IDs](#event-ids) section below for more information.
#### User Identifiers
{{% changed-in v="1.8" %}}
Users within Matrix are uniquely identified by their Matrix user ID. The
user ID is namespaced to the homeserver which allocated the account and
has the form:
@ -529,7 +550,7 @@ has the form:
The `localpart` of a user ID is an opaque identifier for that user. It
MUST NOT be empty, and MUST contain only the characters `a-z`, `0-9`,
`.`, `_`, `=`, `-`, and `/`.
`.`, `_`, `=`, `-`, `/`, and `+`.
The `domain` of a user ID is the [server name](#server-name) of the
homeserver which allocated the account.
@ -543,7 +564,7 @@ The complete grammar for a legal user ID is:
user_id_localpart = 1*user_id_char
user_id_char = DIGIT
/ %x61-7A ; a-z
/ "-" / "." / "=" / "_" / "/"
/ "-" / "." / "=" / "_" / "/" / "+"
{{% boxes/rationale %}}
A number of factors were considered when defining the allowable
@ -626,22 +647,19 @@ allowing representation of *any* character (unlike punycode, which
provides no way to encode ASCII punctuation).
{{% /boxes/rationale %}}
#### Room IDs and Event IDs
#### Room IDs
A room has exactly one room ID. A room ID has the format:
!opaque_id:domain
An event has exactly one event ID. The format of an event ID depends
upon the [room version specification](/rooms).
The `domain` of a room ID is the [server name](#server-name) of the
homeserver which created the room/event. The domain is used only for
homeserver which created the room. 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
different homeservers. There is no implication that the room in
question is still available at the corresponding homeserver.
Event IDs and Room IDs are case-sensitive. They are not meant to be
Room IDs are case-sensitive. They are not meant to be
human-readable. They are intended to be treated as fully opaque strings
by clients.
@ -658,7 +676,21 @@ homeserver to look up the alias.
Room aliases MUST NOT exceed 255 bytes (including the `#` sigil and the
domain).
#### URIs
#### Event IDs
An event has exactly one event ID. Event IDs take the form:
$opaque_id
However, the precise format depends upon the [room version
specification](/rooms): early room versions included a `domain` component,
whereas more recent versions omit the domain and use a base64-encoded hash instead.
Event IDs are case-sensitive. They are not meant to be human-readable. They are
intended to be treated as fully opaque strings by clients.
### URIs
There are two major kinds of referring to a resource in Matrix: matrix.to
and `matrix:` URI. The specification currently defines both as active/valid
@ -669,7 +701,7 @@ be used to reference particular objects in a given context, such as mentioning
a user in a message or linking someone to a particular point in the room's
history (a permalink).
##### Matrix URI scheme
#### Matrix URI scheme
{{% added-in v="1.2" %}}
@ -774,7 +806,7 @@ Examples of common URIs are:
A suggested client implementation algorithm is available in the
[original MSC](https://github.com/matrix-org/matrix-spec-proposals/blob/main/proposals/2312-matrix-uri.md#recommended-implementation).
##### matrix.to navigation
#### matrix.to navigation
{{% boxes/note %}}
This namespacing existed prior to a `matrix:` scheme. This is **not**
@ -789,7 +821,7 @@ defined in [RFC 3986](https://tools.ietf.org/html/rfc3986):
https://matrix.to/#/<identifier>/<extra parameter>?<additional arguments>
```
The identifier may be a room ID, room alias, user ID, or group ID. The
The identifier may be a room ID, room alias, or user 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.
@ -830,16 +862,15 @@ encoded when producing matrix.to URIs, however.
{{% /boxes/note %}}
{{% boxes/note %}}
<!-- TODO: @@TravisR: Make "Spaces" a link when that specification exists -->
In prior versions of this specification, a concept of "groups" were mentioned
to organize rooms. This functionality did not properly get introduced into
the specification and is subsequently replaced with "Spaces". Historical
the specification and is subsequently replaced with [Spaces](/client-server-api/#spaces). Historical
matrix.to URIs pointing to groups might still exist: they take the form
`https://matrix.to/#/%2Bexample%3Aexample.org` (where the `+` sigil may or
may not be encoded).
{{% /boxes/note %}}
##### Routing
#### 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
@ -890,9 +921,53 @@ unique servers based on the following criteria:
specify the servers it can. For example, a room with only 2 users in
it would result in maximum 2 `via` parameters.
### Opaque Identifiers
The specification defines some identifiers to use the *Opaque Identifier
Grammar*. This is a common grammar intended for non-user-visible identifiers
which do not require parsing or interpretation (other than as a unique
identifier).
The grammar is defined as:
* Identifiers must be entirely composed of the characters `[0-9]`, `[A-Z]`,
`[a-z]`, `-`, `.`, `_`, and `~`.
* Unless otherwise specified, identifiers must be at least one character and at
most 255 characters in length.
{{% boxes/note %}}
The acceptable character set matches the unreserved character set in [RFC
3986](https://datatracker.ietf.org/doc/html/rfc3986#section-2.3).
{{% /boxes/note %}}
## Cryptographic key representation
Sometimes it is necessary to present a private cryptographic key in the user
interface.
When this happens, the key SHOULD be presented as a string formatted as
follows:
1. A byte array is created, consisting of two bytes `0x8B` and `0x01`,
followed by the raw key.
2. All the bytes in the array above, including the two header bytes,
are XORed together to form a parity byte. This parity byte is
appended to the byte array.
3. The byte array is encoded using base58, using the the alphabet
`123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`.
4. A space is added after every 4th character.
When reading in a key, clients should disregard whitespace, and
perform the reverse of steps 1 through 4.
{{% boxes/note %}}
The base58 alphabet is the same as that used for [Bitcoin
addresses](https://en.bitcoin.it/wiki/Base58Check_encoding#Base58_symbol_chart).
{{% /boxes/note %}}
## 3PID Types
Third Party Identifiers (3PIDs) represent identifiers on other
Third-party Identifiers (3PIDs) represent identifiers on other
namespaces that might be associated with a particular person. They
comprise a tuple of `medium` which is a string that identifies the
namespace in which the identifier exists, and an `address`: a string
@ -934,6 +1009,30 @@ The `address` is the telephone number represented as a MSISDN (Mobile
Station International Subscriber Directory Number) as defined by the
E.164 numbering plan. Note that MSISDNs do not include a leading '+'.
## Glob-style matching
It is useful to match strings via globbing in some situations. Globbing in Matrix
uses the following rules:
* The character `*` matches zero or more characters.
* `?` matches exactly one character.
## Dot-separated property paths
It is useful to express the "path" to an event property by concatenating property
names with dots, e.g. `content.body` would represent a `body` property in the
event's `content`.
To handle ambiguity when a property name contains a dot, any literal dot or
backslash found in a property name should be escaped with a backslash. E.g. a
property `m.relates_to` in the `content` would be expressed as
`content.m\.relates_to`. Similarly, a `content` property named `m\foo` would be
expressed as `content.m\\foo`.
Other escape sequences are left as-is, e.g. a `\x` would be treated as a literal
backslash followed by 'x'. It is recommended that implementations do not redundantly
escape characters, as other escape sequences are reserved for future use.
## Security Threat Model
### Denial of Service

@ -164,6 +164,14 @@ each is as follows:
Homeservers should periodically try again for the newer endpoints
because the application service may have been updated.
#### Unknown routes
If a request for an unsupported (or unknown) endpoint is received then the server
must respond with a 404 `M_UNRECOGNIZED` error.
Similarly, a 405 `M_UNRECOGNIZED` error is used to denote an unsupported method
to a known endpoint.
#### Pushing events
The application service API provides a transaction API for sending a
@ -199,6 +207,54 @@ processed the events.
{{% http-api spec="application-service" api="transactions" %}}
#### Pinging
{{% added-in v="1.7" %}}
The application service API includes a ping mechanism to allow
appservices to ensure that the homeserver can reach the appservice.
Appservices may use this mechanism to detect misconfigurations and
report them appropriately.
Implementations using this mechanism should take care to not fail
entirely in the event of temporary issues, e.g. gracefully handling
cases where the appservice is started before the homeserver.
The mechanism works as follows (note: the human-readable `error` fields
have been omitted for brevity):
**Typical**
```
AS ---> HS : /_matrix/client/v1/appservice/{appserviceId}/ping {"transaction_id": "meow"}
HS ---> AS : /_matrix/app/v1/ping {"transaction_id": "meow"}
HS <--- AS : 200 OK {}
AS <--- HS : 200 OK {"duration_ms": 123}
```
**Incorrect `hs_token`**
```
AS ---> HS : /_matrix/client/v1/appservice/{appserviceId}/ping {"transaction_id": "meow"}
HS ---> AS : /_matrix/app/v1/ping {"transaction_id": "meow"}
HS <--- AS : 403 Forbidden {"errcode": "M_FORBIDDEN"}
AS <--- HS : 502 Bad Gateway {"errcode": "M_BAD_STATUS", "status": 403, "body": "{\"errcode\": \"M_FORBIDDEN\"}"}
```
**Can't connect to appservice**
```
AS ---> HS : /_matrix/client/v1/appservice/{appserviceId}/ping {"transaction_id": "meow"}
HS -/-> AS : /_matrix/app/v1/ping {"transaction_id": "meow"}
AS <--- HS : 502 Bad Gateway {"errcode": "M_CONNECTION_FAILED"}
```
The `/_matrix/app/v1/ping` endpoint is described here. The
[`/_matrix/client/v1/appservice/{appserviceId}/ping`](#post_matrixclientv1appserviceappserviceidping)
endpoint is under the Client-Server API extensions section below.
{{% http-api spec="application-service" api="ping" %}}
#### Querying
The application service API includes two querying APIs: for room aliases
@ -224,18 +280,18 @@ mappings.
{{% http-api spec="application-service" api="query_room" %}}
#### Third party networks
#### Third-party networks
Application services may declare which protocols they support via their
registration configuration for the homeserver. These networks are
generally for third party services such as IRC that the application
generally for third-party services such as IRC that the application
service is managing. Application services may populate a Matrix room
directory for their registered protocols, as defined in the
Client-Server API Extensions.
Each protocol may have several "locations" (also known as "third party
Each protocol may have several "locations" (also known as "third-party
locations" or "3PLs"). A location within a protocol is a place in the
third party network, such as an IRC channel. Users of the third party
third-party network, such as an IRC channel. Users of the third-party
network may also be represented by the application service.
Locations and users can be searched by fields defined by the application
@ -380,6 +436,21 @@ an application service-defined namespace will receive the same
`M_EXCLUSIVE` error code, but only if the application service has
defined the namespace as `exclusive`.
If `/register` or `/login` is called with the `m.login.application_service`
login type, but without a valid `as_token`, the endpoints will return an error
with the `M_MISSING_TOKEN` or `M_UNKNOWN_TOKEN` error code and 401 as the HTTP
status code. This is the same behavior as invalid auth in the client-server API
(see [Using access tokens](/client-server-api/#using-access-tokens)).
#### Pinging
{{% added-in v="1.7" %}}
This is the client-server API companion endpoint for the
[pinging](#pinging) mechanism described above.
{{% http-api spec="client-server" api="appservice_ping" %}}
#### Using `/sync` and `/events`
Application services wishing to use `/sync` or `/events` from the
@ -391,13 +462,13 @@ the user implied by `sender_localpart`.
#### Application service room directories
Application services can maintain their own room directories for their
defined third party protocols. These room directories may be accessed by
defined third-party protocols. These room directories may be accessed by
clients through additional parameters on the `/publicRooms`
client-server endpoint.
{{% http-api spec="client-server" api="appservice_room_directory" %}}
### Referencing messages from a third party network
### Referencing messages from a third-party network
Application services should include an `external_url` in the `content`
of events it emits to indicate where the message came from. This

@ -0,0 +1,102 @@
---
date: 2024-03-22T09:59:45-06:00
---
<!--
This is a header file for the generated changelog.
Variables:
v1.10 = Replaced by the version number (eg: v1.2)
March 22, 2024 = Replaced by the date (eg: April 01, 2021)
-->
## v1.10
<table class="release-info">
<tr><th>Git commit</th><td><a href="https://github.com/matrix-org/matrix-spec/tree/v1.10">https://github.com/matrix-org/matrix-spec/tree/v1.10</a></td>
<tr><th>Release date</th><td>March 22, 2024</td>
</table>
<!-- Intentionally blank line to ensure headers work in the concatenated changelog -->
### Client-Server API
**Backwards Compatible Changes**
- Allow `/versions` to optionally accept authentication, as per [MSC4026](https://github.com/matrix-org/matrix-spec-proposals/pull/4026). ([#1728](https://github.com/matrix-org/matrix-spec/issues/1728))
- Add local erasure requests, as per [MSC4025](https://github.com/matrix-org/matrix-spec-proposals/pull/4025). ([#1730](https://github.com/matrix-org/matrix-spec/issues/1730))
- Use the `body` field as optional media caption, as per [MSC2530](https://github.com/matrix-org/matrix-spec-proposals/pull/2530). ([#1731](https://github.com/matrix-org/matrix-spec/issues/1731))
- Add server support discovery endpoint, as per [MSC1929](https://github.com/matrix-org/matrix-spec-proposals/pull/1929). ([#1733](https://github.com/matrix-org/matrix-spec/issues/1733))
- Add support for multi-stream VoIP, as per [MSC3077](https://github.com/matrix-org/matrix-spec-proposals/pull/3077). ([#1735](https://github.com/matrix-org/matrix-spec/issues/1735))
- Specify that the `Retry-After` header may be used to rate-limit a client, as per [MSC4041](https://github.com/matrix-org/matrix-spec-proposals/pull/4041). ([#1737](https://github.com/matrix-org/matrix-spec/issues/1737))
- Add support for recursion on the `GET /relations` endpoints, as per [MSC3981](https://github.com/matrix-org/matrix-spec-proposals/pull/3981). ([#1746](https://github.com/matrix-org/matrix-spec/issues/1746))
**Spec Clarifications**
- The [strike](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/strike) element is deprecated in the HTML spec. Clients should prefer [s](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/s) instead. ([#1629](https://github.com/matrix-org/matrix-spec/issues/1629))
- Clarify that read receipts should be batched by thread as well as by room. ([#1685](https://github.com/matrix-org/matrix-spec/issues/1685))
- Clarify that threads can be created based on replies. ([#1687](https://github.com/matrix-org/matrix-spec/issues/1687))
- Clarify in the reply fallbacks example that the prefix sequence should be repeated for each line. ([#1690](https://github.com/matrix-org/matrix-spec/issues/1690))
- Clarify the format of account data objects for secret storage. ([#1695](https://github.com/matrix-org/matrix-spec/issues/1695), [#1734](https://github.com/matrix-org/matrix-spec/issues/1734))
- Clarify that the key backup MAC is implemented incorrectly and does not pass the ciphertext through HMAC-SHA-256. ([#1712](https://github.com/matrix-org/matrix-spec/issues/1712))
- Clarify one-time key and fallback key types in examples. ([#1715](https://github.com/matrix-org/matrix-spec/issues/1715))
- Clarify that the HKDF calculation for SAS uses base64-encoded keys rather than the raw key bytes. ([#1719](https://github.com/matrix-org/matrix-spec/issues/1719))
- Clarify how to perform the ECDH exchange in step 12 of the SAS process. ([#1720](https://github.com/matrix-org/matrix-spec/issues/1720))
- Document the deprecation policy of HTML tags, as per [MSC4077](https://github.com/matrix-org/matrix-spec-proposals/pull/4077). ([#1732](https://github.com/matrix-org/matrix-spec/issues/1732))
- The [font](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/font) element is deprecated in the HTML spec. Clients should prefer [span](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/span) with the `data-mx-bg-color` and `data-mx-color` attributes instead. ([#1739](https://github.com/matrix-org/matrix-spec/issues/1739))
- Disambiguate uses of `PublicRoomsChunk` in the `GET /hierarchy` endpoint. ([#1740](https://github.com/matrix-org/matrix-spec/issues/1740))
- Clarify that `sdpMid` and `sdpMLineIndex` are not required in `m.call.candidates`. ([#1742](https://github.com/matrix-org/matrix-spec/issues/1742))
- Fix various typos throughout the specification. ([#1748](https://github.com/matrix-org/matrix-spec/issues/1748))
- Clearly indicate that each `Content-Type` may have distinct behaviour on non-JSON requests/responses. ([#1756](https://github.com/matrix-org/matrix-spec/issues/1756))
- Clarify that the `m.push_rules` account data type cannot be set using the `/account_data` API, as per [MSC4010](https://github.com/matrix-org/matrix-spec-proposals/pull/4010). ([#1763](https://github.com/matrix-org/matrix-spec/issues/1763))
### Server-Server API
**Spec Clarifications**
- Clarify Server-Server API request signing example by using the `POST` HTTP method, as `GET` requests don't have request bodies. ([#1721](https://github.com/matrix-org/matrix-spec/issues/1721))
- Disambiguate uses of `PublicRoomsChunk` in the `GET /hierarchy` endpoint. ([#1740](https://github.com/matrix-org/matrix-spec/issues/1740))
- Clarify that the `children_state`, `room_type` and `allowed_room_ids` properties in the items of the `children` array of the response of the `GET /hierarchy` endpoint are not required. ([#1741](https://github.com/matrix-org/matrix-spec/issues/1741))
### Application Service API
**Spec Clarifications**
- Clarify that the `/login` and `/register` endpoints should fail when using the `m.login.application_service` login type without a valid `as_token`. ([#1744](https://github.com/matrix-org/matrix-spec/issues/1744))
### Identity Service API
No significant changes.
### Push Gateway API
No significant changes.
### Room Versions
**Spec Clarifications**
- For room versions 7 through 11: Clarify that `invite->knock` is not a legal transition. ([#1717](https://github.com/matrix-org/matrix-spec/issues/1717))
### Appendices
No significant changes.
### Internal Changes/Tooling
**Spec Clarifications**
- Update the spec release process. ([#1680](https://github.com/matrix-org/matrix-spec/issues/1680))
- Minor clarifications to the contributing guide. ([#1697](https://github.com/matrix-org/matrix-spec/issues/1697))
- Update Docsy to v0.8.0. ([#1699](https://github.com/matrix-org/matrix-spec/issues/1699), [#1762](https://github.com/matrix-org/matrix-spec/issues/1762))
- Fix npm release script for `@matrix-org/spec`. ([#1713](https://github.com/matrix-org/matrix-spec/issues/1713))
- Add some clarifications around implementation requirements for MSCs. ([#1718](https://github.com/matrix-org/matrix-spec/issues/1718))
- Update HTML templates to include links to object schema definitions. ([#1724](https://github.com/matrix-org/matrix-spec/issues/1724))
- Factor out all the common parameters of the various `/relations` apis. ([#1745](https://github.com/matrix-org/matrix-spec/issues/1745))
- Add support for `$ref` URIs containing fragments in OpenAPI definitions and JSON schemas. ([#1751](https://github.com/matrix-org/matrix-spec/issues/1751), [#1754](https://github.com/matrix-org/matrix-spec/issues/1754))

@ -0,0 +1,135 @@
---
date: 2023-02-14T08:25:40-07:00
---
<!--
This is a header file for the generated changelog.
Variables:
v1.6 = Replaced by the version number (eg: v1.2)
February 14, 2023 = Replaced by the date (eg: April 01, 2021)
-->
## v1.6
<table class="release-info">
<tr><th>Git commit</th><td><a href="https://github.com/matrix-org/matrix-spec/tree/v1.6">https://github.com/matrix-org/matrix-spec/tree/v1.6</a></td>
<tr><th>Release date</th><td>February 14, 2023</td>
</table>
<!-- Intentionally blank line to ensure headers work in the concatenated changelog -->
### Client-Server API
<strong>Backwards Compatible Changes</strong>
- Add information on standard error responses for unknown endpoints/methods, as per [MSC3743](https://github.com/matrix-org/matrix-spec-proposals/pull/3743). ([#1347](https://github.com/matrix-org/matrix-spec/issues/1347))
- Add `/rooms/<roomID>/timestamp_to_event` endpoint, as per [MSC3030](https://github.com/matrix-org/matrix-spec-proposals/pull/3030). ([#1366](https://github.com/matrix-org/matrix-spec/issues/1366))
- Define `hkdf-hmac-sha256.v2` MAC method for SAS verification, as per [MSC3783](https://github.com/matrix-org/matrix-spec-proposals/pull/3783). ([#1412](https://github.com/matrix-org/matrix-spec/issues/1412))
<strong>Spec Clarifications</strong>
- Clarify the power levels integer range. ([#1169](https://github.com/matrix-org/matrix-spec/issues/1169), [#1355](https://github.com/matrix-org/matrix-spec/issues/1355))
- Clarify that `/context` always returns `event` even if `limit` is zero. Contributed by @sumnerevans at @beeper. ([#1239](https://github.com/matrix-org/matrix-spec/issues/1239))
- Clarify what fields are required when deleting a pusher ([#1321](https://github.com/matrix-org/matrix-spec/issues/1321))
- Improve the presentation of push rule kinds and actions. ([#1348](https://github.com/matrix-org/matrix-spec/issues/1348))
- Add missing description to m.call.answer schema. ([#1353](https://github.com/matrix-org/matrix-spec/issues/1353))
- Fix various typos throughout the specification. ([#1363](https://github.com/matrix-org/matrix-spec/issues/1363))
- Clarify parts of the end-to-end encryption sections. ([#1381](https://github.com/matrix-org/matrix-spec/issues/1381))
- Move login API definitions to the right heading. Contributed by @HarHarLinks. ([#1382](https://github.com/matrix-org/matrix-spec/issues/1382))
- Clarify which events will be included in Stripped State. Contributed by @andybalaam. ([#1409](https://github.com/matrix-org/matrix-spec/issues/1409))
- Add links to the spec for the definition of 3PID `medium`. ([#1417](https://github.com/matrix-org/matrix-spec/issues/1417))
- Correct the order of the default override pushrules in the spec. ([#1421](https://github.com/matrix-org/matrix-spec/issues/1421))
- Improve distinction between tags and their attributes in the rich text section. Contributed by Nico. ([#1433](https://github.com/matrix-org/matrix-spec/issues/1433))
### Server-Server API
<strong>Breaking Changes</strong>
- Remove `keyId` from the server `/keys` endpoints, as per [MSC3938](https://github.com/matrix-org/matrix-spec-proposals/pull/3938). ([#1350](https://github.com/matrix-org/matrix-spec/issues/1350))
<strong>Backwards Compatible Changes</strong>
- Add information on standard error responses for unknown endpoints/methods, as per [MSC3743](https://github.com/matrix-org/matrix-spec-proposals/pull/3743). ([#1347](https://github.com/matrix-org/matrix-spec/issues/1347))
- Add `/timestamp_to_event/<roomID>` endpoint, as per [MSC3030](https://github.com/matrix-org/matrix-spec-proposals/pull/3030). ([#1366](https://github.com/matrix-org/matrix-spec/issues/1366))
- Extend `/_matrix/federation/v2/send_join` to allow omitting membership events, per [MSC3706](https://github.com/matrix-org/matrix-doc/pull/3706). ([#1393](https://github.com/matrix-org/matrix-spec/issues/1393), [#1398](https://github.com/matrix-org/matrix-spec/issues/1398))
- Note that `/_matrix/federation/v2/send_join` should include heroes for nameless rooms, even when allowed to omit membership events, per [MSC3943](https://github.com/matrix-org/matrix-doc/pull/3943). ([#1425](https://github.com/matrix-org/matrix-spec/issues/1425))
<strong>Spec Clarifications</strong>
- Include examples inline instead of using a reference for invite endpoint definitions. ([#1349](https://github.com/matrix-org/matrix-spec/issues/1349))
- Fix `POST _matrix/federation/v1/user/keys/claim` response schema. ([#1351](https://github.com/matrix-org/matrix-spec/issues/1351))
- Correct the default invite level definition in the "Checks performed on receipt of a PDU" section. ([#1371](https://github.com/matrix-org/matrix-spec/issues/1371))
- Clarify that CNAMEs are permissible for server names. ([#1376](https://github.com/matrix-org/matrix-spec/issues/1376))
- Fix `edu_type` in EDU examples. ([#1383](https://github.com/matrix-org/matrix-spec/issues/1383))
### Application Service API
<strong>Backwards Compatible Changes</strong>
- Add information on standard error responses for unknown endpoints/methods, as per [MSC3743](https://github.com/matrix-org/matrix-spec-proposals/pull/3743). ([#1347](https://github.com/matrix-org/matrix-spec/issues/1347))
### Identity Service API
<strong>Backwards Compatible Changes</strong>
- Add information on standard error responses for unknown endpoints/methods, as per [MSC3743](https://github.com/matrix-org/matrix-spec-proposals/pull/3743). ([#1347](https://github.com/matrix-org/matrix-spec/issues/1347))
### Push Gateway API
<strong>Backwards Compatible Changes</strong>
- Add information on standard error responses for unknown endpoints/methods, as per [MSC3743](https://github.com/matrix-org/matrix-spec-proposals/pull/3743). ([#1347](https://github.com/matrix-org/matrix-spec/issues/1347))
### Room Versions
<strong>Backwards Compatible Changes</strong>
- Update the default room version to 10, as per [MSC3904](https://github.com/matrix-org/matrix-spec-proposals/pull/3904). ([#1397](https://github.com/matrix-org/matrix-spec/issues/1397))
<strong>Spec Clarifications</strong>
- Clarify the grammar for room versions. ([#1422](https://github.com/matrix-org/matrix-spec/issues/1422))
- Fix various typos throughout the specification. ([#1423](https://github.com/matrix-org/matrix-spec/issues/1423))
### Appendices
No significant changes.
### Internal Changes/Tooling
<strong>Spec Clarifications</strong>
- Add link to the unstable spec to the README. ([#1357](https://github.com/matrix-org/matrix-spec/issues/1357))
- Improve safety of the proposals retrieval script in the event of failure. ([#1368](https://github.com/matrix-org/matrix-spec/issues/1368))
- Rename `<content>` to `content` in the OpenAPI files for content uploads. ([#1370](https://github.com/matrix-org/matrix-spec/issues/1370))
- Stop autogenerating examples where we already have an example. ([#1384](https://github.com/matrix-org/matrix-spec/issues/1384))
- Improve formatting of definitions in the Push Notifications section. ([#1415](https://github.com/matrix-org/matrix-spec/issues/1415))

@ -0,0 +1,147 @@
---
date: 2023-05-25T09:47:21-06:00
---
<!--
This is a header file for the generated changelog.
Variables:
v1.7 = Replaced by the version number (eg: v1.2)
May 25, 2023 = Replaced by the date (eg: April 01, 2021)
-->
## v1.7
<table class="release-info">
<tr><th>Git commit</th><td><a href="https://github.com/matrix-org/matrix-spec/tree/v1.7">https://github.com/matrix-org/matrix-spec/tree/v1.7</a></td>
<tr><th>Release date</th><td>May 25, 2023</td>
</table>
<!-- Intentionally blank line to ensure headers work in the concatenated changelog -->
### Client-Server API
<strong>New Endpoints</strong>
- [`POST /_matrix/media/v1/create`](/client-server-api/#post_matrixmediav1create) ([#1499](https://github.com/matrix-org/matrix-spec/issues/1499))
- [`PUT /_matrix/media/v3/upload/{serverName}/{mediaId}`](/client-server-api/#put_matrixmediav3uploadservernamemediaid) ([#1499](https://github.com/matrix-org/matrix-spec/issues/1499))
- [`POST /_matrix/client/v1/login/get_token`](/client-server-api/#post_matrixclientv1loginget_token) ([#1530](https://github.com/matrix-org/matrix-spec/issues/1530))
<strong>Backwards Compatible Changes</strong>
- Changes to the server-side aggregation of `m.replace` (edit) events, as per [MSC3925](https://github.com/matrix-org/matrix-spec-proposals/pull/3925). ([#1440](https://github.com/matrix-org/matrix-spec/issues/1440), [#1525](https://github.com/matrix-org/matrix-spec/issues/1525))
- Add new push rule conditions `event_property_is` and `event_property_contains`, as per [MSC3758](https://github.com/matrix-org/matrix-spec-proposals/pull/3758) and [MSC3966](https://github.com/matrix-org/matrix-spec-proposals/pull/3966). ([#1464](https://github.com/matrix-org/matrix-spec/issues/1464))
- Add `m.annotation` relations (reactions), as per [MSC2677](https://github.com/matrix-org/matrix-spec-proposals/pull/2677). ([#1475](https://github.com/matrix-org/matrix-spec/issues/1475), [#1531](https://github.com/matrix-org/matrix-spec/issues/1531))
- Support asynchronous media uploads, as per [MSC2246](https://github.com/matrix-org/matrix-spec-proposals/pull/2246). ([#1499](https://github.com/matrix-org/matrix-spec/issues/1499), [#1510](https://github.com/matrix-org/matrix-spec/issues/1510))
- Document the `m.mentions` property; the `.m.rule.is_user_mention` and `.m.rule.is_room_mention` push rules; and other notification behaviour, as per [MSC3952](https://github.com/matrix-org/matrix-spec-proposals/pull/3952). ([#1508](https://github.com/matrix-org/matrix-spec/issues/1508))
- Improve VoIP signaling, as per [MSC2746](https://github.com/matrix-org/matrix-spec-proposals/pull/2746). ([#1511](https://github.com/matrix-org/matrix-spec/issues/1511), [#1540](https://github.com/matrix-org/matrix-spec/issues/1540))
- Update the scope of transaction IDs, as per [MSC3970](https://github.com/matrix-org/matrix-spec-proposals/pull/3970). ([#1526](https://github.com/matrix-org/matrix-spec/issues/1526))
- Add an ability to redirect media downloads, as per [MSC3860](https://github.com/matrix-org/matrix-spec-proposals/pull/3860). ([#1529](https://github.com/matrix-org/matrix-spec/issues/1529))
- Add an ability to use an existing session to log in another, as per [MSC3882](https://github.com/matrix-org/matrix-spec-proposals/pull/3882). ([#1530](https://github.com/matrix-org/matrix-spec/issues/1530))
<strong>Spec Clarifications</strong>
- Clarify the sections of the specification concerning aggregation of child events. ([#1424](https://github.com/matrix-org/matrix-spec/issues/1424))
- Fix various typos throughout the specification. ([#1432](https://github.com/matrix-org/matrix-spec/issues/1432), [#1442](https://github.com/matrix-org/matrix-spec/issues/1442), [#1447](https://github.com/matrix-org/matrix-spec/issues/1447), [#1455](https://github.com/matrix-org/matrix-spec/issues/1455), [#1465](https://github.com/matrix-org/matrix-spec/issues/1465), [#1500](https://github.com/matrix-org/matrix-spec/issues/1500), [#1509](https://github.com/matrix-org/matrix-spec/issues/1509))
- Clarify that reply chain fallback for threads might not be present. ([#1439](https://github.com/matrix-org/matrix-spec/issues/1439))
- Clarify what event property the content-specific push rules match against. ([#1441](https://github.com/matrix-org/matrix-spec/issues/1441))
- Clarify the semantics that make requests idempotent. ([#1449](https://github.com/matrix-org/matrix-spec/issues/1449))
- Improve documentation of how clients use push rules. ([#1461](https://github.com/matrix-org/matrix-spec/issues/1461))
- Clarify that servers should enforce a default `limit` on a filter if one is not specified. ([#1463](https://github.com/matrix-org/matrix-spec/issues/1463))
- Disambiguate using property names with dots in them during push rule processing, as per [MSC3873](https://github.com/matrix-org/matrix-spec-proposals/pull/3873) and [MSC3980](https://github.com/matrix-org/matrix-spec-proposals/pull/3980). ([#1464](https://github.com/matrix-org/matrix-spec/issues/1464))
- Fix phrasing & typography in the registration endpoint description. Contributed by @HarHarLinks. ([#1474](https://github.com/matrix-org/matrix-spec/issues/1474))
- Remove outdated text saying that `state_default` is 0 if there is no `m.room.power_levels` event in a room. ([#1479](https://github.com/matrix-org/matrix-spec/issues/1479))
- Remove fictitious `token` parameter on `/keys/query` endpoint. ([#1485](https://github.com/matrix-org/matrix-spec/issues/1485))
- Fix rendering of properties with a list of types. ([#1487](https://github.com/matrix-org/matrix-spec/issues/1487))
- Clarify parts of the cross-signing signature upload request. ([#1495](https://github.com/matrix-org/matrix-spec/issues/1495))
- Remove the `dont_notify` and `coalesce` push rule actions, as per [MSC3987](https://github.com/matrix-org/matrix-spec-proposals/pull/3987). ([#1501](https://github.com/matrix-org/matrix-spec/issues/1501))
- Clarify `m.location` scheme by partially reverting [f1f32d3](https://github.com/matrix-org/matrix-spec/commit/f1f32d3a15c325ee8aa9d2c6bafd96c38069bb53). Contributed by @HarHarLinks. ([#1507](https://github.com/matrix-org/matrix-spec/issues/1507))
- Add missing `knock_restricted` join rule to the `m.room.join_rules` schema. ([#1535](https://github.com/matrix-org/matrix-spec/issues/1535))
### Server-Server API
<strong>Spec Clarifications</strong>
- Fix various typos throughout the specification. ([#1431](https://github.com/matrix-org/matrix-spec/issues/1431), [#1447](https://github.com/matrix-org/matrix-spec/issues/1447), [#1466](https://github.com/matrix-org/matrix-spec/issues/1466), [#1518](https://github.com/matrix-org/matrix-spec/issues/1518))
- Fix PDU examples by removing invalid OpenAPI reference to `examples/minimal_pdu.json`. ([#1454](https://github.com/matrix-org/matrix-spec/issues/1454))
- Remove leftover `{key_id}` from `/_matrix/key/v2/server/`. ([#1473](https://github.com/matrix-org/matrix-spec/issues/1473))
- Remove extraneous `age_ts` field from the reference hash calculation section. ([#1536](https://github.com/matrix-org/matrix-spec/issues/1536))
### Application Service API
<strong>New Endpoints</strong>
- [`POST /_matrix/app/v1/ping`](/application-service-api/#post_matrixappv1ping) ([#1516](https://github.com/matrix-org/matrix-spec/issues/1516))
- [`POST /_matrix/client/v1/appservice/{appserviceId}/ping`](/application-service-api/#post_matrixclientv1appserviceappserviceidping) ([#1516](https://github.com/matrix-org/matrix-spec/issues/1516))
<strong>Backwards Compatible Changes</strong>
- Add homeserver->appservice ping mechanism, as per [MSC2659](https://github.com/matrix-org/matrix-spec-proposals/pull/2659). Contributed by @tulir at @beeper. ([#1516](https://github.com/matrix-org/matrix-spec/issues/1516), [#1541](https://github.com/matrix-org/matrix-spec/issues/1541))
<strong>Spec Clarifications</strong>
- Fix various typos throughout the specification. ([#1447](https://github.com/matrix-org/matrix-spec/issues/1447))
### Identity Service API
<strong>Spec Clarifications</strong>
- Corrections to the response format of `/_matrix/identity/v2/store-invite`. ([#1486](https://github.com/matrix-org/matrix-spec/issues/1486))
### Push Gateway API
No significant changes.
### Room Versions
<strong>Spec Clarifications</strong>
- Clarifications of event ID formats in early room versions ([#1484](https://github.com/matrix-org/matrix-spec/issues/1484))
### Appendices
<strong>Spec Clarifications</strong>
- Clarify that the term "Canonical JSON" is a specific thing within the Matrix specification. ([#1468](https://github.com/matrix-org/matrix-spec/issues/1468))
- Remove references to groups. ([#1483](https://github.com/matrix-org/matrix-spec/issues/1483))
- Clarifications of event ID formats in early room versions. ([#1484](https://github.com/matrix-org/matrix-spec/issues/1484))
### Internal Changes/Tooling
<strong>Spec Clarifications</strong>
- Update references to Inter font. ([#1444](https://github.com/matrix-org/matrix-spec/issues/1444))
- Endpoint disclosures now hide everything but the URL. ([#1446](https://github.com/matrix-org/matrix-spec/issues/1446))
- Wrap $ref in allOf where other attributes are present, to improve OpenAPI compliance. ([#1457](https://github.com/matrix-org/matrix-spec/issues/1457))
- Minor cleanups to the GitHub Actions workflows ([#1476](https://github.com/matrix-org/matrix-spec/issues/1476))
- Fix generation of anchors for additional properties. ([#1488](https://github.com/matrix-org/matrix-spec/issues/1488))
- Fix various typos throughout the specification. ([#1534](https://github.com/matrix-org/matrix-spec/issues/1534))
- Document more of the spec release timeline/process. ([#1538](https://github.com/matrix-org/matrix-spec/issues/1538))

@ -0,0 +1,122 @@
---
date: 2023-08-23T09:23:53-06:00
---
<!--
This is a header file for the generated changelog.
Variables:
v1.8 = Replaced by the version number (eg: v1.2)
August 23, 2023 = Replaced by the date (eg: April 01, 2021)
-->
## v1.8
<table class="release-info">
<tr><th>Git commit</th><td><a href="https://github.com/matrix-org/matrix-spec/tree/v1.8">https://github.com/matrix-org/matrix-spec/tree/v1.8</a></td>
<tr><th>Release date</th><td>August 23, 2023</td>
</table>
<!-- Intentionally blank line to ensure headers work in the concatenated changelog -->
### Client-Server API
**Backwards Compatible Changes**
- Require callers to be joined to the room to report its events, as per [MSC2249](https://github.com/matrix-org/matrix-spec-proposals/pull/2249). ([#1517](https://github.com/matrix-org/matrix-spec/issues/1517))
**Spec Clarifications**
- Fix missing `type` property in the JSON schema definition of the `m.reaction` event. Contributed by @chebureki. ([#1552](https://github.com/matrix-org/matrix-spec/issues/1552))
- Make sure examples types match schema in definitions. ([#1563](https://github.com/matrix-org/matrix-spec/issues/1563))
- Allow `null` in `room_types` in `POST /publicRooms` endpoints schemas. ([#1564](https://github.com/matrix-org/matrix-spec/issues/1564))
- Fix broken header formatting. Contributed by @midnightveil. ([#1578](https://github.com/matrix-org/matrix-spec/issues/1578))
- Render binary request and response bodies. ([#1579](https://github.com/matrix-org/matrix-spec/issues/1579))
- Fix description of MAC calculation in SAS verification. ([#1590](https://github.com/matrix-org/matrix-spec/issues/1590))
- Update link to SAS emoji definition data. ([#1593](https://github.com/matrix-org/matrix-spec/issues/1593))
- Fix various typos throughout the specification. ([#1597](https://github.com/matrix-org/matrix-spec/issues/1597))
### Server-Server API
**Deprecations**
- Deprecate `matrix` SRV lookup steps during server discovery, as per [MSC4040](https://github.com/matrix-org/matrix-spec-proposals/pull/4040). ([#1624](https://github.com/matrix-org/matrix-spec/issues/1624))
**Backwards Compatible Changes**
- Add `matrix-fed` SRV lookup steps to server discovery, as per [MSC4040](https://github.com/matrix-org/matrix-spec-proposals/pull/4040). ([#1624](https://github.com/matrix-org/matrix-spec/issues/1624))
**Spec Clarifications**
- Document why `/state_ids` can respond with a 404. ([#1521](https://github.com/matrix-org/matrix-spec/issues/1521))
- Fix response definition for `POST /_matrix/federation/v1/user/keys/claim`. ([#1559](https://github.com/matrix-org/matrix-spec/issues/1559))
- Fix examples in server keys definition. ([#1560](https://github.com/matrix-org/matrix-spec/issues/1560))
- Make sure examples types match schema in definitions. ([#1563](https://github.com/matrix-org/matrix-spec/issues/1563))
- Allow `null` in `room_types` in `POST /publicRooms` endpoints schemas. ([#1564](https://github.com/matrix-org/matrix-spec/issues/1564))
- Fix broken header formatting. Contributed by @midnightveil. ([#1578](https://github.com/matrix-org/matrix-spec/issues/1578))
- Remove spurious mention of a "default port" with respect to SRV record lookup. ([#1615](https://github.com/matrix-org/matrix-spec/issues/1615))
- Switch to ordered list for server name resolution steps. ([#1623](https://github.com/matrix-org/matrix-spec/issues/1623))
### Application Service API
**Spec Clarifications**
- Fix type of custom `fields` in thirdparty lookup queries. ([#1584](https://github.com/matrix-org/matrix-spec/issues/1584))
### Identity Service API
**Spec Clarifications**
- Make sure examples types match schema in definitions. ([#1563](https://github.com/matrix-org/matrix-spec/issues/1563))
### Push Gateway API
No significant changes.
### Room Versions
**Backwards Compatible Changes**
- Add room version 11 as per [MSC3820](https://github.com/matrix-org/matrix-spec-proposals/pull/3820). ([#1604](https://github.com/matrix-org/matrix-spec/issues/1604))
- Move `redacts` from top level to `content` on `m.room.redaction` events in room version 11, as per [MSC2174](https://github.com/matrix-org/matrix-spec-proposals/pull/2174). ([#1604](https://github.com/matrix-org/matrix-spec/issues/1604))
- Remove `creator` from `m.room.creator` events in room version 11, as per [MSC2175](https://github.com/matrix-org/matrix-spec-proposals/pull/2175). ([#1604](https://github.com/matrix-org/matrix-spec/issues/1604))
- Remove remaining usage of `origin` from events in room version 11, as per [MSC3989](https://github.com/matrix-org/matrix-spec-proposals/pull/3989). ([#1604](https://github.com/matrix-org/matrix-spec/issues/1604))
- Update the redaction rules in room version 11, as per [MSC2176](https://github.com/matrix-org/matrix-spec-proposals/pull/2176) and [MSC3821](https://github.com/matrix-org/matrix-spec-proposals/pull/3821). ([#1604](https://github.com/matrix-org/matrix-spec/issues/1604))
### Appendices
**Backwards Compatible Changes**
- Allow `+` in Matrix IDs, as per [MSC4009](https://github.com/matrix-org/matrix-spec-proposals/pull/4009). ([#1583](https://github.com/matrix-org/matrix-spec/issues/1583))
**Spec Clarifications**
- Clarify spec re canonical JSON to handle negative-zero; also, give an example of negative-zero and a large power of ten. ([#1573](https://github.com/matrix-org/matrix-spec/issues/1573))
### Internal Changes/Tooling
**Backwards Compatible Changes**
- Upgrade Swagger data to OpenAPI 3.1. ([#1310](https://github.com/matrix-org/matrix-spec/issues/1310))
- Create `@matrix-org/spec` npm package to ship the SAS Emoji data definitions & translations. ([#1620](https://github.com/matrix-org/matrix-spec/issues/1620))
**Spec Clarifications**
- Update the CI to validate the file extension of changelog entries. ([#1542](https://github.com/matrix-org/matrix-spec/issues/1542))
- Disclosure sections now only display their title when collapsed. ([#1549](https://github.com/matrix-org/matrix-spec/issues/1549))
- Fix the sidebar in recent versions of Hugo. ([#1551](https://github.com/matrix-org/matrix-spec/issues/1551))
- Bump jsonschema to validate JSON Schemas against Draft 2020-12. ([#1556](https://github.com/matrix-org/matrix-spec/issues/1556))
- Use Redocly CLI to validate OpenAPI definitions. ([#1558](https://github.com/matrix-org/matrix-spec/issues/1558))
- Use tag name as the OpenAPI definition version. ([#1561](https://github.com/matrix-org/matrix-spec/issues/1561))
- Make sure version in `x-changedInMatrixVersion` is a string. ([#1562](https://github.com/matrix-org/matrix-spec/issues/1562))
- Clarify usage of ABNF for grammar in the documentation style guide. ([#1582](https://github.com/matrix-org/matrix-spec/issues/1582))
- Remove unnecessary `oneOf`s in JSON schemas. ([#1585](https://github.com/matrix-org/matrix-spec/issues/1585))
- Update the version of Hugo used to render the spec to v0.113.0. ([#1591](https://github.com/matrix-org/matrix-spec/issues/1591))
- Fix rendered changelog with new version of towncrier. ([#1598](https://github.com/matrix-org/matrix-spec/issues/1598))
- Improve the layout of tables on desktop displays. Contributed by Martin Fischer. ([#1601](https://github.com/matrix-org/matrix-spec/issues/1601))

@ -0,0 +1,93 @@
---
date: 2023-11-29T10:04:26-07:00
---
<!--
This is a header file for the generated changelog.
Variables:
v1.9 = Replaced by the version number (eg: v1.2)
November 29, 2023 = Replaced by the date (eg: April 01, 2021)
-->
## v1.9
<table class="release-info">
<tr><th>Git commit</th><td><a href="https://github.com/matrix-org/matrix-spec/tree/v1.9">https://github.com/matrix-org/matrix-spec/tree/v1.9</a></td>
<tr><th>Release date</th><td>November 29, 2023</td>
</table>
<!-- Intentionally blank line to ensure headers work in the concatenated changelog -->
### Client-Server API
**Backwards Compatible Changes**
- Add the `m.rule.suppress_edits` default push rule, as per [MSC3958](https://github.com/matrix-org/matrix-spec-proposals/pull/3958). ([#1617](https://github.com/matrix-org/matrix-spec/issues/1617))
**Spec Clarifications**
- Fix `m.call.negotiate` schema and example. ([#1546](https://github.com/matrix-org/matrix-spec/issues/1546))
- Clarify that the `via` property is required for `m.space.parent` and `m.space.child` as per [MSC1772](https://github.com/matrix-org/matrix-spec-proposals/pull/1772). Contributed by @PaarthShah. ([#1618](https://github.com/matrix-org/matrix-spec/issues/1618))
- Add a note to the `/publicRooms` API that the server name is case sensitive. ([#1638](https://github.com/matrix-org/matrix-spec/issues/1638))
- Clarify that an `m.room.name` event with an absent `name` field is not expected behavior. ([#1639](https://github.com/matrix-org/matrix-spec/issues/1639))
- Fix schemas used for account data and presence events in `GET /initialSync`. ([#1647](https://github.com/matrix-org/matrix-spec/issues/1647))
- Fix various typos throughout the specification. ([#1658](https://github.com/matrix-org/matrix-spec/issues/1658), [#1661](https://github.com/matrix-org/matrix-spec/issues/1661), [#1665](https://github.com/matrix-org/matrix-spec/issues/1665))
- Fix `.m.rule.suppress_notices` push rule not being valid JSON. ([#1671](https://github.com/matrix-org/matrix-spec/issues/1671))
- Add missing properties for `event_property_is` and `event_property_contains` push conditions to `PushConditions` object. ([#1673](https://github.com/matrix-org/matrix-spec/issues/1673))
- Indicate that fallback keys should have a `fallback` property set to `true`. ([#1676](https://github.com/matrix-org/matrix-spec/issues/1676))
- Clarify that thread roots are not considered within the thread. ([#1677](https://github.com/matrix-org/matrix-spec/issues/1677))
### Server-Server API
**Spec Clarifications**
- Fix schema of `m.receipt` EDU. ([#1636](https://github.com/matrix-org/matrix-spec/issues/1636))
- Fix various typos throughout the specification. ([#1661](https://github.com/matrix-org/matrix-spec/issues/1661))
- Clarify that federation requests for non-local users are invalid. ([#1672](https://github.com/matrix-org/matrix-spec/issues/1672))
### Application Service API
No significant changes.
### Identity Service API
No significant changes.
### Push Gateway API
No significant changes.
### Room Versions
No significant changes.
### Appendices
**Spec Clarifications**
- Clarify timestamp specification with respect to leap seconds. ([#1627](https://github.com/matrix-org/matrix-spec/issues/1627))
- Fix various typos throughout the specification. ([#1652](https://github.com/matrix-org/matrix-spec/issues/1652))
### Internal Changes/Tooling
**Backwards Compatible Changes**
- Add more CI checks for OpenAPI definitions and JSON Schemas. ([#1656](https://github.com/matrix-org/matrix-spec/issues/1656))
- Generate server-server OpenAPI definition. ([#1657](https://github.com/matrix-org/matrix-spec/issues/1657))
**Spec Clarifications**
- Replace all mentions of Swagger by OpenAPI. ([#1633](https://github.com/matrix-org/matrix-spec/issues/1633))
- Fix enum types in JSON schemas. ([#1634](https://github.com/matrix-org/matrix-spec/issues/1634))
- Fix schema of `m.mentions` object. ([#1635](https://github.com/matrix-org/matrix-spec/issues/1635))
- Fix rendering of `m.receipt` event in Client-Server API. ([#1637](https://github.com/matrix-org/matrix-spec/issues/1637))
- Remove required `fieldname` in appservice Protocol definition. ([#1646](https://github.com/matrix-org/matrix-spec/issues/1646))
- Fix github action workflow responsible for releasing of @matrix-org/spec package. ([#1648](https://github.com/matrix-org/matrix-spec/issues/1648))
- Upgrade GitHub actions. ([#1660](https://github.com/matrix-org/matrix-spec/issues/1660))

@ -22,11 +22,12 @@ recommended outside test environments.
Clients are authenticated using opaque `access_token` strings (see [Client
Authentication](#client-authentication) for details).
All `POST` and `PUT` endpoints, with the exception of
[`POST /_matrix/media/v3/upload`](#post_matrixmediav3upload), require the
client to supply a request body containing a (potentially empty) JSON object.
Clients should supply a `Content-Type` header of `application/json` for all requests with JSON bodies,
but this is not required.
All `POST` and `PUT` endpoints, with the exception of [`POST
/_matrix/media/v3/upload`](#post_matrixmediav3upload) and [`PUT
/_matrix/media/v3/upload/{serverName}/{mediaId}`](#put_matrixmediav3uploadservernamemediaid),
require the client to supply a request body containing a (potentially empty)
JSON object. Clients should supply a `Content-Type` header of
`application/json` for all requests with JSON bodies, but this is not required.
Similarly, all endpoints require the server to return a JSON object,
with the exception of 200 responses to
@ -61,7 +62,7 @@ error message e.g. `M_FORBIDDEN`. Error codes should have their namespace
first in ALL CAPS, followed by a single `_`. For example, if there was a custom
namespace `com.mydomain.here`, and a `FORBIDDEN` code, the error code should
look like `COM.MYDOMAIN.HERE_FORBIDDEN`. Error codes defined by this
specification should start `M_`.
specification should start with `M_`.
Some `errcode`s define additional keys which should be present in the error
response object, but the keys `error` and `errcode` MUST always be present.
@ -105,7 +106,12 @@ No resource was found for this request.
`M_LIMIT_EXCEEDED`
Too many requests have been sent in a short period of time. Wait a while
then try again.
then try again. See [Rate limiting](#rate-limiting).
`M_UNRECOGNIZED`
The server did not understand the request. This is expected to be returned with
a 404 HTTP status code if the endpoint is not implemented or a 405 HTTP status
code if the endpoint is implemented, but the incorrect HTTP method is used.
`M_UNKNOWN`
An unknown error has occurred.
@ -116,9 +122,6 @@ The following error codes are specific to certain endpoints.
<!-- TODO: move them to the endpoints that return them -->
`M_UNRECOGNIZED`
The server did not understand the request.
`M_UNAUTHORIZED`
The request was not correctly authorized. Usually due to login failures.
@ -148,15 +151,15 @@ Sent when a threepid given to an API cannot be used because no record
matching the threepid was found.
`M_THREEPID_AUTH_FAILED`
Authentication could not be performed on the third party identifier.
Authentication could not be performed on the third-party identifier.
`M_THREEPID_DENIED`
The server does not permit this third party identifier. This may happen
The server does not permit this third-party identifier. This may happen
if the server only permits, for example, email addresses from a
particular domain.
`M_SERVER_NOT_TRUSTED`
The client's request used a third party server, e.g. identity server,
The client's request used a third-party server, e.g. identity server,
that this server does not trust.
`M_UNSUPPORTED_ROOM_VERSION`
@ -209,27 +212,79 @@ only read state (e.g.: `/sync`, get account data, etc).
The user is unable to reject an invite to join the server notices room.
See the [Server Notices](#server-notices) module for more information.
#### Rate limiting
Homeservers SHOULD implement rate limiting to reduce the risk of being
overloaded. If a request is refused due to rate limiting, it should
return a standard error response of the form:
```json
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "string",
"retry_after_ms": integer (optional, deprecated)
}
```
Homeservers SHOULD include a [`Retry-After`](https://www.rfc-editor.org/rfc/rfc9110#field.retry-after)
for any response with a 429 status code.
The `retry_after_ms` property MAY be included to tell the client how long
they have to wait in milliseconds before they can try again. This property is
deprecated, in favour of the `Retry-After` header.
{{< changed-in v="1.10" >}}: `retry_after_ms` property deprecated in favour of `Retry-After` header.
### Transaction identifiers
The client-server API typically uses `HTTP PUT` to submit requests with
a client-generated transaction identifier. This means that these
requests are idempotent. It **only** serves to identify new requests
from retransmits. After the request has finished, the `{txnId}` value
should be changed (how is not specified; a monotonically increasing
integer is recommended).
The scope of a transaction ID is a "client session", where that session
is identified by a particular access token. When [refreshing](#refreshing-access-tokens)
an access token, the transaction ID's scope is retained. This means that
if a client with token `A` uses `TXN1` as their transaction ID, refreshes
the token to `B`, and uses `TXN1` again it'll be assumed to be a duplicate
request and ignored. If the client logs out and back in between the `A` and
`B` tokens, `TXN1` could be used once for each.
a client-generated transaction identifier in the HTTP path.
The purpose of the transaction ID is to allow the homeserver to distinguish a
new request from a retransmission of a previous request so that it can make
the request idempotent.
The transaction ID should **only** be used for this purpose.
From the client perspective, after the request has finished, the `{txnId}`
value should be changed by for the next request (how is not specified; a
monotonically increasing integer is recommended).
The homeserver should identify a request as a retransmission if the
transaction ID is the same as a previous request, and the path of the
HTTP request is the same.
Where a retransmission has been identified, the homeserver should return
the same HTTP response code and content as the original request.
For example, `PUT /_matrix/client/v3/rooms/{roomId}/send/{eventType}/{txnId}`
would return a `200 OK` with the `event_id` of the original request in
the response body.
The scope of a transaction ID is for a single [device](../index.html#devices),
and a single HTTP endpoint. In other words: a single device could use the same
transaction ID for a request to [`PUT
/_matrix/client/v3/rooms/{roomId}/send/{eventType}/{txnId}`](#put_matrixclientv3roomsroomidsendeventtypetxnid)
and [`PUT
/_matrix/client/v3/sendToDevice/{eventType}/{txnId}`](#put_matrixclientv3sendtodeviceeventtypetxnid),
and the two requests would be considered distinct because the two are
considered separate endpoints. Similarly, if a client logs out and back in
between two requests using the same transaction ID, the requests are distinct
because the act of logging in and out creates a new device (unless an existing
`device_id` is passed to [`POST
/_matrix/client/v3/login`](#post_matrixclientv3login)). On the other hand, if a
client re-uses a transaction ID for the same endpoint after
[refreshing](#refreshing-access-tokens) an access token, it will be assumed to
be a duplicate request and ignored. See also
[Relationship between access tokens and devices](#relationship-between-access-tokens-and-devices).
Some API endpoints may allow or require the use of `POST` requests
without a transaction ID. Where this is optional, the use of a `PUT`
request is strongly recommended.
{{% boxes/rationale %}}
Prior to `v1.7`, transaction IDs were scoped to "client sessions" rather than
devices.
{{% /boxes/rationale %}}
## Web Browser Clients
It is realistic to expect that some clients will be written to be run
@ -330,11 +385,12 @@ specify parameter values. The flow for this method is as follows:
{{% http-api spec="client-server" api="versions" %}}
{{% http-api spec="client-server" api="support" %}}
## Client Authentication
Most API endpoints require the user to identify themselves by presenting
previously obtained credentials in the form of an `access_token` query
parameter or through an Authorization Header of `Bearer $access_token`.
previously obtained credentials in the form of an access token.
An access token is typically obtained via the [Login](#login) or
[Registration](#account-registration-and-management) processes. Access tokens
can expire; a new access token can be generated by using a refresh token.
@ -348,16 +404,19 @@ investigate [macaroons](http://research.google.com/pubs/pub41892.html).
### Using access tokens
Access tokens may be provided in two ways, both of which the homeserver
MUST support:
Access tokens may be provided via a request header, using the Authentication
Bearer scheme: `Authorization: Bearer TheTokenHere`.
1. Via a query string parameter, `access_token=TheTokenHere`.
2. Via a request header, `Authorization: Bearer TheTokenHere`.
Clients may alternatively provide the access token via a query string parameter:
`access_token=TheTokenHere`. This method is deprecated to prevent the access
token being leaked in access/HTTP logs and SHOULD NOT be used by clients.
Clients are encouraged to 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.
Homeservers MUST support both methods.
{{% boxes/note %}}
{{% changed-in v="1.11" %}}
Sending the access token as a query string parameter is now deprecated.
{{% /boxes/note %}}
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
@ -487,8 +546,10 @@ request parameter.
A client should first make a request with no `auth` parameter.
The homeserver returns an HTTP 401 response, with a JSON body, as follows:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
```
HTTP/1.1 401 Unauthorized
Content-Type: application/json
```
```json
{
@ -531,8 +592,10 @@ given. It also contains other keys dependent on the auth type being
attempted. For example, if the client is attempting to complete auth
type `example.type.foo`, it might submit something like this:
POST /_matrix/client/v3/endpoint HTTP/1.1
Content-Type: application/json
```
POST /_matrix/client/v3/endpoint HTTP/1.1
Content-Type: application/json
```
```json
{
@ -552,8 +615,10 @@ along with the same object as when no authentication was attempted, with
the addition of the `completed` key which is an array of auth types the
client has completed successfully:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
```
HTTP/1.1 401 Unauthorized
Content-Type: application/json
```
```json
{
@ -584,8 +649,10 @@ but the client may make a second attempt, it returns the same HTTP
status 401 response as above, with the addition of the standard
`errcode` and `error` fields describing the error. For example:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
```
HTTP/1.1 401 Unauthorized
Content-Type: application/json
```
```json
{
@ -612,8 +679,10 @@ status 401 response as above, with the addition of the standard
If the request fails for a reason other than authentication, the server
returns an error message in the standard format. For example:
HTTP/1.1 400 Bad request
Content-Type: application/json
```
HTTP/1.1 400 Bad request
Content-Type: application/json
```
```json
{
@ -737,7 +806,7 @@ submit:
```
Alternatively reply using a 3PID bound to the user's account on the
homeserver using the `/account/3pid`\_ API rather than giving the `user`
homeserver using the [`/account/3pid`](#get_matrixclientv3account3pid) API rather than giving the `user`
explicitly as follows:
```json
@ -745,8 +814,8 @@ explicitly as follows:
"type": "m.login.password",
"identifier": {
"type": "m.id.thirdparty",
"medium": "<The medium of the third party identifier.>",
"address": "<The third party address of the user>"
"medium": "<The medium of the third-party identifier.>",
"address": "<The third-party address of the user>"
},
"password": "<password>",
"session": "<session ID>"
@ -886,11 +955,12 @@ or completely closed registration (where the homeserver administrators create
and distribute accounts).
The token required for this authentication type is shared out of band from
Matrix and is an opaque string with maximum length of 64 characters in the
range `[A-Za-z0-9._~-]`. The server can keep any number of tokens for any
length of time/validity. Such cases might be a token limited to 100 uses or
for the next 2 hours - after the tokens expire, they can no longer be used
to create accounts.
Matrix and is an opaque string using the [Opaque Identifier
Grammar](/appendices#opaque-identifiers), with maximum length of 64
characters. The server can keep any number of tokens for any length of
time/validity. Such cases might be a token limited to 100 uses or for the next
2 hours - after the tokens expire, they can no longer be used to create
accounts.
To use this authentication type, clients should submit an auth dict with just
the type, token, and session:
@ -910,6 +980,129 @@ in the registration process that their token has expired.
{{% http-api spec="client-server" api="registration_tokens" %}}
##### Terms of service at registration
{{% added-in v="1.11" %}}
| Type | Description |
|--------------------------|--------------------------------------------------------------------------|
| `m.login.terms` | Authentication requires the user to accept a set of policy documents. |
{{% boxes/note %}}
The `m.login.terms` authentication type is only valid on the
[`/register`](#post_matrixclientv3register) endpoint.
{{% /boxes/note %}}
This authentication type is used when the homeserver requires new users to
accept a given set of policy documents, such as a terms of service and a privacy
policy. There may be many different types of documents, all of which are
versioned and presented in (potentially) multiple languages.
When the server requires the user to accept some terms, it does so by returning
a 401 response to the `/register` request, where the response body includes
`m.login.terms` in the `flows` list, and the `m.login.terms` property in the
`params` object has the structure [shown below](#definition-mloginterms-params).
If a client encounters an invalid parameter, registration should stop with an
error presented to the user.
The client should present the user with a checkbox to accept each policy,
including a link to the provided URL. Once the user has done so, the client
submits an `auth` dict with just the `type` and `session`, as follows, to
indicate that all of the policies have been accepted:
```json
{
"type": "m.login.terms",
"session": "<session ID>"
}
```
The server is expected to track which document versions it presented to the
user during registration, if applicable.
**Example**
1. A client might submit a registration request as follows:
```
POST /_matrix/client/v3/register
```
```json
{
"username": "cheeky_monkey",
"password": "ilovebananas"
}
```
2. The server requires the user to accept some terms of service before
registration, so returns the following response:
```
HTTP/1.1 401 Unauthorized
Content-Type: application/json
```
```json
{
"flows": [
{ "stages": [ "m.login.terms" ] }
],
"params": {
"m.login.terms": {
"policies": {
"terms_of_service": {
"version": "1.2",
"en": {
"name": "Terms of Service",
"url": "https://example.org/somewhere/terms-1.2-en.html"
},
"fr": {
"name": "Conditions d'utilisation",
"url": "https://example.org/somewhere/terms-1.2-fr.html"
}
}
}
}
},
"session": "kasgjaelkgj"
}
```
3. The client presents the list of documents to the user, inviting them to
accept the polices.
4. The client repeats the registration request, confirming that the user has
accepted the documents:
```
POST /_matrix/client/v3/register
```
```json
{
"username": "cheeky_monkey",
"password": "ilovebananas",
"auth": {
"type": "m.login.terms",
"session": "kasgjaelkgj"
}
}
```
5. All authentication steps have now completed, so the request is successful:
```
HTTP/1.1 200 OK
Content-Type: application/json
```
```json
{
"access_token": "abc123",
"device_id": "GHTYAJCE",
"user_id": "@cheeky_monkey:matrix.org"
}
```
{{% definition path="api/client-server/definitions/m.login.terms_params" %}}
#### Fallback
Clients cannot be expected to be able to know how to process every
@ -1045,15 +1238,15 @@ ID.
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
using the [`/account/3pid`](#get_matrixclientv3account3pid) API. See the [3PID
Types](/appendices#3pid-types) Appendix for a list of Third-party
ID media.
```json
"identifier": {
"type": "m.id.thirdparty",
"medium": "<The medium of the third party identifier>",
"address": "<The canonicalised third party address of the user>"
"medium": "<The medium of the third-party identifier>",
"address": "<The canonicalised third-party address of the user>"
}
```
@ -1065,7 +1258,7 @@ ID media.
A client can identify a user using a phone number associated with the
user's account, where the phone number was previously associated using
the `/account/3pid`\_ API. The phone number can be passed in as entered
the [`/account/3pid`](#get_matrixclientv3account3pid) API. The phone number can be passed in as entered
by the user; the homeserver will be responsible for canonicalising it.
If the client wishes to canonicalise the phone number, then it can use
the `m.id.thirdparty` identifier type with a `medium` of `msisdn`
@ -1106,15 +1299,15 @@ request as follows:
```
Alternatively, a client can use a 3PID bound to the user's account on
the homeserver using the `/account/3pid`\_ API rather than giving the
the homeserver using the [`/account/3pid`](#get_matrixclientv3account3pid) API rather than giving the
`user` explicitly, as follows:
```json
{
"type": "m.login.password",
"identifier": {
"medium": "<The medium of the third party identifier>",
"address": "<The canonicalised third party address of the user>"
"medium": "<The medium of the third-party identifier>",
"address": "<The canonicalised third-party address of the user>"
},
"password": "<password>"
}
@ -1143,6 +1336,18 @@ client supports it, the client should redirect the user to the
is complete, the client will need to submit a `/login` request matching
`m.login.token`.
{{< added-in v="1.7" >}} Already-authenticated clients can additionally generate
a token for their user ID if supported by the homeserver using
[`POST /login/get_token`](/client-server-api/#post_matrixclientv1loginget_token).
{{% http-api spec="client-server" api="login" %}}
{{% http-api spec="client-server" api="login_token" %}}
{{% http-api spec="client-server" api="refresh" %}}
{{% http-api spec="client-server" api="logout" %}}
#### Appservice Login
{{% added-in v="1.2" %}}
@ -1180,12 +1385,6 @@ If the access token does correspond to an appservice, but the user id does
not lie within its namespace then the homeserver will respond with an
errcode of `M_EXCLUSIVE`.
{{% http-api spec="client-server" api="login" %}}
{{% http-api spec="client-server" api="refresh" %}}
{{% http-api spec="client-server" api="logout" %}}
#### Login Fallback
If a client does not recognize any or all login flows it can use the
@ -1239,7 +1438,7 @@ can be added and bound at the same time, depending on context.
#### Notes on identity servers
Identity servers in Matrix store bindings (relationships) between a
user's third party identifier, typically email or phone number, and
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.
@ -1577,15 +1776,18 @@ detail on why this assumption is unsafe.
### Stripped state
Stripped state events are simplified state events to help a potential
joiner identify the room. These state events can only have the `sender`,
`type`, `state_key` and `content` keys present.
Stripped state is a simplified view of the state of a room intended to help a
potential joiner identify the room. It consists of a limited set of state events
that are themselves simplified to reduce the amount of data required.
Stripped state events can only have the `sender`, `type`, `state_key` and
`content` properties present.
These stripped state events typically appear on invites, knocks, and in
other places where a user *could* join the room under the conditions
available (such as a [`restricted` room](#restricted-rooms)).
Stripped state typically appears in invites, knocks, and in other places where a
user *could* join the room under the conditions available (such as a
[`restricted` room](#restricted-rooms)).
Clients should only use stripped state events so long as they don't have
Clients should only use stripped state events when they don't have
access to the proper state of the room. Once the state of the room is
available, all stripped state should be discarded. In cases where the
client has an archived state of the room (such as after being kicked)
@ -1593,8 +1795,8 @@ and the client is receiving stripped state for the room, such as from an
invite or knock, then the stripped state should take precedence until
fresh state can be acquired from a join.
The following state events should be represented as stripped state when
possible:
Stripped state should contain some or all of the following state events, which
should be represented as stripped state events when possible:
* [`m.room.create`](#mroomcreate)
* [`m.room.name`](#mroomname)
@ -1816,6 +2018,8 @@ There are several APIs provided to `GET` events for a room:
{{% http-api spec="client-server" api="message_pagination" %}}
{{% http-api spec="client-server" api="room_event_by_timestamp" %}}
{{% http-api spec="client-server" api="room_initial_sync" %}}
### Sending events to a room
@ -1972,10 +2176,11 @@ This specification describes the following relationship types:
* [Rich replies](#rich-replies) (**Note**: does not use `rel_type`).
* [Event replacements](#event-replacements).
* [Event annotations](#event-annotations-and-reactions).
* [Threads](#threading).
* [References](#reference-relations)
#### Aggregations
#### Aggregations of child events
{{% added-in v="1.3" %}}
@ -1989,14 +2194,12 @@ of times that `key` was used by child events.
The actual aggregation format depends on the `rel_type`.
Aggregations are sometimes automatically included by a server alongside the parent
event. This is known as a "bundled aggregation" or "bundle" for simplicity. The
act of doing this is "bundling".
When an event is served to the client through the APIs listed below, a `m.relations` property
is included under `unsigned` if the event has child events which can be aggregated and point
at it. The `m.relations` property is an object keyed by `rel_type` and value being the type-specific
aggregated format for that `rel_type`, also known as the bundle.
When an event is served to the client through the APIs listed below, a
`m.relations` property is included under `unsigned` if the event has child
events which can be aggregated and point at it. The `m.relations` property is
an object keyed by `rel_type` and value being the type-specific aggregated
format for that `rel_type`. This `m.relations` property is known as a "bundled
aggregation".
For example (unimportant fields not included):
@ -2032,10 +2235,10 @@ For example (unimportant fields not included):
}
```
Note how the `org.example.possible_annotations` bundle is an array compared to the
`org.example.possible_thread` bundle where the server is summarising the state of
the relationship in a single object. Both are valid ways to aggregate, and their
exact types depend on the `rel_type`.
Note how the `org.example.possible_annotations` aggregation is an array, while in the
`org.example.possible_thread` aggregation where the server is summarising the state of
the relationship in a single object. Both are valid ways to aggregate: the format of an
aggregation depends on the `rel_type`.
{{% boxes/warning %}}
State events do not currently receive bundled aggregations. This is not
@ -2062,11 +2265,11 @@ such as `/initialSync`.
While this functionality allows the client to see what was known to the server at the
time of handling, the client should continue to aggregate locally if it is aware of
the relationship type's behaviour. For example, a client might increment a `count`
on a parent event's bundle if it saw a new child event which referenced that parent.
the relationship type's behaviour. For example, a client might internally increment a `count`
in a parent event's aggregation data if it saw a new child event which referenced that parent.
The bundle provided by the server only includes child events which were known at the
time the client would receive the bundle. For example, in a single `/sync` response
The aggregation provided by the server only includes child events which were known at the
time the client would receive the aggregation. For example, in a single `/sync` response
with the parent and multiple child events the child events would have already been
included on the parent's `m.relations` field. Events received in future syncs would
need to be aggregated manually by the client.
@ -2076,7 +2279,7 @@ Events from [ignored users](#ignoring-users) do not appear in the aggregation
from the server, however clients might still have events from ignored users cached. Like
with normal events, clients will need to de-aggregate child events sent by ignored users to
avoid them being considered in counts. Servers must additionally ensure they do not
consider child events from ignored users when preparing a bundle for the client.
consider child events from ignored users when preparing an aggregation for the client.
{{% /boxes/note %}}
When a parent event is redacted, the child events which pointed to that parent remain, however
@ -2085,7 +2288,7 @@ to de-aggregate or disassociate the event once the relationship is lost. Clients
aggregation or which handle redactions locally should do the same.
It is suggested that clients perform local echo on aggregations — for instance, aggregating
a new child event into a bundle optimistically until the server returns a failure or the client
a new child event into a parent event optimistically until the server returns a failure or the client
gives up on sending the event, at which point the event should be de-aggregated and an
error or similar shown. The client should be cautious to not aggregate an event twice if
it has already optimistically aggregated the event. Clients are encouraged to take this
@ -2094,7 +2297,7 @@ likely using the transaction ID as a temporary event ID until a proper event ID
{{% boxes/warning %}}
Due to history visibility restrictions, child events might not be visible to the user
if they are in a section of history the user cannot see. This means any bundles which would
if they are in a section of history the user cannot see. This means any aggregations which would
normally include those events will be lacking them and the client will not be able to
locally aggregate the events either — relating events of importance (such as votes) should
take into consideration history visibility.
@ -2113,6 +2316,19 @@ following endpoint.
This endpoint is particularly useful if the client has lost context on the aggregation for
a parent event and needs to rebuild/verify it.
When using the `recurse` parameter, note that there no way for a client to
control how far the server recurses. If the client decides that the server's
recursion level is insufficient, it could, for example, perform the recursion
itself, or disable whatever feature requires more recursion.
Filters specified via `event_type` or `rel_type` will be applied to all events
returned, whether direct or indirect relations. Events that would match the filter,
but whose only relation to the original given event is through a non-matching
intermediate event, will not be included. This means that supplying a `rel_type`
parameter of `m.thread` is not appropriate for fetching all events in a thread since
relations to the threaded events would be filtered out. For this purpose, clients should
omit the `rel_type` parameter and perform any necessary filtering on the client side.
{{% boxes/note %}}
Because replies do not use `rel_type`, they will not be accessible via this API.
{{% /boxes/note %}}
@ -2478,25 +2694,6 @@ users, they should include the display name and avatar URL fields in
these events so that clients already have these details to hand, and do
not have to perform extra round trips to query it.
## Security
### Rate limiting
Homeservers SHOULD implement rate limiting to reduce the risk of being
overloaded. If a request is refused due to rate limiting, it should
return a standard error response of the form:
```json
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "string",
"retry_after_ms": integer (optional)
}
```
The `retry_after_ms` key SHOULD be included to tell the client how long
they have to wait in milliseconds before they can try again.
## Modules
Modules are parts of the Client-Server API which are not universal to
@ -2542,7 +2739,7 @@ that profile.
| [Room Upgrades](#room-upgrades) | Required | Required | Required | Required | Optional |
| [Server Administration](#server-administration) | Optional | Optional | Optional | Optional | Optional |
| [Event Context](#event-context) | Optional | Optional | Optional | Optional | Optional |
| [Third Party Networks](#third-party-networks) | Optional | Optional | Optional | Optional | Optional |
| [Third-party Networks](#third-party-networks) | Optional | Optional | Optional | Optional | Optional |
| [Send-to-Device Messaging](#send-to-device-messaging) | Optional | Optional | Optional | Optional | Optional |
| [Device Management](#device-management) | Optional | Optional | Optional | Optional | Optional |
| [End-to-End Encryption](#end-to-end-encryption) | Optional | Optional | Optional | Optional | Optional |
@ -2557,6 +2754,7 @@ that profile.
| [Moderation policies](#moderation-policy-lists) | Optional | Optional | Optional | Optional | Optional |
| [Spaces](#spaces) | Optional | Optional | Optional | Optional | Optional |
| [Event Replacements](#event-replacements) | Optional | Optional | Optional | Optional | Optional |
| [Event Annotations and reactions](#event-annotations-and-reactions) | Optional | Optional | Optional | Optional | Optional |
| [Threading](#threading) | Optional | Optional | Optional | Optional | Optional |
| [Reference Relations](#reference-relations) | Optional | Optional | Optional | Optional | Optional |
@ -2643,5 +2841,6 @@ systems.
{{< cs-module name="moderation_policies" >}}
{{< cs-module name="spaces" >}}
{{< cs-module name="event_replacements" >}}
{{< cs-module name="event_annotations" >}}
{{< cs-module name="threading" >}}
{{< cs-module name="reference_relations" >}}
{{< cs-module name="reference_relations" >}}

@ -26,6 +26,15 @@ These events can also be received in a `/events` response or in the
#### Server Behaviour
Servers MUST reject clients from setting account data for event types
that the server manages. Currently, this only includes
[m.fully\_read](#mfully_read).
Servers MUST reject setting account data for event types
that the server manages by using a 405 error response.
Currently, this only includes [`m.fully_read`](#mfully_read)
and [`m.push_rules`](#push-rules-events). This applies to
both global and room-specific account data.
{{% boxes/note %}}
{{% changed-in v="1.10" %}} `m.push_rules` was added to the rejection
list.
{{% /boxes/note %}}
Servers must allow clients to read the above event types as normal.

@ -7,7 +7,7 @@ user wants to send to a room would be uploaded here, as would an avatar
the user wants to use.
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
returns an `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).
@ -23,9 +23,9 @@ When serving content, the server SHOULD provide a
interacting with the media repository.
{{% /boxes/added-in-paragraph %}}
#### Matrix Content (MXC) URIs
#### Matrix Content (`mxc://`) URIs
Content locations are represented as Matrix Content (MXC) URIs. They
Content locations are represented as Matrix Content (`mxc://`) URIs. They
look like:
mxc://<server-name>/<media-id>
@ -88,10 +88,10 @@ The HTTP GET endpoint does not require any authentication. Knowing the
URL of the content is sufficient to retrieve the content, even if the
entity isn't in the room.
MXC URIs are vulnerable to directory traversal attacks such as
`mxc://` URIs are vulnerable to directory traversal attacks such as
`mxc://127.0.0.1/../../../some_service/etc/passwd`. This would cause the
target homeserver to try to access and return this file. As such,
homeservers MUST sanitise MXC URIs by allowing only alphanumeric
homeservers MUST sanitise `mxc://` URIs by allowing only alphanumeric
(`A-Za-z0-9`), `_` and `-` characters in the `server-name` and
`media-id` values. This set of whitelisted characters allows URL-safe
base64 encodings specified in RFC 4648. Applying this character

@ -51,6 +51,9 @@ keys.
##### Key algorithms
Different key algorithms are used for different purposes. Each key algorithm
is identified by a name and is represented in a specific way.
The name `ed25519` corresponds to the
[Ed25519](http://ed25519.cr.yp.to/) signature algorithm. The key is a
32-byte Ed25519 public key, encoded using [unpadded Base64](/appendices/#unpadded-base64). Example:
@ -64,9 +67,9 @@ Example:
"JGLn/yafz74HB2AbPLYJWIVGnKAtqECOBf11yyXac2Y"
The name `signed_curve25519` also corresponds to the Curve25519
algorithm, but a key using this algorithm is represented by an object
with the following properties:
The name `signed_curve25519` also corresponds to the Curve25519 ECDH algorithm,
but the key is signed so that it can be authenticated. A key using this
algorithm is represented by an object with the following properties:
`KeyObject`
@ -74,6 +77,7 @@ with the following properties:
|------------|------------|---------------------------------------------------------------------------------------------------------------------------------------------------|
| 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](/appendices/#signing-json). |
| fallback | boolean | Indicates whether this is a [fallback key](#one-time-and-fallback-keys). Defaults to `false`. |
Example:
@ -88,23 +92,54 @@ Example:
}
```
`ed25519` and `curve25519` keys are used for [device keys](#device-keys).
Additionally, `ed25519` keys are used for [cross-signing keys](#cross-signing).
`signed_curve25519` keys are used for [one-time and fallback keys](#one-time-and-fallback-keys).
##### Device keys
Each device should have one Ed25519 signing key. This key should be
generated on the device from a cryptographically secure source, and the
private part of the key should never be exported from the device. This
key is used as the fingerprint for a device by other clients.
key is used as the fingerprint for a device by other clients, and signs the
device's other keys.
A device will generally need to generate a number of additional keys.
Details of these will vary depending on the messaging algorithm in use.
Algorithms generally require device identity keys as well as signing
keys. Some algorithms also require one-time keys to improve their
secrecy and deniability. These keys are used once during session
establishment, and are then thrown away.
For Olm version 1, each device also requires a single Curve25519 identity
key.
##### One-time and fallback keys
In addition to the device keys, which are long-lived, some encryption
algorithms require that devices may also have a number of one-time keys, which
are only used once and discarded after use. For Olm version 1, devices use
`signed_curve25519` one-time keys, signed by the device's Ed25519 key.
Devices will generate one-time keys and upload them to the server; these will
later be [claimed](#post_matrixclientv3keysclaim) by other users. Servers must
ensure that each one-time key is only claimed once: a homeserver should discard
the one time key once it has been given to another user.
{{% added-in v="1.2" %}} Fallback keys are similar to one-time keys, but are
not consumed once used. If a fallback key has been uploaded, it will be
returned by the server when the device has run out of one-time keys and a user
tries to claim a key. Fallback keys should be replaced with new fallback keys
as soon as possible after they have been used.
{{% boxes/warning %}}
Fallback keys are used to prevent one-time key exhaustion when devices
are offline/unable to upload additional keys, though sessions started using
fallback keys could be vulnerable to replay attacks.
{{% /boxes/warning %}}
For Olm version 1, each device requires a single Curve25519 identity
key, and a number of signed Curve25519 one-time keys.
Devices will be informed, [via `/sync`](#e2e-extensions-to-sync), about the number of
one-time keys remaining that can be claimed, as well as whether the fallback
keys have been used. The device can thus ensure that, while it is online, there
is a sufficient supply of one-time keys available, and that the fallback keys
get replaced if they have been used.
##### Uploading keys
@ -115,11 +150,10 @@ signed by that key, as described in [Signing
JSON](/appendices/#signing-json).
One-time and fallback keys are also uploaded to the homeserver using the
[`/keys/upload`](/client-server-api/#post_matrixclientv3keysupload) API.
{{% added-in v="1.2" %}} Fallback keys are similar to one-time keys, but
are not consumed once used. They are only used when the device has run out
of one-time keys, and can be replaced by a new fallback key.
[`/keys/upload`](/client-server-api/#post_matrixclientv3keysupload) API. New
one-time and fallback keys are uploaded as needed. Fallback keys for key
algorithms whose format is a signed JSON object should contain a property named
`fallback` with a value of `true`.
Devices must store the private part of each key they upload. They can
discard the private part of a one-time key when they receive a message
@ -129,12 +163,6 @@ never know that it can discard the key. Therefore a device could end up
trying to store too many private keys. A device that is trying to store
too many private keys may discard keys starting with the oldest.
{{% boxes/warning %}}
Fallback keys are used to prevent one-time key exhaustion when devices
are offline/unable to upload additional keys, though sessions started using
fallback keys could be vulnerable to replay attacks.
{{% /boxes/warning %}}
{{% boxes/warning %}}
Clients should not store the private half of fallback keys indefinitely
to avoid situations where attackers can decrypt past messages sent using
@ -280,7 +308,7 @@ properties.
| key | JWK | **Required.** A [JSON Web Key](https://tools.ietf.org/html/rfc7517#appendix-A.3) object. |
| 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 should support the SHA-256 hash, which uses the key `sha256`. |
| v | string | **Required.** Version of the encrypted attachments protocol. Must be `v2`. |
| v | string | **Required.** Version of the encrypted attachment's protocol. Must be `v2`. |
`JWK`
@ -353,21 +381,6 @@ Example:
}
```
##### Claiming one-time keys
A client wanting to set up a session with another device can claim a
one-time key for that device. This is done by making a request to the
[`/keys/claim`](/client-server-api/#post_matrixclientv3keysclaim) API.
A homeserver should rate-limit the number of one-time keys that a given
user or remote server can claim. A homeserver should discard the public
part of a one time key once it has given that key to another user.
{{% added-in v="1.2" %}} If the device has run out of one-time keys which
can be claimed, the homeserver will return the fallback key (if one was
uploaded). Fallback keys are not deleted once used and should be replaced
by the device when they are able to upload more one-time keys.
#### Device verification
Before Alice sends Bob encrypted data, or trusts data received from him,
@ -647,32 +660,34 @@ The process between Alice and Bob verifying each other would be:
11. 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.
12. Both Alice and Bob's devices perform an Elliptic-curve
Diffie-Hellman
(*ECDH(K<sub>A</sub><sup>private</sup>*,*K<sub>B</sub><sup>public</sup>*)),
using the result as the shared secret.
12. Both Alice's and Bob's devices perform an Elliptic-curve Diffie-Hellman using
their private ephemeral key, and the other device's ephemeral public key
(*ECDH(K<sub>A</sub><sup>private</sup>*,*K<sub>B</sub><sup>public</sup>*)
for Alice's device and
*ECDH(K<sub>B</sub><sup>private</sup>*,*K<sub>A</sub><sup>public</sup>*)
for Bob's device), using the result as the shared secret.
13. 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.
14. Alice and Bob compare the strings shown by their devices, and tell
their devices if they match or not.
15. Assuming they match, Alice and Bob's devices calculate the HMAC of
their own device keys and a comma-separated sorted list 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](#hkdf-calculation).
15. Assuming they match, Alice and Bob's devices each calculate Message
Authentication Codes (MACs) for:
* Each of the keys that they wish the other user to verify (usually their
device ed25519 key and their master cross-signing key).
* The complete list of key IDs that they wish the other user to verify.
The MAC calculation is defined [below](#mac-calculation).
16. Alice's device sends Bob's device an `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.
17. 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
the device calculates the MACs of its copies of the other device's
keys given in the message, as well as the MAC 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
compares these with the MAC values given in the message, and if
everything matches then the device keys are verified.
18. Alice and Bob's devices send `m.key.verification.done` messages to complete
the verification.
@ -756,7 +771,59 @@ following error codes are used in addition to those already specified:
{{% event event="m.key.verification.mac" %}}
###### HKDF calculation
###### MAC calculation
During the verification process, Message Authentication Codes (MACs) are calculated
for keys and lists of key IDs.
The method used to calculate these MACs depends upon the value of the
`message_authentication_code` property in the [`m.key.verification.accept`](#mkeyverificationaccept)
message. All current implementations should use the `hkdf-hmac-sha256.v2` method which is
defined as follows:
1. An HMAC key is generated using HKDF, as defined in [RFC
5869](https://tools.ietf.org/html/rfc5869), using SHA-256 as the hash
function. The shared secret is supplied as the input keying 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.
- 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.
2. A MAC is then generated using HMAC as defined in [RFC
2104](https://tools.ietf.org/html/rfc2104) with the key generated above and
using SHA-256 as the hash function.
If a key is being MACed, the MAC is performed on the public key as encoded
according to the [key algorithm](#key-algorithms). For example, for `ed25519`
keys, it is the unpadded base64-encoded key.
If the key list is being MACed, the list is sorted lexicographically and
comma-separated with no extra whitespace added, with each key written in the
form `{algorithm}:{keyId}`. For example, the key list could look like:
`ed25519:Cross+Signing+Key,ed25519:DEVICEID`. In this way, the recipient can
reconstruct the list from the names in the `mac` property of the
`m.key.verification.mac` message and ensure that no keys were added or removed.
3. The MAC values are base64-encoded and sent in a
[`m.key.verification.mac`](#mkeyverificationmac) message.
{{% boxes/note %}}
The MAC method `hkdf-hmac-sha256` used an incorrect base64 encoding, due to a
bug in the original implementation in libolm. To remedy this,
`hkdf-hmac-sha256.v2` was introduced, which calculates the MAC in the same way,
but uses a correct base64 encoding. `hkdf-hmac-sha256` is deprecated and will
be removed in a future version of the spec. Use of `hkdf-hmac-sha256` should
be avoided whenever possible: if both parties support `hkdf-hmac-sha256.v2`,
then `hkdf-hmac-sha256` MUST not be used.
{{% /boxes/note %}}
###### SAS 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
@ -771,15 +838,15 @@ is the concatenation of:
- 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 device which sent the `m.key.verification.start` message, encoded as
unpadded base64, 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 device which sent the `m.key.verification.accept` message, encoded as
unpadded base64, followed by `|`.
- The `transaction_id` being used.
When the `key_agreement_protocol` is the deprecated method `curve25519`,
@ -804,23 +871,9 @@ HKDF is used over the plain shared secret as it results in a harder
attack as well as more uniform data to work with.
{{% /boxes/rationale %}}
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 info
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](#hkdf-calculation) then take sequences of 13 bits
Generate 5 bytes using [HKDF](#sas-hkdf-calculation) 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.
@ -838,7 +891,7 @@ separator, such as dashes, or with the numbers on individual lines.
###### SAS method: `emoji`
Generate 6 bytes using [HKDF](#hkdf-calculation) then split the first 42 bits
Generate 6 bytes using [HKDF](#sas-hkdf-calculation) 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:
@ -847,7 +900,7 @@ following table to get the corresponding emoji:
{{% boxes/note %}}
This table is available as JSON at
<https://github.com/matrix-org/matrix-doc/blob/master/data-definitions/sas-emoji.json>
<https://github.com/matrix-org/matrix-spec/blob/main/data-definitions/sas-emoji.json>.
{{% /boxes/note %}}
{{% boxes/rationale %}}
@ -1218,10 +1271,10 @@ 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](#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.
In contrast with [key requests](#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, the client requires a
[decryption key](#decryption-key) to decrypt the session keys.
To create a backup, a client will call [POST
/\_matrix/client/v3/room\_keys/version](#post_matrixclientv3room_keysversion) and define how the keys are to
@ -1242,7 +1295,7 @@ Clients must only store keys in backups after they have ensured that the
- checking that it is signed by the user's [master cross-signing
key](#cross-signing) or by a verified device belonging to the same user, or
- by deriving the public key from a private key that it obtained from a trusted
- deriving the public key from a private key that it obtained from a trusted
source. Trusted sources for the private key include the user entering the
key, retrieving the key stored in [secret storage](#secret-storage), or
obtaining the key via [secret sharing](#sharing) from a verified device
@ -1259,31 +1312,24 @@ replace it with the new key based on the key metadata as follows:
- and finally, if `is_verified` and `first_message_index` are equal,
then it will keep the key with a lower `forwarded_count`.
###### Recovery key
###### Decryption 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:
Normally, the decryption key (i.e. the secret part of the encryption key) is
stored on the server or shared with other devices using the [Secrets](#secrets)
module. When doing so, it is identified using the name `m.megolm_backup.v1`,
and the key is base64-encoded before being encrypted.
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](https://en.bitcoin.it/wiki/Base58Check_encoding#Base58_symbol_chart),
that is, using the alphabet
`123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`.
4. A space should be added after every 4th character.
If the backup decryption key is given directly to the user, the key should be
presented as a string using the common [cryptographic key
representation](/appendices/#cryptographic-key-representation).
When reading in a recovery key, clients must disregard whitespace, and
perform the reverse of steps 1 through 3.
The recovery key can also be stored on the server or shared with other devices
using the [Secrets](#secrets) module. When doing so, it is identified using the
name `m.megolm_backup.v1`, and the key is base64-encoded before being
encrypted.
{{% boxes/note %}}
The backup decryption key was previously referred to as a "recovery
key". However, this conflicted with common practice in client user
interfaces, which often use the term "recovery key" to refer to the [secret
storage](#storage) key. The term "recovery key" is no longer used in this
specification.
{{% /boxes/note %}}
###### Backup algorithm: `m.megolm_backup.v1.curve25519-aes-sha2`
@ -1313,10 +1359,18 @@ The `session_data` field in the backups is constructed as follows:
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`.
5. Pass an empty string 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`.
{{% boxes/warning %}}
Step 5 was intended to pass the raw encrypted data, but due to a bug in libolm,
all implementations have since passed an empty string instead.
Future versions of the spec will fix this problem. See
[MSC4048](https://github.com/matrix-org/matrix-spec-proposals/pull/4048) for a
potential new key backup algorithm version that would fix this issue.
{{% /boxes/warning %}}
{{% definition path="api/client-server/definitions/key_backup_session_data" %}}
@ -1654,7 +1708,7 @@ When a client is updating a Megolm session in its store, the client MUST ensure:
{{% http-api spec="client-server" api="keys" %}}
##### <a name="e2e-extensions-to-sync"> Extensions to /sync
##### Extensions to /sync {#e2e-extensions-to-sync}
This module adds an optional `device_lists` property to the [`/sync`](/client-server-api/#get_matrixclientv3sync) response,
as specified below. The server need only populate this property for an
@ -1717,9 +1771,9 @@ Example response:
],
},
"device_one_time_keys_count": {
"curve25519": 10,
"signed_curve25519": 20
}
},
"device_unused_fallback_key_types": ["signed_curve25519"]
}
```

@ -0,0 +1,99 @@
### Event annotations and reactions
{{% added-in v="1.7" %}}
#### `m.annotation` relationship type
Annotations are events that use an [event
relationship](#forming-relationships-between-events) with a `rel_type` of
`m.annotation`.
Annotations are normally used for "reactions": for example, if the user wants
to react to an event with a thumbs-up, then the client sends an annotation
event with the corresponding emoji (👍). Another potential usage is to allow
bots to send an event indicating the success or failure of a command.
Along with the normal properties `event_id` and `rel_type`, an `m.relates_to`
property with `rel_type: m.annotation` should contain a `key` that indicates the
annotation being applied. For example, when reacting with emojis, the key
contains the emoji being used.
An example `m.annotation` relationship is shown below:
```json
"m.relates_to": {
"rel_type": "m.annotation",
"event_id": "$some_event_id",
"key": "👍"
}
```
{{% boxes/note %}}
Any `type` of event is eligible for an annotation, including state events.
{{% /boxes/note %}}
#### Events
{{% event event="m.reaction" %}}
#### Client behaviour {id="annotations-client-behaviour"}
The intention of annotations is that they are counted up, rather than being
displayed individually. Clients must keep count of the number of annotations
with a given event `type` and annotation `key` they observe for each event;
these counts are typically presented alongside the event in the timeline.
When performing this count:
* Each event `type` and annotation `key` should normally be counted
separately, though whether to actually do so is an implementation decision.
* Annotation events sent by [ignored users](#ignoring-users) should be
excluded from the count.
* Multiple identical annotations (i.e., with the same event `type` and
annotation `key`) from the same user (i.e., events with the same `sender`)
should be treated as a single annotation.
* Implementations should ignore any annotation event which refers to an event
which itself has an `m.relates_to` with `rel_type: m.annotation` or
`rel_type: m.replace`. In other words, it is not possible to annotate a
[replacement event](#event-replacements) or an annotation. Annotations should
instead refer to the original event.
* When an annotation is redacted, it is removed from the count.
{{% boxes/note %}}
It is not possible to edit a reaction, since replacement events do not change
`m.relates_to` (see [Applying `m.new_content`](#applying-mnew_content)), and
there is no other meaningful content within `m.reaction`. If a user wishes to
change their reaction, the original reaction should be redacted and a new one
sent in its place.
{{% /boxes/note %}}
{{% boxes/note %}}
The `key` field in `m.reaction` can be any string so clients must take care to
render long reactions in a sensible manner. For example, clients can elide
overly-long reactions.
{{% /boxes/note %}}
#### Server behaviour
##### Avoiding duplicate annotations
Homeservers should prevent users from sending a second annotation for a given
event with identical event `type` and annotation `key` (unless the first event
has been redacted).
Attempts to send such an annotation should be rejected with a 400 error and an
error code of `M_DUPLICATE_ANNOTATION`.
Note that this does not guarantee that duplicate annotations will not arrive
over federation. Clients are responsible for deduplicating received
annotations when [counting annotations](#annotations-client-behaviour).
##### Server-side aggregation of `m.annotation` relationships
`m.annotation` relationships are *not*
[aggregated](#aggregations-of-child-events) by the server. In other words,
`m.annotation` is not included in the `m.relations` property.

@ -133,13 +133,6 @@ being overwritten entirely by `m.new_content`, with the exception of `m.relates_
which is left *unchanged*. Any `m.relates_to` property within `m.new_content`
is ignored.
{{% boxes/note %}}
Note that server implementations must not *actually* overwrite
the original event's `content`: instead the server presents it as being overwritten
when it is served over the client-server API. See [Server-side replacement of content](#server-side-replacement-of-content)
below.
{{% /boxes/note %}}
For example, given a pair of events:
```json
@ -195,65 +188,81 @@ replacement event.
##### Server-side aggregation of `m.replace` relationships
{{< changed-in v="1.7" >}}
Note that there can be multiple events with an `m.replace` relationship to a
given event (for example, if an event is edited multiple times). These should
be [aggregated](#aggregations) by the homeserver.
be [aggregated](#aggregations-of-child-events) by the homeserver.
The aggregation format of `m.replace` relationships gives the **most recent**
replacement event, formatted [as normal](#room-event-format).
The aggregation format of `m.replace` relationships gives the `event_id`,
`origin_server_ts`, and `sender` of the **most recent** replacement event. The
most recent event is determined by comparing `origin_server_ts`; if two or more
replacement events have identical `origin_server_ts`, the event with the
The most recent event is determined by comparing `origin_server_ts`; if two or
more replacement events have identical `origin_server_ts`, the event with the
lexicographically largest `event_id` is treated as more recent.
This aggregation is bundled under the `unsigned` property as `m.relations` for any
event that is the target of an `m.replace` relationship. For example:
As with any other aggregation of child events, the `m.replace` aggregation is
included under the `m.relations` property in `unsigned` for any event that is
the target of an `m.replace` relationship. For example:
```json
{
"event_id": "$original_event_id",
// irrelevant fields not shown
"type": "m.room.message",
"content": {
"body": "I really like cake",
"msgtype": "m.text",
"formatted_body": "I really like cake"
},
"unsigned": {
"m.relations": {
"m.replace": {
"event_id": "$latest_edit_event_id",
"origin_server_ts": 1649772304313,
"sender": "@editing_user:localhost"
"type": "m.room.message",
"content": {
"body": "* I really like *chocolate* cake",
"msgtype": "m.text",
"m.new_content": {
"body": "I really like *chocolate* cake",
"msgtype": "m.text"
},
"m.relates_to": {
"rel_type": "m.replace",
"event_id": "$original_event_id"
}
}
}
}
}
// irrelevant fields not shown
}
```
If the original event is
[redacted](#redactions), any
If the original event is [redacted](#redactions), any
`m.replace` relationship should **not** be bundled with it (whether or not any
subsequent replacements are themselves redacted). Note that this behaviour is
specific to the `m.replace` relationship. See also [redactions of edited
events](#redactions-of-edited-events) below.
##### Server-side replacement of content
**Note:** the `content` of the original event is left intact. In particular servers
should **not** replace the content with that of the replacement event.
Whenever an `m.replace` is to be bundled with an event as above, the server
should also modify the content of the original event according to the
`m.new_content` of the most recent replacement event (determined as above).
An exception applies to [`GET /_matrix/client/v3/rooms/{roomId}/event/{eventId}`](#get_matrixclientv3roomsroomideventeventid),
which should return the unmodified event (though the relationship should still
be bundled, as described above).
{{% boxes/rationale %}}
In previous versions of the specification, servers were expected to replace the
content of an edited event whenever it was served to clients (with the
exception of the
[`GET /_matrix/client/v3/rooms/{roomId}/event/{eventId}`](#get_matrixclientv3roomsroomideventeventid)
endpoint). However, that behaviour made reliable client-side implementation
difficult, and servers should no longer make this replacement.
{{% /boxes/rationale %}}
#### Client behaviour
Clients can often ignore `m.replace` events, because any events returned
by the server to the client will be updated by the server to account for
subsequent edits.
However, clients should apply the replacement themselves when the server is
unable to do so. This happens in the following situations:
* The client has already received and stored the original event before the
message edit event arrives.
* The original event (and hence its replacement) are encrypted.
Since the server will not replace the content of any edited events, clients
should take note of any replacement events they receive, and apply the
replacement whenever possible and appropriate.
Client authors are reminded to take note of the requirements for [Validity of
replacement events](#validity-of-replacement-events), and to ignore any
@ -280,8 +289,76 @@ subsequent edits, from the visible timeline. In this situation, homeservers
will return an empty `content` for the original event as with any other
redacted event, and as
[above](#server-side-aggregation-of-mreplace-relationships) the replacement
events will not be bundled with the original event. Note that the subsequent edits are
not actually redacted themselves: they simply serve no purpose within the visible timeline.
events will not be included in the aggregation bundled with the original
event. Note that the subsequent edits are not actually redacted themselves:
they simply serve no purpose within the visible timeline.
#### Edits of events with mentions
When editing an event with [user and room mentions](#user-and-room-mentions) the
replacement event will have two `m.mentions` properties:
* One at the top-level of the `content`, which should contain mentions due to
this edit revision.
* One inside the `m.new_content` property, which should contain the resolved mentions
for the final version of the event.
The difference between these properties ensures that users will not be notified
for each edit revision of an event, but allows for new users to be mentioned (or
for re-notifying if the sending client feels a large enough revision was made).
For example, if there is an event mentioning Alice:
```json5
{
"event_id": "$original_event",
"type": "m.room.message",
"content": {
"body": "Hello Alice!",
"m.mentions": {
"user_ids": ["@alice:example.org"]
}
}
}
```
And an edit to also mention Bob:
```json5
{
"content": {
"body": "* Hello Alice & Bob!",
"m.mentions": {
"user_ids": [
// Include only the newly mentioned user.
"@bob:example.org"
]
},
"m.new_content": {
"body": "Hello Alice & Bob!",
"m.mentions": {
"user_ids": [
// Include all of the mentioned users.
"@alice:example.org",
"@bob:example.org"
]
},
},
"m.relates_to": {
"rel_type": "m.replace",
"event_id": "$original_event"
}
},
// other fields as required by events
}
```
If an edit revision removes a user's mention then that user's Matrix ID should be
included in neither `m.mentions` property.
Clients may also wish to modify the [client behaviour](#user-and-room-mentions) of
determining if an event mentions the current user by checking the `m.mentions`
property under `m.new_content`.
#### Edits of replies

@ -27,18 +27,41 @@ instead.
Some message types support HTML in the event content that clients should
prefer to display if available. Currently `m.text`, `m.emote`, `m.notice`,
and `m.key.verification.request` support an additional `format` parameter of
`org.matrix.custom.html`. When this field is present, a `formatted_body`
with the HTML must be provided. The plain text version of the HTML
should be provided in the `body`.
`m.image`, `m.file`, `m.audio`, `m.video` and `m.key.verification.request`
support an additional `format` parameter of `org.matrix.custom.html`. When this
field is present, a `formatted_body` with the HTML must be provided. The plain
text version of the HTML should be provided in the `body`.
{{% boxes/note %}}
{{% changed-in v="1.10" %}}
In previous versions of the specification, the `format` and `formatted` fields
were limited to `m.text`, `m.emote`, `m.notice`, and
`m.key.verification.request`. This list is expanded to include `m.image`,
`m.file`, `m.audio` and `m.video` for [media captions](#media-captions).
{{% /boxes/note %}}
Clients should limit the HTML they render to avoid Cross-Site Scripting,
HTML injection, and similar attacks. The strongly suggested set of HTML
tags to permit, denying the use and rendering of anything else, is:
`font`, `del`, `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `blockquote`, `p`,
`a`, `ul`, `ol`, `sup`, `sub`, `li`, `b`, `i`, `u`, `strong`, `em`,
`strike`, `code`, `hr`, `br`, `div`, `table`, `thead`, `tbody`, `tr`,
`th`, `td`, `caption`, `pre`, `span`, `img`, `details`, `summary`.
`del`, `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `blockquote`, `p`, `a`, `ul`,
`ol`, `sup`, `sub`, `li`, `b`, `i`, `u`, `strong`, `em`, `s`, `code`,
`hr`, `br`, `div`, `table`, `thead`, `tbody`, `tr`, `th`, `td`,
`caption`, `pre`, `span`, `img`, `details`, `summary`.
{{% boxes/note %}}
{{% added-in v="1.10" %}}
HTML features MAY be deprecated and replaced by their modern equivalent without
requiring a [Spec Change Proposal](/proposals) when they are deprecated in the
[WHATWG HTML Living Standard](https://html.spec.whatwg.org/multipage/).
{{% /boxes/note %}}
{{% boxes/note %}}
{{% changed-in v="1.10" %}}
In previous versions of the specification, the `font` tag was suggested with the
`data-mx-bg-color`, `data-mx-color` and `color` attributes. This tag is now
deprecated in favor of the `span` tag with the `data-mx-bg-color` and
`data-mx-color` attributes in new messages.
{{% /boxes/note %}}
Not all attributes on those tags should be permitted as they may be
avenues for other disruption attempts, such as adding `onclick` handlers
@ -48,27 +71,13 @@ are listed, clients should translate the value (a `#` character followed
by a 6-character hex color code) to the appropriate CSS/attributes for
the tag.
`font`
`data-mx-bg-color`, `data-mx-color`, `color`
`span`
`data-mx-bg-color`, `data-mx-color`, `data-mx-spoiler` (see
[spoiler messages](#spoiler-messages))
`a`
`name`, `target`, `href` (provided the value is not relative and has a
scheme matching one of: `https`, `http`, `ftp`, `mailto`, `magnet`)
`img`
`width`, `height`, `alt`, `title`, `src` (provided it is a [Matrix
Content (MXC) URI](#matrix-content-mxc-uris))
`ol`
`start`
`code`
`class` (only classes which start with `language-` for syntax
highlighting)
| Tag | Permitted Attributes |
|--------|--------------------------------------------------------------------------------------------------------------------------------------------|
| `span` | `data-mx-bg-color`, `data-mx-color`, `data-mx-spoiler` (see [spoiler messages](#spoiler-messages)) |
| `a` | `name`, `target`, `href` (provided the value is not relative and has a scheme matching one of: `https`, `http`, `ftp`, `mailto`, `magnet`) |
| `img` | `width`, `height`, `alt`, `title`, `src` (provided it is a [Matrix Content (`mxc://`) URI](#matrix-content-mxc-uris)) |
| `ol` | `start` |
| `code` | `class` (only classes which start with `language-` for syntax highlighting) |
Additionally, web clients should ensure that *all* `a` tags get a
`rel="noopener"` to prevent the target page from referencing the
@ -328,11 +337,54 @@ When sending a spoiler, clients SHOULD provide the fallback in the `body` as sho
(including the reason). The fallback SHOULD NOT include the text containing spoilers since
`body` might show up in text-only clients or in notifications. To prevent spoilers showing up in
such situations, clients are strongly encouraged to first upload the text containing spoilers
to the media repository, then reference the MXC URI in a markdown-style link, as shown above.
to the media repository, then reference the `mxc://` URI in a markdown-style link, as shown above.
Clients SHOULD render spoilers differently with some sort of disclosure. For example, the
client could blur the actual text and ask the user to click on it for it to be revealed.
##### Media captions
{{% added-in v="1.10" %}}
Media messages, comprised of `m.image`, `m.file`, `m.audio` and `m.video`, can
include a caption to convey additional information about the media.
To send captions, clients MUST use the `filename` and the `body`, and optionally
the `formatted_body` with the `org.matrix.custom.html` format, described above.
If the `filename` is present, and its value is different than `body`, then
`body` is considered to be a caption, otherwise `body` is a filename. `format`
and `formatted_body` are only used for captions.
{{% boxes/note %}}
In previous versions of the specification, `body` was usually used to set the
filename of the uploaded file, and `filename` was only present on `m.file` with
the same purpose.
{{% /boxes/note %}}
An example of a media message with a caption is:
```json
{
"msgtype": "m.image",
"url": "mxc://example.org/abc123",
"filename": "dog.jpg",
"body": "this is a ~~cat~~ picture :3",
"format": "org.matrix.custom.html",
"formatted_body": "this is a <s>cat</s> picture :3",
"info": {
"w": 479,
"h": 640,
"mimetype": "image/jpeg",
"size": 27253
},
"m.mentions": {}
}
```
Clients MUST render the caption alongside the media and SHOULD prefer its
formatted representation.
#### Server behaviour
Homeservers SHOULD reject `m.room.message` events which don't have a

@ -1,61 +1,90 @@
### User and room mentions
This module allows users to mention other users and rooms within a room message.
This is achieved by including a [Matrix URI](/appendices/#uris) in the HTML body of
an [m.room.message](#mroommessage) event. This module does not have any server-specific
behaviour to it.
{{% changed-in v="1.7" %}}
Mentions apply only to [m.room.message](#mroommessage) events where the `msgtype` is
`m.text`, `m.emote`, or `m.notice`. The `format` for the event must be
`org.matrix.custom.html` and therefore requires a `formatted_body`.
This module allows users to "mention" other users and rooms within a room event.
This is primarily used as an indicator that the recipient should receive a notification
about the event.
This is achieved by including metadata in the `m.mentions` content property of
the event to reference the entity being mentioned.
`m.mentions` is defined as follows:
To make a mention, reference the entity being mentioned in the
`formatted_body` using an anchor, like so:
{{% definition path="api/client-server/definitions/m.mentions" %}}
An event's content will then look like this:
```json
{
"body": "Hello Alice!",
"msgtype": "m.text",
"format": "org.matrix.custom.html",
"formatted_body": "Hello <a href='https://matrix.to/#/@alice:example.org'>Alice</a>!"
"formatted_body": "Hello <a href='https://matrix.to/#/@alice:example.org'>Alice</a>!",
"m.mentions": {
"user_ids": ["@alice:example.org"]
}
}
```
Additionally, see the [`.m.rule.is_user_mention`](#_m_rule_is_user_mention) and
[`.m.rule.is_room_mention`](#_m_rule_is_room_mention) push rules.
Users should not add their own Matrix ID to the `m.mentions` property as outgoing
messages cannot self-notify.
{{% boxes/warning %}}
If an encrypted event contains an `m.mentions` in its payload, it should be
encrypted as normal. To properly process mentions in encrypted rooms, events
must be decrypted first. See [receiving notifications](#receiving-notifications).
{{% /boxes/warning %}}
Note that, for backwards compatibility, push rules such as [`.m.rule.contains_display_name`](#_m_rule_contains_display_name),
[`.m.rule.contains_user_name`](#_m_rule_contains_user_name), and
[`.m.rule.roomnotif`](#_m_rule_roomnotif) continue to match if the `body` of
the event contains the user's display name or ID. To avoid unintentional notifications,
**it is recommended that clients include a `m.mentions` property on each event**.
(If there are no mentions to include it can be an empty object.)
{{% boxes/rationale %}}
In previous versions of the specification, mentioning users was done by
including the user's display name or the localpart of their Matrix ID and room
mentions were done by including the string "@room" in the plaintext `body` of
the event. This was prone to confusing and buggy behaviour.
{{% /boxes/rationale %}}
#### Client behaviour
In addition to using the appropriate `Matrix URI` for the mention,
clients should use the following guidelines when making mentions in
events to be sent:
Although it is possible to silently mention users, it is recommended to include a
[Matrix URI](/appendices/#uris) in the HTML body of an [m.room.message](#mroommessage)
event. This applies only to [m.room.message](#mroommessage) events where the `msgtype` is
`m.text`, `m.emote`, or `m.notice`. The `format` for the event must be
`org.matrix.custom.html` and therefore requires a `formatted_body`.
Clients should use the following guidelines when adding a `Matrix URI`
representing a mention to events to be sent:
- When mentioning users, use the user's potentially ambiguous display
- When linking to 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.
- When mentioning rooms, use the canonical alias for the room. If the
- When linking to rooms, use the canonical alias for the room. If the
room does not have a canonical alias, prefer one of the aliases
listed on the room. If no alias can be found, fall back to the room
ID. In all cases, use the alias/room ID being linked to as the
anchor's text.
The text component of the anchor should be used in the event's `body`
where the mention would normally be represented, as shown in the example
where the link would normally be represented, as shown in the example
above.
Clients should display mentions differently from other elements. For
example, this may be done by changing the background color of the
mention to indicate that it is different from a normal link.
If the current user is mentioned in a message (either by a mention as
defined in this module or by a push rule), the client should show that
If the current user is mentioned in a message, the client should show that
mention differently from other mentions, such as by using a red
background color to signify to the user that they were mentioned.
background color to signify to the user that they were mentioned. Note that
it is possible for a user to be mentioned without including their `Matrix URI`
in the event.
When clicked, the mention should navigate the user to the appropriate
user or room information.
{{% boxes/note %}}
Similar to legacy [matrix.to URLs](/appendices/#matrixto-navigation),
groups used to be representable by mentions. They follow a similar format
to room mentions, though using the group ID in both the link and anchor
text.
{{% /boxes/note %}}

@ -75,8 +75,8 @@ technique for receiving updates to the policy's rules.
#### Events
The `entity` described by the state events can contain `*` and `?` to
match zero or more characters and exactly one character respectively. Note that
The `entity` described by the state events is interpreted as a
[glob-style pattern](/appendices#glob-style-matching). 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.

@ -1,8 +1,8 @@
### OpenID
This module allows users to verify their identity with a third party
service. The third party service does need to be matrix-aware in that it
This module allows users to verify their identity with a third-party
service. The third-party service does need to be matrix-aware in that it
will need to know to resolve matrix homeservers to exchange the user's
token for identity information.

@ -51,87 +51,41 @@ such as Apple's APNS or Google's GCM. This happens as follows:
Definitions for terms used in this section are below:
Push Provider
A push provider is a service managed by the device vendor which can send
notifications directly to the device. Google Cloud Messaging (GCM) and
Apple Push Notification Service (APNS) are two examples of push
providers.
Push Gateway
A push gateway is a server that receives HTTP event notifications from
homeservers and passes them on to a different protocol such as APNS for
iOS devices or GCM for Android devices. Clients inform the homeserver
which Push Gateway to send notifications to when it sets up a Pusher.
Pusher
A pusher is a worker on the homeserver that manages the sending of HTTP
notifications for a user. A user can have multiple pushers: one per
device.
Push Rule
A push rule is a single rule that states under what *conditions* an
event should be passed onto a push gateway and *how* the notification
should be presented. These rules are stored on the user's homeserver.
They are manually configured by the user, who can create and view them
via the Client/Server API.
Push Ruleset
A push ruleset *scopes a set of rules according to some criteria*. For
example, some rules may only be applied for messages from a particular
sender, a particular room, or by default. The push ruleset contains the
entire set of scopes and rules.
: A push provider is a service managed by the device vendor which can send
notifications directly to the device. Google Cloud Messaging (GCM) and
Apple Push Notification Service (APNS) are two examples of push
providers.
#### Client behaviour
Clients MUST configure a Pusher before they will receive push
notifications. There is a single API endpoint for this, as described
below.
{{% http-api spec="client-server" api="pusher" %}}
##### Listing Notifications
Push Gateway
A client can retrieve a list of events that it has been notified about.
This may be useful so that users can see a summary of what important
messages they have received.
: A push gateway is a server that receives HTTP event notifications from
homeservers and passes them on to a different protocol such as APNS for
iOS devices or GCM for Android devices. Clients inform the homeserver
which Push Gateway to send notifications to when it sets up a Pusher.
{{% http-api spec="client-server" api="notifications" %}}
Pusher
##### Receiving notifications
: A pusher is a worker on the homeserver that manages the sending of HTTP
notifications for a user. A user can have multiple pushers: one per
device.
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.
Push Rule
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. Which specific events are affected can vary depending
on whether a [threaded read receipt](#threaded-read-receipts) was used.
Note that users can send both an `m.read` and `m.read.private` receipt,
both of which are capable of clearing notifications.
: A push rule is a single rule that states under what *conditions* an
event should be passed onto a push gateway and *how* the notification
should be presented. These rules are stored on the user's homeserver.
They are manually configured by the user, who can create and view them
via the Client/Server API.
If the user has both `m.read` and `m.read.private` set in the room then
the receipt which is more recent/ahead must be used to determine where
the user has read up to. For example, given an oldest-first set of events A,
B, C, and D the `m.read` receipt could be at event C and `m.read.private`
at event A - the user is considered to have read up to event C. If the
`m.read.private` receipt is then updated to point to B or C, the user's
notification state doesn't change (the `m.read` receipt is still more
ahead), however if the `m.read.private` receipt were to be updated to
event D then the user has read up to D (the `m.read` receipt is now
behind the `m.read.private` receipt).
Push Ruleset
{{< added-in v="1.4" >}} When handling threaded read receipts, the server
is to partition the notification count to each thread (with the main timeline
being its own thread). To determine if an event is part of a thread the
server follows the [event relationship](#forming-relationships-between-events)
until it finds a thread root (as specified by the [threading module](#threading)),
however it is not recommended that the server traverse infinitely. Instead,
implementations are encouraged to do a maximum of 3 hops to find a thread
before deciding that the event does not belong to a thread. This is primarily
to ensure that future events, like `m.reaction`, are correctly considered
"part of" a given thread.
: A push ruleset *scopes a set of rules according to some criteria*. For
example, some rules may only be applied for messages from a particular
sender, a particular room, or by default. The push ruleset contains the
entire set of scopes and rules.
##### Push Rules
#### Push Rules
A push rule is a single rule that states under what *conditions* an
event should be passed onto a push gateway and *how* the notification
@ -144,27 +98,31 @@ 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.
1. **Override rules (`override`).**
The highest priority rules are user-configured overrides.
Content-specific Rules `content`
These configure behaviour for (unencrypted) messages that match certain
patterns. Content rules take one parameter: `pattern`, that gives the
glob pattern to match against. This is treated in the same way as
`pattern` for `event_match`.
1. **Content-specific rules (`content`).**
These configure behaviour for messages that match certain patterns. Content
rules take one parameter: `pattern`, that gives the
[glob-style pattern](/appendices#glob-style-matching) to match against.
The match is performed case-insensitively, and must match any substring of
the `content.body` property which starts and ends at a word boundary. A word
boundary is defined as the start or end of the value, or any character not
in the sets `[A-Z]`, `[a-z]`, `[0-9]` or `_`.The exact meaning of
"case insensitive" is defined by the implementation of the homeserver.
Room-specific Rules `room`
These rules change the behaviour of all messages for a given room. The
`rule_id` of a room rule is always the ID of the room that it affects.
1. **Room-specific rules (`room`).**
These rules change the behaviour of all messages for a given room. The
`rule_id` of a room rule is always the ID of the room that it affects.
Sender-specific rules `sender`
These rules configure notification behaviour for messages from a
specific Matrix user ID. The `rule_id` of Sender rules is always the
Matrix user ID of the user whose messages they'd apply to.
1. **Sender-specific rules (`sender`).**
These rules configure notification behaviour for messages from a
specific Matrix user ID. The `rule_id` of Sender rules is always the
Matrix user ID of the user whose messages they'd apply to.
Underride rules `underride`
These are identical to `override` rules, but have a lower priority than
`content`, `room` and `sender` rules.
1. **Underride rules (`underride`).**
These are identical to `override` rules, but have a lower priority than
`content`, `room` and `sender` rules.
Rules with the same `kind` can specify an ordering priority. This
determines which rule is selected in the event of multiple matches. For
@ -179,57 +137,60 @@ rules match an event, the homeserver MUST NOT notify the Push Gateway
for that event. Homeservers MUST NOT notify the Push Gateway for events
that the user has sent themselves.
###### Actions
##### Actions
All rules have an associated list of `actions`. An action affects if and
how a notification is delivered for a matching event. The following
actions are defined:
`notify`
This causes each matching event to generate a notification.
`dont_notify`
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 notification. Not all homeservers may support this. Those that do
not support it should treat it as the `notify` action.
: This causes each matching event to generate a notification.
`set_tweak`
Sets an entry in the `tweaks` dictionary key that is sent in the
notification request to the Push Gateway. This takes the form of a
dictionary with a `set_tweak` key whose value is the name of the tweak
to set. It may also have a `value` key which is the value to which it
should be set.
The following tweaks are defined:
* `sound`: A string representing the sound to be played when this notification
arrives. A value of `default` means to play a default sound. A device
may choose to alert the user by some other means if appropriate, eg.
vibration.
* `highlight`: A boolean representing whether or not this message should be highlighted
in the UI. This will normally take the form of presenting the message in
a different colour and/or style. The UI might also be adjusted to draw
particular attention to the room in which the event occurred. If a
`highlight` tweak is given with no value, its value is defined to be
`true`. If no highlight tweak is given at all then the value of
`highlight` is defined to be false.
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.
: Sets an entry in the `tweaks` dictionary key that is sent in the
notification request to the Push Gateway. This takes the form of a
dictionary with a `set_tweak` key whose value is the name of the tweak
to set. It may also have a `value` key which is the value to which it
should be set.
The following tweaks are defined:
`sound`
: A string representing the sound to be played when this notification
arrives. A value of `default` means to play a default sound. A device
may choose to alert the user by some other means if appropriate, eg.
vibration.
`highlight`
: A boolean representing whether or not this message should be highlighted
in the UI. This will normally take the form of presenting the message in
a different colour and/or style. The UI might also be adjusted to draw
particular attention to the room in which the event occurred. If a
`highlight` tweak is given with no value, its value is defined to be
`true`. If no highlight tweak is given at all then the value of
`highlight` is defined to be false.
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.
Actions that have no parameters are represented as a string. Otherwise,
they are represented as a dictionary with a key equal to their name and
other keys as their parameters, e.g.
`{ "set_tweak": "sound", "value": "default" }`
`{ "set_tweak": "sound", "value": "default" }`.
###### Conditions
{{% boxes/note %}}
Older versions of the Matrix specification included the `dont_notify` and
`coalesce` actions. These should both be considered no-ops (ignored, not
rejected) if received from a client.
{{% /boxes/note %}}
##### 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
@ -246,23 +207,18 @@ The following conditions are defined:
**`event_match`**
This is a glob pattern match on a field of the event. Parameters:
This is a glob pattern match on a property of the event. Parameters:
- `key`: The dot-separated path of the property of the event to match, e.g.
`content.body`.
- `key`: The [dot-separated path of the property](/appendices#dot-separated-property-paths)
of the event to match, e.g. `content.body`.
- `pattern`: The glob-style pattern to match against.
- `pattern`: The [glob-style pattern](/appendices#glob-style-matching) to match against.
The match is performed case-insensitively, and must match the entire value of
the event field given by `key` (though see below regarding `content.body`). The
the event property given by `key` (though see below regarding `content.body`). The
exact meaning of "case insensitive" is defined by the implementation of the
homeserver.
Within `pattern`:
* The character `*` matches zero or more characters.
* `?` matches exactly one character.
If the property specified by `key` is completely absent from the event, or does
not have a string value, then the condition will not match, even if `pattern`
is `*`.
@ -288,7 +244,7 @@ Other `topic` values which will match are:
* `"LUNCH"` (case-insensitive; `*` may match zero characters)
The following `membership` values will NOT match:
The following `topic` values will NOT match:
* `" lunch"` (note leading space)
* `"lunc"` (`?` must match a character)
* `null` (not a string)
@ -306,7 +262,7 @@ following event will match:
```json
{
"content": {
"body": "An example event.",
"body": "An example event."
},
"event_id": "$143273976499sgjks:example.org",
"room_id": "!636q39766251:example.com",
@ -332,12 +288,102 @@ For an example of this, see the default rule
[`.m.rule.tombstone`](#mruletombstone) below.
{{% /boxes/warning %}}
**`event_property_is`**
This is an exact value match on a property of the event. Parameters:
- `key`: The [dot-separated path of the property](/appendices#dot-separated-property-paths)
of the event to match, e.g. `content.body`.
- `value`: The value to match against.
The match is performed exactly and only supports non-compound [canonical JSON](/appendices#canonical-json)
values: strings, integers in the range of `[-(2**53)+1, (2**53)-1]`, booleans, and
`null`.
If the property specified by `key` is completely absent from the event, or does
not have a string, integer, boolean, or `null` value, then the condition will not
match.
{{% boxes/note %}}
For example, if `key` is `content.m\.federate`, and `value` is `true`, then
the following event will match:
```json
{
"content": {
"creator": "@example:example.org",
"m.federate": true,
"predecessor": {
"event_id": "$something:example.org",
"room_id": "!oldroom:example.org"
},
"room_version": "1"
},
"event_id": "$143273582443PhrSn:example.org",
"room_id": "!636q39766251:example.com",
"sender": "@example:example.org",
"state_key": "",
"type": "m.room.create"
}
```
The following `m.federate` values will NOT match:
* `"true"` (note the string value)
* `1` (do not cast types)
{{% /boxes/note %}}
**`event_property_contains`**
This matches if an array property of an event exactly contains a value. Parameters:
- `key`: The [dot-separated path of the property](/appendices#dot-separated-property-paths)
of the event to match, e.g. `content.body`.
- `value`: The value to match against.
The array values are matched exactly and only supports non-compound [canonical JSON](/appendices#canonical-json)
values: strings, integers in the range of `[-(2**53)+1, (2**53)-1]`, booleans,
and `null`. Array values not of those types are ignored.
If the property specified by `key` is completely absent from the event, or is not
an array, then the condition will not match.
{{% boxes/note %}}
For example, if `key` is `content.alt_aliases`, and `value` is `"#myroom:example.com"`,
then the following event will match:
```json
{
"content": {
"alias": "#somewhere:localhost",
"alt_aliases": [
"#somewhere:example.org",
"#myroom:example.com"
]
},
"event_id": "$143273582443PhrSn:example.org",
"origin_server_ts": 1432735824653,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"state_key": "",
"type": "m.room.canonical_alias",
"unsigned": {
"age": 1234
}
}
```
The following `alt_aliases` values will NOT match:
* `":example.com"` (partial values do not match)
{{% /boxes/note %}}
**`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.
This matches messages where `content.body` contains the owner's display name in
that room. This is a separate condition 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`**
@ -363,7 +409,7 @@ Parameters:
to look up the power level required to send a notification type from
the `notifications` object in the power level event content.
##### Predefined Rules
#### Predefined Rules
Homeservers can specify "server-default rules". They operate at a lower
priority than "user-defined rules", except for the `.m.rule.master` rule
@ -372,7 +418,7 @@ for all server-default rules MUST start with a dot (".") to identify
them as "server-default". The following server-default rules are
specified:
###### Default Override Rules
##### Default Override Rules
**`.m.rule.master`**
@ -389,9 +435,7 @@ Definition:
"default": true,
"enabled": false,
"conditions": [],
"actions": [
"dont_notify"
]
"actions": []
}
```
@ -410,12 +454,10 @@ Definition:
{
"kind": "event_match",
"key": "content.msgtype",
"pattern": "m.notice",
"pattern": "m.notice"
}
],
"actions": [
"dont_notify",
]
"actions": []
}
```
@ -475,16 +517,53 @@ Definition:
"pattern": "m.room.member"
}
],
"actions": []
}
```
<a id="_m_rule_is_user_mention"/> **`.m.rule.is_user_mention`**
{{< added-in v="1.7" >}}
Matches any message which contains the user's Matrix ID in the list of `user_ids`
under the `m.mentions` property.
Definition:
```json
{
"rule_id": ".m.rule.is_user_mention",
"default": true,
"enabled": true,
"conditions": [
{
"kind": "event_property_contains",
"key": "content.m\\.mentions.user_ids",
"value": "[the user's Matrix ID]"
}
],
"actions": [
"dont_notify"
"notify",
{
"set_tweak": "sound",
"value": "default"
},
{
"set_tweak": "highlight"
}
]
}
```
**`.m.rule.contains_display_name`**
<a id="_m_rule_contains_display_name"/> **`.m.rule.contains_display_name`**
{{% changed-in v="1.7" %}}
Matches any message whose content is unencrypted and contains the user's
current display name in the room in which it was sent.
As of `v1.7`, this rule is deprecated and **should only be enabled if the event
does not have an [`m.mentions` property](#definition-mmentions)**.
Matches any message whose content contains the user's current display name
in the room in which it was sent.
Definition:
@ -511,6 +590,78 @@ Definition:
}
```
<a id="_m_rule_is_room_mention"/> **`.m.rule.is_room_mention`**
{{< added-in v="1.7" >}}
Matches any message from a sender with the proper power level with the `room`
property of the `m.mentions` property set to `true`.
Definition:
```json
{
"rule_id": ".m.rule.is_room_mention",
"default": true,
"enabled": true,
"conditions": [
{
"kind": "event_property_is",
"key": "content.m\\.mentions.room",
"value": true
},
{
"kind": "sender_notification_permission",
"key": "room"
}
],
"actions": [
"notify",
{
"set_tweak": "highlight"
}
]
}
```
<a id="_m_rule_roomnotif"/> **`.m.rule.roomnotif`**
{{% changed-in v="1.7" %}}
As of `v1.7`, this rule is deprecated and **should only be enabled if the event
does not have an [`m.mentions` property](#definition-mmentions)**.
Matches any message from a sender with the proper power level whose content
contains the text `@room`, signifying the whole room should be notified of
the event.
Definition:
```json
{
"rule_id": ".m.rule.roomnotif",
"default": true,
"enabled": true,
"conditions": [
{
"kind": "event_match",
"key": "content.body",
"pattern": "@room"
},
{
"kind": "sender_notification_permission",
"key": "room"
}
],
"actions": [
"notify",
{
"set_tweak": "highlight"
}
]
}
```
**<a name="mruletombstone"></a>`.m.rule.tombstone`**
Matches any state event whose type is `m.room.tombstone`. This is
@ -545,6 +696,31 @@ Definition:
}
```
**<a name="mrulereaction"></a>`.m.rule.reaction`**
{{% added-in v="1.7" %}}
Matches any event whose type is `m.reaction`. This suppresses notifications for [`m.reaction`](#mreaction) events.
Definition:
```json
{
"rule_id": ".m.rule.reaction",
"default": true,
"enabled": true,
"conditions": [
{
"kind": "event_match",
"key": "type",
"pattern": "m.reaction"
}
],
"actions": []
}
```
**`.m.rule.room.server_acl`**
{{% added-in v="1.4" %}}
@ -574,44 +750,41 @@ Definition:
}
```
**`.m.rule.roomnotif`**
**`.m.rule.suppress_edits`**
{{% added-in v="1.9" %}}
Matches any message whose content is unencrypted and contains the text
`@room`, signifying the whole room should be notified of the event.
Suppresses notifications related to [event replacements](#event-replacements).
Definition:
```json
{
"rule_id": ".m.rule.roomnotif",
"rule_id": ".m.rule.suppress_edits",
"default": true,
"enabled": true,
"conditions": [
{
"kind": "event_match",
"key": "content.body",
"pattern": "@room"
},
{
"kind": "sender_notification_permission",
"key": "room"
"kind": "event_property_is",
"key": "content.m\\.relates_to.rel_type",
"value": "m.replace"
}
],
"actions": [
"notify",
{
"set_tweak": "highlight"
}
]
"actions": []
}
```
###### Default Content Rules
##### Default Content Rules
<a id="_m_rule_contains_user_name"/> **`.m.rule.contains_user_name`**
**`.m.rule.contains_user_name`**
{{% changed-in v="1.7" %}}
Matches any message whose content is unencrypted and contains the local
part of the user's Matrix ID, separated by word boundaries.
As of `v1.7`, this rule is deprecated and **should only be enabled if the event
does not have an [`m.mentions` property](#definition-mmentions)**.
Matches any message whose content contains the local part of the user's
Matrix ID, separated by word boundaries.
Definition (as a `content` rule):
@ -634,7 +807,7 @@ Definition (as a `content` rule):
}
```
###### Default Underride Rules
##### Default Underride Rules
**`.m.rule.call`**
@ -783,14 +956,14 @@ Definition:
}
```
##### Push Rules: API
#### Push Rules: API
Clients can retrieve, add, modify and remove push rules globally or
per-device using the APIs below.
{{% http-api spec="client-server" api="pushrules" %}}
##### Push Rules: Events
#### Push Rules: Events
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`](#get_matrixclientv3sync) request.
@ -798,21 +971,21 @@ The content of the event is the current push rules for the user.
{{% event event="m.push_rules" %}}
###### Examples
##### Examples
To create a rule that suppresses notifications for the room with ID
`!dj234r78wl45Gh4D:matrix.org`:
curl -X PUT -H "Content-Type: application/json" "https://example.com/_matrix/client/v3/pushrules/global/room/%21dj234r78wl45Gh4D%3Amatrix.org?access_token=123456" -d \
'{
"actions" : ["dont_notify"]
"actions" : []
}'
To suppress notifications for the user `@spambot:matrix.org`:
curl -X PUT -H "Content-Type: application/json" "https://example.com/_matrix/client/v3/pushrules/global/sender/%40spambot%3Amatrix.org?access_token=123456" -d \
'{
"actions" : ["dont_notify"]
"actions" : []
}'
To always notify for messages that contain the work 'cake' and set a
@ -849,14 +1022,82 @@ than the room, sender and content rules):
]
}'
#### Client behaviour
Clients MUST configure a Pusher before they will receive push
notifications. There is a single API endpoint for this, as described
below.
{{% http-api spec="client-server" api="pusher" %}}
##### Listing Notifications
A client can retrieve a list of events that it has been notified about.
This may be useful so that users can see a summary of what important
messages they have received.
{{% http-api spec="client-server" api="notifications" %}}
##### 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.
For encrypted events, the homeserver has limited access to the event content
and properly processing push rules falls on the client. Clients should process
push rules for each incoming event *after decrypting* them. This may result in
needing to modify the number of unread notifications received from the homeserver.
##### Marking notifications as read
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. Which specific events are affected can vary depending
on whether a [threaded read receipt](#threaded-read-receipts) was used.
Note that users can send both an `m.read` and `m.read.private` receipt,
both of which are capable of clearing notifications.
If the user has both `m.read` and `m.read.private` set in the room then
the receipt which is more recent/ahead must be used to determine where
the user has read up to. For example, given an oldest-first set of events A,
B, C, and D the `m.read` receipt could be at event C and `m.read.private`
at event A - the user is considered to have read up to event C. If the
`m.read.private` receipt is then updated to point to B or C, the user's
notification state doesn't change (the `m.read` receipt is still more
ahead), however if the `m.read.private` receipt were to be updated to
event D then the user has read up to D (the `m.read` receipt is now
behind the `m.read.private` receipt).
{{< added-in v="1.4" >}} When handling threaded read receipts, the server is to
partition the notification count to each thread (with the main timeline being
its own thread). To determine if an event is part of a thread the server follows
the [event relationship](#forming-relationships-between-events) until it finds a
thread root via an `m.thread` relation (as specified by the [threading
module](#threading)), however it is not recommended that the server traverse
infinitely. Instead, implementations are encouraged to do a maximum of 3 hops to
find a thread before deciding that the event does not belong to a thread. This
is primarily to ensure that future events, like `m.reaction`, are correctly
considered "part of" a given thread.
#### Server behaviour
When receiving a new event homeservers process push rules for each of the local
users in the room (excluding the sender). This may result in:
* Generating a new number of unread notifications for the user.
* Making a request to the configured push gateway.
The updated notification count from a new event MUST appear in the same `/sync`
response as the event itself.
#### Push Gateway behaviour
##### Recommendations for APNS
The exact format for sending APNS notifications is flexible and up to
the client app and its' push gateway to agree on. As APNS requires that
the client app and its push gateway to agree on. As APNS requires that
the sender has a private key owned by the app developer, each app must
have its own push gateway. It is recommended that:

@ -137,28 +137,26 @@ either a thread root's event ID or `main` for the main timeline.
Threading introduces a concept of multiple conversations being held in the same
room and thus deserve their own read receipts and notification counts. An event is
considered to be "in a thread" if it meets any of the following criteria:
* It has a `rel_type` of `m.thread`.
* It has child events with a `rel_type` of `m.thread` (in which case it'd be the
thread root).
* Following the event relationships, it has a parent event which qualifies for
one of the above. Implementations should not recurse infinitely, though: a
maximum of 3 hops is recommended to cover indirect relationships.
considered to be "in a thread" if:
Events not in a thread but still in the room are considered to be part of the
"main timeline", or a special thread with an ID of `main`.
* It has a `rel_type` of `m.thread`, or
* Following the event relationships, it has a parent event which references
the thread root with a `rel_type` of `m.thread`. Implementations should
not recurse infinitely, though: a maximum of 3 hops is recommended to
cover indirect relationships.
Events not in a thread but still in the room are considered to be in the "main
timeline". When referring to the main timeline as a thread (e.g. in receipts
and notifications counts) a special thread ID of `main` is used.
Thread roots are considered to be in the main timeline, as are events that are
related to a thread root via non-thread relations.
The following is an example DAG for a room, with dotted lines showing event
relationships and solid lines showing topological ordering.
![threaded-dag](/diagrams/threaded-dag.png)
{{% boxes/note %}}
`m.reaction` relationships are not currently specified, but are shown here for
their conceptual place in a threaded DAG. They are currently proposed as
[MSC2677](https://github.com/matrix-org/matrix-spec-proposals/pull/2677).
{{% /boxes/note %}}
This DAG can be represented as 3 threaded timelines, with `A` and `B` being thread
roots:
@ -210,7 +208,7 @@ event when the user expands that thread.
#### Server behaviour
For efficiency, receipts SHOULD be batched into one event per room
For efficiency, receipts SHOULD be batched into one event per room and thread
before delivering them to clients.
Some receipts are sent across federation as EDUs with type `m.receipt`. The

@ -1,7 +1,7 @@
### Reference relations
{{% added-in v="1.4" %}}
{{% added-in v="1.5" %}}
Generically referencing another event can be done with a `rel_type` of `m.reference`
as a form of [relationship](#forming-relationships-between-events). There is no
@ -19,11 +19,12 @@ messages.
##### Server-side aggregation of `m.reference`
The aggregation format of `m.reference` relations consists of a single `chunk` property,
which lists all the events which `m.reference` the event (the parent). Currently,
only a single `event_id` field is present on the events in the `chunk`.
The [aggregation](#aggregations-of-child-events) format of `m.reference`
relations consists of a single `chunk` property, which lists all the events
which `m.reference` the event (the parent). Currently, only a single `event_id`
field is present on the events in the `chunk`.
An example `m.reference` would be:
For example, given an event with the following `m.reference` relationship:
```json
{
@ -38,7 +39,7 @@ An example `m.reference` would be:
}
```
The [bundle](#aggregations) under `m.relations` would appear similar to the following:
The aggregation would appear similar to the following:
```json
{

@ -18,3 +18,7 @@ Servers are free to handle the reported content however they desire.
This may be a dedicated room to alert server administrators to the
reported content or some other mechanism for notifying the appropriate
people.
{{< changed-in v="1.8" >}} The server MUST verify that the user
reporting the event is currently joined to the room the event is
in before accepting a report.

@ -60,7 +60,8 @@ specific fallback text is different for each `msgtype`, however the
general format for the `body` is:
```text
> <@alice:example.org> This is the original body
> <@alice:example.org> This is the first line of the original body
> This is the second line
This is where the reply goes
```
@ -176,4 +177,34 @@ This is where the reply goes.
For `m.image`, the text should be `"sent an image."`. For `m.video`, the
text should be `"sent a video."`. For `m.audio`, the text should be
`"sent an audio file"`.
`"sent an audio file"`.
#### Mentioning the replied to user
In order to notify users of the reply, it may be desirable to include the `sender`
of the replied to event and any users mentioned in that event. See
[user and room mentions](#user-and-room-mentions) for additional information.
An example including mentioning the original sender and other users:
```json5
{
"content": {
"m.relates_to": {
"m.in_reply_to": {
"event_id": "$another_event"
}
},
"body": "That sounds like a great idea!",
"m.mentions": {
"user_ids": [
// The sender of $another_event.
"@alice:example.org",
// Another Matrix ID copied from the m.mentions property of $another_event.
"@bob:example.org"
]
}
},
// other fields as required by events
}
```

@ -66,6 +66,70 @@ default key.
|------------|-----------|------------------------------------------|
| key | string | **Required.** The ID of the default key. |
###### `m.secret_storage.v1.aes-hmac-sha2`
For the purposes of allowing clients to check whether a user has correctly
entered the key, keys for use with the `m.secret_storage.v1.aes-hmac-sha2`
algorithm are stored with some additional data.
When storing a key, clients SHOULD:
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 the empty
string 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 (IV).
3. Encrypt a message consisting of 32 bytes of 0, using AES-CTR-256 using the
AES key and IV generated above.
4. Pass the raw encrypted data through HMAC-SHA-256 using the MAC key
generated above.
5. Encode the IV from step 2, and the MAC from step 4, using [unpadded
base64](/appendices/#unpadded-base64), and store the results in the `iv`
and `mac` properties respectively in the `m.secret_storage.key.[key ID]`
account-data. (The ciphertext from step 3 is discarded after passing
through the MAC calculation.)
This process can be repeated by a client checking if the key is correct: the
MAC should match if the key is correct. Note, however, that these properties
are **optional**. If they are not present, clients must assume that the key is
valid.
Note also, that although clients SHOULD use unpadded base64 as specified above,
some existing implementations use standard [RFC4648-compliant
base64](https://datatracker.ietf.org/doc/html/rfc4648#section-4) with padding,
so clients must accept either encoding.
The structure of a `m.secret_storage.key.[key ID]` account data object for use
with this algorithm is therefore as follows:
`AesHmacSha2KeyDescription`
| Parameter | Type | Description |
|-------------|--------|------------------------------------------------------------------------------------------------------|
| name | string | Optional. The name of the key. |
| algorithm | string | **Required.** The encryption algorithm to be used for this key: `m.secret_storage.v1.aes-hmac-sha2`. |
| passphrase | object | See [deriving keys from passphrases](#deriving-keys-from-passphrases) section for a description of this property. |
| iv | string | Optional. The 16-byte initialization vector for the validation check, encoded as base64. |
| mac | string | Optional. The MAC of the result of encrypting 32 bytes of 0, encoded as base64. |
For example, it could look like:
```json
{
"name": "m.default",
"algorithm": "m.secret_storage.v1.aes-hmac-sha2",
"iv": "random+data",
"mac": "mac+of+encrypted+zeros"
}
```
##### Secret storage
Encrypted data is stored in the user's account data using the event
@ -82,7 +146,7 @@ of the data.
| Parameter | Type | Description |
|-----------|------------------|-------------|
| encrypted | {string: object} | **Required.** Map from key ID the encrypted data. The 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](#msecret_storagev1aes-hmac-sha2) section. |
| encrypted | {string: object} | **Required.** Map from key ID the encrypted data. The 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](#msecret_storagev1aes-hmac-sha2-1) section. |
Example:
@ -147,58 +211,41 @@ 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
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.
initialization vector (IV).
`AesHmacSha2EncryptedData`
3. Encrypt the data using AES-CTR-256 using the AES key and IV generated
above.
| 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. |
4. Pass the raw encrypted data through HMAC-SHA-256 using the MAC key
generated above.
For the purposes of allowing clients to check whether a user has
correctly entered the key, clients should:
5. Encode the IV from step 2, the ciphertext from step 3, and MAC from step 4,
using [unpadded base64](/appendices/#unpadded-base64), and store them as
the `iv`, `ciphertext`, and `mac` properties respectively in the account
data object.
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.
**Note**: some existing implementations encode these properties using
standard [RFC4648-compliant
base64](https://datatracker.ietf.org/doc/html/rfc4648#section-4) with
padding, so clients must accept either encoding.
`AesHmacSha2KeyDescription`
The structure of the `encrypted` property of an account data object encrypted
with this algorithm is therefore as follows:
| Parameter | Type | Description |
|-------------|--------|-----------------------------------------------------------------------------------------------------------------------------------|
| name | string | Optional. 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 | object | See [deriving keys from passphrases](#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. |
`AesHmacSha2EncryptedData`
For example, the `m.secret_storage.key.key_id` for a key using this
algorithm could look like:
| 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. |
```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:
For example, data encrypted using this algorithm could look like this:
```json
{
@ -212,27 +259,13 @@ and data encrypted using this algorithm could look like this:
}
```
###### Key representation
##### 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](https://en.bitcoin.it/wiki/Base58Check_encoding#Base58_symbol_chart),
that is, using the alphabet
`123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`.
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.
###### Deriving keys from passphrases
the key should be presented as a string using the common [cryptographic key
representation](/appendices/#cryptographic-key-representation).
##### 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

@ -1,5 +1,3 @@
weight: 340
### Spaces
{{% added-in v="1.2" %}}

@ -10,7 +10,7 @@ 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:
- A Matrix client, using the APIs defined this specification, which
- A Matrix client, using the APIs defined in 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

@ -1,12 +1,12 @@
### Third party invites
### Third-party invites
This module adds in support for inviting new members to a room where
their Matrix user ID is not known, instead addressing them by a third
party identifier such as an email address. There are two flows here; one
if a Matrix user ID is known for the third party identifier, and one if
their Matrix user ID is not known, instead addressing them by a third-party
identifier such as an email address. There are two flows here; one
if a Matrix user ID is known for the third-party identifier, and one if
not. Either way, the client calls `/invite` with the details of the
third party identifier.
third-party identifier.
The homeserver asks the identity server whether a Matrix user ID is
known for that identifier:
@ -22,7 +22,7 @@ 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. See the
invitee does indeed own that third-party identifier. See the
[m.room.member](#mroommember) schema for more information.
#### Events
@ -31,14 +31,14 @@ invitee does indeed own that third party identifier. See the
#### Client behaviour
A client asks a server to invite a user by their third party identifier.
A client asks a server to invite a user by their third-party identifier.
{{% http-api spec="client-server" api="third_party_membership" %}}
#### Server behaviour
Upon receipt of an `/invite`, the server is expected to look up the
third party identifier with the provided identity server. If the lookup
third-party identifier with the provided identity server. If the lookup
yields a result for a Matrix User ID then the normal invite process can
be initiated. This process ends up looking like this:
@ -104,12 +104,12 @@ looking like this:
All homeservers MUST verify the signature in the event's
`content.third_party_invite.signed` object.
The third party user will then need to verify their identity, which
The third-party user will then need to verify their identity, which
results in a call from the identity server to the homeserver that bound
the third party identifier to a user. The homeserver then exchanges the
the third-party identifier to a user. The homeserver then exchanges the
`m.room.third_party_invite` event in the room for a complete
`m.room.member` event for `membership: invite` for the user that has
bound the third party identifier.
bound the third-party identifier.
If a homeserver is joining a room for the first time because of an
`m.room.third_party_invite`, the server which is already participating
@ -123,7 +123,7 @@ view of the room. They may, however, indicate to their clients that a
member's membership is questionable.
For example, given H1, H2, and H3 as homeservers, UserA as a user of H1,
and an identity server IS, the full sequence for a third party invite
and an identity server IS, the full sequence for a third-party invite
would look like the following. This diagram assumes H1 and H2 are
residents of the room while H3 is attempting to join.
@ -144,7 +144,7 @@ residents of the room while H3 is attempting to join.
| | | POST /store-invite | | |
| | |---------------------------------------------------------------------------------------------->|
| | | | | |
| | | | Token, keys, etc for third party invite |
| | | | Token, keys, etc for third-party invite |
| | |<----------------------------------------------------------------------------------------------|
| | | | | |
| | | (Federation) Emit m.room.third_party_invite | | |
@ -214,13 +214,13 @@ still be performed, so the attack surface here is minimized.
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 all third party identifiers from a matrix user ID
(and accordingly, being able to link each third party identifier) should
be avoided wherever possible. To this end, the third party identifier is
matrix user ID and a third-party identifier is hard. In particular,
being able to look up all third-party identifiers from a matrix user ID
(and accordingly, being able to link each third-party identifier) should
be avoided wherever possible. To this end, the third-party identifier is
not put in any event, rather an opaque display name provided by the
identity server is put into the events. Clients should not remember or
display third party identifiers from invites, other than for the use of
display third-party identifiers from invites, other than for the use of
the inviter themself.
Homeservers are not required to trust any particular identity server(s).

@ -1,18 +1,18 @@
### Third Party Networks
### Third-party Networks
Application services can provide access to third party networks via
Application services can provide access to third-party networks via
bridging. This allows Matrix users to communicate with users on other
communication platforms, with messages ferried back and forth by the
application service. A single application service may bridge multiple
third party networks, and many individual locations within those
networks. A single third party network location may be bridged to
third-party networks, and many individual locations within those
networks. A single third-party network location may be bridged to
multiple Matrix rooms.
#### Third Party Lookups
#### Third-party Lookups
A client may wish to provide a rich interface for joining third party
locations and connecting with third party users. Information necessary
for such an interface is provided by third party lookups.
A client may wish to provide a rich interface for joining third-party
locations and connecting with third-party users. Information necessary
for such an interface is provided by third-party lookups.
{{% http-api spec="client-server" api="third_party_lookup" %}}

@ -11,12 +11,16 @@ Clients SHOULD render threads differently to regular messages or replies in the
as by providing some context to what is going on in the thread but keeping the full conversation
history behind a disclosure.
Threads are established using a `rel_type` of `m.thread` and reference the *thread root* (the
first event in a thread). It is not possible to create a thread from an event with a `rel_type`,
which includes not being able to nest threads. All conversation in a thread reference the thread
root instead of the most recent message, unlike rich reply chains.
Threads are established using a `rel_type` of `m.thread` and reference the
*thread root* (the main timeline event to which the thread events refer). It is not possible to create a thread from an event which itself
is the child of an event relationship (i.e., one with an `m.relates_to`
property with a `rel_type` property - see [Relationship types](#relationship-types)).
It is therefore also not possible to nest threads.
As a worked example, the following represents a thread and how it'd be formed:
Unlike rich reply chains, all events in a thread reference the thread root
instead of the most recent message.
As a worked example, the following represents a thread and how it would be formed:
```json
{
@ -74,7 +78,7 @@ Clients which understand how to work with threads should simply do so, however c
might not be aware of threads (due to age or scope) might not be able to helpfully represent
the conversation history to its users.
To work around this, events sent by clients which understand threads include [rich reply](#rich-replies)
To work around this, events sent by clients which understand threads SHOULD include [rich reply](#rich-replies)
metadata to attempt to form a reply chain representation of the conversation. This representation
is not ideal for heavily threaded rooms, but allows for users to have context as to what is
being discussed with respect to other messages in the room.
@ -128,11 +132,11 @@ clients is used to create a reply within a thread: clients should render the eve
##### Validation of `m.thread` relationships
Servers SHOULD reject client requests which attempt to start a thread off an event with a
`rel_type`. If the client attempts to target an event which already has an `m.thread`,
`m.reference`, or any other `rel_type` then it should receive a HTTP 400 error response
with appropriate error message, as per the [standard error response](#standard-error-response)
structure.
Servers SHOULD reject client requests which attempt to start a thread off an
event with an `m.relates_to` property. If the client attempts to target an event which itself
has an `m.relates_to` property, then it should receive a HTTP 400 error
response with appropriate error message, as per the [standard error
response](#standard-error-response) structure.
{{% boxes/note %}}
A specific error code is not currently available for this case: servers should use `M_UNKNOWN`
@ -141,12 +145,16 @@ alongside the HTTP 400 status code.
##### Server-side aggregation of `m.thread` relationships
Given threads always reference the thread root, an event can have multiple "child" events which
then form the thread itself. These events should be [aggregated](#aggregations) by the server.
Given threads always reference the thread root, an event can have multiple
"child" events which then form the thread itself. These events should be
[aggregated](#aggregations-of-child-events) by the server.
The aggregation for threads includes some information about the user's participation in the thread,
the approximate number of events in the thread (as known to the server), and the most recent event
in the thread (topologically). This is then bundled into the event as `m.thread`:
in the thread (topologically).
As with any other aggregation of child events, the `m.thread` aggregation is
included under the `m.relations` property in `unsigned` for the thread root. For example:
```json
{
@ -165,6 +173,11 @@ in the thread (topologically). This is then bundled into the event as `m.thread`
"content": {
"msgtype": "m.text",
"body": "Woo! Threads!"
},
"unsigned": {
"m.relations": {
// ...
}
}
},
"count": 7,
@ -178,15 +191,17 @@ in the thread (topologically). This is then bundled into the event as `m.thread`
`latest_event` is the most recent event (topologically to the server) in the thread sent by an
un-[ignored user](#ignoring-users).
Note that any bundled aggregations on `latest_event` should also be present. The server should be
careful to avoid loops, though loops are not currently possible due to `m.thread` not being possible
to target an event with a `rel_type` already.
Note that, as in the example above, child events of the `latest_event` should
themselves be aggregated and included under `m.relations` for that event. The
server should be careful to avoid loops, though loops are not currently
possible due to `m.thread` not being permitted to target an event with an
`m.relates_to` property.
`count` is simply the number of events using `m.thread` as a `rel_type` pointing to the target event.
It does not include events sent by [ignored users](#ignoring-users).
`current_user_participated` is `true` when the authenticated user is either:
1. The `sender` of the event receiving the bundle (they sent the thread root).
1. The `sender` of the thread root event.
2. The `sender` of an event which references the thread root with a `rel_type` of `m.thread`.
#### Querying threads in a room

@ -6,11 +6,123 @@ This module outlines how two users in a room can set up a Voice over IP
WebRTC 1.0 standard. Call signalling is achieved by sending [message
events](#events) to the room. In this version of the spec, only two-party
communication is supported (e.g. between two peers, or between a peer
and a multi-point conferencing unit). This means that clients MUST only
send call events to rooms with exactly two participants.
and a multi-point conferencing unit). Calls can take place in rooms with
multiple members, but only two devices can take part in the call.
All VoIP events have a `version` field. This is used to determine whether
devices support this new version of the protocol. For example, clients can use
this field to know whether to expect an `m.call.select_answer` event from their
opponent. If clients see events with `version` other than `0` or `"1"`
(including, for example, the numeric value `1`), they should treat these the
same as if they had `version` == `"1"`.
Note that this implies any and all future versions of VoIP events should be
backwards-compatible. If it does become necessary to introduce a non
backwards-compatible VoIP spec, the intention would be for it to simply use a
separate set of event types.
#### Party Identifiers
Whenever a client first participates in a new call, it generates a `party_id` for itself to use for the
duration of the call. This needs to be long enough that the chance of a collision between multiple devices
both generating an answer at the same time generating the same party ID is vanishingly small: 8 uppercase +
lowercase alphanumeric characters is recommended. Parties in the call are identified by the tuple of
`(user_id, party_id)`.
The client adds a `party_id` field containing this ID to the top-level of the content of all VoIP events
it sends on the call, including `m.call.invite`. Clients use this to identify remote echo of their own
events: since a user may call themselves, they cannot simply ignore events from their own user. This
field also identifies different answers sent by different clients to an invite, and matches `m.call.candidates`
events to their respective answer/invite.
A client implementation may choose to use the device ID used in end-to-end cryptography for this purpose,
or it may choose, for example, to use a different one for each call to avoid leaking information on which
devices were used in a call (in an unencrypted room) or if a single device (ie. access token) were used to
send signalling for more than one call party.
A grammar for `party_id` is defined [below](#grammar-for-voip-ids).
#### Politeness
In line with [WebRTC perfect negotiation](https://w3c.github.io/webrtc-pc/#perfect-negotiation-example)
there are rules to establish which party is polite in the process of renegotiation. The callee is
always the polite party. In a glare situation, the politeness of a party is therefore determined by
whether the inbound or outbound call is used: if a client discards its outbound call in favour of
an inbound call, it becomes the polite party.
#### Call Event Liveness
`m.call.invite` contains a `lifetime` field that indicates how long the offer is valid for. When
a client receives an invite, it should use the event's `age` field in the sync response plus the
time since it received the event from the homeserver to determine whether the invite is still valid.
The use of the `age` field ensures that incorrect clocks on client devices don't break calls.
If the invite is still valid *and will remain valid for long enough for the user to accept the call*,
it should signal an incoming call. The amount of time allowed for the user to accept the call may
vary between clients. For example, it may be longer on a locked mobile device than on an unlocked
desktop device.
The client should only signal an incoming call in a given room once it has completed processing the
entire sync response and, for encrypted rooms, attempted to decrypt all encrypted events in the
sync response for that room. This ensures that if the sync response contains subsequent events that
indicate the call has been hung up, rejected, or answered elsewhere, the client does not signal it.
If on startup, after processing locally stored events, the client determines that there is an invite
that is still valid, it should still signal it but only after it has completed a sync from the homeserver.
The minimal recommended lifetime is 90 seconds - this should give the user enough time to actually pick
up the call.
#### ICE Candidate Batching
Clients should aim to send a small number of candidate events, with guidelines:
* ICE candidates which can be discovered immediately or almost immediately in the invite/answer
event itself (eg. host candidates). If server reflexive or relay candidates can be gathered in
a sufficiently short period of time, these should be sent here too. A delay of around 200ms is
suggested as a starting point.
* The client should then allow some time for further candidates to be gathered in order to batch them,
rather than sending each candidate as it arrives. A starting point of 2 seconds after sending the
invite or 500ms after sending the answer is suggested as a starting point (since a delay is natural
anyway after the invite whilst the client waits for the user to accept it).
#### End-of-candidates
An ICE candidate whose value is the empty string means that no more ICE candidates will
be sent. Clients must send such a candidate in an `m.call.candidates` message.
The WebRTC spec requires browsers to generate such a candidate, however note that at time of writing,
not all browsers do (Chrome does not, but does generate an `icegatheringstatechange` event). The
client should send any remaining candidates once candidate generation finishes, ignoring timeouts above.
This allows bridges to batch the candidates together when bridging to protocols that don't support
trickle ICE.
#### DTMF
Matrix clients can send DTMF as specified by WebRTC. The WebRTC standard as of August
2020 does not support receiving DTMF but a Matrix client can receive and interpret the DTMF sent
in the RTP payload.
#### Grammar for VoIP IDs
`call_id`s and `party_id` must follow the [Opaque Identifier Grammar](/appendices#opaque-identifiers).
#### Behaviour on Room Leave
If the client sees the user it is in a call with leave the room, the client should treat this
as a hangup event for any calls that are in progress. No specific requirement is given for the
situation where a client has sent an invite and the invitee leaves the room, but the client may
wish to treat it as a rejection if there are no more users in the room who could answer the call
(eg. the user is now alone or the `invitee` field was set on the invite).
The same behaviour applies when a client is looking at historic calls.
#### Supported Codecs
The Matrix spec does not mandate particular audio or video codecs, but instead defers to the
WebRTC spec. A compliant Matrix VoIP client will behave in the same way as a supported 'browser'
in terms of what codecs it supports and what variants thereof. The latest WebRTC specification
applies, so clients should keep up to date with new versions of the WebRTC specification whether
or not there have been any changes to the Matrix spec.
#### Events
##### Common Fields
{{% event-fields event_type="call_event" %}}
##### Events
{{% event-group group_name="m.call" %}}
#### Client behaviour
@ -25,6 +137,7 @@ A call is set up with message events exchanged as follows:
[..candidates..] -------->
[Answers call]
<--------------- m.call.answer
m.call.select_answer ----------->
[Call is active and ongoing]
<--------------- m.call.hangup
```
@ -42,6 +155,60 @@ Or a rejected call:
Calls are negotiated according to the WebRTC specification.
In response to an incoming invite, a client may do one of several things:
* Attempt to accept the call by sending an `m.call.answer`.
* Actively reject the call everywhere: send an `m.call.reject` as per above, which will stop the call from
ringing on all the user's devices and the caller's client will inform them that the user has
rejected their call.
* Ignore the call: send no events, but stop alerting the user about the call. The user's other
devices will continue to ring, and the caller's device will continue to indicate that the call
is ringing, and will time the call out in the normal way if no other device responds.
##### Streams
Clients may send more than one stream in a VoIP call. The streams should be
differentiated by including metadata in the [`m.call.invite`](/client-server-api/#mcallinvite),
[`m.call.answer`](/client-server-api/#mcallanswer) and [`m.call.negotiate`](/client-server-api/#mcallnegotiate)
events, using the `sdp_stream_metadata` property. An [`m.call.sdp_stream_metadata_changed`](/client-server-api/#mcallsdp_stream_metadata_changed)
event can be sent when the metadata changes but no negotiation is required.
Clients are recommended to not mute the audio of WebRTC tracks locally when an
incoming stream has the `audio_muted` field set to `true`. This is because when
the other user unmutes themselves, there may be a slight delay between their
client sending audio and the [`m.call.sdp_stream_metadata_changed`](/client-server-api/#mcallsdp_stream_metadata_changed)
event arriving and any audio sent in between will not be heard. The other user
will still stop transmitting audio once they mute on their side, so no audio is
sent without the user's knowledge.
The same suggestion does not apply to `video_muted`. Clients _should_ mute video
locally, so that the receiving side doesn't see a black video.
If `sdp_stream_metadata` is present and an incoming stream is not listed in it,
the stream should be ignored. If a stream has a `purpose` of an unknown type, it
should also be ignored.
For backwards compatibility, if `sdp_stream_metadata` is not present in the
initial [`m.call.invite`](/client-server-api/#mcallinvite) or [`m.call.answer`](/client-server-api/#mcallanswer)
event sent by the other party, the client should assume that this property is
not supported by the other party. It means that multiple streams cannot be
differentiated: the client should only use the first incoming stream and
shouldn't send more than one stream.
Clients implementing this specification should ignore any streamless tracks.
##### Invitees
The `invitee` field should be added whenever the call is intended for one
specific user, and should be set to the Matrix user ID of that user. Invites
without an `invitee` field are defined to be intended for any member of the
room other than the sender of the event.
Clients should consider an incoming call if they see a non-expired invite event where the `invitee` field is either
absent or equal to their user's Matrix ID, however they should evaluate whether or not to ring based on their
user's trust relationship with the callers and/or where the call was placed. As a starting point, it is
suggested that clients ignore call invites from users in public rooms. It is strongly recommended that
when clients do not ring for an incoming call invite, they still display the call invite in the room and
annotate that it was ignored.
##### Glare
"Glare" is a problem which occurs when two users call each other at

@ -98,20 +98,25 @@ There was an error sending an email. Typically seen when attempting to
verify ownership of a given email address.
`M_INVALID_ADDRESS`
The provided third party address was not valid.
The provided third-party address was not valid.
`M_SEND_ERROR`
There was an error sending a notification. Typically seen when
attempting to verify ownership of a given third party address.
attempting to verify ownership of a given third-party address.
`M_UNRECOGNIZED`
The request contained an unrecognised value, such as an unknown token or
medium.
This is also used as the response if a server did not understand the request.
This is expected to be returned with a 404 HTTP status code if the endpoint is
not implemented or a 405 HTTP status code if the endpoint is implemented, but
the incorrect HTTP method is used.
`M_THREEPID_IN_USE`
The third party identifier is already in use by another user. Typically
The third-party identifier is already in use by another user. Typically
this error will have an additional `mxid` property to indicate who owns
the third party identifier.
the third-party identifier.
`M_UNKNOWN`
An unknown error has occurred.
@ -157,15 +162,20 @@ 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:
Access tokens may be provided via a request header, using the
Authentication Bearer scheme: `Authorization: Bearer TheTokenHere`.
Clients may alternatively provide the access token via a query string
parameter: `access_token=TheTokenHere`. This method is deprecated to
prevent the access token being leaked in access/HTTP logs and SHOULD NOT
be used by clients.
1. Via a query string parameter, `access_token=TheTokenHere`.
2. Via a request header, `Authorization: Bearer TheTokenHere`.
Identity Servers MUST support both methods.
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.
{{% boxes/note %}}
{{% changed-in v="1.11" %}}
Sending the access token as a query string parameter is now deprecated.
{{% /boxes/note %}}
When credentials are required but missing or invalid, the HTTP call will
return with a status of 401 and the error code `M_UNAUTHORIZED`.
@ -364,7 +374,7 @@ To start a session, the client makes a request to the appropriate
token to the user, and the user provides the token to the client. The
client then provides the token to the appropriate `/submitToken`
endpoint, completing the session. At this point, the client should
`/bind` the third party identifier or leave it for another entity to
`/bind` the third-party identifier or leave it for another entity to
bind.
### Format of a validation token

@ -380,9 +380,18 @@ 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 an MSC will
require an implementation proof, ask in
[\#matrix-spec:matrix.org](https://matrix.to/#/#matrix-spec:matrix.org).
small enough to be considered proven. Implementations do not need to be
merged or released, but must be of sufficient quality to show that the
MSC works. Where it's unclear if an MSC will require an implementation
proof, ask in [\#matrix-spec:matrix.org](https://matrix.to/#/#matrix-spec:matrix.org).
Proposals may require both server-side and client-side implementations.
Proposals that have not yet been implemented will have the
`needs-implementation` label. After an implementation has been made, add a
comment in the GitHub issue indicating so. After an implementation has been
made, we will check it to verify that it implements the MSC. Proposals that
have implementations that have not yet been checked will have the
`implementation-needs-checking` label.
### Early release of an MSC/idea

@ -37,6 +37,16 @@ notification provider (e.g. APNS, GCM).
Mobile Device or Client
```
## API standards
### Unsupported endpoints
If a request for an unsupported (or unknown) endpoint is received then the server
must respond with a 404 `M_UNRECOGNIZED` error.
Similarly, a 405 `M_UNRECOGNIZED` error is used to denote an unsupported method
to a known endpoint.
## Homeserver behaviour
This describes the format used by "HTTP" pushers to send notifications

@ -36,11 +36,11 @@ Alternatively, consider flipping the column/row organization to be features
up top and versions on the left.
-->
| Feature \ Version | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|-------------------|---|---|---|---|---|---|---|---|---|----|
| **Knocking** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ |
| **Restricted join rules** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ |
| **`knock_restricted` join rule** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ |
| Feature \ Version | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
|-------------------|---|---|---|---|---|---|---|---|---|----|----|
| **Knocking** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ |
| **Restricted join rules** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ |
| **`knock_restricted` join rule** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | ✔ |
## Complete list of room versions
@ -52,13 +52,12 @@ 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 9** as
room is running a stable version. Servers SHOULD use **room version 10** as
the default room version when creating new rooms.
The available room versions are:
- [Version 1](/rooms/v1) - **Stable**. The current version of most
rooms.
- [Version 1](/rooms/v1) - **Stable**. The initial room version.
- [Version 2](/rooms/v2) - **Stable**. Implements State Resolution
Version 2.
- [Version 3](/rooms/v3) - **Stable**. Introduces events whose IDs
@ -76,6 +75,7 @@ The available room versions are:
redacting some membership events.
- [Version 10](/rooms/v10) - **Stable**. Enforces integer-only power levels
and adds `knock_restricted` join rule.
- [Version 11](/rooms/v11) - **Stable**. Clarifies the redaction algorithm.
## Room version grammar
@ -86,7 +86,7 @@ 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 the characters `a-z`, `0-9`, `.`, and `-`.
MUST 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,0 +1,11 @@
An event has exactly one event ID. Event IDs in this room version have the
format:
$opaque_id:domain
where `domain` is the [server name](/appendices/#server-name) of the homeserver
which created the room, and `opaque_id` is a locally-unique string.
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.

@ -19,12 +19,14 @@ not in the following list:
- `membership`
The content object must also be stripped of all keys, unless it is one
of one of the following event types:
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`.
- [`m.room.member`](/client-server-api#mroommember) allows key `membership`.
- [`m.room.create`](/client-server-api#mroomcreate) allows key `creator`.
- [`m.room.join_rules`](/client-server-api#mroomjoin_rules) allows key `join_rule`.
- [`m.room.power_levels`](/client-server-api#mroompower_levels) allows keys
`ban`, `events`, `events_default`, `kick`, `redact`, `state_default`, `users`,
`users_default`.
- [`m.room.aliases`](/client-server-api#historical-events) allows key `aliases`.
- [`m.room.history_visibility`](/client-server-api#mroomhistory_visibility) allows
key `history_visibility`.

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save