Spec for MSC4133: Update profile endpoints to support extended fields (#2071)

Signed-off-by: Tom Foster <tom@tcpip.uk>
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
Co-authored-by: Patrick Cloke <clokep@users.noreply.github.com>
Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org>
Co-authored-by: Richard van der Hoff <richard@matrix.org>
pull/2193/head
Tom Foster 4 months ago committed by GitHub
parent 04f42ac208
commit c4bfd2feb8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1 @@
Deprecate `m.set_avatar_url` and `m.set_displayname` capabilities, as per [MSC4133](https://github.com/matrix-org/matrix-spec-proposals/pull/4133).

@ -0,0 +1 @@
Update user profile endpoints to handle custom fields, and add a new `m.profile_fields` capability,as per [MSC4133](https://github.com/matrix-org/matrix-spec-proposals/pull/4133).

@ -2491,8 +2491,66 @@ using an `unstable` version.
When this capability is not listed, clients should use `"1"` as the When this capability is not listed, clients should use `"1"` as the
default and only stable `available` room version. default and only stable `available` room version.
### `m.profile_fields` capability
{{% added-in v="1.16" %}}
This capability defines which [profile](#profiles) fields the user is
able to change.
The capability value has a required flag, `enabled`, and two optional lists, `allowed` and
`disallowed`.
When `enabled` is `false`, all profile fields are managed by the server
and the client is not permitted to make any changes.
When `enabled` is `true`, clients are permitted to modify profile fields,
subject to the restrictions implied by the OPTIONAL lists `allowed` and
`disallowed`.
If `allowed` is present, clients can modify only the fields
listed. They SHOULD assume all other fields to be managed by
the server. In this case, `disallowed` has no meaning and should be ignored.
If `disallowed` is present (and `allowed` is not), clients SHOULD assume
that the listed fields are managed by the server. Clients may modify any
fields that are *not* listed, provided `enabled` is `true`.
If neither `allowed` nor `disallowed` is present, clients can modify all fields
without restrictions, provided `enabled` is `true`.
When this capability is not listed, clients SHOULD assume the user is able to change
profile fields without any restrictions, provided the homeserver
advertises a specification version that includes the `m.profile_fields`
capability in the [`/versions`](/client-server-api/#get_matrixclientversions)
response.
An example of the capability API's response for this capability is:
```json
{
"capabilities": {
"m.profile_fields": {
"enabled": true,
"disallowed": ["displayname"]
}
}
}
```
### `m.set_displayname` capability ### `m.set_displayname` capability
{{% boxes/note %}}
{{% changed-in v="1.16" %}}
This capability is now deprecated. Clients SHOULD use the
[`m.profile_fields`](/client-server-api/#mprofile_fields-capability)
capability instead.
For backwards compatibility, servers that forbid setting the
`displayname` profile field in the `m.profile_fields` capability
MUST still present this capability with `"enabled": false`.
{{% /boxes/note %}}
This capability has a single flag, `enabled`, to denote whether the user This capability has a single flag, `enabled`, to denote whether the user
is able to change their own display name via profile endpoints. Cases for is able to change their own display name via profile endpoints. Cases for
disabling might include users mapped from external identity/directory disabling might include users mapped from external identity/directory
@ -2517,6 +2575,17 @@ An example of the capability API's response for this capability is:
### `m.set_avatar_url` capability ### `m.set_avatar_url` capability
{{% boxes/note %}}
{{% changed-in v="1.16" %}}
This capability is now deprecated. Clients SHOULD use the
[`m.profile_fields`](/client-server-api/#mprofile_fields-capability)
capability instead.
For backwards compatibility, servers that forbid setting the
`avatar_url` profile field in the `m.profile_fields` capability
MUST still present this capability with `"enabled": false`.
{{% /boxes/note %}}
This capability has a single flag, `enabled`, to denote whether the user This capability has a single flag, `enabled`, to denote whether the user
is able to change their own avatar via profile endpoints. Cases for is able to change their own avatar via profile endpoints. Cases for
disabling might include users mapped from external identity/directory disabling might include users mapped from external identity/directory

@ -63,7 +63,8 @@ for sending events:
The following API endpoints are allowed to be accessed by guest accounts The following API endpoints are allowed to be accessed by guest accounts
for their own account maintenance: for their own account maintenance:
* [PUT /profile/{userId}/displayname](#put_matrixclientv3profileuseriddisplayname) * [PUT /profile/{userId}/displayname](#put_matrixclientv3profileuseridkeyname). Guest users may only modify their display name; other profile fields may not be changed.
* {{% added-in v="1.16" %}} [DELETE /profile/{userId}/displayname](#delete_matrixclientv3profileuseridkeyname). Again, guest users may delete their display name but not other profile fields.
* [GET /devices](#get_matrixclientv3devices) * [GET /devices](#get_matrixclientv3devices)
* [GET /devices/{deviceId}](#get_matrixclientv3devicesdeviceid) * [GET /devices/{deviceId}](#get_matrixclientv3devicesdeviceid)
* [PUT /devices/{deviceId}](#put_matrixclientv3devicesdeviceid) * [PUT /devices/{deviceId}](#put_matrixclientv3devicesdeviceid)

@ -73,11 +73,25 @@ paths:
- default - default
- available - available
m.set_displayname: m.set_displayname:
deprecated: true
$ref: '#/components/schemas/booleanCapability' $ref: '#/components/schemas/booleanCapability'
description: Capability to indicate if the user can change their display name. 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.
m.set_avatar_url: m.set_avatar_url:
deprecated: true
$ref: '#/components/schemas/booleanCapability' $ref: '#/components/schemas/booleanCapability'
description: Capability to indicate if the user can change their avatar. description: |
**Deprecated:** Capability to indicate if the user can change their avatar.
Refer to `m.profile_fields` for extended profile management.
For backwards compatibility, servers that directly or indirectly include the
`avatar_url` profile field in the `m.profile_fields` capability MUST also
set this capability accordingly.
m.3pid_changes: m.3pid_changes:
$ref: '#/components/schemas/booleanCapability' $ref: '#/components/schemas/booleanCapability'
description: Capability to indicate if the user can change 3PID associations description: Capability to indicate if the user can change 3PID associations
@ -86,6 +100,47 @@ paths:
$ref: '#/components/schemas/booleanCapability' $ref: '#/components/schemas/booleanCapability'
description: Capability to indicate if the user can generate tokens to log further description: Capability to indicate if the user can generate tokens to log further
clients into their account. clients into their account.
m.profile_fields:
x-addedInMatrixVersion: "1.16"
type: object
title: ProfileFieldsCapability
description: Capability to indicate if the user can set or modify extended profile fields via
[`PUT /_matrix/client/v3/profile/{userId}/{keyName}`](/client-server-api/#put_matrixclientv3profileuseridkeyname).
If absent, clients SHOULD assume custom profile fields are supported, provided the
homeserver advertises a specification version that includes `m.profile_fields` in the
[`/versions`](/client-server-api/#get_matrixclientversions) response.
properties:
allowed:
type: array
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:
type: string
example:
- "m.example_field"
- "org.example.job_title"
disallowed:
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.
items:
type: string
example:
- "org.example.managed_field"
enabled:
type: boolean
description: "`true` if the user can create, update or delete any profile fields, `false` otherwise."
example: true
required:
- enabled
examples: examples:
response: response:
value: { value: {

@ -16,48 +16,117 @@ info:
title: Matrix Client-Server Profile API title: Matrix Client-Server Profile API
version: 1.0.0 version: 1.0.0
paths: paths:
"/profile/{userId}/displayname": "/profile/{userId}/{keyName}":
put: put:
summary: Set the user's display name. x-changedInMatrixVersion:
"1.16": This endpoint now accepts a variable `keyName` parameter. Previously only `displayname` and `avatar_url` were accepted.
summary: Set a profile field for a user.
description: |- description: |-
This API sets the given user's display name. You must have permission to Set or update a profile field for a user. Must be authenticated with an
set this user's display name, e.g. you need to have their `access_token`. access token authorised to make changes. Servers MAY impose size limits
operationId: setDisplayName on individual fields, and the total profile MUST be under 64 KiB.
Servers MAY reject `null` values. Servers that accept `null` values SHOULD store
them rather than treating `null` as a deletion request. Clients that want to delete a
field, including its key and value, SHOULD use the `DELETE` endpoint instead.
operationId: setProfileField
security: security:
- accessTokenQuery: [] - accessTokenQuery: []
- accessTokenBearer: [] - accessTokenBearer: []
parameters: parameters:
- in: path - in: path
name: userId name: userId
description: The user whose display name to set. description: The user whose profile field should be set.
required: true required: true
example: "@alice:example.com" example: "@alice:example.com"
schema: schema:
type: string type: string
- in: path
name: keyName
description: The name of the profile field to set. This MUST be either
`avatar_url`, `displayname`, or a custom field following the
[Common Namespaced Identifier Grammar](/appendices/#common-namespaced-identifier-grammar).
required: true
example: "displayname"
schema:
type: string
pattern: '^(avatar_url|displayname|[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+)$'
requestBody: requestBody:
description: A JSON object containing the property whose name matches
the `keyName` specified in the URL. See `additionalProperties` for
further details.
required: true
content: content:
application/json: application/json:
schema: schema:
type: object type: object
example: { minProperties: 1
"displayname": "Alice Margatroid" description: |
} An object which contains exactly one property. The key
properties: of that property MUST match the `keyName` specified in the URL.
displayname:
type: string For `avatar_url`, the value MUST be an MXC URI string.
description: The new display name for this user.
description: The new display name information. For `displayname`, the value MUST be a string.
required: true
For custom keys, any JSON type is allowed. Servers MAY not validate
these values, but clients SHOULD follow the format defined for that key.
additionalProperties: true
example: { "displayname": "Alice Wonderland" }
responses: responses:
"200": "200":
description: The display name was set. description: The profile field was set.
content: content:
application/json: application/json:
schema: schema:
type: object # empty json object type: object # empty JSON object
examples: examples:
response: response:
value: {} value: {}
"400":
description: |
The input was invalid in some way. This can include one
of the following error codes:
- `M_BAD_JSON`: The provided value is not valid JSON.
- `M_MISSING_PARAM`: The required `keyName` property is
missing from the request body.
- `M_PROFILE_TOO_LARGE`: Storing the supplied value would
make the profile exceed its maximum allowed size of 64 KiB.
- `M_KEY_TOO_LARGE`: The supplied profile key exceeds the
maximum allowed key length of 255 bytes.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
bad_json:
value:
{
"errcode": "M_BAD_JSON",
"error": "Malformed JSON payload.",
}
invalid_key:
value:
{
"errcode": "M_INVALID_PARAM",
"error": "Invalid profile key.",
}
"403":
description: The server is unwilling to perform the operation, either
due to insufficient permissions or because profile modifications
are disabled.
content:
application/json:
schema:
$ref: definitions/errors/error.yaml
examples:
forbidden:
value:
{
"errcode": "M_FORBIDDEN",
"error": "Profile modification is not permitted.",
}
"429": "429":
description: This request was rate-limited. description: This request was rate-limited.
content: content:
@ -67,163 +136,138 @@ paths:
tags: tags:
- User data - User data
get: get:
summary: Get the user's display name. x-changedInMatrixVersion:
description: |- "1.16": This endpoint now accepts a variable `keyName` parameter. Previously only `displayname` and `avatar_url` were accepted.
Get the user's display name. This API may be used to fetch the user's summary: Get a profile field for a user.
own displayname or to query the name of other users; either locally or description: Get the value of a profile field for a user.
on remote homeservers. operationId: getProfileField
operationId: getDisplayName
parameters: parameters:
- in: path - in: path
name: userId name: userId
description: The user whose display name to get. description: The user whose profile field should be returned.
required: true required: true
example: "@alice:example.com" example: "@alice:example.com"
schema: schema:
type: string type: string
- in: path
name: keyName
description: The name of the profile field to retrieve.
required: true
example: "displayname"
schema:
type: string
pattern: '^(avatar_url|displayname|[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+)$'
responses: responses:
"200": "200":
description: The display name for this user. description: The profile field value was retrieved.
content: content:
application/json: application/json:
schema: schema:
type: object type: object
properties: description: |
displayname: An object with one property, whose key matches the `keyName` specified
type: string in the URL, and whose value is the current setting of that profile field.
description: The user's display name if they have set one, otherwise not additionalProperties: true
present.
examples: examples:
response: response:
value: { value: { "displayname": "Alice" }
"displayname": "Alice Margatroid"
}
"403": "403":
x-addedInMatrixVersion: "1.12" x-addedInMatrixVersion: "1.12"
description: The server is unwilling to disclose whether the user exists and/or description: The server is unwilling to disclose whether the user
has a display name. exists and/or has the specified profile field.
content: content:
application/json: application/json:
schema: schema:
$ref: definitions/errors/error.yaml $ref: definitions/errors/error.yaml
examples: examples:
response: response:
value: { value:
{
"errcode": "M_FORBIDDEN", "errcode": "M_FORBIDDEN",
"error": "Profile lookup is disabled on this homeserver" "error": "Profile lookup is disabled on this homeserver",
} }
"404": "404":
description: There is no display name for this user or this user does not exist. description: There is no profile field with this key for this user, or
the user does not exist.
tags: tags:
- User data - User data
"/profile/{userId}/avatar_url": delete:
put: x-addedInMatrixVersion: "1.16"
summary: Set the user's avatar URL. summary: Remove a profile field from a user.
description: |- description: Remove a specific field from a user's profile.
This API sets the given user's avatar URL. You must have permission to operationId: deleteProfileField
set this user's avatar URL, e.g. you need to have their `access_token`.
operationId: setAvatarUrl
security: security:
- accessTokenQuery: [] - accessTokenQuery: []
- accessTokenBearer: [] - accessTokenBearer: []
parameters: parameters:
- in: path - in: path
name: userId name: userId
description: The user whose avatar URL to set. description: The user whose profile field should be deleted.
required: true required: true
example: "@alice:example.com" example: "@alice:example.com"
schema: schema:
type: string type: string
requestBody: - in: path
content: name: keyName
application/json: description: The name of the profile field to delete.
required: true
example: "displayname"
schema: schema:
type: object
example: {
"avatar_url": "mxc://matrix.org/wefh34uihSDRGhw34"
}
properties:
avatar_url:
type: string type: string
format: uri pattern: '^(avatar_url|displayname|[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+)$'
description: The new avatar URL for this user.
description: The new avatar information.
required: true
responses: responses:
"200": "200":
description: The avatar URL was set. description: The profile field was deleted or it doesn't exist.
content: content:
application/json: application/json:
schema: schema:
type: object # empty json object type: object
examples: examples:
response: response:
value: {} value: {}
"429": "400":
description: This request was rate-limited. description: The request is malformed, contains invalid JSON, or
content: specifies an invalid key.
application/json:
schema:
$ref: definitions/errors/rate_limited.yaml
tags:
- User data
get:
summary: Get the user's avatar URL.
description: |-
Get the user's avatar URL. This API may be used to fetch the user's
own avatar URL or to query the URL of other users; either locally or
on remote homeservers.
operationId: getAvatarUrl
parameters:
- in: path
name: userId
description: The user whose avatar URL to get.
required: true
example: "@alice:example.com"
schema:
type: string
responses:
"200":
description: The avatar URL for this user.
content: content:
application/json: application/json:
schema: schema:
type: object $ref: definitions/errors/error.yaml
properties:
avatar_url:
type: string
format: uri
description: The user's avatar URL if they have set one, otherwise not present.
examples: examples:
response: bad_json:
value: { value:
"avatar_url": "mxc://matrix.org/SDGdghriugerRg" { "errcode": "M_BAD_JSON", "error": "Malformed request." }
invalid_key:
value:
{
"errcode": "M_INVALID_PARAM",
"error": "Invalid profile key.",
} }
"403": "403":
x-addedInMatrixVersion: "1.12" description: The user is not authorised to delete this profile field.
description: The server is unwilling to disclose whether the user exists and/or
has an avatar URL.
content: content:
application/json: application/json:
schema: schema:
$ref: definitions/errors/error.yaml $ref: definitions/errors/error.yaml
examples: examples:
response: forbidden:
value: { value:
{
"errcode": "M_FORBIDDEN", "errcode": "M_FORBIDDEN",
"error": "Profile lookup is disabled on this homeserver" "error": "Profile deletion is not permitted.",
} }
"404": "429":
description: There is no avatar URL for this user or this user does not exist. description: This request was rate-limited.
content:
application/json:
schema:
$ref: definitions/errors/rate_limited.yaml
tags: tags:
- User data - User data
"/profile/{userId}": "/profile/{userId}":
get: get:
summary: Get this user's profile information. summary: Get all profile information for a user.
description: |- description: |-
Get the combined profile information for this user. This API may be used Get the complete profile for a user.
to fetch the user's own profile information or other users; either
locally or on remote homeservers.
operationId: getUserProfile operationId: getUserProfile
parameters: parameters:
- in: path - in: path
@ -243,45 +287,49 @@ paths:
properties: properties:
avatar_url: avatar_url:
type: string type: string
format: uri format: mx-mxc-uri
description: The user's avatar URL if they have set one, otherwise not present. description: The user's avatar URL if they have set one, otherwise not present.
displayname: displayname:
type: string type: string
description: The user's display name if they have set one, otherwise not description: The user's display name if they have set one, otherwise not
present. present.
additionalProperties:
x-addedInMatrixVersion: "1.16"
description: Additional profile fields.
examples: examples:
response: response:
value: { value:
{
"avatar_url": "mxc://matrix.org/SDGdghriugerRg", "avatar_url": "mxc://matrix.org/SDGdghriugerRg",
"displayname": "Alice Margatroid" "displayname": "Alice Margatroid",
"m.example_field": "custom_value",
} }
"403": "403":
x-addedInMatrixVersion: "1.2" x-addedInMatrixVersion: "1.2"
description: The server is unwilling to disclose whether the user exists and/or description: The server is unwilling to disclose whether the user
has profile information. exists and/or has profile information.
content: content:
application/json: application/json:
schema: schema:
$ref: definitions/errors/error.yaml $ref: definitions/errors/error.yaml
examples: examples:
response: response:
value: { value:
{
"errcode": "M_FORBIDDEN", "errcode": "M_FORBIDDEN",
"error": "Profile lookup is disabled on this homeserver" "error": "Profile lookup is disabled on this homeserver",
} }
"404": "404":
description: There is no profile information for this user or this user does not description: There is no profile information for this user or this
exist. user does not exist.
content: content:
application/json: application/json:
schema: schema:
$ref: definitions/errors/error.yaml $ref: definitions/errors/error.yaml
examples: examples:
response: response:
value: { value:
"errcode": "M_NOT_FOUND", { "errcode": "M_NOT_FOUND", "error": "Profile not found" }
"error": "Profile not found"
}
tags: tags:
- User data - User data
servers: servers:

Loading…
Cancel
Save