Compare commits

...

50 Commits
v1.10 ... main

Author SHA1 Message Date
Johannes Marbach 7d5b506555
Remove extra preposition in room version 11 description of redactions (#1848)
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
3 days ago
Johannes Marbach 5a86e384dd
Clarify that per-request UIA for /login/get_token is an RFC 2119 MUST requirement (#1846)
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
3 days ago
Kévin Commaille 1e303b3bbc
Do not require UIA when first uploading cross-signing keys (#1828)
As per MSC3967.
4 days ago
Matthew Hodgson e15a36b0a1
MSC4132: deprecate linking to events in rooms identified by alias (#1823) 6 days ago
Matthias Ahouansou 7ff785fc38
Clarify that the event field of the send_join is only required when performing a restricted join (#1834) 7 days ago
Johannes Marbach a17550648c
Fix typo in moderation policy lists spec (#1832) 1 week ago
Richard van der Hoff 722c2b1e9a
Clean up pull request template (#1831)
As far as I can tell, these header files only encourage people to create
badly-formatted PRs.

Also we only have one template so let's give it the default name.
1 week ago
Matthias Ahouansou 49765e0e0a
Clarify that redaction events are subject to auth rules (#1824)
Signed-off-by: Matthias Ahouansou <matthias@ahouansou.cz>
2 weeks ago
Kévin Commaille ea781ef7b2
Spec markup for mathematical messages (#1816)
* Spec markup for mathematical messages

As per MSC2191.

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

* Add changelog

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

* Add warning box

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

* Improve warning

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

* Add links

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

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 weeks ago
Sumner Evans 500e83b9b7
e2ee/qr: clarify that the device's Ed25519 signing key should be used (#1829)
Signed-off-by: Sumner Evans <sumner.evans@automattic.com>
2 weeks ago
Kévin Commaille 3674985dd6
Factor out the common definitions of the content repo APIs and add new formats (#1822)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 weeks ago
Matthias Ahouansou 041be547d6
Fix typo of object being spelt as "obiect" (#1827) 2 weeks ago
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>
4 weeks 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 month 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 month ago
Andrew Morgan f4b34ba962
Note that whitespace around `Authorization` param commas is allowed (#1818) 1 month ago
Kévin Commaille 98d85cf421
Add support for rendering string formats (#1814)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 month 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.
1 month ago
Matthias Ahouansou eea3dfa969
Mention notifying AS for sender_localpart events (#1810)
Signed-off-by: Matthias Ahouansou <matthias@ahouansou.cz>
1 month 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>
1 month 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>
1 month ago
Kévin Commaille 85ad0c767c
Render response headers (#1809)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 month ago
Kévin Commaille 625999a039
Deprecate authentication via a query string (#1808)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 month ago
Kévin Commaille ae70b5fcf3
Replace `set-output` with environment files in CI (#1806)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 month 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>
1 month ago
Kévin Commaille d6b1d7300f
Update most CI actions (#1803)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 month ago
Kévin Commaille b0115a9613
Update typos CI action (#1804)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 month ago
Kévin Commaille a0bc6e7f83
Add anchors in `definition` shortcode (#1802)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 month ago
Kévin Commaille 7201042894
Fix anchors for schemas under `oneOf` (#1799)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 months ago
Kévin Commaille 2edfb21d5d
Add support for pattern formats for `patternProperties` (#1796)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 months ago
Kévin Commaille 26ce3929b4
Clean up unecessary `allOf`s (#1797)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2 months 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>
2 months ago
Richard van der Hoff 2b5f990f60
Factor out common definition of `Tag` type (#1793)
... and remove spurious `additionalProperties: true`
2 months 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>
2 months 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.
2 months 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>
2 months 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>
2 months 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>
2 months ago
Richard van der Hoff becc667672
Update github-labels.rst (#1781)
Fix formatting
2 months 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>
2 months 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.
2 months ago
Kévin Commaille efe72d3b26
Fix security schemes in OpenAPI definitions (#1772) 2 months 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>
2 months ago
Kévin Commaille e74c7c1540
Fix Hugo warnings (#1775) 2 months 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>
3 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>
3 months ago
Richard van der Hoff c25ff9e012
Formatting fixes in CONTRIBUTING.rst (#1769)
* Formatting fix in CONTRIBUTING.rst

* Fix link

* Create 1769.clarification
3 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
3 months ago
Travis Ralston bd122b35b0 Return to unstable 3 months ago

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

@ -1,11 +1,3 @@
---
name: Spec clarification/not a proposal
about: A change that's not a spec proposal, such as a clarification to the spec itself.
title: ''
labels: ''
assignees: ''
---
### Pull Request Checklist ### Pull Request Checklist

@ -20,9 +20,9 @@ jobs:
- name: "📥 Source checkout" - name: "📥 Source checkout"
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: " Setup Node" - name: " Setup Node"
uses: actions/setup-node@v3 uses: actions/setup-node@v4
with: with:
node-version: '18' node-version: '20'
- name: "🔎 Run validator" - name: "🔎 Run validator"
run: | run: |
npx @redocly/cli@latest lint data/api/*/*.yaml npx @redocly/cli@latest lint data/api/*/*.yaml
@ -34,7 +34,7 @@ jobs:
- name: "📥 Source checkout" - name: "📥 Source checkout"
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: " Setup Python" - name: " Setup Python"
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.9' python-version: '3.9'
cache: 'pip' cache: 'pip'
@ -51,9 +51,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: "📥 Source checkout" - name: "📥 Source checkout"
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: " Setup Python" - name: " Setup Python"
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.9' python-version: '3.9'
cache: 'pip' cache: 'pip'
@ -70,9 +70,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: "📥 Source checkout" - name: "📥 Source checkout"
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: " Setup Python" - name: " Setup Python"
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.9' python-version: '3.9'
cache: 'pip' cache: 'pip'
@ -99,11 +99,11 @@ jobs:
# the asterisk matching behaviour, not the literal string. # the asterisk matching behaviour, not the literal string.
run: | run: |
if [ "${GITHUB_EVENT_NAME}" == "pull_request" ]; then if [ "${GITHUB_EVENT_NAME}" == "pull_request" ]; then
echo ::set-output name=baseURL::/ echo "baseURL=/" >> "$GITHUB_OUTPUT"
elif [[ "${GITHUB_REF}" == refs/tags/* ]]; then elif [[ "${GITHUB_REF}" == refs/tags/* ]]; then
echo ::set-output name=baseURL::"/${GITHUB_REF/refs\/tags\//}" echo "baseURL=/${GITHUB_REF/refs\/tags\//}" >> "$GITHUB_OUTPUT"
else else
echo ::set-output name=baseURL::/unstable echo "baseURL=/unstable" >> "$GITHUB_OUTPUT"
fi fi
build-openapi: build-openapi:
@ -114,7 +114,7 @@ jobs:
- name: "📥 Source checkout" - name: "📥 Source checkout"
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: " Setup Python" - name: " Setup Python"
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.9' python-version: '3.9'
cache: 'pip' cache: 'pip'
@ -152,7 +152,7 @@ jobs:
-o spec/server-server-api/api.json -o spec/server-server-api/api.json
tar -czf openapi.tar.gz spec tar -czf openapi.tar.gz spec
- name: "📤 Artifact upload" - name: "📤 Artifact upload"
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: openapi-artifact name: openapi-artifact
path: openapi.tar.gz path: openapi.tar.gz
@ -166,13 +166,15 @@ jobs:
- name: "📥 Source checkout" - name: "📥 Source checkout"
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: " Setup Python" - name: " Setup Python"
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with:
python-version: '3.9'
- name: " Install towncrier" - name: " Install towncrier"
run: "pip install 'towncrier'" run: "pip install 'towncrier'"
- name: "Generate changelog" - name: "Generate changelog"
run: ./scripts/generate-changelog.sh vUNSTABLE run: ./scripts/generate-changelog.sh vUNSTABLE
- name: "📤 Artifact upload" - name: "📤 Artifact upload"
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: changelog-artifact name: changelog-artifact
path: content/changelog/vUNSTABLE.md path: content/changelog/vUNSTABLE.md
@ -185,11 +187,11 @@ jobs:
if: ${{ always() }} if: ${{ always() }}
steps: steps:
- name: " Setup Node" - name: " Setup Node"
uses: actions/setup-node@v3 uses: actions/setup-node@v4
with: with:
node-version: '18' node-version: '20'
- name: " Setup Hugo" - name: " Setup Hugo"
uses: peaceiris/actions-hugo@16361eb4acea8698b220b76c0d4e84e1fd22c61d uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3.0.0
with: with:
hugo-version: '0.113.0' hugo-version: '0.113.0'
extended: true extended: true
@ -201,7 +203,7 @@ jobs:
npm run get-proposals npm run get-proposals
- name: "📥 Download generated changelog" - name: "📥 Download generated changelog"
if: "needs.generate-changelog.result == 'success'" if: "needs.generate-changelog.result == 'success'"
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
name: changelog-artifact name: changelog-artifact
path: content/changelog path: content/changelog
@ -212,7 +214,7 @@ jobs:
# https://spec.matrix.org/latest/client-server-api/api.json # https://spec.matrix.org/latest/client-server-api/api.json
# Works for /unstable/ and /v1.1/ as well. # Works for /unstable/ and /v1.1/ as well.
- name: "📥 Spec definition download" - name: "📥 Spec definition download"
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
name: openapi-artifact name: openapi-artifact
- name: "📝 Unpack the OpenAPI definitions in the right location" - name: "📝 Unpack the OpenAPI definitions in the right location"
@ -222,7 +224,7 @@ jobs:
- name: "📦 Tarball creation" - name: "📦 Tarball creation"
run: tar -czf spec.tar.gz spec run: tar -czf spec.tar.gz spec
- name: "📤 Artifact upload" - name: "📤 Artifact upload"
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: spec-artifact name: spec-artifact
path: spec.tar.gz path: spec.tar.gz
@ -236,7 +238,7 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: "📥 Fetch built spec" - name: "📥 Fetch built spec"
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
name: spec-artifact name: spec-artifact
@ -262,13 +264,14 @@ jobs:
if: ${{ startsWith(github.ref, 'refs/tags/') }} if: ${{ startsWith(github.ref, 'refs/tags/') }}
steps: steps:
- name: " Setup Node" - name: " Setup Node"
uses: actions/setup-node@v3 uses: actions/setup-node@v4
with: with:
node-version: '18' node-version: '20'
- name: " Setup Hugo" - name: " Setup Hugo"
uses: peaceiris/actions-hugo@16361eb4acea8698b220b76c0d4e84e1fd22c61d uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3.0.0
with: with:
hugo-version: '0.113.0' # 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 extended: true
- name: "📥 Source checkout" - name: "📥 Source checkout"
uses: actions/checkout@v4 uses: actions/checkout@v4
@ -283,7 +286,7 @@ jobs:
hugo --config config.toml,historical.toml --baseURL "/${GITHUB_REF/refs\/tags\//}" -d "spec" hugo --config config.toml,historical.toml --baseURL "/${GITHUB_REF/refs\/tags\//}" -d "spec"
- name: "📥 Spec definition download" - name: "📥 Spec definition download"
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
name: openapi-artifact name: openapi-artifact
- name: "📝 Unpack the OpenAPI definitions in the right location" - name: "📝 Unpack the OpenAPI definitions in the right location"
@ -293,7 +296,7 @@ jobs:
- name: "📦 Tarball creation" - name: "📦 Tarball creation"
run: tar -czf spec-historical.tar.gz spec run: tar -czf spec-historical.tar.gz spec
- name: "📤 Artifact upload" - name: "📤 Artifact upload"
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: spec-historical-artifact name: spec-historical-artifact
path: spec-historical.tar.gz path: spec-historical.tar.gz

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

@ -17,7 +17,7 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: 🔧 Yarn cache - name: 🔧 Yarn cache
uses: actions/setup-node@v3 uses: actions/setup-node@v4
with: with:
cache: "yarn" cache: "yarn"
cache-dependency-path: packages/npm/yarn.lock cache-dependency-path: packages/npm/yarn.lock
@ -26,14 +26,15 @@ jobs:
- name: 🔨 Install dependencies - name: 🔨 Install dependencies
run: "yarn install --frozen-lockfile" 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 - name: 🎖 Bump package.json version
run: "yarn version --new-version $VERSION" run: "yarn version --new-version ${VERSION#v} --no-git-tag-version"
env: env:
VERSION: ${{ github.event.release.tag_name }}.0 VERSION: ${{ github.event.release.tag_name }}.0
- name: 🚀 Publish to npm - name: 🚀 Publish to npm
id: npm-publish id: npm-publish
uses: JS-DevTools/npm-publish@5a85faf05d2ade2d5b6682bfe5359915d5159c6c # v2.2.1 uses: JS-DevTools/npm-publish@19c28f1ef146469e409470805ea4279d47c3d35c # v3.1.1
with: with:
token: ${{ secrets.NPM_TOKEN }} token: ${{ secrets.NPM_TOKEN }}
package: packages/npm package: packages/npm

@ -14,6 +14,6 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Check spelling of proposals - name: Check spelling of proposals
uses: crate-ci/typos@ff3f309513469397e1094520fb7a054e057589e1 uses: crate-ci/typos@f2c1f08a7b3c1b96050cb786baaa2a94797bdb7d # v1.20.10
with: with:
config: ${{github.workspace}}/.github/_typos.toml config: ${{github.workspace}}/.github/_typos.toml

@ -12,7 +12,7 @@ The documentation style is described at
https://github.com/matrix-org/matrix-spec/blob/main/meta/documentation_style.rst. https://github.com/matrix-org/matrix-spec/blob/main/meta/documentation_style.rst.
Matrix-spec workflows Matrix-spec workflows
-------------------- ---------------------
Specification changes Specification changes
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
@ -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 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 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>`_, 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/>`_ projects: the `Developer Certificate of Origin <http://developercertificate.org/>`_
(DCO). This is a simple declaration that you wrote (DCO). This is a simple declaration that you wrote
the contribution or otherwise have the right to contribute it to Matrix:: the contribution or otherwise have the right to contribute it to Matrix::

@ -61,7 +61,7 @@ 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: 1. Install the extended version (often the OS default) of Hugo:
<https://gohugo.io/getting-started/installing>. Note that at least Hugo <https://gohugo.io/getting-started/installing>. Note that at least Hugo
v0.110.0 is required. v0.113.0 is required.
Alternatively, use the Docker image at Alternatively, use the Docker image at
https://hub.docker.com/r/klakegg/hugo/. (The "extended edition" is required https://hub.docker.com/r/klakegg/hugo/. (The "extended edition" is required

@ -40,10 +40,13 @@ Custom SCSS for the Matrix spec
.navbar-brand { .navbar-brand {
font-size: 1.1rem; font-size: 1.1rem;
/* Allow the text to wrap if it is wider than the viewport */
text-align: center;
white-space: normal;
.navbar-version { .navbar-version {
color: $secondary; color: $secondary;
} }
} }
.nav-link { .nav-link {
@ -115,7 +118,7 @@ Custom SCSS for the Matrix spec
} }
} }
@media (min-width: 768px) { @include media-breakpoint-up(md) {
@supports (position: sticky) { @supports (position: sticky) {
.td-sidebar-nav { .td-sidebar-nav {
/* This overrides calc(100vh - 10rem);, which gives us a blank space at the bottom of the sidebar */ /* This overrides calc(100vh - 10rem);, which gives us a blank space at the bottom of the sidebar */
@ -172,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 /* Adjust the scroll margin for everything in the main content, so that
* it doesn't disappear behind the header bar */ * it doesn't disappear behind the header bar */
.td-content * { .td-content * {
@ -427,6 +437,31 @@ footer {
&.basic-info th { &.basic-info th {
width: 15rem; width: 15rem;
} }
/* 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;
}
/* 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;
}
/* 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 { pre {
@ -471,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) Make padding symmetrical (this selector is used in the default styles to apply padding-left: 3rem)
*/ */
.pl-md-5, .px-md-5 { .pl-md-5, .px-md-5 {
padding-right: 3rem; @include media-breakpoint-up(md) {
padding-right: 3rem;
}
} }
/* Adjust default styles for info banner */ /* Adjust default styles for info banner */
.pageinfo-primary { .pageinfo-primary {
max-width: 80%; @include media-breakpoint-up(lg) {
max-width: 80%;
}
margin-top: 0;
margin-right: 0;
margin-left: 0; margin-left: 0;
border: 0; border: 0;
border-left: solid 5px $secondary; border-left: solid 5px $secondary;

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

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

@ -0,0 +1 @@
Deprecate linking to events in rooms identified by alias, as per [MSC4132](https://github.com/matrix-org/matrix-spec-proposals/pull/4132).

@ -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 @@
Add support for mathematical messages, as per [MSC2191](https://github.com/matrix-org/matrix-spec-proposals/pull/2191).

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

@ -0,0 +1 @@
Refactor the OpenAPI definitions of the content repository endpoints.

@ -0,0 +1 @@
Do not require UIA when first uploading cross-signing keys, as per [MSC3967](https://github.com/matrix-org/matrix-spec-proposals/pull/3967).

@ -0,0 +1 @@
Clarify that the device's Ed25519 signing key should be used in QR code verification (as opposed to the device's Curve25519 identity key).

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

@ -0,0 +1 @@
Clarify that per-request UIA for /login/get_token is an RFC 2119 MUST requirement.

@ -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.

@ -0,0 +1 @@
Clean up pull request template.

@ -0,0 +1 @@
Clarify that redaction events are still subject to all applicable auth rules.

@ -0,0 +1 @@
Fix minor spelling mistake of object being spelt "obiect".

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

@ -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 @@
Clarify that the `event` field of the `/v2/send_join` response is only required when `join_authorised_via_users_server` was present in the `content` field of the request.

@ -10,15 +10,16 @@ enableRobotsTXT = true
# We disable RSS, because (a) it's useless, (b) Hugo seems to generate broken # 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/ # 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">`). # 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]
[languages.en] [languages.en]
title = "Matrix Specification" title = "Matrix Specification"
description = "Home of the Matrix specification for decentralised communication"
languageName ="English" languageName ="English"
# Weight used for sorting. # Weight used for sorting.
weight = 1 weight = 1
[languages.en.params]
description = "Home of the Matrix specification for decentralised communication"
# Entries in the main menu in the header. # Entries in the main menu in the header.
[menus] [menus]
@ -59,14 +60,14 @@ privacy_policy = "https://matrix.org/legal/privacy-notice"
[params.version] [params.version]
# must be one of "unstable", "current", "historical" # must be one of "unstable", "current", "historical"
# this is used to decide whether to show a banner pointing to the current release # 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. # 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" 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 # 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. # of the spec. CI will set these values here automatically when a release git tag (i.e `v1.5`) is created.
major = "1" # major = "1"
minor = "10" # minor = "10"
release_date = "March 22, 2024" # release_date = "March 22, 2024"
# User interface configuration # User interface configuration
[params.ui] [params.ui]
@ -129,7 +130,7 @@ sidebar_menu_compact = true
[module] [module]
[module.hugoVersion] [module.hugoVersion]
extended = true extended = true
min = "0.110.0" min = "0.113.0"
[[module.imports]] [[module.imports]]
path = "github.com/matrix-org/docsy" path = "github.com/matrix-org/docsy"
disable = false disable = false

@ -745,7 +745,7 @@ Specifically, the following mappings are used:
* `r` for room aliases. * `r` for room aliases.
* `u` for users. * `u` for users.
* `roomid` for room IDs (note the distinction from room aliases). * `roomid` for room IDs (note the distinction from room aliases).
* `e` for events, when after a room reference (`r` or `roomid`). * `e` for events, when after a room ID (`roomid`). Use of `e` after a room alias (`r`) is deprecated.
{{% boxes/note %}} {{% boxes/note %}}
During development of this URI format, types of `user`, `room`, and `event` During development of this URI format, types of `user`, `room`, and `event`
@ -755,6 +755,13 @@ wish to consider handling them as `u`, `r`, and `e` respectively.
`roomid` was otherwise unchanged. `roomid` was otherwise unchanged.
{{% /boxes/note %}} {{% /boxes/note %}}
{{% boxes/note %}}
{{< changed-in v="1.11" >}}
Referencing event IDs within a room identified by room alias (`r`) rather than room ID
(`roomid`) is now deprecated. We are not aware of these ever having been used in
practice, and are nonsensical given room aliases are mutable.
{{% /boxes/note %}}
The `id without sigil` is simply the identifier for the entity without the defined The `id without sigil` is simply the identifier for the entity without the defined
sigil. For example, `!room:example.org` becomes `room:example.org` (`!` is the sigil sigil. For example, `!room:example.org` becomes `room:example.org` (`!` is the sigil
for room IDs). The sigils are described under the for room IDs). The sigils are described under the
@ -799,7 +806,6 @@ Examples of common URIs are:
<!-- Author's note: These examples should be consistent with the matrix.to counterparts. --> <!-- Author's note: These examples should be consistent with the matrix.to counterparts. -->
* Link to `#somewhere:example.org`: `matrix:r/somewhere:example.org` * Link to `#somewhere:example.org`: `matrix:r/somewhere:example.org`
* Link to `!somewhere:example.org`: `matrix:roomid/somewhere:example.org?via=elsewhere.ca` * Link to `!somewhere:example.org`: `matrix:roomid/somewhere:example.org?via=elsewhere.ca`
* Link to `$event` in `#somewhere:example.org`: `matrix:r/somewhere:example.org/e/event`
* Link to `$event` in `!somewhere:example.org`: `matrix:roomid/somewhere:example.org/e/event?via=elsewhere.ca` * Link to `$event` in `!somewhere:example.org`: `matrix:roomid/somewhere:example.org/e/event?via=elsewhere.ca`
* Link to chat with `@alice:example.org`: `matrix:u/alice:example.org?action=chat` * Link to chat with `@alice:example.org`: `matrix:u/alice:example.org?action=chat`
@ -809,9 +815,9 @@ A suggested client implementation algorithm is available in the
#### matrix.to navigation #### matrix.to navigation
{{% boxes/note %}} {{% boxes/note %}}
This namespacing existed prior to a `matrix:` scheme. This is **not** matrix.to is a Namespace URI which existed prior to a `matrix:` URI scheme.
meant to be interpreted as an available web service - see below for more This is **not** meant to be interpreted as an available web service - see
details. below for more details.
{{% /boxes/note %}} {{% /boxes/note %}}
A matrix.to URI has the following format, based upon the specification A matrix.to URI has the following format, based upon the specification
@ -843,10 +849,16 @@ Examples of matrix.to URIs are:
<!-- Author's note: These examples should be consistent with the matrix scheme counterparts. --> <!-- Author's note: These examples should be consistent with the matrix scheme counterparts. -->
* Link to `#somewhere:example.org`: `https://matrix.to/#/%23somewhere%3Aexample.org` * Link to `#somewhere:example.org`: `https://matrix.to/#/%23somewhere%3Aexample.org`
* Link to `!somewhere:example.org`: `https://matrix.to/#/!somewhere%3Aexample.org?via=elsewhere.ca` * Link to `!somewhere:example.org`: `https://matrix.to/#/!somewhere%3Aexample.org?via=elsewhere.ca`
* Link to `$event` in `#somewhere:example.org`: `https://matrix.to/#/%23somewhere:example.org/%24event%3Aexample.org`
* Link to `$event` in `!somewhere:example.org`: `https://matrix.to/#/!somewhere%3Aexample.org/%24event%3Aexample.org?via=elsewhere.ca` * Link to `$event` in `!somewhere:example.org`: `https://matrix.to/#/!somewhere%3Aexample.org/%24event%3Aexample.org?via=elsewhere.ca`
* Link to `@alice:example.org`: `https://matrix.to/#/%40alice%3Aexample.org` * Link to `@alice:example.org`: `https://matrix.to/#/%40alice%3Aexample.org`
{{% boxes/note %}}
{{< changed-in v="1.11" >}}
Referencing event IDs within a room identified by room alias rather than room ID
is now deprecated. We are not aware of these ever having been used in
practice, and are nonsensical given room aliases are mutable.
{{% /boxes/note %}}
{{% boxes/note %}} {{% boxes/note %}}
Historically, clients have not produced URIs which are fully encoded. Historically, clients have not produced URIs which are fully encoded.
Clients should try to interpret these cases to the best of their Clients should try to interpret these cases to the best of their
@ -921,6 +933,50 @@ unique servers based on the following criteria:
specify the servers it can. For example, a room with only 2 users in specify the servers it can. For example, a room with only 2 users in
it would result in maximum 2 `via` parameters. 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 ## 3PID Types
Third-party Identifiers (3PIDs) represent identifiers on other Third-party Identifiers (3PIDs) represent identifiers on other

@ -390,8 +390,7 @@ specify parameter values. The flow for this method is as follows:
## Client Authentication ## Client Authentication
Most API endpoints require the user to identify themselves by presenting Most API endpoints require the user to identify themselves by presenting
previously obtained credentials in the form of an `access_token` query previously obtained credentials in the form of an access token.
parameter or through an Authorization Header of `Bearer $access_token`.
An access token is typically obtained via the [Login](#login) or An access token is typically obtained via the [Login](#login) or
[Registration](#account-registration-and-management) processes. Access tokens [Registration](#account-registration-and-management) processes. Access tokens
can expire; a new access token can be generated by using a refresh token. can expire; a new access token can be generated by using a refresh token.
@ -405,16 +404,19 @@ investigate [macaroons](http://research.google.com/pubs/pub41892.html).
### Using access tokens ### Using access tokens
Access tokens may be provided in two ways, both of which the homeserver Access tokens may be provided via a request header, using the Authentication
MUST support: Bearer scheme: `Authorization: Bearer TheTokenHere`.
1. Via a query string parameter, `access_token=TheTokenHere`. Clients may alternatively provide the access token via a query string parameter:
2. Via a request header, `Authorization: Bearer TheTokenHere`. `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 Homeservers MUST support both methods.
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 {{% boxes/note %}}
inaccessible for the client. {{% 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 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 return with a status of 401 and the error code, `M_MISSING_TOKEN` or
@ -544,8 +546,10 @@ request parameter.
A client should first make a request with no `auth` 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: 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 ```json
{ {
@ -588,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 attempted. For example, if the client is attempting to complete auth
type `example.type.foo`, it might submit something like this: 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 ```json
{ {
@ -609,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 the addition of the `completed` key which is an array of auth types the
client has completed successfully: client has completed successfully:
HTTP/1.1 401 Unauthorized ```
Content-Type: application/json HTTP/1.1 401 Unauthorized
Content-Type: application/json
```
```json ```json
{ {
@ -641,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 status 401 response as above, with the addition of the standard
`errcode` and `error` fields describing the error. For example: `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 ```json
{ {
@ -669,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 If the request fails for a reason other than authentication, the server
returns an error message in the standard format. For example: 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 ```json
{ {
@ -943,11 +955,12 @@ or completely closed registration (where the homeserver administrators create
and distribute accounts). and distribute accounts).
The token required for this authentication type is shared out of band from 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 Matrix and is an opaque string using the [Opaque Identifier
range `[A-Za-z0-9._~-]`. The server can keep any number of tokens for any Grammar](/appendices#opaque-identifiers), with maximum length of 64
length of time/validity. Such cases might be a token limited to 100 uses or characters. The server can keep any number of tokens for any length of
for the next 2 hours - after the tokens expire, they can no longer be used time/validity. Such cases might be a token limited to 100 uses or for the next
to create accounts. 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 To use this authentication type, clients should submit an auth dict with just
the type, token, and session: the type, token, and session:
@ -967,6 +980,129 @@ in the registration process that their token has expired.
{{% http-api spec="client-server" api="registration_tokens" %}} {{% 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 #### Fallback
Clients cannot be expected to be able to know how to process every Clients cannot be expected to be able to know how to process every
@ -1201,7 +1337,7 @@ is complete, the client will need to submit a `/login` request matching
`m.login.token`. `m.login.token`.
{{< added-in v="1.7" >}} Already-authenticated clients can additionally generate {{< added-in v="1.7" >}} Already-authenticated clients can additionally generate
a token for their user ID if supported by the homeserver using a token for their user ID if supported by the homeserver using
[`POST /login/get_token`](/client-server-api/#post_matrixclientv1loginget_token). [`POST /login/get_token`](/client-server-api/#post_matrixclientv1loginget_token).
{{% http-api spec="client-server" api="login" %}} {{% http-api spec="client-server" api="login" %}}

@ -674,7 +674,7 @@ The process between Alice and Bob verifying each other would be:
their devices if they match or not. their devices if they match or not.
15. Assuming they match, Alice and Bob's devices each calculate Message 15. Assuming they match, Alice and Bob's devices each calculate Message
Authentication Codes (MACs) for: Authentication Codes (MACs) for:
* Each of the keys that they wish the other user to verify (usually their * Each of the keys that they wish the other user to verify (usually their
device ed25519 key and their master cross-signing key). device ed25519 key and their master cross-signing key).
* The complete list of key IDs that they wish the other user to verify. * The complete list of key IDs that they wish the other user to verify.
@ -1197,11 +1197,12 @@ strings in the general form:
- the ID as a UTF-8 string - the ID as a UTF-8 string
- the first key, as 32 bytes. The key to use depends on the mode field: - the first key, as 32 bytes. The key to use depends on the mode field:
- if `0x00` or `0x01`, then the current user's own master cross-signing public key - if `0x00` or `0x01`, then the current user's own master cross-signing public key
- if `0x02`, then the current device's device key - if `0x02`, then the current device's Ed25519 signing key
- the second key, as 32 bytes. The key to use depends on the mode field: - the second key, as 32 bytes. The key to use depends on the mode field:
- if `0x00`, then what the device thinks the other user's master - if `0x00`, then what the device thinks the other user's master
cross-signing key is cross-signing key is
- if `0x01`, then what the device thinks the other device's device key is - if `0x01`, then what the device thinks the other device's Ed25519 signing
key is
- if `0x02`, then what the device thinks the user's master cross-signing key - if `0x02`, then what the device thinks the user's master cross-signing key
is is
- a random shared secret, as a byte string. It is suggested to use a secret - a random shared secret, as a byte string. It is suggested to use a secret
@ -1271,10 +1272,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 the key from the server and decrypt it. Backups are per-user, and users
may replace backups with new backups. may replace backups with new backups.
In contrast with [Key requests](#key-requests), Server-side key backups In contrast with [key requests](#key-requests), server-side key backups do not
do not require another device to be online from which to request keys. require another device to be online from which to request keys. However, as
However, as the session keys are stored on the server encrypted, it the session keys are stored on the server encrypted, the client requires a
requires users to enter a decryption key to decrypt the session keys. [decryption key](#decryption-key) to decrypt the session keys.
To create a backup, a client will call [POST 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 /\_matrix/client/v3/room\_keys/version](#post_matrixclientv3room_keysversion) and define how the keys are to
@ -1295,7 +1296,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 - 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 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 source. Trusted sources for the private key include the user entering the
key, retrieving the key stored in [secret storage](#secret-storage), or key, retrieving the key stored in [secret storage](#secret-storage), or
obtaining the key via [secret sharing](#sharing) from a verified device obtaining the key via [secret sharing](#sharing) from a verified device
@ -1312,31 +1313,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, - and finally, if `is_verified` and `first_message_index` are equal,
then it will keep the key with a lower `forwarded_count`. 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 Normally, the decryption key (i.e. the secret part of the encryption key) is
presented to the user to save, it is presented as a string constructed stored on the server or shared with other devices using the [Secrets](#secrets)
as follows: 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` If the backup decryption key is given directly to the user, the key should be
2. All the bytes in the string above, including the two header bytes, presented as a string using the common [cryptographic key
are XORed together to form a parity byte. This parity byte is representation](/appendices/#cryptographic-key-representation).
appended to the byte string.
3. The byte string is encoded using base58, using the same [mapping as {{% boxes/note %}}
is used for Bitcoin The backup decryption key was previously referred to as a "recovery
addresses](https://en.bitcoin.it/wiki/Base58Check_encoding#Base58_symbol_chart), key". However, this conflicted with common practice in client user
that is, using the alphabet interfaces, which often use the term "recovery key" to refer to the [secret
`123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`. storage](#storage) key. The term "recovery key" is no longer used in this
4. A space should be added after every 4th character. specification.
{{% /boxes/note %}}
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.
###### Backup algorithm: `m.megolm_backup.v1.curve25519-aes-sha2` ###### Backup algorithm: `m.megolm_backup.v1.curve25519-aes-sha2`

@ -73,11 +73,12 @@ the tag.
| Tag | Permitted Attributes | | Tag | Permitted Attributes |
|--------|--------------------------------------------------------------------------------------------------------------------------------------------| |--------|--------------------------------------------------------------------------------------------------------------------------------------------|
| `span` | `data-mx-bg-color`, `data-mx-color`, `data-mx-spoiler` (see [spoiler messages](#spoiler-messages)) | | `span` | `data-mx-bg-color`, `data-mx-color`, `data-mx-spoiler` (see [spoiler messages](#spoiler-messages)), `data-mx-maths` (see [mathematical messages](#mathematical-messages)) |
| `a` | `name`, `target`, `href` (provided the value is not relative and has a scheme matching one of: `https`, `http`, `ftp`, `mailto`, `magnet`) | | `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)) | | `img` | `width`, `height`, `alt`, `title`, `src` (provided it is a [Matrix Content (`mxc://`) URI](#matrix-content-mxc-uris)) |
| `ol` | `start` | | `ol` | `start` |
| `code` | `class` (only classes which start with `language-` for syntax highlighting) | | `code` | `class` (only classes which start with `language-` for syntax highlighting) |
| `div` | `data-mx-maths` (see [mathematical messages](#mathematical-messages)) |
Additionally, web clients should ensure that *all* `a` tags get a Additionally, web clients should ensure that *all* `a` tags get a
`rel="noopener"` to prevent the target page from referencing the `rel="noopener"` to prevent the target page from referencing the
@ -385,6 +386,64 @@ An example of a media message with a caption is:
Clients MUST render the caption alongside the media and SHOULD prefer its Clients MUST render the caption alongside the media and SHOULD prefer its
formatted representation. formatted representation.
##### Mathematical messages
{{% added-in v="1.11" %}}
Users might want to send mathematical notations in their messages.
To send mathematical notations clients MUST use the `formatted_body` and
therefore the `org.matrix.custom.html` format, described above. This makes
mathematical notations valid on any `msgtype` which can support this format
appropriately.
Mathematical notations themselves use the `span` or `div` tags, depending
whether the notation should be presented inline or not. The mathematical
notation is written in [LaTeX](https://www.latex-project.org/) format using the
`data-mx-maths` attribute.
The contents of the tag should be a fallback representation for clients that
cannot render the LaTeX format. The fallback representation could be, for
example, an image, or an HTML approximation, or the raw LaTeX source. When using
an image as a fallback, the sending client should be aware of issues that may
arise from the receiving client using a different background colour. The `body`
should include a textual representation of the notation.
An example of a mathematical notation is:
```json
{
"msgtype": "m.text",
"format": "org.matrix.custom.html",
"body": "This is an equation: sin(x)=a/b.",
"formatted_body": "This is an equation:
<span data-mx-maths=\"\\sin(x)=\\frac{a}{b}\">
sin(<i>x</i>)=<sup><i>a</i></sup>/<sub><i>b</i></sub>
</span>"
}
```
The LaTeX format is poorly defined and has several extensions, so if a client
encounters syntax that it cannot render, it SHOULD present the fallback
representation instead. Clients SHOULD, however, aim to support, at minimum, the
basic [LaTeX2e](https://www.latex-project.org/) maths commands and the
[TeX](https://tug.org/) maths commands, with the possible exception of commands
that could be security risks.
{{% boxes/warning %}}
In general, LaTeX places a heavy burden on client authors to ensure that it is
processed safely. Certain commands, such as [those that can create macros](https://katex.org/docs/supported#macros),
are potentially dangerous. Clients should either decline to process those
commands, or should take care to ensure that they are handled in safe ways (such
as by limiting recursion). In general, LaTeX commands should be filtered by
allowing known-good commands rather than forbidding known-bad commands.
Therefore, clients should not render mathematics by calling a LaTeX compiler
without proper sandboxing, as those executables were not written to handle
untrusted input. Some LaTeX rendering libraries are better suited for that by
allowing only a subset of LaTeX and enforcing recursion limits.
{{% /boxes/warning %}}
#### Server behaviour #### Server behaviour
Homeservers SHOULD reject `m.room.message` events which don't have a Homeservers SHOULD reject `m.room.message` events which don't have a

@ -13,7 +13,7 @@ deciding what content is undesirable for any particular entity and
should instead be empowering those entities to make their own decisions. should instead be empowering those entities to make their own decisions.
As such, a generic framework for communicating "moderation policy lists" As such, a generic framework for communicating "moderation policy lists"
or "moderation policy rooms" is described. Note that this module only or "moderation policy rooms" is described. Note that this module only
describes the data structures and not how they should be interpreting: describes the data structures and not how they should be interpreted:
the entity making the decisions on filtering is best positioned to the entity making the decisions on filtering is best positioned to
interpret the rules how it sees fit. interpret the rules how it sees fit.

@ -262,22 +262,8 @@ For example, 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`, 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: the key should be presented as a string using the common [cryptographic key
representation](/appendices/#cryptographic-key-representation).
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 ##### Deriving keys from passphrases

@ -96,13 +96,8 @@ Matrix clients can send DTMF as specified by WebRTC. The WebRTC standard as of A
in the RTP payload. in the RTP payload.
#### Grammar for VoIP IDs #### Grammar for VoIP IDs
`call_id`s and `party_id` are explicitly defined to be between 1 and 255 characters long, consisting
of the characters `[0-9a-zA-Z._~-]`.
(Note that this matches the grammar of 'opaque IDs' from `call_id`s and `party_id` must follow the [Opaque Identifier Grammar](/appendices#opaque-identifiers).
[MSC1597](https://github.com/matrix-org/matrix-spec-proposals/blob/rav/proposals/id_grammar/proposals/1597-id-grammar.md#opaque-ids),
and that of the `id` property of the
[`m.login.sso` flow schema](#definition-mloginsso-flow-schema).)
#### Behaviour on Room Leave #### Behaviour on Room Leave
If the client sees the user it is in a call with leave the room, the client should treat this If the client sees the user it is in a call with leave the room, the client should treat this
@ -174,15 +169,19 @@ In response to an incoming invite, a client may do one of several things:
Clients may send more than one stream in a VoIP call. The streams should be 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), 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) [`m.call.answer`](/client-server-api/#mcallanswer) and [`m.call.negotiate`](/client-server-api/#mcallnegotiate)
events, using the `sdp_stream_metadata` property. 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.
`sdp_stream_metadata` maps from the `id` of a stream in the session description,
to metadata about that stream. Currently only one property is defined for the Clients are recommended to not mute the audio of WebRTC tracks locally when an
metadata. This is `purpose`, which should be a string indicating the purpose of incoming stream has the `audio_muted` field set to `true`. This is because when
the stream. The following `purpose`s are defined: 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)
* `m.usermedia` - stream that contains the webcam and/or microphone tracks event arriving and any audio sent in between will not be heard. The other user
* `m.screenshare` - stream with the screen-sharing tracks 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, 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 the stream should be ignored. If a stream has a `purpose` of an unknown type, it

@ -162,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 Identity Server cannot be used to authenticate Client-Server API
requests. 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`.
1. Via a query string parameter, `access_token=TheTokenHere`. Clients may alternatively provide the access token via a query string
2. Via a request header, `Authorization: Bearer TheTokenHere`. 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 the use the `Authorization` header where Identity Servers MUST support both methods.
possible to prevent the access token being leaked in access/HTTP logs.
The query string should only be used in cases where the `Authorization` {{% boxes/note %}}
header is inaccessible for the client. {{% 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 When credentials are required but missing or invalid, the HTTP call will
return with a status of 401 and the error code `M_UNAUTHORIZED`. return with a status of 401 and the error code `M_UNAUTHORIZED`.

@ -1,12 +1,6 @@
Events must be signed by the server denoted by the `sender` property. Events must be signed by the server denoted by the `sender` property.
`m.room.redaction` events are not explicitly part of the auth rules.
They are still subject to the minimum power level rules, but should always
fall into "10. Otherwise, allow". Instead of being authorized at the time
of receipt, they are authorized at a later stage: see the
[Redactions](#redactions) section below for more information.
The types of state events that affect authorization are: The types of state events that affect authorization are:
- [`m.room.create`](/client-server-api#mroomcreate) - [`m.room.create`](/client-server-api#mroomcreate)
@ -21,6 +15,18 @@ For example, mentions of the `sender`'s power level can also refer to
the default power level for users in the room. the default power level for users in the room.
{{% /boxes/note %}} {{% /boxes/note %}}
{{% boxes/note %}}
`m.room.redaction` events are subject to auth rules in the same way as any other event.
In practice, that means they will normally be allowed by the auth rules, unless the
`m.room.power_levels` event sets a power level requirement for `m.room.redaction`
events via the `events` or `events_default` properties. In particular, the _redact
level_ is **not** considered by the auth rules.
The ability to send a redaction event does not mean that the redaction itself should
be performed. Receiving servers must perform additional checks, as described in
the [Handling Redactions](#handling-redactions) section.
{{% /boxes/note %}}
The rules are as follows: The rules are as follows:
1. If type is `m.room.create`: 1. If type is `m.room.create`:

@ -76,12 +76,6 @@ correctly structured are rejected under the authorization rules below.
Events must be signed by the server denoted by the `sender` property. Events must be signed by the server denoted by the `sender` property.
`m.room.redaction` events are not explicitly part of the auth rules.
They are still subject to the minimum power level rules, but should always
fall into "10. Otherwise, allow". Instead of being authorized at the time
of receipt, they are authorized at a later stage: see the
[Redactions](#redactions) section below for more information.
The types of state events that affect authorization are: The types of state events that affect authorization are:
- [`m.room.create`](/client-server-api#mroomcreate) - [`m.room.create`](/client-server-api#mroomcreate)
@ -96,6 +90,18 @@ For example, mentions of the `sender`'s power level can also refer to
the default power level for users in the room. the default power level for users in the room.
{{% /boxes/note %}} {{% /boxes/note %}}
{{% boxes/note %}}
`m.room.redaction` events are subject to auth rules in the same way as any other event.
In practice, that means they will normally be allowed by the auth rules, unless the
`m.room.power_levels` event sets a power level requirement for `m.room.redaction`
events via the `events` or `events_default` properties. In particular, the _redact
level_ is **not** considered by the auth rules.
The ability to send a redaction event does not mean that the redaction itself should
be performed. Receiving servers must perform additional checks, as described in
the [Handling redactions](#handling-redactions) section.
{{% /boxes/note %}}
The rules are as follows: The rules are as follows:
1. If type is `m.room.create`: 1. If type is `m.room.create`:
@ -215,7 +221,7 @@ The rules are as follows:
If either of the properties `events` or `notifications` in `content` If either of the properties `events` or `notifications` in `content`
are present and not an object with values that are integers, are present and not an object with values that are integers,
reject. reject.
3. If the `users` property in `content` is not an obiect with keys that 3. If the `users` property in `content` is not an object with keys that
are valid user IDs with values that are integers, reject. are valid user IDs with values that are integers, reject.
4. If there is no previous `m.room.power_levels` event in the room, 4. If there is no previous `m.room.power_levels` event in the room,
allow. allow.

@ -72,7 +72,7 @@ The `redacts` property of `m.room.redaction` events is moved from a top-level
event property to a property under the event `content`. event property to a property under the event `content`.
For backwards-compatibility with older clients, servers should add a `redacts` property For backwards-compatibility with older clients, servers should add a `redacts` property
to the top level of `m.room.redaction` events in when serving such events over the to the top level of `m.room.redaction` events when serving such events over the
Client-Server API. Client-Server API.
For improved compatibility with newer clients, servers should add a `redacts` property For improved compatibility with newer clients, servers should add a `redacts` property
@ -83,12 +83,6 @@ such events over the Client-Server API.
Events must be signed by the server denoted by the `sender` property. Events must be signed by the server denoted by the `sender` property.
`m.room.redaction` events are not explicitly part of the auth rules.
They are still subject to the minimum power level rules, but should always
fall into "10. Otherwise, allow". Instead of being authorized at the time
of receipt, they are authorized at a later stage: see the
[Redactions](#redactions) section below for more information.
The types of state events that affect authorization are: The types of state events that affect authorization are:
- [`m.room.create`](/client-server-api#mroomcreate) - [`m.room.create`](/client-server-api#mroomcreate)
@ -103,6 +97,18 @@ For example, mentions of the `sender`'s power level can also refer to
the default power level for users in the room. the default power level for users in the room.
{{% /boxes/note %}} {{% /boxes/note %}}
{{% boxes/note %}}
`m.room.redaction` events are subject to auth rules in the same way as any other event.
In practice, that means they will normally be allowed by the auth rules, unless the
`m.room.power_levels` event sets a power level requirement for `m.room.redaction`
events via the `events` or `events_default` properties. In particular, the _redact
level_ is **not** considered by the auth rules.
The ability to send a redaction event does not mean that the redaction itself should
be performed. Receiving servers must perform additional checks, as described in
the [Handling redactions](#handling-redactions) section.
{{% /boxes/note %}}
The rules are as follows: The rules are as follows:
1. {{< changed-in this="true" >}} 1. {{< changed-in this="true" >}}
@ -219,7 +225,7 @@ The rules are as follows:
2. If either of the properties `events` or `notifications` in `content` 2. If either of the properties `events` or `notifications` in `content`
are present and not an object with values that are integers, are present and not an object with values that are integers,
reject. reject.
3. If the `users` property in `content` is not an obiect with keys that 3. If the `users` property in `content` is not an object with keys that
are valid user IDs with values that are integers, reject. are valid user IDs with values that are integers, reject.
4. If there is no previous `m.room.power_levels` event in the room, 4. If there is no previous `m.room.power_levels` event in the room,
allow. allow.

@ -89,12 +89,17 @@ The complete structure of a event in a v3 room is shown below.
### Authorization rules ### Authorization rules
{{< added-in this=true >}} `m.room.redaction` events are no longer {{% boxes/note %}}
explicitly part of the auth rules. They are still subject to the {{< added-in this=true >}} `m.room.redaction` events are subject to auth rules in
minimum power level rules, but should always fall into "11. Otherwise, the same way as any other event. In practice, that means they will normally be allowed
allow". Instead of being authorized at the time of receipt, they are by the auth rules, unless the `m.room.power_levels` event sets a power level requirement
authorized at a later stage: see the [Handling Redactions](#handling-redactions) for `m.room.redaction`events via the `events` or `events_default` properties. In
section below for more information. particular, the _redact level_ is **not** considered by the auth rules.
The ability to send a redaction event does not mean that the redaction itself should
be performed. Receiving servers must perform additional checks, as described in
the [Handling Redactions](#handling-redactions) section.
{{% /boxes/note %}}
<!-- set withVersioning=true so we get all the "new in this version" stuff --> <!-- set withVersioning=true so we get all the "new in this version" stuff -->
{{< rver-fragment name="v3-auth-rules" withVersioning=true >}} {{< rver-fragment name="v3-auth-rules" withVersioning=true >}}

@ -40,12 +40,6 @@ in [room version 5](/rooms/v5).
### Authorization rules ### Authorization rules
`m.room.redaction` events are not explicitly part of the auth rules.
They are still subject to the minimum power level rules, but should always
fall into "10. Otherwise, allow". Instead of being authorized at the time
of receipt, they are authorized at a later stage: see the
[Handling Redactions](#handling-redactions) section below for more information.
{{< added-in this=true >}} Rule 4, which related specifically to events {{< added-in this=true >}} Rule 4, which related specifically to events
of type `m.room.aliases`, is removed. `m.room.aliases` events must still pass of type `m.room.aliases`, is removed. `m.room.aliases` events must still pass
authorization checks relating to state events. authorization checks relating to state events.
@ -71,6 +65,18 @@ For example, mentions of the `sender`'s power level can also refer to
the default power level for users in the room. the default power level for users in the room.
{{% /boxes/note %}} {{% /boxes/note %}}
{{% boxes/note %}}
`m.room.redaction` events are subject to auth rules in the same way as any other event.
In practice, that means they will normally be allowed by the auth rules, unless the
`m.room.power_levels` event sets a power level requirement for `m.room.redaction`
events via the `events` or `events_default` properties. In particular, the _redact
level_ is **not** considered by the auth rules.
The ability to send a redaction event does not mean that the redaction itself should
be performed. Receiving servers must perform additional checks, as described in
the [Handling Redactions](#handling-redactions) section.
{{% /boxes/note %}}
The rules are as follows: The rules are as follows:
1. If type is `m.room.create`: 1. If type is `m.room.create`:

@ -37,12 +37,6 @@ new point for `membership=knock` is added.
Events must be signed by the server denoted by the `sender` property. Events must be signed by the server denoted by the `sender` property.
`m.room.redaction` events are not explicitly part of the auth rules.
They are still subject to the minimum power level rules, but should always
fall into "10. Otherwise, allow". Instead of being authorized at the time
of receipt, they are authorized at a later stage: see the
[Redactions](#redactions) section below for more information.
The types of state events that affect authorization are: The types of state events that affect authorization are:
- [`m.room.create`](/client-server-api#mroomcreate) - [`m.room.create`](/client-server-api#mroomcreate)
@ -57,6 +51,18 @@ For example, mentions of the `sender`'s power level can also refer to
the default power level for users in the room. the default power level for users in the room.
{{% /boxes/note %}} {{% /boxes/note %}}
{{% boxes/note %}}
`m.room.redaction` events are subject to auth rules in the same way as any other event.
In practice, that means they will normally be allowed by the auth rules, unless the
`m.room.power_levels` event sets a power level requirement for `m.room.redaction`
events via the `events` or `events_default` properties. In particular, the _redact
level_ is **not** considered by the auth rules.
The ability to send a redaction event does not mean that the redaction itself should
be performed. Receiving servers must perform additional checks, as described in
the [Handling redactions](#handling-redactions) section.
{{% /boxes/note %}}
The rules are as follows: The rules are as follows:
1. If type is `m.room.create`: 1. If type is `m.room.create`:

@ -350,9 +350,10 @@ def authorization_headers(origin_name, origin_signing_key,
The format of the Authorization header is given in The format of the Authorization header is given in
[RFC 7235](https://datatracker.ietf.org/doc/html/rfc7235#section-2.1). In [RFC 7235](https://datatracker.ietf.org/doc/html/rfc7235#section-2.1). In
summary, the header begins with authorization scheme `X-Matrix`, followed by summary, the header begins with authorization scheme `X-Matrix`, followed by one
one or more spaces, followed by a comma-separated list of parameters written as or more spaces, followed by a comma-separated list of parameters written as
name=value pairs. The names are case insensitive and order does not matter. The name=value pairs. Zero or more spaces and tabs around each comma are allowed.
The names are case insensitive and order does not matter. The
values must be enclosed in quotes if they contain characters that are not values must be enclosed in quotes if they contain characters that are not
allowed in `token`s, as defined in allowed in `token`s, as defined in
[RFC 7230](https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6); if a [RFC 7230](https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6); if a
@ -363,8 +364,9 @@ replaced by the character that follows the backslash.
For compatibility with older servers, the sender should For compatibility with older servers, the sender should
- only include one space after `X-Matrix`, - only include one space after `X-Matrix`,
- only use lower-case names, and - only use lower-case names,
- avoid using backslashes in parameter values. - avoid using backslashes in parameter values, and
- avoid including whitespace around the commas between name=value pairs.
For compatibility with older servers, the recipient should allow colons to be For compatibility with older servers, the recipient should allow colons to be
included in values without requiring the value to be enclosed in quotes. included in values without requiring the value to be enclosed in quotes.

@ -29,7 +29,9 @@ properties:
description: A secret token that the homeserver will use authenticate requests to the application service. description: A secret token that the homeserver will use authenticate requests to the application service.
sender_localpart: sender_localpart:
type: string type: string
description: The localpart of the user associated with the application service. description: |-
The localpart of the user associated with the application service. Events will be sent to the AS if this user is the target of the event, or
is a joined member of the room where the event occurred.
namespaces: namespaces:
type: object type: object
title: Namespaces title: Namespaces
@ -40,9 +42,10 @@ properties:
- $ref: namespace_list.yaml - $ref: namespace_list.yaml
- description: |- - description: |-
A list of namespaces defining the user IDs that the application A list of namespaces defining the user IDs that the application
service is interested in. Events will be sent to the AS if a service is interested in, in addition to its `sender_localpart`.
local user matching one of the namespaces is the target of the event, Events will be sent to the AS if a local user matching one of the
or is a joined member of the room where the event occurred. namespaces is the target of the event, or is a joined member of
the room where the event occurred.
rooms: rooms:
allOf: allOf:
- $ref: namespace_list.yaml - $ref: namespace_list.yaml

@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
homeserverAccessToken: homeserverAccessToken:
type: apiKey type: http
name: Authorization scheme: bearer
in: header
description: The `Bearer` `hs_token` provided by the application service's registration. description: The `Bearer` `hs_token` provided by the application service's registration.

@ -69,4 +69,5 @@ servers:
default: /_matrix/app/v1 default: /_matrix/app/v1
components: components:
securitySchemes: securitySchemes:
$ref: definitions/security.yaml homeserverAccessToken:
$ref: definitions/security.yaml#/homeserverAccessToken

@ -339,4 +339,5 @@ servers:
default: /_matrix/app/v1 default: /_matrix/app/v1
components: components:
securitySchemes: securitySchemes:
$ref: definitions/security.yaml homeserverAccessToken:
$ref: definitions/security.yaml#/homeserverAccessToken

@ -103,4 +103,5 @@ servers:
default: /_matrix/app/v1 default: /_matrix/app/v1
components: components:
securitySchemes: securitySchemes:
$ref: definitions/security.yaml homeserverAccessToken:
$ref: definitions/security.yaml#/homeserverAccessToken

@ -100,4 +100,5 @@ servers:
default: /_matrix/app/v1 default: /_matrix/app/v1
components: components:
securitySchemes: securitySchemes:
$ref: definitions/security.yaml homeserverAccessToken:
$ref: definitions/security.yaml#/homeserverAccessToken

@ -88,4 +88,5 @@ servers:
default: /_matrix/app/v1 default: /_matrix/app/v1
components: components:
securitySchemes: securitySchemes:
$ref: definitions/security.yaml homeserverAccessToken:
$ref: definitions/security.yaml#/homeserverAccessToken

@ -26,7 +26,8 @@ paths:
[/sync](#get_matrixclientv3sync). [/sync](#get_matrixclientv3sync).
operationId: setAccountData operationId: setAccountData
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
parameters: parameters:
- in: path - in: path
name: userId name: userId
@ -117,7 +118,8 @@ paths:
that set the account data. that set the account data.
operationId: getAccountData operationId: getAccountData
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
parameters: parameters:
- in: path - in: path
name: userId name: userId
@ -186,7 +188,8 @@ paths:
clients in the per-room entries via [/sync](#get_matrixclientv3sync). clients in the per-room entries via [/sync](#get_matrixclientv3sync).
operationId: setAccountDataPerRoom operationId: setAccountDataPerRoom
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
parameters: parameters:
- in: path - in: path
name: userId name: userId
@ -285,7 +288,8 @@ paths:
visible to the user that set the account data. visible to the user that set the account data.
operationId: getAccountDataPerRoom operationId: getAccountDataPerRoom
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
parameters: parameters:
- in: path - in: path
name: userId name: userId
@ -379,4 +383,7 @@ servers:
default: /_matrix/client/v3 default: /_matrix/client/v3
components: components:
securitySchemes: securitySchemes:
$ref: definitions/security.yaml accessTokenQuery:
$ref: definitions/security.yaml#/accessTokenQuery
accessTokenBearer:
$ref: definitions/security.yaml#/accessTokenBearer

@ -27,7 +27,8 @@ paths:
specified in this document. specified in this document.
operationId: getWhoIs operationId: getWhoIs
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
parameters: parameters:
- in: path - in: path
name: userId name: userId
@ -120,4 +121,7 @@ servers:
default: /_matrix/client/v3 default: /_matrix/client/v3
components: components:
securitySchemes: securitySchemes:
$ref: definitions/security.yaml accessTokenQuery:
$ref: definitions/security.yaml#/accessTokenQuery
accessTokenBearer:
$ref: definitions/security.yaml#/accessTokenBearer

@ -31,7 +31,8 @@ paths:
identifiers that it will accept to reset the user's account password. identifiers that it will accept to reset the user's account password.
operationId: getAccount3PIDs operationId: getAccount3PIDs
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
responses: responses:
"200": "200":
description: The lookup was successful. description: The lookup was successful.
@ -101,7 +102,8 @@ paths:
operationId: post3PIDs operationId: post3PIDs
deprecated: true deprecated: true
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
requestBody: requestBody:
content: content:
application/json: application/json:
@ -201,7 +203,8 @@ paths:
already been added to another user's account on the homeserver. already been added to another user's account on the homeserver.
operationId: add3PID operationId: add3PID
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
requestBody: requestBody:
content: content:
application/json: application/json:
@ -263,7 +266,8 @@ paths:
Homeservers should track successful binds so they can be unbound later. Homeservers should track successful binds so they can be unbound later.
operationId: bind3PID operationId: bind3PID
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
requestBody: requestBody:
content: content:
application/json: application/json:
@ -324,7 +328,8 @@ paths:
identity server instead. identity server instead.
operationId: delete3pidFromAccount operationId: delete3pidFromAccount
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
requestBody: requestBody:
content: content:
application/json: application/json:
@ -393,7 +398,8 @@ paths:
identity server instead. identity server instead.
operationId: unbind3pidFromAccount operationId: unbind3pidFromAccount
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
requestBody: requestBody:
content: content:
application/json: application/json:
@ -584,4 +590,7 @@ servers:
default: /_matrix/client/v3 default: /_matrix/client/v3
components: components:
securitySchemes: securitySchemes:
$ref: definitions/security.yaml accessTokenQuery:
$ref: definitions/security.yaml#/accessTokenQuery
accessTokenBearer:
$ref: definitions/security.yaml#/accessTokenBearer

@ -57,8 +57,8 @@ paths:
example: mautrix-go_1683636478256400935_123 example: mautrix-go_1683636478256400935_123
required: true required: true
security: security:
# again, this is the appservice's token - not a typical client's - appserviceAccessTokenQuery: []
- accessToken: [] - appserviceAccessTokenBearer: []
responses: responses:
"200": "200":
description: The ping was successful. description: The ping was successful.
@ -177,6 +177,7 @@ servers:
default: /_matrix/client/v1 default: /_matrix/client/v1
components: components:
securitySchemes: securitySchemes:
# Note: this is the same access_token definition used elsewhere in the client appserviceAccessTokenQuery:
# server API, however this expects an access token for an application service. $ref: definitions/security.yaml#/appserviceAccessTokenQuery
$ref: definitions/security.yaml appserviceAccessTokenBearer:
$ref: definitions/security.yaml#/appserviceAccessTokenBearer

@ -67,8 +67,8 @@ paths:
- visibility - visibility
required: true required: true
security: security:
# again, this is the appservice's token - not a typical client's - appserviceAccessTokenQuery: []
- accessToken: [] - appserviceAccessTokenBearer: []
responses: responses:
"200": "200":
description: The room's directory visibility has been updated. description: The room's directory visibility has been updated.
@ -95,6 +95,7 @@ servers:
default: /_matrix/client/v3 default: /_matrix/client/v3
components: components:
securitySchemes: securitySchemes:
# Note: this is the same access_token definition used elsewhere in the client appserviceAccessTokenQuery:
# server API, however this expects an access token for an application service. $ref: definitions/security.yaml#/appserviceAccessTokenQuery
$ref: definitions/security.yaml appserviceAccessTokenBearer:
$ref: definitions/security.yaml#/appserviceAccessTokenBearer

@ -27,7 +27,8 @@ paths:
The caller must have the required power level in order to perform this operation. The caller must have the required power level in order to perform this operation.
operationId: ban operationId: ban
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
parameters: parameters:
- in: path - in: path
name: roomId name: roomId
@ -96,7 +97,8 @@ paths:
The caller must have the required power level in order to perform this operation. The caller must have the required power level in order to perform this operation.
operationId: unban operationId: unban
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
parameters: parameters:
- in: path - in: path
name: roomId name: roomId
@ -169,4 +171,7 @@ servers:
default: /_matrix/client/v3 default: /_matrix/client/v3
components: components:
securitySchemes: securitySchemes:
$ref: definitions/security.yaml accessTokenQuery:
$ref: definitions/security.yaml#/accessTokenQuery
accessTokenBearer:
$ref: definitions/security.yaml#/accessTokenBearer

@ -24,7 +24,8 @@ paths:
and other relevant capabilities. and other relevant capabilities.
operationId: getCapabilities operationId: getCapabilities
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
responses: responses:
"200": "200":
description: The capabilities of the server. description: The capabilities of the server.
@ -120,4 +121,7 @@ servers:
default: /_matrix/client/v3 default: /_matrix/client/v3
components: components:
securitySchemes: securitySchemes:
$ref: definitions/security.yaml accessTokenQuery:
$ref: definitions/security.yaml#/accessTokenQuery
accessTokenBearer:
$ref: definitions/security.yaml#/accessTokenBearer

@ -22,26 +22,13 @@ paths:
summary: Upload some content to the content repository. summary: Upload some content to the content repository.
operationId: uploadContent operationId: uploadContent
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
parameters: parameters:
- in: header - $ref: '#/components/parameters/contentType'
name: Content-Type - $ref: '#/components/parameters/filename'
description: The content type of the file being uploaded
example: application/pdf
schema:
type: string
- in: query
name: filename
description: The name of the file being uploaded
example: War and Peace.pdf
schema:
type: string
requestBody: requestBody:
content: $ref: '#/components/requestBodies/bytes'
application/octet-stream:
example: <bytes>
description: The content to be uploaded.
required: true
responses: responses:
"200": "200":
description: The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) for description: The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) for
@ -55,7 +42,8 @@ paths:
properties: properties:
content_uri: content_uri:
type: string type: string
format: uri format: mx-mxc-uri
pattern: "^mxc:\\/\\/"
description: The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) to description: The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) to
the uploaded content. the uploaded content.
examples: examples:
@ -80,23 +68,9 @@ paths:
"error": "Cannot upload this content" "error": "Cannot upload this content"
} }
"413": "413":
description: The uploaded content is too large for the server. $ref: '#/components/responses/uploadTooLarge'
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_TOO_LARGE",
"error": "Cannot upload files larger than 100mb"
}
"429": "429":
description: This request was rate-limited. $ref: '#/components/responses/rateLimited'
content:
application/json:
schema:
$ref: definitions/errors/rate_limited.yaml
tags: tags:
- Media - Media
"/media/v3/upload/{serverName}/{mediaId}": "/media/v3/upload/{serverName}/{mediaId}":
@ -108,40 +82,16 @@ paths:
operationId: uploadContentToMXC operationId: uploadContentToMXC
x-addedInMatrixVersion: "1.7" x-addedInMatrixVersion: "1.7"
parameters: parameters:
- in: path - $ref: '#/components/parameters/serverName'
name: serverName
required: true
description: | description: |
The server name from the `mxc://` URI returned by `POST /_matrix/media/v1/create` (the authoritory component). The server name from the `mxc://` URI returned by `POST /_matrix/media/v1/create` (the authority component).
example: matrix.org - $ref: '#/components/parameters/mediaId'
schema:
type: string
- in: path
name: mediaId
required: true
description: | description: |
The media ID from the `mxc://` URI returned by `POST /_matrix/media/v1/create` (the path component). The media ID from the `mxc://` URI returned by `POST /_matrix/media/v1/create` (the path component).
example: ascERGshawAWawugaAcauga - $ref: '#/components/parameters/contentType'
schema: - $ref: '#/components/parameters/filename'
type: string
- in: header
name: Content-Type
description: The content type of the file being uploaded
example: application/pdf
schema:
type: string
- in: query
name: filename
description: The name of the file being uploaded
example: War and Peace.pdf
schema:
type: string
requestBody: requestBody:
content: $ref: '#/components/requestBodies/bytes'
application/octet-stream:
example: <bytes>
description: The content to be uploaded.
required: true
responses: responses:
"200": "200":
description: The upload was successful. description: The upload was successful.
@ -189,23 +139,9 @@ paths:
"error": "Media already uploaded" "error": "Media already uploaded"
} }
"413": "413":
description: The uploaded content is too large for the server. $ref: '#/components/responses/uploadTooLarge'
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_TOO_LARGE",
"error": "Cannot upload files larger than 100mb"
}
"429": "429":
description: This request was rate-limited. $ref: '#/components/responses/rateLimited'
content:
application/json:
schema:
$ref: definitions/errors/rate_limited.yaml
tags: tags:
- Media - Media
/media/v1/create: /media/v1/create:
@ -234,7 +170,8 @@ paths:
operationId: createContent operationId: createContent
x-addedInMatrixVersion: "1.7" x-addedInMatrixVersion: "1.7"
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
# empty json object # empty json object
responses: responses:
"200": "200":
@ -249,7 +186,8 @@ paths:
properties: properties:
content_uri: content_uri:
type: string type: string
format: uri format: mx-mxc-uri
pattern: "^mxc:\\/\\/"
description: |- description: |-
The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) at The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) at
which the content will be available, once it is uploaded. which the content will be available, once it is uploaded.
@ -274,11 +212,7 @@ paths:
"error": "Cannot upload this content" "error": "Cannot upload this content"
} }
"429": "429":
description: This request was rate-limited. $ref: '#/components/responses/rateLimited'
content:
application/json:
schema:
$ref: definitions/errors/rate_limited.yaml
tags: tags:
- Media - Media
"/media/v3/download/{serverName}/{mediaId}": "/media/v3/download/{serverName}/{mediaId}":
@ -286,68 +220,17 @@ paths:
summary: Download content from the content repository. summary: Download content from the content repository.
operationId: getContent operationId: getContent
parameters: parameters:
- in: path - $ref: '#/components/parameters/serverName'
name: serverName - $ref: '#/components/parameters/mediaId'
required: true - $ref: '#/components/parameters/allow_remote'
description: | - $ref: '#/components/parameters/timeout_ms'
The server name from the `mxc://` URI (the authoritory component) - $ref: '#/components/parameters/allow_redirect'
example: matrix.org
schema:
type: string
- in: path
name: mediaId
required: true
description: |
The media ID from the `mxc://` URI (the path component)
example: ascERGshawAWawugaAcauga
schema:
type: string
- in: query
name: allow_remote
required: false
description: |
Indicates to the server that it should not attempt to fetch the media if it is deemed
remote. This is to prevent routing loops where the server contacts itself. Defaults to
true if not provided.
example: false
schema:
type: boolean
default: true
- in: query
name: timeout_ms
x-addedInMatrixVersion: "1.7"
description: |
The maximum number of milliseconds that the client is willing to
wait to start receiving data, in the case that the content has not
yet been uploaded. The default value is 20000 (20 seconds). The
content repository can and should impose a maximum value for this
parameter. The content repository may also choose to respond before
the timeout.
example: 5000
schema:
type: integer
format: int64
default: 20000
- in: query
name: allow_redirect
x-addedInMatrixVersion: "1.7"
required: false
description: |
Indicates to the server that it may return a 307 or 308 redirect response that points
at the relevant media content. When not explicitly set to true the server must return
the media content itself.
example: false
schema:
type: boolean
default: false
responses: responses:
"200": "200":
description: The content that was previously uploaded. description: The content that was previously uploaded.
headers: headers:
Content-Type: Content-Type:
description: The content type of the file that was previously uploaded. $ref: '#/components/headers/downloadContentType'
schema:
type: string
Content-Disposition: Content-Disposition:
description: The name of the file that was previously uploaded, if set. description: The name of the file that was previously uploaded, if set.
schema: schema:
@ -358,51 +241,15 @@ paths:
# This is a workaround for us not being able to say the response is required. # This is a workaround for us not being able to say the response is required.
description: "**Required.** The bytes for the uploaded file." description: "**Required.** The bytes for the uploaded file."
"307": "307":
description: A redirect to the thumbnail of the requested content. $ref: '#/components/responses/downloadRedirect'
headers:
Location:
description: The URL of the thumbnail content.
schema:
type: string
"308": "308":
description: A redirect to the thumbnail of the requested content. $ref: '#/components/responses/downloadRedirect'
headers:
Location:
description: The URL of the thumbnail content.
schema:
type: string
"429": "429":
description: This request was rate-limited. $ref: '#/components/responses/rateLimited'
content:
application/json:
schema:
$ref: definitions/errors/rate_limited.yaml
"502": "502":
description: The content is too large for the server to serve. $ref: '#/components/responses/downloadTooLarge'
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_TOO_LARGE",
"error": "Content is too large to serve"
}
"504": "504":
description: |- $ref: '#/components/responses/notYetUploaded'
The content is not yet available. A [standard error response](/client-server-api/#standard-error-response)
will be returned with the `errcode` `M_NOT_YET_UPLOADED`.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_NOT_YET_UPLOADED",
"error": "Content has not yet been uploaded"
}
tags: tags:
- Media - Media
"/media/v3/download/{serverName}/{mediaId}/{fileName}": "/media/v3/download/{serverName}/{mediaId}/{fileName}":
@ -414,22 +261,8 @@ paths:
provided by the caller. provided by the caller.
operationId: getContentOverrideName operationId: getContentOverrideName
parameters: parameters:
- in: path - $ref: '#/components/parameters/serverName'
name: serverName - $ref: '#/components/parameters/mediaId'
required: true
description: |
The server name from the `mxc://` URI (the authoritory component)
example: matrix.org
schema:
type: string
- in: path
name: mediaId
required: true
description: |
The media ID from the `mxc://` URI (the path component)
example: ascERGshawAWawugaAcauga
schema:
type: string
- in: path - in: path
name: fileName name: fileName
required: true required: true
@ -437,52 +270,15 @@ paths:
example: filename.jpg example: filename.jpg
schema: schema:
type: string type: string
- in: query - $ref: '#/components/parameters/allow_remote'
name: allow_remote - $ref: '#/components/parameters/timeout_ms'
required: false - $ref: '#/components/parameters/allow_redirect'
description: |
Indicates to the server that it should not attempt to fetch the media if it is deemed
remote. This is to prevent routing loops where the server contacts itself. Defaults to
true if not provided.
example: false
schema:
type: boolean
default: true
- in: query
name: timeout_ms
x-addedInMatrixVersion: "1.7"
description: |
The maximum number of milliseconds that the client is willing to
wait to start receiving data, in the case that the content has not
yet been uploaded. The default value is 20000 (20 seconds). The
content repository can and should impose a maximum value for this
parameter. The content repository may also choose to respond before
the timeout.
example: 5000
schema:
type: integer
format: int64
default: 20000
- in: query
name: allow_redirect
x-addedInMatrixVersion: "1.7"
required: false
description: |
Indicates to the server that it may return a 307 or 308 redirect response that points
at the relevant media content. When not explicitly set to true the server must return
the media content itself.
example: false
schema:
type: boolean
default: false
responses: responses:
"200": "200":
description: The content that was previously uploaded. description: The content that was previously uploaded.
headers: headers:
Content-Type: Content-Type:
description: The content type of the file that was previously uploaded. $ref: '#/components/headers/downloadContentType'
schema:
type: string
Content-Disposition: Content-Disposition:
description: |- description: |-
The `fileName` requested or the name of the file that was previously The `fileName` requested or the name of the file that was previously
@ -495,51 +291,15 @@ paths:
# This is a workaround for us not being able to say the response is required. # This is a workaround for us not being able to say the response is required.
description: "**Required.** The bytes for the uploaded file." description: "**Required.** The bytes for the uploaded file."
"307": "307":
description: A redirect to the thumbnail of the requested content. $ref: '#/components/responses/downloadRedirect'
headers:
Location:
description: The URL of the thumbnail content.
schema:
type: string
"308": "308":
description: A redirect to the thumbnail of the requested content. $ref: '#/components/responses/downloadRedirect'
headers:
Location:
description: The URL of the thumbnail content.
schema:
type: string
"429": "429":
description: This request was rate-limited. $ref: '#/components/responses/rateLimited'
content:
application/json:
schema:
$ref: definitions/errors/rate_limited.yaml
"502": "502":
description: The content is too large for the server to serve. $ref: '#/components/responses/downloadTooLarge'
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_TOO_LARGE",
"error": "Content is too large to serve"
}
"504": "504":
description: |- $ref: '#/components/responses/notYetUploaded'
The content is not yet available. A [standard error response](/client-server-api/#standard-error-response)
will be returned with the `errcode` `M_NOT_YET_UPLOADED`.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_NOT_YET_UPLOADED",
"error": "Content has not yet been uploaded"
}
tags: tags:
- Media - Media
"/media/v3/thumbnail/{serverName}/{mediaId}": "/media/v3/thumbnail/{serverName}/{mediaId}":
@ -550,22 +310,8 @@ paths:
See the [Thumbnails](/client-server-api/#thumbnails) section for more information. See the [Thumbnails](/client-server-api/#thumbnails) section for more information.
operationId: getContentThumbnail operationId: getContentThumbnail
parameters: parameters:
- in: path - $ref: '#/components/parameters/serverName'
name: serverName - $ref: '#/components/parameters/mediaId'
required: true
description: |
The server name from the `mxc://` URI (the authoritory component)
example: example.org
schema:
type: string
- in: path
name: mediaId
required: true
description: |
The media ID from the `mxc://` URI (the path component)
example: ascERGshawAWawugaAcauga
schema:
type: string
- in: query - in: query
name: width name: width
required: true required: true
@ -595,44 +341,31 @@ paths:
enum: enum:
- crop - crop
- scale - scale
- $ref: '#/components/parameters/allow_remote'
- $ref: '#/components/parameters/timeout_ms'
- $ref: '#/components/parameters/allow_redirect'
- in: query - in: query
name: allow_remote name: animated
required: false x-addedInMatrixVersion: "1.11"
description: |-
Indicates to the server that it should not attempt to fetch
the media if it is deemed remote. This is to prevent routing loops
where the server contacts itself. Defaults to true if not provided.
example: false
schema:
type: boolean
default: true
- in: query
name: timeout_ms
x-addedInMatrixVersion: "1.7"
description: |
The maximum number of milliseconds that the client is willing to
wait to start receiving data, in the case that the content has not
yet been uploaded. The default value is 20000 (20 seconds). The
content repository can and should impose a maximum value for this
parameter. The content repository may also choose to respond before
the timeout.
example: 5000
schema:
type: integer
format: int64
default: 20000
- in: query
name: allow_redirect
x-addedInMatrixVersion: "1.7"
required: false required: false
description: | description: |
Indicates to the server that it may return a 307 or 308 redirect response that points Indicates preference for an animated thumbnail from the server, if possible. Animated
at the relevant media content. When not explicitly set to true the server must return thumbnails typically use the content types `image/gif`, `image/png` (with APNG format),
the media content itself. `image/apng`, and `image/webp` instead of the common static `image/png` or `image/jpeg`
content types.
When `true`, the server SHOULD return an animated thumbnail if possible and supported.
When `false`, the server MUST NOT return an animated thumbnail. For example, returning a
static `image/png` or `image/jpeg` thumbnail. When not provided, the server SHOULD NOT
return an animated thumbnail.
Servers SHOULD prefer to return `image/webp` thumbnails when supporting animation.
When `true` and the media cannot be animated, such as in the case of a JPEG or PDF, the
server should behave as though `animated` is `false`.
example: false example: false
schema: schema:
type: boolean type: boolean
default: false
responses: responses:
"200": "200":
description: A thumbnail of the requested content. description: A thumbnail of the requested content.
@ -644,6 +377,9 @@ paths:
enum: enum:
- image/jpeg - image/jpeg
- image/png - image/png
- image/apng
- image/gif
- image/webp
content: content:
image/jpeg: image/jpeg:
schema: schema:
@ -651,21 +387,27 @@ paths:
description: "**Required.** The bytes for the thumbnail." description: "**Required.** The bytes for the thumbnail."
image/png: image/png:
schema: schema:
description: "**Required.** The bytes for the thumbnail." x-changedInMatrixVersion:
"307": "1.11": The PNG may be of the APNG variety if animation is supported and requested.
description: A redirect to the thumbnail of the requested content. description: |
headers: **Required.** The bytes for the thumbnail. The thumbnail MAY use an animated
Location: format if `animated=true`.
description: The URL of the thumbnail content. image/apng:
schema: schema:
type: string x-addedInMatrixVersion: "1.11"
"308": description: "**Required.** The bytes for the *animated* thumbnail."
description: A redirect to the thumbnail of the requested content. image/gif:
headers:
Location:
description: The URL of the thumbnail content.
schema: schema:
type: string x-addedInMatrixVersion: "1.11"
description: "**Required.** The bytes for the *animated* thumbnail."
image/webp:
schema:
x-addedInMatrixVersion: "1.11"
description: "**Required.** The bytes for the *animated* thumbnail."
"307":
$ref: '#/components/responses/thumbnailRedirect'
"308":
$ref: '#/components/responses/thumbnailRedirect'
"400": "400":
description: |- description: |-
The request does not make sense to the server, or the server cannot thumbnail The request does not make sense to the server, or the server cannot thumbnail
@ -694,11 +436,7 @@ paths:
"error": "Content is too large to thumbnail" "error": "Content is too large to thumbnail"
} }
"429": "429":
description: This request was rate-limited. $ref: '#/components/responses/rateLimited'
content:
application/json:
schema:
$ref: definitions/errors/rate_limited.yaml
"502": "502":
description: The remote content is too large for the server to thumbnail. description: The remote content is too large for the server to thumbnail.
content: content:
@ -712,19 +450,7 @@ paths:
"error": "Content is too large to thumbnail" "error": "Content is too large to thumbnail"
} }
"504": "504":
description: |- $ref: '#/components/responses/notYetUploaded'
The content is not yet available. A [standard error response](/client-server-api/#standard-error-response)
will be returned with the `errcode` `M_NOT_YET_UPLOADED`.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_NOT_YET_UPLOADED",
"error": "Content has not yet been uploaded"
}
tags: tags:
- Media - Media
/media/v3/preview_url: /media/v3/preview_url:
@ -741,7 +467,8 @@ paths:
being shared should also not be shared with the homeserver. being shared should also not be shared with the homeserver.
operationId: getUrlPreview operationId: getUrlPreview
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
parameters: parameters:
- in: query - in: query
name: url name: url
@ -793,11 +520,7 @@ paths:
"matrix:image:size": 102400 "matrix:image:size": 102400
} }
"429": "429":
description: This request was rate-limited. $ref: '#/components/responses/rateLimited'
content:
application/json:
schema:
$ref: definitions/errors/rate_limited.yaml
tags: tags:
- Media - Media
/media/v3/config: /media/v3/config:
@ -816,7 +539,8 @@ paths:
than is advertised by the server on this endpoint. than is advertised by the server on this endpoint.
operationId: getConfig operationId: getConfig
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
responses: responses:
"200": "200":
description: The public content repository configuration for the matrix server. description: The public content repository configuration for the matrix server.
@ -838,11 +562,7 @@ paths:
"m.upload.size": 50000000 "m.upload.size": 50000000
} }
"429": "429":
description: This request was rate-limited. $ref: '#/components/responses/rateLimited'
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
tags: tags:
- Media - Media
servers: servers:
@ -859,4 +579,157 @@ servers:
default: /_matrix default: /_matrix
components: components:
securitySchemes: securitySchemes:
$ref: definitions/security.yaml accessTokenQuery:
$ref: definitions/security.yaml#/accessTokenQuery
accessTokenBearer:
$ref: definitions/security.yaml#/accessTokenBearer
parameters:
contentType:
in: header
name: Content-Type
description: The content type of the file being uploaded
example: application/pdf
schema:
type: string
filename:
in: query
name: filename
description: The name of the file being uploaded
example: War and Peace.pdf
schema:
type: string
serverName:
in: path
name: serverName
required: true
description: |
The server name from the `mxc://` URI (the authority component).
example: matrix.org
schema:
type: string
format: mx-server-name
mediaId:
in: path
name: mediaId
required: true
description: |
The media ID from the `mxc://` URI (the path component).
example: ascERGshawAWawugaAcauga
schema:
type: string
allow_remote:
in: query
name: allow_remote
required: false
description: |-
Indicates to the server that it should not attempt to fetch the media if
it is deemed remote. This is to prevent routing loops where the server
contacts itself.
Defaults to `true` if not provided.
example: false
schema:
type: boolean
default: true
timeout_ms:
in: query
name: timeout_ms
x-addedInMatrixVersion: "1.7"
description: |
The maximum number of milliseconds that the client is willing to wait to
start receiving data, in the case that the content has not yet been
uploaded. The default value is 20000 (20 seconds). The content
repository can and should impose a maximum value for this parameter. The
content repository may also choose to respond before the timeout.
example: 5000
schema:
type: integer
format: int64
default: 20000
allow_redirect:
in: query
name: allow_redirect
x-addedInMatrixVersion: "1.7"
required: false
description: |
Indicates to the server that it may return a 307 or 308 redirect
response that points at the relevant media content. When not explicitly
set to `true` the server must return the media content itself.
example: false
schema:
type: boolean
default: false
requestBodies:
bytes:
content:
application/octet-stream:
example: <bytes>
description: The content to be uploaded.
required: true
responses:
uploadTooLarge:
description: The uploaded content is too large for the server.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_TOO_LARGE",
"error": "Cannot upload files larger than 100mb"
}
rateLimited:
description: This request was rate-limited.
content:
application/json:
schema:
$ref: definitions/errors/rate_limited.yaml
notYetUploaded:
description: |-
The content is not yet available. A [standard error response](/client-server-api/#standard-error-response)
will be returned with the `errcode` `M_NOT_YET_UPLOADED`.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_NOT_YET_UPLOADED",
"error": "Content has not yet been uploaded"
}
downloadRedirect:
description: A redirect to the requested content.
headers:
Location:
description: The URL of the content.
schema:
type: string
format: uri
downloadTooLarge:
description: The content is too large for the server to serve.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_TOO_LARGE",
"error": "Content is too large to serve"
}
thumbnailRedirect:
description: A redirect to the thumbnail of the requested content.
headers:
Location:
description: The URL of the thumbnail content.
schema:
type: string
format: uri
headers:
downloadContentType:
description: The content type of the file that was previously uploaded.
schema:
type: string

@ -64,7 +64,8 @@ paths:
`creation_content`. `creation_content`.
operationId: createRoom operationId: createRoom
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
requestBody: requestBody:
content: content:
application/json: application/json:
@ -290,4 +291,7 @@ servers:
default: /_matrix/client/v3 default: /_matrix/client/v3
components: components:
securitySchemes: securitySchemes:
$ref: definitions/security.yaml accessTokenQuery:
$ref: definitions/security.yaml#/accessTokenQuery
accessTokenBearer:
$ref: definitions/security.yaml#/accessTokenBearer

@ -19,14 +19,30 @@ paths:
/keys/device_signing/upload: /keys/device_signing/upload:
post: post:
x-addedInMatrixVersion: "1.1" x-addedInMatrixVersion: "1.1"
x-changedInMatrixVersion:
"1.11": UIA is not always required for this endpoint.
summary: Upload cross-signing keys. summary: Upload cross-signing keys.
description: |- description: |-
Publishes cross-signing keys for the user. Publishes cross-signing keys for the user.
This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api). This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api).
User-Interactive Authentication MUST be performed, except in these cases:
- there is no existing cross-signing master key uploaded to the homeserver, OR
- there is an existing cross-signing master key and it exactly matches the
cross-signing master key provided in the request body. If there are any additional
keys provided in the request (self-signing key, user-signing key) they MUST also
match the existing keys stored on the server. In other words, the request contains
no new keys.
This allows clients to freely upload one set of keys, but not modify/overwrite keys if
they already exist. Allowing clients to upload the same set of keys more than once
makes this endpoint idempotent in the case where the response is lost over the network,
which would otherwise cause a UIA challenge upon retry.
operationId: uploadCrossSigningKeys operationId: uploadCrossSigningKeys
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
requestBody: requestBody:
content: content:
application/json: application/json:
@ -155,7 +171,8 @@ paths:
property, which contains the new signature(s) to add. property, which contains the new signature(s) to add.
operationId: uploadCrossSigningSignatures operationId: uploadCrossSigningSignatures
security: security:
- accessToken: [] - accessTokenQuery: []
- accessTokenBearer: []
requestBody: requestBody:
content: content:
application/json: application/json:
@ -163,10 +180,12 @@ paths:
type: object type: object
description: |- description: |-
A map of user ID to a map of key ID to signed JSON object. A map of user ID to a map of key ID to signed JSON object.
additionalProperties: patternProperties:
type: object "^@":
additionalProperties: x-pattern-format: mx-user-id
type: object type: object
additionalProperties:
type: object
example: { example: {
"@alice:example.com": { "@alice:example.com": {
"HIJKLMN": { "HIJKLMN": {
@ -236,11 +255,13 @@ paths:
A map from user ID to key ID to an error for any signatures A map from user ID to key ID to an error for any signatures
that failed. If a signature was invalid, the `errcode` will that failed. If a signature was invalid, the `errcode` will
be set to `M_INVALID_SIGNATURE`. be set to `M_INVALID_SIGNATURE`.
additionalProperties: patternProperties:
type: object "^@":
additionalProperties:
type: object type: object
title: Error x-pattern-format: mx-user-id
additionalProperties:
type: object
title: Error
example: example:
"@alice:example.com": "@alice:example.com":
HIJKLMN: HIJKLMN:
@ -262,4 +283,7 @@ servers:
default: /_matrix/client/v3 default: /_matrix/client/v3
components: components:
securitySchemes: securitySchemes:
$ref: definitions/security.yaml accessTokenQuery:
$ref: definitions/security.yaml#/accessTokenQuery
accessTokenBearer:
$ref: definitions/security.yaml#/accessTokenBearer

@ -53,10 +53,12 @@ properties:
`<algorithm>:<device_id>` to the signature. `<algorithm>:<device_id>` to the signature.
The signature is calculated using the process described at [Signing JSON](/appendices/#signing-json). The signature is calculated using the process described at [Signing JSON](/appendices/#signing-json).
additionalProperties: patternProperties:
type: object "^@":
additionalProperties: x-pattern-format: mx-user-id
type: string type: object
additionalProperties:
type: string
example: example:
"@alice:example.com": "@alice:example.com":
"ed25519:JLAFKJWSCS": "dSO80A01XiigH3uBiDVx/EjzaoycHcjq9lfQX0uWsqxl2giMIiSPR8a4d291W1ihKJL/a+myXS367WT6NAIcBA" "ed25519:JLAFKJWSCS": "dSO80A01XiigH3uBiDVx/EjzaoycHcjq9lfQX0uWsqxl2giMIiSPR8a4d291W1ihKJL/a+myXS367WT6NAIcBA"

@ -0,0 +1,82 @@
# Copyright 2024 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
type: object
title: m.login.terms params
description: Schema for `m.login.terms` entry in the `params` object in a User-Interactive Authentication response.
required: ['policies']
properties:
policies:
type: object
description: |
A map from "Policy ID" to the current definition of this policy document. The Policy ID is a unique
identifier for a given policy document, using the [Opaque Identifier Grammar](/appendices/#opaque-identifiers).
additionalProperties:
type: object
title: Policy Definition
required: [version]
properties:
version:
type: string
description: |
The version of this policy document. This is provided as a convenience for the client,
and uses the [Opaque Identifier Grammar](/appendices/#opaque-identifiers).
additionalProperties:
type: object
title: Policy Translation
required: [name, url]
description: |
Map from language codes to details of the document in that language.
Language codes SHOULD be formatted as per [Section 2.2 of RFC
5646](https://datatracker.ietf.org/doc/html/rfc5646#section-2.2),
though some implementations may use an underscore instead of dash
(for example, `en_US` instead of `en-US`).
properties:
name:
type: string
description: |
The name of this document, in the appropriate language. An
arbitrary string with no specified maximum length.
url:
type: string
description: |
A link to the text of this document, in the appropriate
language. MUST be a valid URI with scheme `https://` or
`http://`. Insecure HTTP is discouraged.
example: {
"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"
}
},
"privacy_policy": {
"version": "1.2",
"en": {
"name": "Privacy Policy",
"url": "https://example.org/somewhere/privacy-1.2-en.html"
},
"fr": {
"name": "Politique de confidentialité",
"url": "https://example.org/somewhere/privacy-1.2-fr.html"
}
}
}
}

@ -9,6 +9,7 @@ additionalProperties:
oneOf: oneOf:
- type: string - type: string
- type: object - type: object
title: KeyObject
properties: properties:
key: key:
type: string type: string
@ -18,7 +19,9 @@ additionalProperties:
description: |- description: |-
Signature for the device. Mapped from user ID to signature object, Signature for the device. Mapped from user ID to signature object,
containing mapping from _key signing identifier_ to the signature containing mapping from _key signing identifier_ to the signature
(see also: https://spec.matrix.org/v1.2/appendices/#signing-json) (see also: [Signing JSON](/appendices/#signing-json))
additionalProperties: patternProperties:
type: object "^@":
x-pattern-format: mx-user-id
type: object
required: ['key', 'signatures'] required: ['key', 'signatures']

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

Loading…
Cancel
Save