diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3bcc6010..92b841f4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,8 +1,9 @@ name: "Spec" env: - HUGO_VERSION: 0.148.1 + HUGO_VERSION: 0.153.3 PYTHON_VERSION: 3.13 + NODE_VERSION: 24 on: push: @@ -27,7 +28,7 @@ jobs: - name: "➕ Setup Node" uses: actions/setup-node@v4 with: - node-version: '20' + node-version: ${{ env.NODE_VERSION }} - name: "🔎 Run validator" run: | npx @redocly/cli@latest lint data/api/*/*.yaml @@ -195,11 +196,13 @@ jobs: needs: [calculate-baseurl, build-openapi, generate-changelog] # run even if generate-changelog was skipped if: ${{ always() }} + env: + baseURL: "${{ needs.calculate-baseurl.outputs.baseURL }}" steps: - name: "➕ Setup Node" uses: actions/setup-node@v4 with: - node-version: '20' + node-version: ${{ env.NODE_VERSION }} - name: "➕ Setup Hugo" uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3.0.0 with: @@ -217,8 +220,10 @@ jobs: with: name: changelog-artifact path: content/changelog + - name: "⚙️ hugo" - run: hugo --baseURL "${{ needs.calculate-baseurl.outputs.baseURL }}" -d "spec" + run: hugo --baseURL "${baseURL}" -d "spec${baseURL}" + # We manually unpack the spec OpenAPI definition JSON to the website tree # to make it available to the world in a canonical place: # https://spec.matrix.org/latest/client-server-api/api.json @@ -229,10 +234,13 @@ jobs: name: openapi-artifact - name: "📝 Unpack the OpenAPI definitions in the right location" run: | - tar -xzf openapi.tar.gz + tar -C "spec${baseURL}" --strip-components=1 -xzf openapi.tar.gz - name: "📦 Tarball creation" - run: tar -czf spec.tar.gz spec + run: | + cd spec + tar -czf ../spec.tar.gz * + - name: "📤 Artifact upload" uses: actions/upload-artifact@v4 with: @@ -243,6 +251,14 @@ jobs: name: "🔎 Validate generated HTML" runs-on: ubuntu-latest needs: [calculate-baseurl, build-spec] + # Run even if `generate-changelog` was skipped. + # + # `build-spec` has a dependency on `generate-changelog` to ensure order of execution + # and to access `needs.generate-changelog.result`. However, `generate-changelog` is + # skipped on tag builds; even a transient dependency on `generate-changelog` is then + # enough for this step to also be skipped by default on tag builds. Hence the need for + # this explicit `if`. + if: ${{ !failure() && !cancelled() }} steps: - name: "📥 Source checkout" uses: actions/checkout@v4 @@ -253,14 +269,9 @@ jobs: name: spec-artifact - name: "📝 Unpack the spec" - # we have to unpack it into the right path given the baseurl, so that the - # links are correct. - # eg if baseurl is `/unstable`, we want to put the site in `spec/unstable`. run: | - mkdir -p "spec${baseURL}" - tar -C "spec${baseURL}" --strip-components=1 -xvzf spec.tar.gz - env: - baseURL: "${{ needs.calculate-baseurl.outputs.baseURL }}" + mkdir spec + tar -C spec -xvzf spec.tar.gz - name: "Run htmltest" uses: wjdp/htmltest-action@master @@ -270,13 +281,15 @@ jobs: build-historical-spec: name: "📖 Build the historical backup spec" runs-on: ubuntu-latest - needs: [build-openapi] + needs: [calculate-baseurl, build-openapi] if: ${{ startsWith(github.ref, 'refs/tags/') }} + env: + baseURL: "${{ needs.calculate-baseurl.outputs.baseURL }}" steps: - name: "➕ Setup Node" uses: actions/setup-node@v4 with: - node-version: '20' + node-version: ${{ env.NODE_VERSION }} - name: "➕ Setup Hugo" uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3.0.0 with: @@ -291,9 +304,8 @@ jobs: - name: "⚙️ hugo" env: HUGO_PARAMS_VERSION_STATUS: "historical" - # Create a baseURL like `/v1.2` out of the `v1.2` tag run: | - hugo --baseURL "/${GITHUB_REF/refs\/tags\//}" -d "spec" + hugo --baseURL "${baseURL}" -d "spec${baseURL}" - name: "📥 Spec definition download" uses: actions/download-artifact@v4 @@ -301,12 +313,51 @@ jobs: name: openapi-artifact - name: "📝 Unpack the OpenAPI definitions in the right location" run: | - tar -xzf openapi.tar.gz + tar -C "spec${baseURL}" --strip-components=1 -xzf openapi.tar.gz - name: "📦 Tarball creation" - run: tar -czf spec-historical.tar.gz spec + run: | + cd spec + tar -czf ../spec-historical.tar.gz * + - name: "📤 Artifact upload" uses: actions/upload-artifact@v4 with: name: spec-historical-artifact path: spec-historical.tar.gz + + # If we're building a tag, create a release and publish the artifacts + create_release: + name: "Create release" + if: ${{ !failure() && !cancelled() && startsWith(github.ref, 'refs/tags/') }} + needs: + - build-spec + - build-historical-spec + runs-on: ubuntu-latest + steps: + - name: "📥 Check out changelogs" + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + with: + sparse-checkout: | + content/changelog + - name: "📥 Download built spec" + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + with: + name: spec-artifact + - name: "📥 Download historical spec artifact" + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + with: + name: spec-historical-artifact + - name: "✨ Create draft release" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # Remove front-matter from changelog + sed '1,/^---$/d' "content/changelog/${{ github.ref_name }}.md" > changelog.md + + # Create a draft release, using the changelog as release notes, and attaching the spec artifacts. + gh release create -d -t "${{ github.ref_name }}" \ + -F "changelog.md" \ + "${{ github.ref_name }}" \ + spec.tar.gz \ + spec-historical.tar.gz diff --git a/.github/workflows/netlify.yaml b/.github/workflows/netlify.yaml index 7c59f64c..6b4258a1 100644 --- a/.github/workflows/netlify.yaml +++ b/.github/workflows/netlify.yaml @@ -45,7 +45,9 @@ jobs: name: spec-artifact - name: "📦 Extract Artifacts" - run: tar -xzvf spec.tar.gz && rm spec.tar.gz + run: | + mkdir spec + tar -C spec -xzvf spec.tar.gz && rm spec.tar.gz - name: "📤 Deploy to Netlify" id: netlify diff --git a/assets/js/toc.js b/assets/js/toc.js index 89a83ced..a7103f9d 100644 --- a/assets/js/toc.js +++ b/assets/js/toc.js @@ -50,7 +50,7 @@ function getHeadings() { let headings = []; // First get the anchors in the ToC. - const toc_anchors = document.querySelectorAll("#toc nav a"); + const toc_anchors = document.querySelectorAll("#TableOfContents a"); for (const anchor of toc_anchors) { // Then get the heading from its selector in the anchor's href. @@ -59,7 +59,7 @@ function getHeadings() { console.error("Got ToC anchor without href"); continue; } - + const heading = document.querySelector(selector); if (!heading) { console.error("Heading not found for selector:", selector); @@ -122,13 +122,13 @@ function getCurrentHeading(headings, headerOffset) { */ function selectTocEntry(id) { // Deselect previously selected entries. - const activeEntries = document.querySelectorAll("#toc nav a.active"); + const activeEntries = document.querySelectorAll("#TableOfContents a.active"); for (const activeEntry of activeEntries) { activeEntry.classList.remove('active'); } // Find the new entry and select it. - const newEntry = document.querySelector(`#toc nav a[href="#${id}"]`); + const newEntry = document.querySelector(`#TableOfContents a[href="#${id}"]`); if (!newEntry) { console.error("ToC entry not found for ID:", id); return; diff --git a/assets/scss/_styles_project.scss b/assets/scss/_styles_project.scss index f20dc096..cd9937a9 100644 --- a/assets/scss/_styles_project.scss +++ b/assets/scss/_styles_project.scss @@ -76,52 +76,126 @@ Custom SCSS for the Matrix spec scroll-behavior: smooth; overscroll-behavior: contain; - &>.td-sidebar-nav__section { + & > .td-sidebar-nav__section { margin-top: 1rem; - } - .td-sidebar-nav__section .ul-1 ul { - padding-left: 0; - } - - /* This is to make the width of the items that have sub-items (like room versions) - the same as the width of items that don't (like changelog) */ - .pr-md-3, .px-md-3 { - padding-right: 0 !important; - } - - .ul-1 > li > a { - padding-left: 1rem !important; - } - - .ul-2 > li > a { - padding-left: 2rem !important; - } - - a.td-sidebar-link.tree-root { - color: $gray-800; - font-weight: $font-weight-bold; - font-size: 1.3rem; - margin-bottom: 0; - border-bottom: none; - } - - a, a.td-sidebar-link { - color: $gray-800; - font-weight: $font-weight-normal; - padding-top: .2rem; - padding-bottom: .2rem; - - display: block; - transition: all 100ms ease-in-out; - - &:hover { - background-color: $secondary-lighter-background; - color: $gray-800; + .ul-1 ul { + padding-left: 0; } - &.active, &active:hover { - background-color: $secondary-background; + /* This is to make the width of the items that have sub-items (like room versions) + the same as the width of items that don't (like changelog) */ + .pr-md-3, .px-md-3 { + padding-right: 0 !important; + } + + .ul-1 > li > a { + padding-left: 1rem !important; + } + + .ul-2 > li > a { + padding-left: 2rem !important; + } + } + + /* Styles for the table of contents */ + & > .td-toc { + padding-top: 1rem; + padding-left: 1.5rem; + /* Add border above the toc */ + border-top: 1px solid var(--bs-tertiary-color); + + ol { + padding-left: 1rem; + counter-reset: section; + list-style-type: none; + } + + #TableOfContents { + /* Remove the space between the title and the ToC */ + margin-top: 0; + + &>ol>li { + margin-bottom: .5rem; + + &>a { + font-weight: $font-weight-bold; + } + } + + ol { + padding-left: 0; + } + + &>ol>li>a { + padding-left: 1rem; + } + + &>ol>li>ol>li>a { + padding-left: 2rem; + } + + &>ol>li>ol>li>ol>li>a { + padding-left: 3rem; + } + + &>ol>li>ol>li>ol>li>ol>li>a { + padding-left: 4rem; + } + + &>ol>li>ol>li>ol>li>ol>li>ol>li>a { + padding-left: 5rem; + } + + } + + li a:before { + counter-increment: section; + content: counters(section, ".") " "; + } + + .td-toc-title { + font-weight: $font-weight-bold; + font-size: 1.3rem; + + /* Remove the border under the title */ + border-bottom: 0; + /* Remove the space under the title */ + margin-bottom: 0; + + /* Fix the top of page link color */ + a, a:hover { + color: $secondary; + } + } + } + + /* Apply the same style to links in the navigation and in the ToC */ + & > .td-sidebar-nav__section, & > .td-toc #TableOfContents { + li a.td-sidebar-link.tree-root { + color: $gray-800; + font-weight: $font-weight-bold; + font-size: 1.3rem; + margin-bottom: 0; + border-bottom: none; + } + + li a, li a.td-sidebar-link { + color: $gray-800; + font-weight: $font-weight-normal; + padding-top: .2rem; + padding-bottom: .2rem; + + transition: all 100ms ease-in-out; + + &:hover { + background-color: $secondary-lighter-background; + color: $gray-800; + } + + &.active, &active:hover { + background-color: $secondary-background; + } } } } @@ -199,64 +273,6 @@ Custom SCSS for the Matrix spec scroll-margin-top: 5.5rem; } -/* Styles for the table of contents */ -#toc { - padding-top: .5rem; - padding-left: 1.5rem; - - ol { - padding-left: 1rem; - counter-reset: section; - list-style-type: none; - } - - #TableOfContents { - &>ol>li { - margin-bottom: .5rem; - - &>a { - font-weight: $font-weight-bold; - } - } - - ol { - padding-left: 0; - } - - &>ol>li>a { - padding-left: 1rem; - } - - &>ol>li>ol>li>a { - padding-left: 2rem; - } - - &>ol>li>ol>li>ol>li>a { - padding-left: 3rem; - } - - &>ol>li>ol>li>ol>li>ol>li>a { - padding-left: 4rem; - } - - &>ol>li>ol>li>ol>li>ol>li>ol>li>a { - padding-left: 5rem; - } - - } - - li a:before { - counter-increment: section; - content: counters(section, ".") " "; - } - - #toc-title { - font-weight: $font-weight-bold; - font-size: 1.3rem; - } - -} - .endpoints-toc { summary { cursor: pointer; diff --git a/assets/scss/_variables_project.scss b/assets/scss/_variables_project.scss index c2ec03c6..75e5379f 100644 --- a/assets/scss/_variables_project.scss +++ b/assets/scss/_variables_project.scss @@ -18,6 +18,7 @@ $primary: #FFF; $secondary: #0098D4; $dark: #333; $gray-100: #FBFBFB; +$code-color: #005b7f; $secondary-background: #E5F5FB; $secondary-lighter-background: #F4FAFC; diff --git a/changelogs/appendices/newsfragments/2307.clarification b/changelogs/appendices/newsfragments/2307.clarification new file mode 100644 index 00000000..e81f3952 --- /dev/null +++ b/changelogs/appendices/newsfragments/2307.clarification @@ -0,0 +1 @@ +Add identifier pronunciation guidelines. Contributed by @HarHarLinks. diff --git a/changelogs/client_server/newsfragments/2270.feature b/changelogs/client_server/newsfragments/2270.feature new file mode 100644 index 00000000..b675c947 --- /dev/null +++ b/changelogs/client_server/newsfragments/2270.feature @@ -0,0 +1 @@ +Add the account management capabilities for the OAuth 2.0 authentication API, as per [MSC4191](https://github.com/matrix-org/matrix-spec-proposals/pull/4191). diff --git a/changelogs/client_server/newsfragments/2272.feature b/changelogs/client_server/newsfragments/2272.feature new file mode 100644 index 00000000..34b6a493 --- /dev/null +++ b/changelogs/client_server/newsfragments/2272.feature @@ -0,0 +1 @@ +Add OAuth 2.0 aware clients, as per [MSC3824](https://github.com/matrix-org/matrix-spec-proposals/pull/3824). diff --git a/changelogs/client_server/newsfragments/2277.clarification b/changelogs/client_server/newsfragments/2277.clarification new file mode 100644 index 00000000..bf818eaf --- /dev/null +++ b/changelogs/client_server/newsfragments/2277.clarification @@ -0,0 +1,3 @@ +The optional `submit_url` response parameter of the `/requestToken` endpoints uses the same request +and response parameters and error codes as the Identity Service API's `POST /_matrix/identity/v2/validate/email/submitToken`, +as per [MSC4183](https://github.com/matrix-org/matrix-spec-proposals/pull/4183). diff --git a/changelogs/client_server/newsfragments/2280.clarification b/changelogs/client_server/newsfragments/2280.clarification new file mode 100644 index 00000000..38fa5012 --- /dev/null +++ b/changelogs/client_server/newsfragments/2280.clarification @@ -0,0 +1 @@ +Update non-historic mentions of matrix-doc repo to matrix-spec/-proposals. Contributed by @HarHarLinks. diff --git a/changelogs/client_server/newsfragments/2283.clarification b/changelogs/client_server/newsfragments/2283.clarification new file mode 100644 index 00000000..2dc18986 --- /dev/null +++ b/changelogs/client_server/newsfragments/2283.clarification @@ -0,0 +1 @@ +Remove unintended TeX formatting. Contributed by @HarHarLinks. diff --git a/changelogs/client_server/newsfragments/2291.feature b/changelogs/client_server/newsfragments/2291.feature new file mode 100644 index 00000000..93a509dc --- /dev/null +++ b/changelogs/client_server/newsfragments/2291.feature @@ -0,0 +1 @@ +Add `m.recent_emoji` account data event to track recently used emoji as per [MSC4356](https://github.com/matrix-org/matrix-spec-proposals/pull/4356). diff --git a/changelogs/client_server/newsfragments/2292.feature b/changelogs/client_server/newsfragments/2292.feature new file mode 100644 index 00000000..6547782b --- /dev/null +++ b/changelogs/client_server/newsfragments/2292.feature @@ -0,0 +1 @@ +Add `m.forget_forced_upon_leave` capability for servers to transparently auto-forget rooms that the user leaves as per [MSC4267](https://github.com/matrix-org/matrix-spec-proposals/pull/4267). diff --git a/changelogs/client_server/newsfragments/2298.feature b/changelogs/client_server/newsfragments/2298.feature new file mode 100644 index 00000000..9f55d7ee --- /dev/null +++ b/changelogs/client_server/newsfragments/2298.feature @@ -0,0 +1 @@ +Add support for `m.room.redaction` events at the `PUT /rooms/{roomId}/send/{eventType}/{txnId}` endpoint, as per [MSC4169](https://github.com/matrix-org/matrix-spec-proposals/pull/4169). diff --git a/changelogs/client_server/newsfragments/2299.feature b/changelogs/client_server/newsfragments/2299.feature new file mode 100644 index 00000000..dc36c6db --- /dev/null +++ b/changelogs/client_server/newsfragments/2299.feature @@ -0,0 +1 @@ +Clients supporting the `ol` HTML element must also support the `start` attribute, as per [MSC4313](https://github.com/matrix-org/matrix-spec-proposals/pull/4313). diff --git a/changelogs/client_server/newsfragments/2305.feature b/changelogs/client_server/newsfragments/2305.feature new file mode 100644 index 00000000..2282230f --- /dev/null +++ b/changelogs/client_server/newsfragments/2305.feature @@ -0,0 +1 @@ +Add invite blocking, as per [MSC4380](https://github.com/matrix-org/matrix-spec-proposals/pull/4380). diff --git a/changelogs/identity_service/newsfragments/2277.clarification b/changelogs/identity_service/newsfragments/2277.clarification new file mode 100644 index 00000000..58510ecf --- /dev/null +++ b/changelogs/identity_service/newsfragments/2277.clarification @@ -0,0 +1,3 @@ +Clarify the error codes that can be returned with a 400 HTTP status code by the `POST /_matrix/identity/v2/validate/email/submitToken` +and `POST /_matrix/identity/v2/validate/msisdn/submitToken` endpoints, introducing the `M_TOKEN_INCORRECT` +error code, as per [MSC4183](https://github.com/matrix-org/matrix-spec-proposals/pull/4183). diff --git a/changelogs/internal/newsfragments/2222.clarification b/changelogs/internal/newsfragments/2222.clarification new file mode 100644 index 00000000..188d64bb --- /dev/null +++ b/changelogs/internal/newsfragments/2222.clarification @@ -0,0 +1 @@ +Clarify vendor prefixing requirements. diff --git a/changelogs/internal/newsfragments/2275.clarification b/changelogs/internal/newsfragments/2275.clarification new file mode 100644 index 00000000..0a0f28a7 --- /dev/null +++ b/changelogs/internal/newsfragments/2275.clarification @@ -0,0 +1 @@ +Auto-create draft releases when building release tags. diff --git a/changelogs/internal/newsfragments/2276.feature b/changelogs/internal/newsfragments/2276.feature new file mode 100644 index 00000000..a0e2b795 --- /dev/null +++ b/changelogs/internal/newsfragments/2276.feature @@ -0,0 +1 @@ +Include the spec release version in the filenames in the tarballs generated by CI. diff --git a/changelogs/internal/newsfragments/2287.clarification b/changelogs/internal/newsfragments/2287.clarification new file mode 100644 index 00000000..5d0bdcc5 --- /dev/null +++ b/changelogs/internal/newsfragments/2287.clarification @@ -0,0 +1 @@ +Upgrade to docsy v0.13.0. diff --git a/changelogs/internal/newsfragments/2289.clarification b/changelogs/internal/newsfragments/2289.clarification new file mode 100644 index 00000000..7991ce2e --- /dev/null +++ b/changelogs/internal/newsfragments/2289.clarification @@ -0,0 +1 @@ +Updates to the release documentation. diff --git a/changelogs/internal/newsfragments/2290.clarification b/changelogs/internal/newsfragments/2290.clarification new file mode 100644 index 00000000..30231938 --- /dev/null +++ b/changelogs/internal/newsfragments/2290.clarification @@ -0,0 +1 @@ +Remove unused leftover CSS files. diff --git a/changelogs/room_versions/newsfragments/2303.clarification b/changelogs/room_versions/newsfragments/2303.clarification new file mode 100644 index 00000000..3a105e98 --- /dev/null +++ b/changelogs/room_versions/newsfragments/2303.clarification @@ -0,0 +1 @@ +Remove the post-1.16 release note for room version 12. diff --git a/changelogs/server_server/newsfragments/2191.clarification b/changelogs/server_server/newsfragments/2191.clarification new file mode 100644 index 00000000..3247bbf5 --- /dev/null +++ b/changelogs/server_server/newsfragments/2191.clarification @@ -0,0 +1 @@ +Clarify what the `minimum_valid_until_ts` field means when it is set in key queries. diff --git a/changelogs/server_server/newsfragments/2288.clarification b/changelogs/server_server/newsfragments/2288.clarification new file mode 100644 index 00000000..3558f255 --- /dev/null +++ b/changelogs/server_server/newsfragments/2288.clarification @@ -0,0 +1 @@ +Specify that callers of `/_matrix/federation/v1/openid/userinfo` must validate the returned user ID. diff --git a/changelogs/server_server/newsfragments/2300.clarification b/changelogs/server_server/newsfragments/2300.clarification new file mode 100644 index 00000000..2df0b588 --- /dev/null +++ b/changelogs/server_server/newsfragments/2300.clarification @@ -0,0 +1 @@ +Change `m.signing_update` typo to `m.signing_key_update`. Contributed by @velikopter \ No newline at end of file diff --git a/config/_default/hugo.toml b/config/_default/hugo.toml index 2fb69279..76c3f9bb 100644 --- a/config/_default/hugo.toml +++ b/config/_default/hugo.toml @@ -166,3 +166,11 @@ sidebar_menu_compact = true mediaType = "text/markdown" isPlainText = true baseName = "checklist" + +# Add font media types for downloading KaTeX fonts. +# See: https://www.docsy.dev/docs/content/diagrams-and-formulae/#create-media-types-for-katex-fonts +[mediaTypes] + [mediaTypes.'font/woff'] + suffixes = ['woff'] + [mediaTypes.'font/woff2'] + suffixes = ['woff2'] diff --git a/content/appendices.md b/content/appendices.md index 52bb79fb..5f943df1 100644 --- a/content/appendices.md +++ b/content/appendices.md @@ -533,6 +533,11 @@ where `domain` is the [server name](#server-name) of the homeserver which allocated the identifier, and `localpart` is an identifier allocated by that homeserver. +Because the domain part identifies the server on which the ID resolves, +the canonical pronunciation of the separating `:` is "on". +For example, `@user:matrix.org` would be pronounced as "at user on matrix dot +org". + The precise grammar defining the allowable format of an identifier depends on the type of identifier. For example, event IDs can sometimes be represented with a `domain` component under some conditions - see the diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index 8f8092b5..90fd2879 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -480,6 +480,13 @@ Currently the OAuth 2.0 API doesn't cover all the use cases of the legacy API, such as automated applications that cannot use a web browser. {{% /boxes/note %}} +{{% boxes/note %}} +{{% added-in v="1.18" %}} +A compatibility feature, called [OAuth 2.0 aware clients](#oauth-20-aware-clients), +is available to ease the transition to the OAuth 2.0 API for clients that only +support the legacy API. +{{% /boxes/note %}} + ### Authentication API discovery To discover if a homeserver supports the legacy API, the [`GET /login`](#get_matrixclientv3login) @@ -645,7 +652,7 @@ manage their account like [changing their password](#password-management), [deactivating their account](#account-deactivation). With the OAuth 2.0 API, all account management is done via the homeserver's web -UI. +UI that can be accessed by users via the [account management URL](#oauth-20-account-management). ### Legacy API @@ -1612,6 +1619,73 @@ MAY reject weak passwords with an error code `M_WEAK_PASSWORD`. {{% http-api spec="client-server" api="account_deactivation" %}} +#### OAuth 2.0 aware clients + +{{% added-in v="1.18" %}} + +This is a compatibility feature to aide clients in the transition to the OAuth +2.0 API. It allows clients that only support the legacy API to make some +less-invasive changes to improve the user experience when talking to a +homeserver that is using the OAuth 2.0 API without actually having to implement +the full OAuth 2.0 API. + +##### Client behaviour + +For a client to be considered fully OAuth 2.0 aware it MUST: + +* Support the [`m.login.sso` authentication flow](#client-login-via-sso). +* Where a `oauth_aware_preferred` value of `true` is present on an `m.login.sso` + flow, *only* offer that auth flow to the user. +* Append `action=login` or `action=register` parameters to the [SSO redirect + endpoints](#get_matrixclientv3loginssoredirect). The client might determine + the value to use based on whether the user clicked a "Login" or "Register" + button. +* Check and honour the [`m.3pid_changes` capability](#m3pid_changes-capability) + so that the user is not offered the ability to add or remove 3PIDs if the + homeserver says the capability is not available. +* Determine if the homeserver is using the OAuth 2.0 API by using + [server metadata discovery](#get_matrixclientv1auth_metadata) from the OAuth + 2.0 API. +* If a homeserver is using the OAuth 2.0 API as discovered in the previous step + then the client MUST redirect users to manage their account at the [account + management URL](#oauth-20-account-management), if available, instead of + providing a native UI using the legacy API endpoints. + + * If the user wishes to deactivate their account then the client MUST refer + them to the account management URL. + * If the user wishes to sign out a device other than its own then the client + MUST deep link the user to the account management URL by adding the + `action=org.matrix.device_delete` and `device_id=` parameters so + that the web UI knows that the user wishes to sign out a device and which + one it is. + +Optionally, an OAuth 2.0 aware client MAY: + +* Label the SSO button as "Continue" rather than "SSO" when + `oauth_aware_preferred` is `true`. This is because after redirect the server + may then offer a password and/or further upstream IdPs. +* Pass other [account management URL parameters](#account-management-url-parameters) + for context when linking to the account web UI. + +##### Server behaviour + +For a homeserver to provide support for OAuth 2.0 aware clients it MUST: + +* Support the [OAuth 2.0 API](#oauth-20-api). +* Provide an implementation of the [`m.login.sso` authentication flow](#client-login-via-sso) + from the legacy API. +* If password authentication was previously enabled on the homeserver then + provide an implementation of the [`m.login.password` authentication flow](#legacy-login) + from the legacy API. +* Indicate that the `m.login.sso` flow is preferred by setting + `oauth_aware_preferred` to `true`. +* Support a value for the `action` param on the [SSO redirect endpoints](#get_matrixclientv3loginssoredirect). + +Additionally, the homeserver SHOULD: + +* Advertise the [account management URL](#oauth-20-account-management) in the + [server metadata](#get_matrixclientv1auth_metadata). + ### OAuth 2.0 API {{% added-in v="1.15" %}} @@ -2271,6 +2345,46 @@ The server SHOULD return one of the following responses: - For other errors, the server returns a `400 Bad Request` response with error details +#### Account management {id="oauth-20-account-management"} + +{{% added-in v="1.18" %}} + +All account management is done via the homeserver's web UI. + +This specification defines extensions to the [OAuth Authorization Server +Metadata registry](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#authorization-server-metadata) +to offer clients a way to deep-link to the account management capabilities of +the homeserver to allow the user to complete the account management operations +in a browser. + +##### Account management URL discovery + +The [OAuth 2.0 authorization server metadata](#server-metadata-discovery) is +extended to include the following **optional** fields. + +{{% definition path="schemas/oauth2-account-management-server-metadata" %}} + +##### Account management URL parameters + +The account management URL MAY accept the following minimum query parameters. + +{{% definition path="schemas/oauth2-account-management-url" %}} + +##### Account management URL actions + +Account management actions are unique to the application. They SHOULD follow the +[Common Namespaced Identifier Grammar](/appendices/#common-namespaced-identifier-grammar) +where feasible. The Matrix-specific actions are: + +| Action | Description | +|----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------| +| `org.matrix.profile` | The user wishes to view/edit their profile (name, avatar, contact details). | +| `org.matrix.devices_list` | The user wishes to view a list of their devices. | +| `org.matrix.device_view` | The user wishes to view the details of a specific device. A `device_id` SHOULD be provided. | +| `org.matrix.device_delete` | The user wishes to delete/log out a specific device. A `device_id` SHOULD be provided. | +| `org.matrix.account_deactivate` | The user wishes to deactivate their account. | +| `org.matrix.cross_signing_reset` | The user wishes to reset their cross-signing identity. Servers SHOULD use this action in the URL of the [`m.oauth`](#oauth-authentication) UIA type. | + ### Account moderation #### Account locking @@ -2505,6 +2619,40 @@ An example of the capability API's response for this capability is: } ``` +### `m.forget_forced_upon_leave` capability + +{{% added-in v="1.18" %}} + +This capability has a single flag, `enabled`, which indicates whether or +not the server automatically forgets rooms which the user has left. + +When `enabled` is `true` and the user leaves a room, the server will automatically +forget the room — just as if the user had called [`/forget`](#post_matrixclientv3roomsroomidforget) +themselves. This behavior applies irrespective of whether the user has left the +room on their own (through [`/leave`](#post_matrixclientv3roomsroomidleave)) or +has been kicked or banned from the room by another user. + +When `enabled` is `false`, the server does not automatically forget rooms +upon leave. In this case, clients MAY distinguish the actions of leaving +and forgetting a room in their UI. Similarly, clients MAY retrieve and +visualize left but unforgotten rooms using a [filter](#filtering) with +`include_leave = true`. + +When the capability or the `enabled` property are not present, clients SHOULD +assume that the server does not automatically forget rooms. + +An example of the capability API's response for this capability is: + +```json +{ + "capabilities": { + "m.forget_forced_upon_leave": { + "enabled": true + } + } +} +``` + ### `m.room_versions` capability This capability describes the default and available room versions a @@ -3201,6 +3349,14 @@ the topic to be removed from the room. #### Client behaviour +{{% changed-in v="1.18" %}} + +If the server advertises support for a spec version that supports it, clients +MAY use the [`PUT /rooms/{roomId}/send/{eventType}/{txnId}`](#put_matrixclientv3roomsroomidsendeventtypetxnid) +endpoint to send `m.room.redaction` events in all room versions. + +They can also use the following endpoint. + {{% http-api spec="client-server" api="redaction" %}} ### Forming relationships between events @@ -3898,6 +4054,7 @@ that profile. | [Guest Access](#guest-access) | Optional | Optional | Optional | Optional | Optional | | [Moderation Policy Lists](#moderation-policy-lists) | Optional | Optional | Optional | Optional | Optional | | [OpenID](#openid) | Optional | Optional | Optional | Optional | Optional | +| [Recently used emoji](#recently-used-emoji) | Optional | Optional | Optional | Optional | Optional | | [Reference Relations](#reference-relations) | Optional | Optional | Optional | Optional | Optional | | [Reporting Content](#reporting-content) | Optional | Optional | Optional | Optional | Optional | | [Rich replies](#rich-replies) | Optional | Optional | Optional | Optional | Optional | @@ -3914,6 +4071,7 @@ that profile. | [Sticker Messages](#sticker-messages) | Optional | Optional | Optional | Optional | Optional | | [Third-party Networks](#third-party-networks) | Optional | Optional | Optional | Optional | Optional | | [Threading](#threading) | Optional | Optional | Optional | Optional | Optional | +| [Invite permission](#invite-permission) | Optional | Optional | Optional | Optional | Optional | *Please see each module for more details on what clients need to implement.* @@ -3987,6 +4145,7 @@ systems. {{% cs-module name="SSO client login/authentication" filename="sso_login" %}} {{% cs-module name="Direct Messaging" filename="dm" %}} {{% cs-module name="Ignoring Users" filename="ignore_users" %}} +{{% cs-module name="Invite permission" filename="invite_permission" %}} {{% cs-module name="Sticker Messages" filename="stickers" %}} {{% cs-module name="Reporting Content" filename="report_content" %}} {{% cs-module name="Third-party Networks" filename="third_party_networks" %}} @@ -3999,5 +4158,6 @@ systems. {{% cs-module name="Spaces" filename="spaces" %}} {{% cs-module name="Event replacements" filename="event_replacements" %}} {{% cs-module name="Event annotations and reactions" filename="event_annotations" %}} +{{% cs-module name="Recently used emoji" filename="recent_emoji" %}} {{% cs-module name="Threading" filename="threading" %}} {{% cs-module name="Reference relations" filename="reference_relations" %}} diff --git a/content/client-server-api/modules/content_repo.md b/content/client-server-api/modules/content_repo.md index 39fe33ec..ad65ea42 100644 --- a/content/client-server-api/modules/content_repo.md +++ b/content/client-server-api/modules/content_repo.md @@ -87,7 +87,7 @@ Matrix 1.12 is expected to be released in the July-September 2024 calendar quart The homeserver SHOULD be able to supply thumbnails for uploaded images and videos. The exact file types which can be thumbnailed are not currently specified - see [Issue -\#1938](https://github.com/matrix-org/matrix-doc/issues/1938) for more +\#1938](https://github.com/matrix-org/matrix-spec/issues/453) for more information. The thumbnail methods are "crop" and "scale". "scale" tries to return an diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index 97786f59..25617978 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -921,7 +921,7 @@ collaborate to create a common set of translations for all languages. {{% boxes/note %}} Known translations for the emoji are available from - + and can be translated online: {{% /boxes/note %}} diff --git a/content/client-server-api/modules/instant_messaging.md b/content/client-server-api/modules/instant_messaging.md index d5c0cb6a..a64baa25 100644 --- a/content/client-server-api/modules/instant_messaging.md +++ b/content/client-server-api/modules/instant_messaging.md @@ -84,6 +84,10 @@ Additionally, web clients should ensure that *all* `a` tags get a `rel="noopener"` to prevent the target page from referencing the client's tab/window. +{{% added-in v="1.18" %}} Clients that support rendering numbered lists via the +`ol` tag MUST also support the `start` attribute in order to prevent loss of +meaning of a message due to the numbering of list items. + Tags must not be nested more than 100 levels deep. Clients should only support the subset of tags they can render, falling back to other representations of the tags where possible. For example, a client may @@ -119,7 +123,7 @@ Clients SHOULD verify the structure of incoming events to ensure that the expected keys exist and that they are of the right type. Clients can discard malformed events or display a placeholder message to the user. Redacted `m.room.message` events MUST be removed from the client. This -can either be replaced with placeholder text (e.g. "\[REDACTED\]") or +can either be replaced with placeholder text (e.g. "[REDACTED]") or the redacted message can be removed entirely from the messages view. Events which have attachments (e.g. `m.image`, `m.file`) SHOULD be diff --git a/content/client-server-api/modules/invite_permission.md b/content/client-server-api/modules/invite_permission.md new file mode 100644 index 00000000..5e5b2ac3 --- /dev/null +++ b/content/client-server-api/modules/invite_permission.md @@ -0,0 +1,51 @@ + +### Invite permission + +{{% added-in v="1.18" %}} + +Users may want to control who is allowed to invite them to new rooms. This module defines how +clients and servers can implement invite permission. + +#### Account data + +{{% event event="m.invite_permission_config" %}} + +#### Client behaviour + +To reject invites from all users automatically, clients MAY add an [`m.invite_permission_config`](#minvite_permission_config) +event in the user's [account data](#client-config) with the `default_action` property set to +`block`. To stop rejecting all invites, the same event without the `default_action` property MUST be +added to the account data. + +When the `default_action` field is unset, other parts of the specification might still have effects +on invites seen by clients, like [ignoring users](#ignoring-users). + +Attempting to send an invite to a user that blocks invites will result in an error response with the +`M_INVITE_BLOCKED` error code. + +#### Server behaviour + +When invites to a given user are blocked, the user's homeserver MUST respond to the following +endpoints with an HTTP 403 status code, with the Matrix error code `M_INVITE_BLOCKED`, if the user +is invited: + +* [`PUT /_matrix/federation/v1/invite/{roomId}/{eventId}`](/server-server-api/#put_matrixfederationv1inviteroomideventid) +* [`PUT /_matrix/federation/v2/invite/{roomId}/{eventId}`](/server-server-api/#put_matrixfederationv2inviteroomideventid) +* [`POST /_matrix/client/v3/rooms/{roomId}/invite`](#post_matrixclientv3roomsroomidinvite) +* [`POST /_matrix/client/v3/createRoom`](#post_matrixclientv3createroom), due to a user in the + `invite` list. It is possible for one of the invited users to be rejected whilst the room creation + as a whole succeeds. +* [`PUT /_matrix/client/v3/rooms/{roomId}/state/m.room.member/{stateKey}`](#put_matrixclientv3roomsroomidstateeventtypestatekey), + when the `membership` is set to `invite`. + +In addition, invite events for this user already in the database, or received over federation, MUST +NOT be served over client synchronisation endpoints such as [`GET /sync`](#get_matrixclientv3sync). + +Servers MAY return any suppressed invite events over `GET /sync` if invite blocking is later +disabled. + +Other endpoints, such as [`GET /rooms/{roomId}/state`](#get_matrixclientv3roomsroomidstate), are not +affected by invite blocking: invite events are returned as normal. + +The Application Services API is also unaffected by invite blocking: invite events are sent over +[`PUT /_matrix/app/v1/transactions/{txnId}`](/application-service-api/#put_matrixappv1transactionstxnid). diff --git a/content/client-server-api/modules/recent_emoji.md b/content/client-server-api/modules/recent_emoji.md new file mode 100644 index 00000000..77c0c12b --- /dev/null +++ b/content/client-server-api/modules/recent_emoji.md @@ -0,0 +1,40 @@ +### Recently used emoji + +{{% added-in v="1.18" %}} + +This module enables clients to track a user's cumulated emoji usage across different +devices. The data is stored in the [`m.recent_emoji`](#mrecent_emoji) +global [account data](#client-config) and can, among other things, be used to +generate recommendations in emoji pickers. + +#### Events + +{{% event event="m.recent_emoji" %}} + +#### Client behaviour + +What exactly constitutes trackable emoji usage is left as an implementation detail +for clients. It is RECOMMENDED to include sending emoji in both messages and +annotations. + +When an emoji is used, the sending client moves (or adds) it to the beginning of +the `recent_emoji` array and increments (or initializes) its counter. This keeps +the array ordered by last usage time which facilitates evaluating the data. How +exactly the client evaluates and uses the collected data is deliberately left +unspecified. + +To prevent excessive growth of the event as new emoji are being used, clients +SHOULD limit the length of the `recent_emoji` array by dropping elements from +its end. A RECOMMENDED maximum length is 100 emoji. + +To enable future extension, clients MUST tolerate and preserve array elements +within `recent_emoji` regardless of whether they understand or support the +contained `emoji` value. This means ignoring entries with unrecognised values +of `emoji` when deciding what to display to the user while retaining them when +modifying the array (unless the modification is for truncation). + +To prevent undefined behavior, clients SHOULD remove array elements that +don't conform to the event schema such as elements with negative counters. + + + diff --git a/content/proposals.md b/content/proposals.md index 8abf79d1..3b9a707f 100644 --- a/content/proposals.md +++ b/content/proposals.md @@ -408,41 +408,9 @@ development or testing data. that a particular MSC works) do not have to follow this process. 1. Have an idea for a feature. -1. Implement the feature using unstable endpoints, vendor prefixes, and - unstable feature flags as appropriate. - - When using unstable endpoints, they MUST include a vendor - prefix. For example: - `/_matrix/client/unstable/com.example/login`. Vendor prefixes - throughout Matrix always use the Java package naming convention. - The MSC for the feature should identify which preferred vendor - prefix is to be used by early adopters. - - Note that unstable namespaces do not automatically inherit - endpoints from stable namespaces: for example, the fact that - `/_matrix/client/r0/sync` exists does not imply that - `/_matrix/client/unstable/com.example/sync` exists. - - If the client needs to be sure the server supports the feature, - an unstable feature flag that MUST be vendor prefixed is to be - used. This kind of flag shows up in the `unstable_features` - section of `/versions` as, for example, `com.example.new_login`. - The MSC for the feature should identify which preferred feature - flag is to be used by early adopters. - - When using this approach correctly, the implementation can - ship/release the feature at any time, so long as the - implementation is able to accept the technical debt that results - from needing to provide adequate backwards and forwards - compatibility. The implementation MUST support the flag (and - server-side implementation) disappearing and be generally safe - for users. Note that implementations early in the MSC review - process may also be required to provide backwards compatibility - with earlier editions of the proposal. - - If the implementation cannot support the technical debt (or if - it's impossible to provide forwards/backwards compatibility - - e.g. a user authentication change which can't be safely rolled - back), the implementation should not attempt to implement the - feature and should instead wait for a spec release. - - If at any point after early release, the idea changes in a - backwards-incompatible way, the feature flag should also change - so that implementations can adapt as needed. +1. Implement the feature using [unstable endpoints, vendor prefixes, and + unstable feature flags](#unstable-endpoints-features-and-vendor-prefixes) + as appropriate. 1. In parallel, or ahead of implementation, open an MSC and solicit review per above. 1. Before FCP can be called, the Spec Core Team will require evidence @@ -452,10 +420,7 @@ that a particular MSC works) do not have to follow this process. forwards/backwards compatibility concerns mentioned here. 1. The FCP process is completed, and assuming nothing is flagged the MSC lands. -1. Implementations can now switch to using stable prefixes - (for example, for an endpoint, moving from - `/unstable/org.matrix.mscxxxx/frobnicate` - to `/v1/frobnicate`), assuming that the change +1. Implementations can now switch to using stable prefixes, assuming that the change is backwards compatible with older implementations. In the rare occasion where backwards compatibility is not possible without a new spec release, implementations should continue to use unstable prefixes. @@ -471,13 +436,6 @@ that a particular MSC works) do not have to follow this process. started supporting the new spec release, some noise should be raised in the general direction of the implementation. -{{% boxes/note %}} -MSCs MUST still describe what the stable endpoints/feature looks like -with a note towards the bottom for what the unstable feature -flag/prefixes are. For example, an MSC would propose `/_matrix/client/r0/new/endpoint`, not `/_matrix/client/unstable/ -com.example/new/endpoint`. -{{% /boxes/note %}} - In summary: - Implementations MUST NOT use stable endpoints before the MSC has @@ -489,14 +447,90 @@ In summary: - Implementations SHOULD be wary of the technical debt they are incurring by moving faster than the spec. - The vendor prefix is chosen by the developer of the feature, using - the Java package naming convention. The foundation's preferred - vendor prefix is `org.matrix`. + the Java package naming convention. - The vendor prefixes, unstable feature flags, and unstable endpoints should be included in the MSC, though the MSC MUST be written in a way that proposes new stable endpoints. Typically this is solved by a small table at the bottom mapping the various values from stable to unstable. +#### Unstable endpoints, features and vendor prefixes + +Unstable endpoints MUST use `/unstable` as the endpoint version and a +vendor prefix in Java package naming format. For example: +`/_matrix/client/unstable/com.example.mscxxxx/login`. + +{{% boxes/note %}} +Proposal authors operating with a Matrix.org Foundation mandate SHOULD use +a vendor prefix within the `org.matrix` namespace. This namespace is otherwise +restricted. Authors who don't own a domain MAY use the `io.github` namespace +instead. +{{% /boxes/note %}} + +Note that unstable namespaces do not automatically inherit endpoints from +stable namespaces: for example, the fact that `/_matrix/client/v3/sync` +exists does not imply that `/_matrix/client/unstable/com.example.mscxxxx/sync` +exists. + +Vendor prefixes MUST also be used for: + +- New parameters on existing endpoints. For example: + `/_matrix/client/v3/publicRooms?com.example.mscxxxx.ordered_by=member_count`. +- New properties in existing JSON objects. For example: + + ```json + { + "avatar_url": "mxc://matrix.org/SDGdghriugerRg", + "displayname": "Alice Margatroid", + "com.example.mscxxxx.phone": [{ + "type": "landline", + "number": "+1-206-555-7000" + }], + ... + } + ``` + +- New values for existing parameters or properties. For example: + + ```json + { + "errcode": "COM.EXAMPLE.MSCXXXX.M_INVALID_EMAIL", + "error": "The email address you provided is invalid." + } + ``` + +If the client needs to be sure the server supports the feature, an +unstable feature flag that MUST also be vendor prefixed is to be used. +This flag shows up in the `unstable_features` section of +[`/_matrix/client/versions`](/client-server-api/#get_matrixclientversions) +as, for example, `com.example.mscxxxx.new_login`. + +{{% boxes/note %}} +MSCs MUST still describe what the stable endpoints/feature looks like +with a note towards the bottom for what the unstable feature +flag/prefixes are. For example, an MSC would propose `/_matrix/client/v1/new/endpoint`, +not `/_matrix/client/unstable/com.example.mscxxxx/new/endpoint`. +{{% /boxes/note %}} + +When using this approach correctly, the implementation can release +the feature at any time, so long as the implementation is able to +accept the technical debt that results from needing to provide +adequate backwards and forwards compatibility. The implementation +MUST support the flag (and server-side implementation) disappearing +and be generally safe for users. Note that implementations early in +the MSC review process may also be required to provide backwards +compatibility with earlier editions of the proposal. + +If the implementation cannot support the technical debt (or if it's +impossible to provide forwards/backwards compatibility - e.g. a user +authentication change which can't be safely rolled back), the +implementation should not attempt to implement the feature and should +instead wait for a spec release. + +If at any point after early release, the idea changes in a +backwards-incompatible way, the feature flag should also change so +that implementations can adapt as needed. + ### Placeholder MSCs Some proposals may contain security-sensitive or private context which can't be diff --git a/content/rooms/_index.md b/content/rooms/_index.md index 3e7aec72..bbf5a08d 100644 --- a/content/rooms/_index.md +++ b/content/rooms/_index.md @@ -56,19 +56,6 @@ Clients should not ask room administrators to upgrade their rooms if the room is running a stable version. Servers SHOULD use **room version 12** as the default room version when creating new rooms. -{{% boxes/note %}} - -{{% added-in v="1.16" %}} - -Room version 12 is introduced and made default in this specification release. -Servers are encouraged to continue using room version 11 as the default room -version for the early days and weeks following this specification release, -and then gradually switch the default over when they deem appropriate. - - - -{{% /boxes/note %}} - The available room versions are: - [Version 1](/rooms/v1) - **Stable**. The initial room version. diff --git a/data/api/client-server/account_deactivation.yaml b/data/api/client-server/account_deactivation.yaml index 467af659..2275fdff 100644 --- a/data/api/client-server/account_deactivation.yaml +++ b/data/api/client-server/account_deactivation.yaml @@ -35,6 +35,14 @@ paths: Unlike other endpoints, this endpoint does not take an `id_access_token` parameter because the homeserver is expected to sign the request to the identity server instead. + + {{% boxes/warning %}} + {{% added-in v="1.18" %}} [OAuth 2.0 aware clients](/client-server-api/#oauth-20-aware-clients) + MUST NOT use this endpoint when the server supports the [OAuth 2.0 API](/client-server-api/#oauth-20-api). + Instead they MUST refer the user to the [account management URL](/client-server-api/#oauth-20-account-management), + if available, and MAY use the `action=org.matrix.account_deactivate` + parameter. + {{% /boxes/warning %}} security: - {} - accessTokenQuery: [] diff --git a/data/api/client-server/capabilities.yaml b/data/api/client-server/capabilities.yaml index 2e8c8849..f73e8b46 100644 --- a/data/api/client-server/capabilities.yaml +++ b/data/api/client-server/capabilities.yaml @@ -50,6 +50,12 @@ paths: m.change_password: $ref: '#/components/schemas/booleanCapability' description: Capability to indicate if the user can change their password. + m.forget_forced_upon_leave: + x-addedInMatrixVersion: "1.18" + $ref: '#/components/schemas/booleanCapability' + description: |- + Capability to indicate if the server automatically forgets rooms once the user + leaves. m.room_versions: type: object description: The room versions the server supports. diff --git a/data/api/client-server/create_room.yaml b/data/api/client-server/create_room.yaml index 2f9d3449..2abe963f 100644 --- a/data/api/client-server/create_room.yaml +++ b/data/api/client-server/create_room.yaml @@ -250,7 +250,6 @@ paths: } "400": description: |- - The request is invalid. A meaningful `errcode` and description error text will be returned. Example reasons for rejection include: @@ -274,6 +273,17 @@ paths: application/json: schema: $ref: definitions/errors/error.yaml + "403": + description: |- + Creating the room is not allowed. + + {{% added-in v="1.18"%}} The `M_INVITE_BLOCKED` error code is used to + indicate that one of the homeservers of the invited users rejected + the invite due to [invite blocking](/client-server-api/#invite-permission). + content: + application/json: + schema: + $ref: definitions/errors/error.yaml tags: - Room creation servers: diff --git a/data/api/client-server/definitions/recent_emoji.yaml b/data/api/client-server/definitions/recent_emoji.yaml new file mode 100644 index 00000000..c2deab94 --- /dev/null +++ b/data/api/client-server/definitions/recent_emoji.yaml @@ -0,0 +1,29 @@ +# Copyright 2026 The Matrix.org Foundation C.I.C. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +title: Recent Emoji +type: object +properties: + emoji: + type: string + description: The Unicode emoji as string. + example: 🚀 + total: + type: number + description: |- + The number of times the emoji has been used. + MUST be non-negative and smaller than 2^53. +required: + - emoji + - total diff --git a/data/api/client-server/definitions/request_token_response.yaml b/data/api/client-server/definitions/request_token_response.yaml index 0f8c8cab..693cffce 100644 --- a/data/api/client-server/definitions/request_token_response.yaml +++ b/data/api/client-server/definitions/request_token_response.yaml @@ -24,16 +24,23 @@ properties: submit_url: type: string format: uri + x-changedInMatrixVersion: + "1.18": |- + The URL has the same request and response parameters and error codes as + the Identity Service API's endpoint. description: |- An optional field containing a URL where the client must submit the - validation token to, with identical parameters to the Identity Service - API's `POST /validate/email/submitToken` endpoint (without the requirement - for an access token). The homeserver must send this token to the user (if - applicable), who should then be prompted to provide it to the client. + validation token, with identical request and response parameters and error + codes to the Identity Service API's + [`POST /validate/email/submitToken`](/identity-service-api/#post_matrixidentityv2validateemailsubmittoken) + and [`POST /validate/msisdn/submitToken`](/identity-service-api/#post_matrixidentityv2validatemsisdnsubmittoken) + endpoints (without the requirement for an access token). The homeserver + must send this token to the user (if applicable), who should then be + prompted to provide it to the client. If this field is not present, the client can assume that verification will happen without the client's involvement provided the homeserver - advertises this specification version in the `/versions` response - (ie: r0.5.0). + advertises a sufficiently recent version in the [`GET /versions`](/client-server-api/#get_matrixclientversions) + response (ie: r0.5.0). example: "https://example.org/path/to/submitToken" required: ['sid'] diff --git a/data/api/client-server/definitions/sso_login_flow.yaml b/data/api/client-server/definitions/sso_login_flow.yaml index 0996511e..18c32054 100644 --- a/data/api/client-server/definitions/sso_login_flow.yaml +++ b/data/api/client-server/definitions/sso_login_flow.yaml @@ -86,5 +86,13 @@ properties: brand usage as intended by the server. example: "github" required: ['id', 'name'] + oauth_aware_preferred: + type: boolean + x-addedInMatrixVersion: "1.18" + description: | + Whether the `m.login.sso` flow is preferred over other flows. If this is `true`, + [OAuth 2.0 aware clients](/client-server-api/#oauth-20-aware-clients) MUST only + offer this flow to the user. + example: true required: ['type'] diff --git a/data/api/client-server/device_management.yaml b/data/api/client-server/device_management.yaml index 94dde899..e5ae56ce 100644 --- a/data/api/client-server/device_management.yaml +++ b/data/api/client-server/device_management.yaml @@ -170,6 +170,13 @@ paths: When this endpoint requires User-Interactive Authentication, it cannot be used when the access token was obtained via the [OAuth 2.0 API](/client-server-api/#oauth-20-api). {{% /boxes/warning %}} + + {{% boxes/warning %}} + {{% added-in v="1.18" %}} [OAuth 2.0 aware clients](/client-server-api/#oauth-20-aware-clients) + MUST NOT use this endpoint when the server supports the [OAuth 2.0 API](/client-server-api/#oauth-20-api). + Instead they MUST refer the user to the [account management URL](/client-server-api/#oauth-20-account-management), + if available, with the `action=org.matrix.device_delete` and `device_id={deviceId}` parameters. + {{% /boxes/warning %}} operationId: deleteDevice security: - accessTokenQuery: [] @@ -232,6 +239,13 @@ paths: When this endpoint requires User-Interactive Authentication, it cannot be used when the access token was obtained via the [OAuth 2.0 API](/client-server-api/#oauth-20-api). {{% /boxes/warning %}} + + {{% boxes/warning %}} + {{% added-in v="1.18" %}} [OAuth 2.0 aware clients](/client-server-api/#oauth-20-aware-clients) + MUST NOT use this endpoint when the server supports the [OAuth 2.0 API](/client-server-api/#oauth-20-api). + Instead they MUST refer the user to the [account management URL](/client-server-api/#oauth-20-account-management), + if available. + {{% /boxes/warning %}} operationId: deleteDevices security: - accessTokenQuery: [] diff --git a/data/api/client-server/inviting.yaml b/data/api/client-server/inviting.yaml index 6aa9e08a..89e3e08e 100644 --- a/data/api/client-server/inviting.yaml +++ b/data/api/client-server/inviting.yaml @@ -83,7 +83,7 @@ paths: value: {} "400": description: |- - + The request is invalid. A meaningful `errcode` and description error text will be returned. Example reasons for rejection include: @@ -99,12 +99,18 @@ paths: $ref: definitions/errors/error.yaml "403": description: |- - You do not have permission to invite the user to the room. A meaningful `errcode` and description error text will be returned. Example reasons for rejections are: + You do not have permission to invite the user to the room. A + meaningful `errcode` and description error text will be returned. + Example reasons for rejections are: - The invitee has been banned from the room. - The invitee is already a member of the room. - The inviter is not currently in the room. - The inviter's power level is insufficient to invite users to the room. + + {{% added-in v="1.18"%}} The `M_INVITE_BLOCKED` error code is used to + indicate that the homeserver rejected the invite due to + [invite blocking](/client-server-api/#invite-permission). content: application/json: schema: diff --git a/data/api/client-server/leaving.yaml b/data/api/client-server/leaving.yaml index 6bdadb08..edb8ffd3 100644 --- a/data/api/client-server/leaving.yaml +++ b/data/api/client-server/leaving.yaml @@ -19,6 +19,10 @@ paths: "/rooms/{roomId}/leave": post: summary: Stop the requesting user participating in a particular room. + x-changedInMatrixVersion: + "1.18": |- + Servers may additionally forget the room provided that they make this behavior + transparent. description: |- This API stops a user participating in a particular room. @@ -29,8 +33,15 @@ paths: If the user was invited to the room, but had not joined, this call serves to reject the invite. - The user will still be allowed to retrieve history from the room which - they were previously allowed to see. + Servers MAY additionally forget the room when this endpoint is called – + just as if the user had also invoked [`/forget`](/client-server-api/#post_matrixclientv3roomsroomidforget). + Servers that do this, MUST inform clients about this behavior using the + [`m.forget_forced_upon_leave`](/client-server-api/#mforget_forced_upon_leave-capability) + capability. + + If the server doesn't automatically forget the room, the user will still be + allowed to retrieve history from the room which they were previously allowed + to see. operationId: leaveRoom security: - accessTokenQuery: [] diff --git a/data/api/client-server/oauth_server_metadata.yaml b/data/api/client-server/oauth_server_metadata.yaml index 4cdb3aa6..719a1e16 100644 --- a/data/api/client-server/oauth_server_metadata.yaml +++ b/data/api/client-server/oauth_server_metadata.yaml @@ -139,6 +139,32 @@ paths: items: type: string description: A prompt value that the server supports. + account_management_uri: + x-addedInMatrixVersion: "1.18" + type: string + format: uri + description: |- + The URL where the user is able to access the account management capabilities + of the homeserver. + + This is an extension [defined in this specification](/client-server-api/#oauth-20-account-management). + account_management_actions_supported: + x-addedInMatrixVersion: "1.18" + type: array + description: |- + List of actions that the account management URL supports. + + This is an extension [defined in this specification](/client-server-api/#oauth-20-account-management). + items: + type: string + enum: + - "org.matrix.profile" + - "org.matrix.devices_list" + - "org.matrix.device_view" + - "org.matrix.device_delete" + - "org.matrix.account_deactivate" + - "org.matrix.cross_signing_reset" + description: An action that the account management URL supports. required: - issuer - authorization_endpoint @@ -159,6 +185,15 @@ paths: "grant_types_supported": ["authorization_code", "refresh_token"], "response_modes_supported": ["query", "fragment"], "code_challenge_methods_supported": ["S256"], + "account_management_uri": "https://account.example.com/manage", + "account_management_actions_supported": [ + "org.matrix.profile", + "org.matrix.devices_list", + "org.matrix.device_view", + "org.matrix.device_delete", + "org.matrix.account_deactivate", + "org.matrix.cross_signing_reset", + ], } tags: - Session management diff --git a/data/api/client-server/registration.yaml b/data/api/client-server/registration.yaml index 7a923f9e..acb0b135 100644 --- a/data/api/client-server/registration.yaml +++ b/data/api/client-server/registration.yaml @@ -72,6 +72,15 @@ paths: `inhibit_login` parameter is not set to `true`, the server MUST return a 400 HTTP status code with an `M_APPSERVICE_LOGIN_UNSUPPORTED` error code. {{% /boxes/note %}} + + {{% boxes/warning %}} + {{% added-in v="1.18" %}} [OAuth 2.0 aware clients](/client-server-api/#oauth-20-aware-clients) + MUST NOT use this endpoint when the server offers the [`m.login.sso` + authentication flow](/client-server-api/#client-login-via-sso) with + `oauth_aware_preferred` set to `true`. Instead they MUST use the + [`/login/sso/redirect`](/client-server-api/#get_matrixclientv3loginssoredirect) + endpoint, adding the `action=register` parameter. + {{% /boxes/warning %}} operationId: register parameters: - in: query diff --git a/data/api/client-server/room_send.yaml b/data/api/client-server/room_send.yaml index 25d8a75b..5c3d0019 100644 --- a/data/api/client-server/room_send.yaml +++ b/data/api/client-server/room_send.yaml @@ -20,6 +20,10 @@ paths: "/rooms/{roomId}/send/{eventType}/{txnId}": put: summary: Send a message event to the given room. + x-changedInMatrixVersion: + "1.18": |- + Homeservers must support sending `m.room.redaction` events with this endpoint + for all room versions. description: |- This endpoint is used to send a message event to a room. Message events allow access to historical events and pagination, making them suited @@ -28,6 +32,11 @@ paths: The body of the request should be the content object of the event; the fields in this object will vary depending on the type of event. See [Room Events](/client-server-api/#room-events) for the m. event specification. + + Homeservers MUST allow clients to send `m.room.redaction` events with this + endpoint for all room versions. In rooms with a version older than 11 they + MUST move the `redacts` property inside the `content` to the top level of + the event. operationId: sendMessage security: - accessTokenQuery: [] diff --git a/data/api/client-server/room_state.yaml b/data/api/client-server/room_state.yaml index 7096f511..015f8f9d 100644 --- a/data/api/client-server/room_state.yaml +++ b/data/api/client-server/room_state.yaml @@ -116,7 +116,13 @@ paths: "error": "The alias '#hello:example.org' does not point to this room." } "403": - description: The sender doesn't have permission to send the event into the room. + description: |- + The sender doesn't have permission to send the event into the room. + + {{% added-in v="1.18"%}} If the `eventType` is `m.room.member` and + the `membership` is `invite`, the `M_INVITE_BLOCKED` error code is + used to indicate that the homeserver rejected the invite due to + [invite blocking](/client-server-api/#invite-permission). content: application/json: schema: diff --git a/data/api/client-server/rooms.yaml b/data/api/client-server/rooms.yaml index a5c9977e..3716b6a4 100644 --- a/data/api/client-server/rooms.yaml +++ b/data/api/client-server/rooms.yaml @@ -223,7 +223,7 @@ paths: type: string # XXX: As mentioned in MSC1227, replacing `[not_]membership` with a JSON # filter might be a better alternative. - # See https://github.com/matrix-org/matrix-doc/issues/1337 + # See https://github.com/matrix-org/matrix-doc/issues/1227 - in: query name: membership description: |- diff --git a/data/api/client-server/sso_login_redirect.yaml b/data/api/client-server/sso_login_redirect.yaml index 9f9d758b..2276eb70 100644 --- a/data/api/client-server/sso_login_redirect.yaml +++ b/data/api/client-server/sso_login_redirect.yaml @@ -37,6 +37,22 @@ paths: required: true schema: type: string + - in: query + name: action + x-addedInMatrixVersion: "1.18" + description: |- + The action that the user wishes to take at the SSO redirect. + + The following values are supported: + * `login`: the SSO redirect is for the purposes of signing an + existing user in. + * `register`: the SSO redirect is for the purpose of registering a + new user account. + schema: + type: string + enum: + - login + - register responses: "302": description: A redirect to the SSO interface. @@ -75,6 +91,22 @@ paths: required: true schema: type: string + - in: query + name: action + x-addedInMatrixVersion: "1.18" + description: |- + The action that the user wishes to take at the SSO redirect. + + The following values are supported: + * `login`: the SSO redirect is for the purposes of signing an + existing user in. + * `register`: the SSO redirect is for the purpose of registering a + new user account. + schema: + type: string + enum: + - login + - register responses: "302": description: A redirect to the SSO interface. diff --git a/data/api/client-server/third_party_lookup.yaml b/data/api/client-server/third_party_lookup.yaml index 152f277d..32adb094 100644 --- a/data/api/client-server/third_party_lookup.yaml +++ b/data/api/client-server/third_party_lookup.yaml @@ -78,7 +78,7 @@ paths: }, "room": { "regexp": "[^\\s]+\\/[^\\s]+", - "placeholder": "matrix-org/matrix-doc" + "placeholder": "matrix-org/matrix-spec" } }, "instances": [ diff --git a/data/api/client-server/third_party_membership.yaml b/data/api/client-server/third_party_membership.yaml index 67caa387..87b47e1d 100644 --- a/data/api/client-server/third_party_membership.yaml +++ b/data/api/client-server/third_party_membership.yaml @@ -97,6 +97,10 @@ paths: - The invitee is already a member of the room. - The inviter is not currently in the room. - The inviter's power level is insufficient to invite users to the room. + + {{% added-in v="1.18"%}} The `M_INVITE_BLOCKED` error code is used to + indicate that the homeserver rejected the invite due to + [invite blocking](/client-server-api/#invite-permission). content: application/json: schema: diff --git a/data/api/identity/v2_email_associations.yaml b/data/api/identity/v2_email_associations.yaml index 81f4486c..da6c9c1b 100644 --- a/data/api/identity/v2_email_associations.yaml +++ b/data/api/identity/v2_email_associations.yaml @@ -153,6 +153,24 @@ paths: value: { "success": true } + "400": + description: | + An error occurred. Some possible errors are: + + - {{% added-in v="1.18" %}} `M_TOKEN_INCORRECT`: The token that the user entered to validate the session is + incorrect. + - {{% added-in v="1.18" %}} `M_INVALID_PARAM`: One of the supplied parameters is not valid. + - {{% added-in v="1.18" %}} `M_SESSION_EXPIRED`: The validation session in question has expired. + content: + application/json: + schema: + $ref: ../client-server/definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_TOKEN_INCORRECT", + "error": "The token is incorrect" + } "403": description: | The user must do something in order to use this endpoint. One example diff --git a/data/api/identity/v2_phone_associations.yaml b/data/api/identity/v2_phone_associations.yaml index b985a972..5ebf58bc 100644 --- a/data/api/identity/v2_phone_associations.yaml +++ b/data/api/identity/v2_phone_associations.yaml @@ -155,6 +155,24 @@ paths: value: { "success": true } + "400": + description: | + An error occurred. Some possible errors are: + + - {{% added-in v="1.18" %}} `M_TOKEN_INCORRECT`: The token that the user entered to validate the session is + incorrect. + - {{% added-in v="1.18" %}} `M_INVALID_PARAM`: One of the supplied parameters is not valid. + - {{% added-in v="1.18" %}} `M_SESSION_EXPIRED`: The validation session in question has expired. + content: + application/json: + schema: + $ref: ../client-server/definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_TOKEN_INCORRECT", + "error": "The token is incorrect" + } "403": description: | The user must do something in order to use this endpoint. One example diff --git a/data/api/server-server/definitions/event-schemas/m.signing_key_update.yaml b/data/api/server-server/definitions/event-schemas/m.signing_key_update.yaml index 0748bc35..2dc2bddb 100644 --- a/data/api/server-server/definitions/event-schemas/m.signing_key_update.yaml +++ b/data/api/server-server/definitions/event-schemas/m.signing_key_update.yaml @@ -25,7 +25,7 @@ allOf: edu_type: type: string enum: ['m.signing_key_update'] - description: The string `m.signing_update`. + description: The string `m.signing_key_update`. example: "m.signing_key_update" content: type: object diff --git a/data/api/server-server/invites-v1.yaml b/data/api/server-server/invites-v1.yaml index 5ec95d5e..b1d86208 100644 --- a/data/api/server-server/invites-v1.yaml +++ b/data/api/server-server/invites-v1.yaml @@ -179,11 +179,17 @@ paths: ] "403": description: |- - The invite is not allowed. This could be for a number of reasons, including: + The invite is not allowed. + + The `M_FORBIDDEN` error code is used to indicate one of the following: * The sender is not allowed to send invites to the target user/homeserver. * The homeserver does not permit anyone to invite its users. * The homeserver refuses to participate in the room. + + {{% added-in v="1.18"%}} The `M_INVITE_BLOCKED` error code is used to + indicate that the homeserver rejected the invite due to + [invite blocking](/client-server-api/#invite-permission). content: application/json: schema: diff --git a/data/api/server-server/invites-v2.yaml b/data/api/server-server/invites-v2.yaml index 72b69e10..b919b7a6 100644 --- a/data/api/server-server/invites-v2.yaml +++ b/data/api/server-server/invites-v2.yaml @@ -202,11 +202,17 @@ paths: } "403": description: |- - The invite is not allowed. This could be for a number of reasons, including: + The invite is not allowed. + + The `M_FORBIDDEN` error code is used to indicate one of the following: * The sender is not allowed to send invites to the target user/homeserver. * The homeserver does not permit anyone to invite its users. * The homeserver refuses to participate in the room. + + {{% added-in v="1.18"%}} The `M_INVITE_BLOCKED` error code is used to + indicate that the homeserver rejected the invite due to + [invite blocking](/client-server-api/#invite-permission). content: application/json: schema: diff --git a/data/api/server-server/keys_query.yaml b/data/api/server-server/keys_query.yaml index 791deb0a..02d31568 100644 --- a/data/api/server-server/keys_query.yaml +++ b/data/api/server-server/keys_query.yaml @@ -34,10 +34,10 @@ paths: - in: query name: minimum_valid_until_ts description: |- - A millisecond POSIX timestamp in milliseconds indicating when the returned - certificates will need to be valid until to be useful to the requesting server. + A millisecond POSIX timestamp. The returned keys SHOULD be valid + until at least this timestamp. - If not supplied, the current time as determined by the notary server is used. + If not supplied, the notary server MUST use the current time. required: false example: 1234567890 schema: @@ -98,12 +98,11 @@ paths: type: integer format: int64 description: |- - A millisecond POSIX timestamp in milliseconds indicating when - the returned certificates will need to be valid until to be - useful to the requesting server. + A millisecond POSIX timestamp. The returned keys + SHOULD be valid until at least this timestamp. - If not supplied, the current time as determined by the notary - server is used. + If not supplied, the notary server MUST use the + current time. example: 1234567890 required: - server_keys diff --git a/data/api/server-server/openid.yaml b/data/api/server-server/openid.yaml index ce7d8866..22b7f941 100644 --- a/data/api/server-server/openid.yaml +++ b/data/api/server-server/openid.yaml @@ -43,7 +43,12 @@ paths: properties: sub: type: string - description: The Matrix User ID who generated the token. + description: | + The Matrix User ID who generated the token. + + The caller MUST validate that the returned user ID is on the server they + called (i.e. if you make a request to example.com and it returns + `@alice:matrix.org`, the result is invalid). example: "@alice:example.com" required: - sub diff --git a/data/event-schemas/examples/m.invite_permission_config.yaml b/data/event-schemas/examples/m.invite_permission_config.yaml new file mode 100644 index 00000000..c7bb9ee7 --- /dev/null +++ b/data/event-schemas/examples/m.invite_permission_config.yaml @@ -0,0 +1,7 @@ +{ + "$ref": "core/event.json", + "type": "m.invite_permission_config", + "content": { + "default_action": "block" + } +} diff --git a/data/event-schemas/examples/m.recent_emoji.yaml b/data/event-schemas/examples/m.recent_emoji.yaml new file mode 100644 index 00000000..85b15cc6 --- /dev/null +++ b/data/event-schemas/examples/m.recent_emoji.yaml @@ -0,0 +1,16 @@ +{ + "$ref": "core/event.json", + "type": "m.recent_emoji", + "content": { + "recent_emoji": [{ + "emoji": "🤔", + "total": 19 + }, { + "emoji": "👍", + "total": 7 + }, { + "emoji": "😅", + "total": 84 + }] + } +} diff --git a/data/event-schemas/schema/m.invite_permission_config.yaml b/data/event-schemas/schema/m.invite_permission_config.yaml new file mode 100644 index 00000000..ae08cc82 --- /dev/null +++ b/data/event-schemas/schema/m.invite_permission_config.yaml @@ -0,0 +1,21 @@ +--- +$schema: https://json-schema.org/draft/2020-12/schema +allOf: + - $ref: core-event-schema/event.yaml + - title: Invite Permission + type: object + description: |- + The permission configuration for receiving invites for the current account. + properties: + content: + type: object + properties: + default_action: + type: string + description: |- + When set to `block`, the user does not wish to receive *any* room invites, and they + should be rejected automatically by the homeserver. + + A missing, invalid or unsupported value means that the user wants to receive invites + as normal. Other parts of the specification might still have effects on invites, like + [ignoring users](/client-server-api/#ignoring-users). diff --git a/data/event-schemas/schema/m.recent_emoji.yaml b/data/event-schemas/schema/m.recent_emoji.yaml new file mode 100644 index 00000000..8db49a48 --- /dev/null +++ b/data/event-schemas/schema/m.recent_emoji.yaml @@ -0,0 +1,29 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "Recent Emoji Event", + "description": "Lets clients maintain a list of recently used emoji.", + "allOf": [{ + "$ref": "core-event-schema/event.yaml" + }], + "properties": { + "type": { + "type": "string", + "enum": ["m.recent_emoji"] + }, + "content": { + "type": "object", + "properties": { + "recent_emoji": { + "description": "The list of recently used emoji. Elements in the list are ordered descendingly by last usage time.", + "type": "array", + "items": { + "$ref": "../../api/client-server/definitions/recent_emoji.yaml" + }, + } + }, + "required": ["recent_emoji"] + } + }, + "required": ["type", "content"] +} diff --git a/data/schemas/oauth2-account-management-server-metadata.yaml b/data/schemas/oauth2-account-management-server-metadata.yaml new file mode 100644 index 00000000..7bb43db4 --- /dev/null +++ b/data/schemas/oauth2-account-management-server-metadata.yaml @@ -0,0 +1,30 @@ +# Copyright 2026 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: OAuth 2.0 Server Metadata Account Management Extension +properties: + account_management_uri: + type: string + format: uri + description: |- + The URL where the user is able to access the account management capabilities of the + server. + account_management_actions_supported: + type: array + description: |- + List of [actions](/client-server-api/#account-management-url-actions) that the account + management URL supports. + items: + type: string + description: An action that the account management URL supports. diff --git a/data/schemas/oauth2-account-management-url.yaml b/data/schemas/oauth2-account-management-url.yaml new file mode 100644 index 00000000..d6220841 --- /dev/null +++ b/data/schemas/oauth2-account-management-url.yaml @@ -0,0 +1,29 @@ +# Copyright 2026 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: OAuth 2.0 Account Management URL Query Parameters +properties: + action: + type: string + description: |- + The action that the user wishes to take. Must match one of the actions advertised by the + server in [`account_management_actions_supported`](/client-server-api/#account-management-url-discovery). + device_id: + type: string + description: |- + For Matrix-specific actions, the user's device ID. Actions which don't support the device ID + will ignore it. + + If the `org.matrix.device_view` or `org.matrix.device_delete` actions are advertised as + supported by the server then the server SHOULD support the `device_id` parameter. diff --git a/go.mod b/go.mod index 60143ea9..6b13c46b 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,4 @@ module github.com/matrix-org/matrix-spec go 1.12 -require github.com/matrix-org/docsy v0.0.0-20250722140156-5df72519f5af // indirect +require github.com/matrix-org/docsy v0.0.0-20260106184755-71d103ebb20a // indirect diff --git a/go.sum b/go.sum index ea991476..3897374a 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,4 @@ github.com/FortAwesome/Font-Awesome v0.0.0-20241216213156-af620534bfc3/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo= -github.com/matrix-org/docsy v0.0.0-20250722140156-5df72519f5af h1:XghgUC0H5BoGrvtT9/oWBUi+5Zux875qRHhpAZ0RURI= -github.com/matrix-org/docsy v0.0.0-20250722140156-5df72519f5af/go.mod h1:4/t21g/nPraob/DVMm3jrk26k0CDL5I7Mxf+ar0IAgs= -github.com/twbs/bootstrap v5.3.6+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0= +github.com/matrix-org/docsy v0.0.0-20260106184755-71d103ebb20a h1:WB3unuZJy7ewAf33sxbtEwYnC+i+Jt1sJpAR3BtzvEo= +github.com/matrix-org/docsy v0.0.0-20260106184755-71d103ebb20a/go.mod h1:mdn1m5HJug6ZddQgrOyCrXNegbtdl5evHiqqbEQLzdI= +github.com/twbs/bootstrap v5.3.8+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0= diff --git a/layouts/_markup/render-passthrough.html b/layouts/_markup/render-passthrough.html index 425471a9..d5f85ded 100644 --- a/layouts/_markup/render-passthrough.html +++ b/layouts/_markup/render-passthrough.html @@ -5,15 +5,7 @@ We use it to send the delimited passthrough element through KaTeX to render maths in the Olm / Megolm spec. - See: https://gohugo.io/functions/transform/tomath/#step-2 + See: https://www.docsy.dev/docs/content/diagrams-and-formulae/#add-passthrough-render-hook */ -}} -{{- $opts := dict "output" "htmlAndMathml" "displayMode" (eq .Type "block") }} -{{- with try (transform.ToMath .Inner $opts) }} - {{- with .Err }} - {{- errorf "Unable to render mathematical markup to HTML using the transform.ToMath function. The KaTeX display engine threw the following error: %s: see %s." . $.Position }} - {{- else }} - {{- .Value }} - {{- $.Page.Store.Set "hasMath" true }} - {{- end }} -{{- end -}} +{{ partial "scripts/math.html" . }} diff --git a/layouts/_partials/breadcrumb.html b/layouts/_partials/breadcrumb.html index af3a9551..bfe89399 100644 --- a/layouts/_partials/breadcrumb.html +++ b/layouts/_partials/breadcrumb.html @@ -1,28 +1,35 @@ {{/* - A copy of the breadcrumb.html partial in Docsy, modified - to: + A copy of the breadcrumb.html partial in Docsy, modified to: + + * show the breadcrumbs by default by removing the `td-breadcrumbs__single` + class * omit breadcrumbs when this is the homepage * otherwise, include the homepage in the breadcrumbs */}} -{{ if not .IsHome }} +{{ if not .IsHome -}} -{{ end }} + + +{{ end -}} -{{ define "breadcrumbnav" }} -{{ if .p1.Parent }} -{{ template "breadcrumbnav" (dict "p1" .p1.Parent "p2" .p2 ) }} -{{ else if not .p1.IsHome }} -{{ template "breadcrumbnav" (dict "p1" .p1.Site.Home "p2" .p2 ) }} -{{ end }} -{{ $isActive := eq .p1 .p2 }} - -{{ end }} +{{- define "breadcrumbnav" -}} + {{ if .p1.Parent -}} + {{ template "breadcrumbnav" (dict "p1" .p1.Parent "p2" .p2 ) -}} + {{ else if not .p1.IsHome -}} + {{ template "breadcrumbnav" (dict "p1" .p1.Site.Home "p2" .p2 ) -}} + {{ end -}} + {{ $isActive := eq .p1 .p2 }} + +{{- end -}} diff --git a/layouts/_partials/navbar.html b/layouts/_partials/navbar.html index 0de6f46c..0a563d8f 100644 --- a/layouts/_partials/navbar.html +++ b/layouts/_partials/navbar.html @@ -1,8 +1,11 @@ {{- /* - A version of the navbar.html partial in Docsy, only modified - to include the spec version, which is calculated using an - inline `version-string` partial. + A copy of the navbar.html partial in Docsy, modified to: + + * remove `data-bs-theme` at L20, otherwise the title disappears on hover. + * replace the site title with "specification" at L31. + * include the spec version from the config at L34-35, which is calculated + using an inline `version-string` partial. */ -}} @@ -13,8 +16,8 @@ {{ $baseURL := urls.Parse $.Site.Params.Baseurl -}} -{{ define "_partials/version-string" }} - {{ $ret := "unstable version"}} +{{- define "_partials/version-string" -}} + {{ $ret := "unstable version" -}} - {{ $status := .Site.Params.version.status }} + {{ $status := .Site.Params.version.status -}} - {{ if ne $status "unstable"}} - {{ $path := path.Join "changelogs" }} + {{ if ne $status "unstable" -}} + {{ $path := path.Join "changelogs" -}} - {{/* produces a string similar to "version v1.5" */}} - {{ $ret = delimit (slice "version v" .Site.Params.version.major "." .Site.Params.version.minor) "" }} - {{ end }} + {{/* produces a string similar to "version v1.5" */ -}} + {{ $ret = delimit (slice "version v" .Site.Params.version.major "." .Site.Params.version.minor) "" -}} + {{ end -}} - {{ return $ret }} -{{ end }} + {{ return $ret -}} +{{- end -}} diff --git a/layouts/_partials/sidebar-tree.html b/layouts/_partials/sidebar-tree.html index dba63f3a..e5f00807 100644 --- a/layouts/_partials/sidebar-tree.html +++ b/layouts/_partials/sidebar-tree.html @@ -1,37 +1,57 @@ {{- /* - A modified version of the siderbar-tree.html partial in Docsy, adding: - - * The "toc.html" partial at L45. + A copy of the siderbar-tree.html partial in Docsy, modified to: + + * Ignore the `sidebarRoot` parameter, because of this regression: + + * Add the "toc.html" partial at L68. */ -}} -{{/* We cache this partial for bigger sites and set the active class client side. */ -}} -{{ $sidebarCacheLimit := .Site.Params.ui.sidebar_cache_limit | default 2000 -}} -{{ $shouldDelayActive := ge (len .Site.Pages) $sidebarCacheLimit -}} +{{ $context := .context -}} +{{ $sidebarRoot := .sidebarRoot -}} +{{ $sidebarRootID := .sidebarRootID -}} +{{ $cacheSidebar := .cacheSidebar -}} + +{{ with $context -}} +{{/* When the sidebar is cached, "active" class is set client side. */ -}} +{{ $shouldDelayActive := $cacheSidebar -}} +
{{ if not .Site.Params.ui.sidebar_search_disable -}} + - {{ else -}} + + {{- else -}} +
- {{ end -}} + + {{- end }} + {{/* */ -}} +
+ +{{- end }}{{/* with $context */ -}} + {{ define "section-tree-nav-section" -}} -{{ $s := .section -}} -{{ $p := .page -}} -{{ $shouldDelayActive := .shouldDelayActive -}} -{{ $sidebarMenuTruncate := .sidebarMenuTruncate -}} -{{ $treeRoot := cond (eq .ulNr 0) true false -}} -{{ $ulNr := .ulNr -}} -{{ $ulShow := .ulShow -}} -{{ $active := and (not $shouldDelayActive) (eq $s $p) -}} -{{ $activePath := and (not $shouldDelayActive) (or (eq $p $s) ($p.IsDescendant $s)) -}} -{{ $show := cond (or (lt $ulNr $ulShow) $activePath (and (not $shouldDelayActive) (eq $s.Parent $p.Parent)) (and (not $shouldDelayActive) (eq $s.Parent $p)) (not $p.Site.Params.ui.sidebar_menu_compact) (and (not $shouldDelayActive) ($p.IsDescendant $s.Parent))) true false -}} -{{ $mid := printf "m-%s" ($s.RelPermalink | anchorize) -}} -{{ $pages_tmp := where (union $s.Pages $s.Sections).ByWeight ".Params.toc_hide" "!=" true -}} -{{ $pages := $pages_tmp | first $sidebarMenuTruncate -}} -{{ $truncatedEntryCount := sub (len $pages_tmp) $sidebarMenuTruncate -}} -{{ if gt $truncatedEntryCount 0 -}} - {{ warnf "WARNING: %d sidebar entries have been truncated. To avoid this, increase `params.ui.sidebar_menu_truncate` to at least %d (from %d) in your config file. Section: %s" - $truncatedEntryCount (len $pages_tmp) $sidebarMenuTruncate $s.Path -}} -{{ end -}} -{{ $withChild := gt (len $pages) 0 -}} -{{ $manualLink := cond (isset $s.Params "manuallink") $s.Params.manualLink ( cond (isset $s.Params "manuallinkrelref") (relref $s $s.Params.manualLinkRelref) $s.RelPermalink) -}} -{{ $manualLinkTitle := cond (isset $s.Params "manuallinktitle") $s.Params.manualLinkTitle $s.Title -}} -
  • - {{ if (and $p.Site.Params.ui.sidebar_menu_foldable (ge $ulNr 1)) -}} - - - {{ else -}} - {{ with $s.Params.Icon}}{{ end }}{{ $s.LinkTitle }} - {{- end }} - {{- if $withChild }} - {{- $ulNr := add $ulNr 1 }} -
      - {{ range $pages -}} - {{ if (not (and (eq $s $p.Site.Home) (eq .Params.toc_root true))) -}} - {{ template "section-tree-nav-section" (dict "page" $p "section" . "shouldDelayActive" $shouldDelayActive "sidebarMenuTruncate" $sidebarMenuTruncate "ulNr" $ulNr "ulShow" $ulShow) }} + {{/* cSpell:ignore manuallink manuallinkrelref manuallinktitle */ -}} + {{ $s := .section -}} + {{ $p := .page -}} + {{ $shouldDelayActive := .shouldDelayActive -}} + {{ $sidebarMenuTruncate := .sidebarMenuTruncate -}} + {{ $treeRoot := cond (eq .ulNr 0) true false -}} + {{ $ulNr := .ulNr -}} + {{ $ulShow := .ulShow -}} + {{ $active := and (not $shouldDelayActive) (eq $s $p) -}} + {{ $activePath := and (not $shouldDelayActive) (or (eq $p $s) ($p.IsDescendant $s)) -}} + {{ $show := cond + (or + (lt $ulNr $ulShow) + $activePath + (and (not $shouldDelayActive) (eq $s.Parent $p.Parent)) + (and (not $shouldDelayActive) (eq $s.Parent $p)) + (not $p.Site.Params.ui.sidebar_menu_compact) + (and (not $shouldDelayActive) ($p.IsDescendant $s.Parent)) + ) + true false + -}} + {{ $mid := printf "m-%s" ($s.RelPermalink | anchorize) -}} + {{ $pages_tmp := where (union $s.Pages $s.Sections).ByWeight ".Params.toc_hide" "!=" true -}} + {{ $pages := $pages_tmp | first $sidebarMenuTruncate -}} + {{ $truncatedEntryCount := sub (len $pages_tmp) $sidebarMenuTruncate -}} + + {{ if gt $truncatedEntryCount 0 -}} + {{ warnf "WARNING: %d sidebar entries have been truncated. To avoid this, increase `params.ui.sidebar_menu_truncate` to at least %d (from %d) in your config file. Section: %s" + $truncatedEntryCount (len $pages_tmp) $sidebarMenuTruncate $s.Path -}} + {{ end -}} + + {{ $withChild := gt (len $pages) 0 -}} + {{ $manualLink := + cond + (isset $s.Params "manuallink") + $s.Params.manualLink + (cond + (isset $s.Params "manuallinkrelref") + (relref $s $s.Params.manualLinkRelref) + $s.RelPermalink + ) + -}} + {{ $manualLinkTitle := + cond + (isset $s.Params "manuallinktitle") + $s.Params.manualLinkTitle + $s.Title + -}} + {{ if and $treeRoot (eq $s.Params.sidebar_root_for "self") -}} + {{ with $s.Parent -}} + {{ $manualLink = .RelPermalink -}} + {{ end -}} + {{ end -}} +
    • + {{ if (and $p.Site.Params.ui.sidebar_menu_foldable (ge $ulNr 1)) -}} + + + {{ else -}} + + {{- with $s.Params.Icon -}} + + {{- end -}} + + {{- $s.LinkTitle -}} + + {{- end -}} + {{ if $withChild -}} + {{ $ulNr := add $ulNr 1 }} +
        + {{ range $pages -}} + {{ if (not (and (eq $s $p.Site.Home) (eq .Params.toc_root true))) -}} + {{ template "section-tree-nav-section" (dict "page" $p "section" . "shouldDelayActive" $shouldDelayActive "sidebarMenuTruncate" $sidebarMenuTruncate "ulNr" $ulNr "ulShow" $ulShow) }} + {{- end }} + {{- end }} +
      {{- end }} - {{- end }} -
    - {{- end }} -
  • -{{- end -}} + +{{- end }} diff --git a/layouts/_partials/toc.html b/layouts/_partials/toc.html index 318335f2..adfbd161 100644 --- a/layouts/_partials/toc.html +++ b/layouts/_partials/toc.html @@ -1,15 +1,29 @@ {{/* - A modified version of the toc.html partial in Docsy. + A copy of the toc.html partial in Docsy, modified to: -*/}} -{{ $page := .Params }} + * show the page's title instead of "on this page" + +*/ -}} + +{{/* + + Always render the td-toc element. ScrollSpy is counting on it to exist, + even if it's empty. + + cSpell:ignore notoc +*/ -}} + +
    {{ if not .Params.notoc -}} - {{ with .TableOfContents -}} -
    -
    - {{ $page.Title }} - {{ . }} + {{ $toc := .TableOfContents -}} + {{ if and $toc (ne $toc ``) -}} +
    + {{ .Params.Title }} +
    + {{ $toc | safeHTML }} {{ end -}} {{ end -}} +
    +{{/* */ -}} diff --git a/layouts/docs/baseof.html b/layouts/docs/baseof.html index b5b7a0f0..e18864dd 100644 --- a/layouts/docs/baseof.html +++ b/layouts/docs/baseof.html @@ -1,11 +1,14 @@ {{/* - A copy of the baseof.html partial in Docsy, modified - to remove the right-hand column from the layout. + A copy of the baseof.html partial in Docsy, modified to: -*/}} + * generate a static file `versions.json` that can be used to populate the + version picker. + * remove the right-hand column from the layout. -{{/* Generate a static file versions.json that can be used to populate the version picker */}} +*/ -}} + +{{/* Generate a static file versions.json that can be used to populate the version picker */ -}} {{ if .IsHome }} {{- /* Load all changelog subpages, sorted by release date */ -}} {{ $changelog := site.GetPage "changelog" }} @@ -28,20 +31,18 @@ + class="no-js" + {{- $darkMode := partialCached "dark-mode-config.html" "dark-mode-global" -}} + {{- if $darkMode.enable }} data-theme-init{{ end }}> {{ partial "head.html" . }} - {{ if .Page.Store.Get "hasMath" }} - - - {{ end }}
    {{ partial "navbar.html" . }}
    -
    +