Compare commits

...

8 commits

Author SHA1 Message Date
Kévin Commaille 62bb8d5db0
Merge f95dcfb0e7 into fa78688f57 2026-01-14 10:01:21 +00:00
Johannes Marbach fa78688f57
Spec for MSC4356: Recently used emoji (#2291)
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
Spec / Create release (push) Has been cancelled
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
2026-01-14 09:15:24 +00:00
Kévin Commaille f95dcfb0e7
Fix changelog (again)
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-12-19 13:09:53 +01:00
Kévin Commaille c98c03b32c
Fix changelogs
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-12-19 13:06:50 +01:00
Kévin Commaille 19bf443d0e
Fix examples
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-12-19 13:03:03 +01:00
Kévin Commaille 147f8703d4
Fix fragments
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-12-19 12:59:01 +01:00
Kévin Commaille bcd5f6bcfb
Add changelog
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-12-19 12:54:20 +01:00
Kévin Commaille 05b0d0602d
Spec User suspension & locking endpoints
As per MSC4323.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2025-12-19 12:46:54 +01:00
13 changed files with 551 additions and 11 deletions

View file

@ -0,0 +1 @@
Add endpoints to lock and suspend server-local users for administrations and add the `m.account_management` capability, as per [MSC4323](https://github.com/matrix-org/matrix-spec-proposals/pull/4323).

View file

@ -0,0 +1 @@
Add `GET /_matrix/client/v1/admin/suspend/{userId}`, as per [MSC4323](https://github.com/matrix-org/matrix-spec-proposals/pull/4323).

View file

@ -0,0 +1 @@
Add `PUT /_matrix/client/v1/admin/suspend/{userId}`, as per [MSC4323](https://github.com/matrix-org/matrix-spec-proposals/pull/4323).

View file

@ -0,0 +1 @@
Add `GET /_matrix/client/v1/admin/lock/{userId}`, as per [MSC4323](https://github.com/matrix-org/matrix-spec-proposals/pull/4323).

View file

@ -0,0 +1 @@
Add `PUT /_matrix/client/v1/admin/lock/{userId}`, as per [MSC4323](https://github.com/matrix-org/matrix-spec-proposals/pull/4323).

View file

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

View file

@ -2280,9 +2280,12 @@ The server SHOULD return one of the following responses:
Server administrators may apply locks to prevent users from usefully
using their accounts, for instance, due to safety or security concerns.
In contrast to account deactivation, locking is a non-destructive action
that can be reversed. This specification describes the behaviour of clients
and servers when an account is locked. It deliberately leaves the methods
for locking and unlocking accounts as a server implementation detail.
that can be reversed.
{{% added-in v="1.18" %}} To lock or unlock an account, the administrators
SHOULD use the [`PUT /admin/lock/{userId}`](#put_matrixclientv1adminlockuserid)
endpoint. They MAY also use [`GET /admin/lock/{userId}`](#get_matrixclientv1adminlockuserid)
to check whether a user's account is locked.
When an account is locked, servers MUST return a `401 Unauthorized` error
response with an `M_USER_LOCKED` error code and [`soft_logout`](#soft-logout)
@ -2331,6 +2334,11 @@ from that account. The effect is similar to [locking](#account-locking), though
without risk of the client losing state from a logout. Suspensions are reversible,
like locks and unlike deactivations.
{{% added-in v="1.18" %}} To suspend or unsuspend an account, the administrators
SHOULD use the [`PUT /admin/suspend/{userId}`](#put_matrixclientv1adminsuspenduserid)
endpoint. They MAY also use [`GET /admin/suspend/{userId}`](#get_matrixclientv1adminsuspenduserid)
to check whether a user's account is suspended.
The actions a user can perform while suspended is deliberately left as an
implementation detail. Servers SHOULD permit the user to perform at least the
following, however:
@ -2386,9 +2394,6 @@ Content-Type: application/json
}
```
APIs for initiating suspension or unsuspension are not included in this version
of the specification, and left as an implementation detail.
### Adding Account Administrative Contact Information
A homeserver may keep some contact information for administrative use.
@ -3898,6 +3903,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 |
@ -3999,5 +4005,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" %}}

View file

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

View file

@ -16,7 +16,7 @@ info:
title: Matrix Client-Server Administration API
version: 1.0.0
paths:
"/admin/whois/{userId}":
"/v3/admin/whois/{userId}":
get:
summary: Gets information about a particular user.
description: |-
@ -107,6 +107,391 @@ paths:
}
tags:
- Server administration
"/v1/admin/suspend/{userId}":
get:
summary: Gets information about the suspended status of a particular user.
x-addedInMatrixVersion: "1.18"
description: |-
Gets information about the suspended status of a particular server-local user.
The user calling this endpoint MUST be a server admin.
In order to prevent user enumeration, servers MUST ensure that authorization is checked
prior to trying to do account lookups.
operationId: getAdminSuspendUser
security:
- accessTokenQuery: []
- accessTokenBearer: []
parameters:
- in: path
name: userId
description: The user to look up.
required: true
example: "@peter:rabbit.rocks"
schema:
type: string
format: mx-user-id
pattern: "^@"
responses:
"200":
description: The lookup was successful.
content:
application/json:
schema:
type: object
properties:
suspended:
type: boolean
description: Whether the target account is suspended.
example: true
required:
- suspended
examples:
response:
value: {
"suspended": true,
}
"400":
description: |-
The user ID does not belong to the local server. The errcode is `M_INVALID_PARAM`.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_INVALID_PARAM",
"error": "User does not belong to the local server."
}
"403":
description: |-
The requesting user is not a server administrator, or the target user is another
administrator. The errcode is `M_FORBIDDEN`.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_FORBIDDEN",
"error": "Requesting user is not a server administrator."
}
"404":
description: |-
The user ID is not found, or is deactivated. The errcode is `M_NOT_FOUND`.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_NOT_FOUND",
"error": "User not found."
}
tags:
- Server administration
put:
summary: Set the suspended status of a particular user.
x-addedInMatrixVersion: "1.18"
description: |-
Sets the suspended status of a particular server-local user.
The user calling this endpoint MUST be a server admin. The client SHOULD check that the user
is allowed to suspend other users at the [`GET /capabilities`](/client-server-api/#get_matrixclientv3capabilities)
endpoint prior to using this endpoint.
In order to prevent user enumeration, servers MUST ensure that authorization is checked
prior to trying to do account lookups.
operationId: setAdminSuspendUser
security:
- accessTokenQuery: []
- accessTokenBearer: []
parameters:
- in: path
name: userId
description: The user to change the suspended status of.
required: true
example: "@peter:rabbit.rocks"
schema:
type: string
format: mx-user-id
pattern: "^@"
requestBody:
content:
application/json:
schema:
type: object
properties:
suspended:
type: boolean
description: Whether to suspend the target account.
example: true
required:
- suspended
examples:
request:
value: {
"suspended": true,
}
required: true
responses:
"200":
description: The action was successful.
content:
application/json:
schema:
type: object
properties:
suspended:
type: boolean
description: Whether the target account is suspended.
example: true
required:
- suspended
examples:
response:
value: {
"suspended": true,
}
"400":
description: |-
The user ID does not belong to the local server. The errcode is `M_INVALID_PARAM`.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_INVALID_PARAM",
"error": "User does not belong to the local server."
}
"403":
description: |-
The requesting user is not a server administrator, is trying to suspend their own
account, or the target user is another administrator. The errcode is `M_FORBIDDEN`.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_FORBIDDEN",
"error": "Requesting user is not a server administrator."
}
"404":
description: |-
The user ID is not found, or is deactivated. The errcode is `M_NOT_FOUND`.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_NOT_FOUND",
"error": "User not found."
}
tags:
- Server administration
"/v1/admin/lock/{userId}":
get:
summary: Gets information about the locked status of a particular user.
x-addedInMatrixVersion: "1.18"
description: |-
Gets information about the locked status of a particular server-local user.
The user calling this endpoint MUST be a server admin.
In order to prevent user enumeration, servers MUST ensure that authorization is checked
prior to trying to do account lookups.
operationId: getAdminLockUser
security:
- accessTokenQuery: []
- accessTokenBearer: []
parameters:
- in: path
name: userId
description: The user to look up.
required: true
example: "@peter:rabbit.rocks"
schema:
type: string
format: mx-user-id
pattern: "^@"
responses:
"200":
description: The lookup was successful.
content:
application/json:
schema:
type: object
properties:
locked:
type: boolean
description: Whether the target account is locked.
required:
- locked
examples:
response:
value: {
"locked": true,
}
"400":
description: |-
The user ID does not belong to the local server. The errcode is `M_INVALID_PARAM`.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_INVALID_PARAM",
"error": "User does not belong to the local server."
}
"403":
description: |-
The requesting user is not a server administrator, or the target user is another
administrator. The errcode is `M_FORBIDDEN`.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_FORBIDDEN",
"error": "Requesting user is not a server administrator."
}
"404":
description: |-
The user ID is not found, or is deactivated. The errcode is `M_NOT_FOUND`.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_NOT_FOUND",
"error": "User not found."
}
tags:
- Server administration
put:
summary: Set the locked status of a particular user.
x-addedInMatrixVersion: "1.18"
description: |-
Sets the locked status of a particular server-local user.
The user calling this endpoint MUST be a server admin. The client SHOULD check that the user
is allowed to lock other users at the [`GET /capabilities`](/client-server-api/#get_matrixclientv3capabilities)
endpoint prior to using this endpoint.
In order to prevent user enumeration, servers MUST ensure that authorization is checked
prior to trying to do account lookups.
operationId: setAdminLockUser
security:
- accessTokenQuery: []
- accessTokenBearer: []
parameters:
- in: path
name: userId
description: The user to change the locked status of.
required: true
example: "@peter:rabbit.rocks"
schema:
type: string
format: mx-user-id
pattern: "^@"
requestBody:
content:
application/json:
schema:
type: object
properties:
locked:
type: boolean
description: Whether to lock the target account.
example: true
required:
- locked
examples:
request:
value: {
"locked": true,
}
required: true
responses:
"200":
description: The action was successful.
content:
application/json:
schema:
type: object
properties:
locked:
type: boolean
description: Whether the target account is locked.
example: true
required:
- locked
examples:
response:
value: {
"locked": true,
}
"400":
description: |-
The user ID does not belong to the local server. The errcode is `M_INVALID_PARAM`.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_INVALID_PARAM",
"error": "User does not belong to the local server."
}
"403":
description: |-
The requesting user is not a server administrator, is trying to lock their own
account, or the target user is another administrator. The errcode is `M_FORBIDDEN`.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_FORBIDDEN",
"error": "Requesting user is not a server administrator."
}
"404":
description: |-
The user ID is not found, or is deactivated. The errcode is `M_NOT_FOUND`.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_NOT_FOUND",
"error": "User not found."
}
tags:
- Server administration
servers:
- url: "{protocol}://{hostname}{basePath}"
variables:
@ -118,7 +503,7 @@ servers:
hostname:
default: localhost:8008
basePath:
default: /_matrix/client/v3
default: /_matrix/client
components:
securitySchemes:
accessTokenQuery:

View file

@ -78,7 +78,7 @@ paths:
description: |
**Deprecated:** Capability to indicate if the user can change their display name.
Refer to `m.profile_fields` for extended profile management.
For backwards compatibility, servers that directly or indirectly include the
`displayname` profile field in the `m.profile_fields` capability MUST also
set this capability accordingly.
@ -115,7 +115,7 @@ paths:
description: |
If present, a list of profile fields that clients are allowed to create, modify or delete,
provided `enabled` is `true`; no other profile fields may be changed.
If absent, clients may set all profile fields except those forbidden by the `disallowed`
list, where present.
items:
@ -127,7 +127,7 @@ paths:
type: array
description: |
This property has no meaning if `allowed` is also specified.
Otherwise, if present, a list of profile fields that clients are _not_ allowed to create, modify or delete.
Provided `enabled` is `true`, clients MAY assume that they can set any profile field which is not
included in this list.
@ -141,6 +141,34 @@ paths:
example: true
required:
- enabled
m.account_moderation:
x-addedInMatrixVersion: "1.18"
type: object
title: AccountModerationCapability
description: |-
Capability to indicate if the user can perform account moderation actions
via [server administration](/client-server-api/#server-administration)
endpoints.
This property should be omitted altogether if `suspend` and `lock` would
be `false`.
properties:
suspend:
type: boolean
description: |-
`true` if the user can suspend a user via [`PUT /admin/suspend/{userId}`](/client-server-api/#put_matrixclientv1adminsuspenduserid),
`false` otherwise.
Defaults to `false`.
example: true
lock:
type: boolean
description: |-
`true` if the user can lock a user via [`PUT /admin/lock/{userId}`](/client-server-api/#put_matrixclientv1adminlockuserid),
`false` otherwise.
Defaults to `false`.
example: true
examples:
response:
value: {

View file

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

View file

@ -0,0 +1,16 @@
{
"$ref": "core/event.json",
"type": "m.recent_emoji",
"content": {
"recent_emoji": [{
"emoji": "🤔",
"total": 19
}, {
"emoji": "👍",
"total": 7
}, {
"emoji": "😅",
"total": 84
}]
}
}

View file

@ -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"]
}