diff --git a/changelogs/client_server/newsfragments/2141.feature b/changelogs/client_server/newsfragments/2141.feature new file mode 100644 index 00000000..6eff5607 --- /dev/null +++ b/changelogs/client_server/newsfragments/2141.feature @@ -0,0 +1 @@ +Add the OAuth 2.0 based authentication API, as per [MSC3861](https://github.com/matrix-org/matrix-spec-proposals/pull/3861) and its sub-proposals. diff --git a/changelogs/client_server/newsfragments/2148.feature b/changelogs/client_server/newsfragments/2148.feature new file mode 100644 index 00000000..6eff5607 --- /dev/null +++ b/changelogs/client_server/newsfragments/2148.feature @@ -0,0 +1 @@ +Add the OAuth 2.0 based authentication API, as per [MSC3861](https://github.com/matrix-org/matrix-spec-proposals/pull/3861) and its sub-proposals. diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index d4dfd561..708f1045 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -439,7 +439,7 @@ endpoints it supports. Most API endpoints require the user to identify themselves by presenting previously obtained credentials in the form of an access token. An access token is typically obtained via the [Login](#login) or -[Registration](#account-registration-and-management) processes. Access tokens +[Registration](#account-registration) processes. Access tokens can expire; a new access token can be generated by using a refresh token. {{% boxes/note %}} @@ -494,7 +494,7 @@ used to generate a new access token and refresh token, the new access and refresh tokens are now bound to the device associated with the initial refresh token. -By default, the [Login](#login) and [Registration](#account-registration-and-management) +By default, the [Login](#login) and [Registration](#account-registration) processes auto-generate a new `device_id`. A client is also free to generate its own `device_id` or, provided the user remains the same, reuse a device: in either case the client should pass the `device_id` in @@ -560,9 +560,11 @@ specifying the device ID it is already using to the login API. with an `M_USER_LOCKED` error code, cannot obtain a new access token until the account has been [unlocked](#account-locking). -### User-Interactive Authentication API +### Legacy API -#### Overview +#### User-Interactive Authentication API + +##### Overview Some API endpoints require authentication that interacts with the user. The homeserver may provide many different ways of authenticating, such @@ -586,7 +588,7 @@ the flows in order must result in an HTTP 401 response, as defined below. When all stages in a flow are complete, authentication is complete and the API call succeeds. -#### User-interactive API in the REST API +##### User-interactive API in the REST API In the REST API described in this specification, authentication works by the client and server exchanging JSON dictionaries. The server indicates @@ -764,7 +766,7 @@ auth by offering a stage with only the `m.login.dummy` auth type, but they must still give a 401 response to requests with no auth data. {{% /boxes/note %}} -#### Example +**Example** At a high level, the requests made for an API call completing an auth flow with three stages will resemble the following diagram: @@ -806,7 +808,7 @@ flow with three stages will resemble the following diagram: |_______________________| ``` -#### Authentication types +##### Authentication types This specification defines the following auth types: - `m.login.password` @@ -817,7 +819,7 @@ This specification defines the following auth types: - `m.login.dummy` - `m.login.registration_token` -##### Password-based +###### Password-based | Type | Description | @@ -876,7 +878,7 @@ explicitly as follows: In the case that the homeserver does not know about the supplied 3PID, the homeserver must respond with 403 Forbidden. -##### Google ReCaptcha +###### Google ReCaptcha | Type | Description | |---------------------|------------------------------------------------------| @@ -893,7 +895,7 @@ follows: } ``` -##### Single Sign-On +###### Single Sign-On | Type | Description | |---------------|--------------------------------------------------------------------------------------| @@ -903,7 +905,7 @@ A client wanting to complete authentication using SSO should use the [Fallback](#fallback) mechanism. See [SSO during User-Interactive Authentication](#sso-during-user-interactive-authentication) for more information. -##### Email-based (identity / homeserver) +###### Email-based (identity / homeserver) | Type | Description | |--------------------------|------------------------------------------------------------------------------------------------------------------| @@ -932,7 +934,7 @@ follows: Note that `id_server` (and therefore `id_access_token`) is optional if the [`/requestToken`](#post_matrixclientv3registeremailrequesttoken) request did not include them. -##### Phone number/MSISDN-based (identity / homeserver) +###### Phone number/MSISDN-based (identity / homeserver) | Type | Description | |------------------|----------------------------------------------------------------------------------------------------------------| @@ -961,7 +963,7 @@ follows: Note that `id_server` (and therefore `id_access_token`) is optional if the [`/requestToken`](#post_matrixclientv3registermsisdnrequesttoken) request did not include them. -##### Dummy Auth +###### Dummy Auth | Type | Description | |------------------|------------------------------------------------------------------------| @@ -987,7 +989,7 @@ just the type and session, if provided: } ``` -##### Token-authenticated registration +###### Token-authenticated registration {{% added-in v="1.2" %}} @@ -1031,7 +1033,7 @@ in the registration process that their token has expired. {{% http-api spec="client-server" api="registration_tokens" %}} -##### Terms of service at registration +###### Terms of service at registration {{% added-in v="1.11" %}} @@ -1154,7 +1156,7 @@ user during registration, if applicable. {{% definition path="api/client-server/definitions/m.login.terms_params" %}} -#### Fallback +##### Fallback Clients cannot be expected to be able to know how to process every single login type. If a client does not know how to handle a given login @@ -1195,7 +1197,7 @@ with just the session ID: } ``` -##### Example +**Example** A client webapp might use the following JavaScript to open a popup window which will handle unknown login types: @@ -1251,7 +1253,7 @@ function unknownLoginType(homeserverUrl, apiEndpoint, loginType, sessionID, onCo } ``` -#### Identifier types +##### Identifier types Some authentication mechanisms use a user identifier object to identify a user. The user identifier object has a `type` field to indicate the @@ -1264,7 +1266,7 @@ This specification defines the following identifier types: - `m.id.thirdparty` - `m.id.phone` -##### Matrix User ID +###### Matrix User ID | Type | Description | |-------------|--------------------------------------------| @@ -1281,7 +1283,7 @@ ID. } ``` -##### Third-party ID +###### Third-party ID | Type | Description | |-------------------|---------------------------------------------------------------------------| @@ -1301,7 +1303,7 @@ ID media. } ``` -##### Phone number +###### Phone number | Type | Description | |--------------|-------------------------------------------| @@ -1327,7 +1329,7 @@ The `country` is the two-letter uppercase ISO-3166-1 alpha-2 country code that the number in `phone` should be parsed as if it were dialled from. -### Login +#### Login A client can obtain access tokens using the [`/login`](#post_matrixclientv3login) API. @@ -1399,7 +1401,7 @@ a token for their user ID if supported by the homeserver using {{% http-api spec="client-server" api="logout" %}} -#### Appservice Login +##### Appservice Login {{% added-in v="1.2" %}} @@ -1436,7 +1438,7 @@ If the access token does correspond to an appservice, but the user id does not lie within its namespace then the homeserver will respond with an errcode of `M_EXCLUSIVE`. -#### Login Fallback +##### Login Fallback If a client does not recognize any or all login flows it can use the fallback login API: @@ -1456,11 +1458,13 @@ forwarded to the login endpoint during the login process. For example: GET /_matrix/static/client/login/?device_id=GHTYAJCE -### Account registration and management +#### Account registration {{% http-api spec="client-server" api="registration" %}} -#### Notes on password management +#### Account management + +##### Password management {{% boxes/warning %}} Clients SHOULD enforce that the password provided is suitably complex. @@ -1469,6 +1473,218 @@ number and a symbol and be at a minimum 8 characters in length. Servers MAY reject weak passwords with an error code `M_WEAK_PASSWORD`. {{% /boxes/warning %}} +{{% http-api spec="client-server" api="password_management" %}} + +##### Account deactivation + +{{% http-api spec="client-server" api="account_deactivation" %}} + +### OAuth 2.0 API + +#### Client registration + +Before being able to use the authorization flow to obtain an access token, a +client needs to obtain a `client_id` by registering itself with the server. + +One way to do that is to leverage OAuth 2.0 Dynamic Client Registration as +defined in [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591). + +##### Client metadata + +In OAuth 2.0, clients register a set of metadata values with the authorization +server which associates it to a newly generated `client_id`. These values are +used to describe the client to the user and define how the client interacts with +the server. + +{{% json-schema name="oauth2-client-metadata" %}} + +###### Metadata localization + +As per [RFC 7591 section 2.2](https://tools.ietf.org/html/rfc7591#section-2.2), +all the human-readable metadata values MAY be localized. + +The human-readable values include: +- `client_name` +- `logo_uri` +- `tos_uri` +- `policy-uri` + +For example: + +```json +{ + "client_name": "Digital mailbox", + "client_name#en-US": "Digital mailbox", + "client_name#en-GB": "Digital postbox", + "client_name#fr": "Boîte aux lettres numérique", + "tos_uri": "https://example.com/tos.html", + "tos_uri#fr": "https://example.com/fr/tos.html", + "policy_uri": "https://example.com/policy.html", + "policy_uri#fr": "https://example.com/fr/policy.html" +} +``` + +###### Redirect URI validation + +The redirect URI plays a critical role in validating the authenticity of the +client. The client "proves" its identity by demonstrating that it controls the +redirect URI. This is why it is critical to have strict validation of the +redirect URI. + +The `application_type` metadata is used to determine the type of client. + +In all cases, the redirect URI MUST NOT have a fragment component. + +**Web clients** + +`web` clients can use redirect URIs that: + +- MUST use the `https` scheme +- MUST NOT use a user or password in the authority component of the URI +- MUST use the client URI as a common base for the authority component, as + defined previously +- MAY include an `application/x-www-form-urlencoded` formatted query component + +For example, with `https://example.com/` as the client URI, + +These are valid redirect URIs: +- `https://example.com/callback` +- `https://app.example.com/callback` +- `https://example.com:5173/?query=value` + +These are invalid redirect URIs: +- `https://example.com/callback#fragment` +- `http://example.com/callback` +- `http://localhost/` + +**Native clients** + +`native` clients can use three types of redirect URIs: + +1. Private-Use URI Scheme: + - the scheme MUST be prefixed with the client URI hostname in reverse-DNS + notation. For example, if the client URI is `https://example.com/`, then a + valid custom URI scheme would be `com.example.app:/`. + - the URI MUST NOT have an authority component. This means that it MUST have + either a single slash or none immediately following the scheme, with no + hostname, username, or port. +2. `http` URI on the loopback interface: + - it MUST use the `http` scheme + - the host part MUST be `localhost`, `127.0.0.1`, or `[::1]` + - it MUST have no port. The homeserver MUST then accept any port number during + the authorization flow. +3. Claimed `https` Scheme URI: some operating systems allow apps to claim + `https` scheme URIs in the domains they control. When the browser encounters a + claimed URI, instead of the page being loaded in the browser, the native app + is launched with the URI supplied as a launch parameter. The same rules as for + `web` clients apply. + +These restrictions are the same as defined by [RFC 8252 section 7](https://tools.ietf.org/html/rfc8252#section-7). + +For example, with `https://example.com/` as the client URI, + +These are valid redirect URIs: +- `com.example.app:/callback` +- `com.example:/` +- `com.example:callback` +- `http://localhost/callback` +- `http://127.0.0.1/callback` +- `http://[::1]/callback` + +These are invalid redirect URIs: +- `example:/callback` +- `com.example.app://callback` +- `https://localhost/callback` +- `http://localhost:1234/callback` + +##### Dynamic client registration flow + +To register, the client sends an HTTP `POST` request to the +`registration_endpoint`, which can be found in the server metadata. The body of +the request is the JSON client metadata. + +For example, the client could send the following registration request: + +```http +POST /register HTTP/1.1 +Content-Type: application/json +Accept: application/json +Server: auth.example.com +``` + +```json +{ + "client_name": "My App", + "client_name#fr": "Mon application", + "client_uri": "https://example.com/", + "logo_uri": "https://example.com/logo.png", + "tos_uri": "https://example.com/tos.html", + "tos_uri#fr": "https://example.com/fr/tos.html", + "policy_uri": "https://example.com/policy.html", + "policy_uri#fr": "https://example.com/fr/policy.html", + "redirect_uris": ["https://app.example.com/callback"], + "token_endpoint_auth_method": "none", + "response_types": ["code"], + "grant_types": [ + "authorization_code", + "refresh_token", + "urn:ietf:params:oauth:grant-type:token-exchange" + ], + "application_type": "web" +} +``` + +Upon successful registration, the server replies with an `HTTP 201 Created` +response, with a JSON object containing the allocated `client_id` and all the +registered metadata values. + +With the previous registration request, the server would reply with: + +```json +{ + "client_id": "s6BhdRkqt3", + "client_name": "My App", + "client_uri": "https://example.com/", + "logo_uri": "https://example.com/logo.png", + "tos_uri": "https://example.com/tos.html", + "policy_uri": "https://example.com/policy.html", + "redirect_uris": ["https://app.example.com/callback"], + "token_endpoint_auth_method": "none", + "response_types": ["code"], + "grant_types": ["authorization_code", "refresh_token"], + "application_type": "web" +} +``` + +In this example, the server has not registered the locale-specific values for +`client_name`, `tos_uri`, and `policy_uri`, which is why they are not present in +the response. The server also does not support the +`urn:ietf:params:oauth:grant-type:token-exchange` grant type, which is why it is +not present in the response. + +The client MUST store the `client_id` for future use. + +To avoid the number of client registrations growing over time, the server MAY +choose to delete client registrations that don't have an active session. The +server MUST NOT delete client registrations that have an active session. + +Clients MUST perform a new client registration at the start of each +authorization flow. + +{{% boxes/note %}} +Because each client on each user device will do its own registration, they may +all have different `client_id`s. This means that the server may store the same +client registration multiple times, which could lead to a large number of client +registrations. + +This can be mitigated by de-duplicating client registrations that have identical +metadata. By doing so, different users on different devices using the same +client can share a single `client_id`, reducing the overall number of +registrations. +{{% /boxes/note %}} + +### Account moderation + #### Account locking {{% added-in v="1.12" %}} diff --git a/data/api/client-server/account_deactivation.yaml b/data/api/client-server/account_deactivation.yaml new file mode 100644 index 00000000..467af659 --- /dev/null +++ b/data/api/client-server/account_deactivation.yaml @@ -0,0 +1,141 @@ +# Copyright 2016 OpenMarket Ltd +# Copyright 2022 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. +openapi: 3.1.0 +info: + title: Matrix Client-Server Account Deactivation API + version: 1.0.0 +paths: + /account/deactivate: + post: + summary: Deactivate a user's account. + description: |- + Deactivate the user's account, removing all ability for the user to + login again. + + This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api). + + An access token should be submitted to this endpoint if the client has + an active session. + + The homeserver may change the flows available depending on whether a + valid access token is provided. + + 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. + security: + - {} + - accessTokenQuery: [] + - accessTokenBearer: [] + operationId: deactivateAccount + requestBody: + content: + application/json: + schema: + type: object + properties: + auth: + description: Additional authentication information for the user-interactive + authentication API. + allOf: + - $ref: definitions/auth_data.yaml + id_server: + type: string + description: |- + The identity server to unbind all of the user's 3PIDs from. + If not provided, the homeserver MUST use the `id_server` + that was originally use to bind each identifier. If the + homeserver does not know which `id_server` that was, + it must return an `id_server_unbind_result` of + `no-support`. + example: example.org + erase: + x-addedInMatrixVersion: "1.10" + type: boolean + description: |- + Whether the user would like their content to be erased as + much as possible from the server. + + Erasure means that any users (or servers) which join the + room after the erasure request are served redacted copies of + the events sent by this account. Users which had visibility + on those events prior to the erasure are still able to see + unredacted copies. No redactions are sent and the erasure + request is not shared over federation, so other servers + might still serve unredacted copies. + + The server should additionally erase any non-event data + associated with the user, such as [account data](/client-server-api/#client-config) + and [contact 3PIDs](/client-server-api/#adding-account-administrative-contact-information). + + Defaults to `false` if not present. + required: true + responses: + "200": + description: The account has been deactivated. + content: + application/json: + schema: + type: object + properties: + id_server_unbind_result: + type: string + enum: + - success + - no-support + description: |- + An indicator as to whether or not the homeserver was able to unbind + the user's 3PIDs from the identity server(s). `success` indicates + that all identifiers have been unbound from the identity server while + `no-support` indicates that one or more identifiers failed to unbind + due to the identity server refusing the request or the homeserver + being unable to determine an identity server to unbind from. This + must be `success` if the homeserver has no identifiers to unbind + for the user. + example: success + required: + - id_server_unbind_result + "401": + description: The homeserver requires additional authentication information. + content: + application/json: + schema: + $ref: definitions/auth_response.yaml + "429": + description: This request was rate-limited. + content: + application/json: + schema: + $ref: definitions/errors/rate_limited.yaml + tags: + - Account management +servers: + - url: "{protocol}://{hostname}{basePath}" + variables: + protocol: + enum: + - http + - https + default: https + hostname: + default: localhost:8008 + basePath: + default: /_matrix/client/v3 +components: + securitySchemes: + accessTokenQuery: + $ref: definitions/security.yaml#/accessTokenQuery + accessTokenBearer: + $ref: definitions/security.yaml#/accessTokenBearer diff --git a/data/api/client-server/password_management.yaml b/data/api/client-server/password_management.yaml new file mode 100644 index 00000000..bf310ff9 --- /dev/null +++ b/data/api/client-server/password_management.yaml @@ -0,0 +1,242 @@ +# Copyright 2016 OpenMarket Ltd +# Copyright 2022 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. +openapi: 3.1.0 +info: + title: Matrix Client-Server Password Management API + version: 1.0.0 +paths: + /account/password: + post: + summary: Changes a user's password. + description: |- + Changes the password for an account on this homeserver. + + This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api) to + ensure the user changing the password is actually the owner of the + account. + + An access token should be submitted to this endpoint if the client has + an active session. + + The homeserver may change the flows available depending on whether a + valid access token is provided. The homeserver SHOULD NOT revoke the + access token provided in the request. Whether other access tokens for + the user are revoked depends on the request parameters. + security: + - {} + - accessTokenQuery: [] + - accessTokenBearer: [] + operationId: changePassword + requestBody: + content: + application/json: + schema: + type: object + properties: + new_password: + type: string + description: The new password for the account. + example: ihatebananas + logout_devices: + type: boolean + description: |- + Whether the user's other access tokens, and their associated devices, should be + revoked if the request succeeds. Defaults to true. + + When `false`, the server can still take advantage of the [soft logout method](/client-server-api/#soft-logout) + for the user's remaining devices. + example: true + auth: + description: Additional authentication information for the user-interactive + authentication API. + allOf: + - $ref: definitions/auth_data.yaml + required: + - new_password + required: true + responses: + "200": + description: The password has been changed. + content: + application/json: + schema: + type: object + examples: + response: + value: {} + "401": + description: The homeserver requires additional authentication information. + content: + application/json: + schema: + $ref: definitions/auth_response.yaml + "429": + description: This request was rate-limited. + content: + application/json: + schema: + $ref: definitions/errors/rate_limited.yaml + tags: + - Account management + /account/password/email/requestToken: + post: + summary: Requests a validation token be sent to the given email address for the + purpose of resetting a user's password + description: |- + The homeserver must check that the given email address **is + associated** with an account on this homeserver. This API should be + used to request validation tokens when authenticating for the + `/account/password` endpoint. + + This API's parameters and response are identical to that of the + [`/register/email/requestToken`](/client-server-api/#post_matrixclientv3registeremailrequesttoken) + endpoint, except that + `M_THREEPID_NOT_FOUND` may be returned if no account matching the + given email address could be found. The server may instead send an + email to the given address prompting the user to create an account. + `M_THREEPID_IN_USE` may not be returned. + + The homeserver should validate the email itself, either by sending a + validation email itself or by using a service it has control over. + operationId: requestTokenToResetPasswordEmail + requestBody: + content: + application/json: + schema: + $ref: definitions/request_email_validation.yaml + required: true + responses: + "200": + description: An email was sent to the given address. + content: + application/json: + schema: + $ref: definitions/request_token_response.yaml + "400": + description: |- + The referenced third-party identifier is not recognised by the + homeserver, or the request was invalid. The error code `M_SERVER_NOT_TRUSTED` + can be returned if the server does not trust/support the identity server + provided in the request. + content: + application/json: + schema: + $ref: definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_THREEPID_NOT_FOUND", + "error": "Email not found" + } + "403": + description: |- + The homeserver does not allow the third-party identifier as a + contact option. + content: + application/json: + schema: + $ref: definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_THREEPID_DENIED", + "error": "Third-party identifier is not allowed" + } + tags: + - Account management + /account/password/msisdn/requestToken: + post: + summary: Requests a validation token be sent to the given phone number for the + purpose of resetting a user's password. + description: |- + The homeserver must check that the given phone number **is + associated** with an account on this homeserver. This API should be + used to request validation tokens when authenticating for the + `/account/password` endpoint. + + This API's parameters and response are identical to that of the + [`/register/msisdn/requestToken`](/client-server-api/#post_matrixclientv3registermsisdnrequesttoken) + endpoint, except that + `M_THREEPID_NOT_FOUND` may be returned if no account matching the + given phone number could be found. The server may instead send the SMS + to the given phone number prompting the user to create an account. + `M_THREEPID_IN_USE` may not be returned. + + The homeserver should validate the phone number itself, either by sending a + validation message itself or by using a service it has control over. + operationId: requestTokenToResetPasswordMSISDN + requestBody: + content: + application/json: + schema: + $ref: definitions/request_msisdn_validation.yaml + required: true + responses: + "200": + description: An SMS message was sent to the given phone number. + content: + application/json: + schema: + $ref: definitions/request_token_response.yaml + "400": + description: |- + The referenced third-party identifier is not recognised by the + homeserver, or the request was invalid. The error code `M_SERVER_NOT_TRUSTED` + can be returned if the server does not trust/support the identity server + provided in the request. + content: + application/json: + schema: + $ref: definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_THREEPID_NOT_FOUND", + "error": "Phone number not found" + } + "403": + description: |- + The homeserver does not allow the third-party identifier as a + contact option. + content: + application/json: + schema: + $ref: definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_THREEPID_DENIED", + "error": "Third-party identifier is not allowed" + } + tags: + - Account management +servers: + - url: "{protocol}://{hostname}{basePath}" + variables: + protocol: + enum: + - http + - https + default: https + hostname: + default: localhost:8008 + basePath: + default: /_matrix/client/v3 +components: + securitySchemes: + accessTokenQuery: + $ref: definitions/security.yaml#/accessTokenQuery + accessTokenBearer: + $ref: definitions/security.yaml#/accessTokenBearer diff --git a/data/api/client-server/registration.yaml b/data/api/client-server/registration.yaml index a418d2d2..e7ede561 100644 --- a/data/api/client-server/registration.yaml +++ b/data/api/client-server/registration.yaml @@ -373,315 +373,6 @@ paths: } tags: - Account management - /account/password: - post: - summary: Changes a user's password. - description: |- - Changes the password for an account on this homeserver. - - This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api) to - ensure the user changing the password is actually the owner of the - account. - - An access token should be submitted to this endpoint if the client has - an active session. - - The homeserver may change the flows available depending on whether a - valid access token is provided. The homeserver SHOULD NOT revoke the - access token provided in the request. Whether other access tokens for - the user are revoked depends on the request parameters. - security: - - {} - - accessTokenQuery: [] - - accessTokenBearer: [] - operationId: changePassword - requestBody: - content: - application/json: - schema: - type: object - properties: - new_password: - type: string - description: The new password for the account. - example: ihatebananas - logout_devices: - type: boolean - description: |- - Whether the user's other access tokens, and their associated devices, should be - revoked if the request succeeds. Defaults to true. - - When `false`, the server can still take advantage of the [soft logout method](/client-server-api/#soft-logout) - for the user's remaining devices. - example: true - auth: - description: Additional authentication information for the user-interactive - authentication API. - allOf: - - $ref: definitions/auth_data.yaml - required: - - new_password - required: true - responses: - "200": - description: The password has been changed. - content: - application/json: - schema: - type: object - examples: - response: - value: {} - "401": - description: The homeserver requires additional authentication information. - content: - application/json: - schema: - $ref: definitions/auth_response.yaml - "429": - description: This request was rate-limited. - content: - application/json: - schema: - $ref: definitions/errors/rate_limited.yaml - tags: - - Account management - /account/password/email/requestToken: - post: - summary: Requests a validation token be sent to the given email address for the - purpose of resetting a user's password - description: |- - The homeserver must check that the given email address **is - associated** with an account on this homeserver. This API should be - used to request validation tokens when authenticating for the - `/account/password` endpoint. - - This API's parameters and response are identical to that of the - [`/register/email/requestToken`](/client-server-api/#post_matrixclientv3registeremailrequesttoken) - endpoint, except that - `M_THREEPID_NOT_FOUND` may be returned if no account matching the - given email address could be found. The server may instead send an - email to the given address prompting the user to create an account. - `M_THREEPID_IN_USE` may not be returned. - - The homeserver should validate the email itself, either by sending a - validation email itself or by using a service it has control over. - operationId: requestTokenToResetPasswordEmail - requestBody: - content: - application/json: - schema: - $ref: definitions/request_email_validation.yaml - required: true - responses: - "200": - description: An email was sent to the given address. - content: - application/json: - schema: - $ref: definitions/request_token_response.yaml - "400": - description: |- - The referenced third-party identifier is not recognised by the - homeserver, or the request was invalid. The error code `M_SERVER_NOT_TRUSTED` - can be returned if the server does not trust/support the identity server - provided in the request. - content: - application/json: - schema: - $ref: definitions/errors/error.yaml - examples: - response: - value: { - "errcode": "M_THREEPID_NOT_FOUND", - "error": "Email not found" - } - "403": - description: |- - The homeserver does not allow the third-party identifier as a - contact option. - content: - application/json: - schema: - $ref: definitions/errors/error.yaml - examples: - response: - value: { - "errcode": "M_THREEPID_DENIED", - "error": "Third-party identifier is not allowed" - } - tags: - - Account management - /account/password/msisdn/requestToken: - post: - summary: Requests a validation token be sent to the given phone number for the - purpose of resetting a user's password. - description: |- - The homeserver must check that the given phone number **is - associated** with an account on this homeserver. This API should be - used to request validation tokens when authenticating for the - `/account/password` endpoint. - - This API's parameters and response are identical to that of the - [`/register/msisdn/requestToken`](/client-server-api/#post_matrixclientv3registermsisdnrequesttoken) - endpoint, except that - `M_THREEPID_NOT_FOUND` may be returned if no account matching the - given phone number could be found. The server may instead send the SMS - to the given phone number prompting the user to create an account. - `M_THREEPID_IN_USE` may not be returned. - - The homeserver should validate the phone number itself, either by sending a - validation message itself or by using a service it has control over. - operationId: requestTokenToResetPasswordMSISDN - requestBody: - content: - application/json: - schema: - $ref: definitions/request_msisdn_validation.yaml - required: true - responses: - "200": - description: An SMS message was sent to the given phone number. - content: - application/json: - schema: - $ref: definitions/request_token_response.yaml - "400": - description: |- - The referenced third-party identifier is not recognised by the - homeserver, or the request was invalid. The error code `M_SERVER_NOT_TRUSTED` - can be returned if the server does not trust/support the identity server - provided in the request. - content: - application/json: - schema: - $ref: definitions/errors/error.yaml - examples: - response: - value: { - "errcode": "M_THREEPID_NOT_FOUND", - "error": "Phone number not found" - } - "403": - description: |- - The homeserver does not allow the third-party identifier as a - contact option. - content: - application/json: - schema: - $ref: definitions/errors/error.yaml - examples: - response: - value: { - "errcode": "M_THREEPID_DENIED", - "error": "Third-party identifier is not allowed" - } - tags: - - Account management - /account/deactivate: - post: - summary: Deactivate a user's account. - description: |- - Deactivate the user's account, removing all ability for the user to - login again. - - This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api). - - An access token should be submitted to this endpoint if the client has - an active session. - - The homeserver may change the flows available depending on whether a - valid access token is provided. - - 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. - security: - - {} - - accessTokenQuery: [] - - accessTokenBearer: [] - operationId: deactivateAccount - requestBody: - content: - application/json: - schema: - type: object - properties: - auth: - description: Additional authentication information for the user-interactive - authentication API. - allOf: - - $ref: definitions/auth_data.yaml - id_server: - type: string - description: |- - The identity server to unbind all of the user's 3PIDs from. - If not provided, the homeserver MUST use the `id_server` - that was originally use to bind each identifier. If the - homeserver does not know which `id_server` that was, - it must return an `id_server_unbind_result` of - `no-support`. - example: example.org - erase: - x-addedInMatrixVersion: "1.10" - type: boolean - description: |- - Whether the user would like their content to be erased as - much as possible from the server. - - Erasure means that any users (or servers) which join the - room after the erasure request are served redacted copies of - the events sent by this account. Users which had visibility - on those events prior to the erasure are still able to see - unredacted copies. No redactions are sent and the erasure - request is not shared over federation, so other servers - might still serve unredacted copies. - - The server should additionally erase any non-event data - associated with the user, such as [account data](/client-server-api/#client-config) - and [contact 3PIDs](/client-server-api/#adding-account-administrative-contact-information). - - Defaults to `false` if not present. - required: true - responses: - "200": - description: The account has been deactivated. - content: - application/json: - schema: - type: object - properties: - id_server_unbind_result: - type: string - enum: - - success - - no-support - description: |- - An indicator as to whether or not the homeserver was able to unbind - the user's 3PIDs from the identity server(s). `success` indicates - that all identifiers have been unbound from the identity server while - `no-support` indicates that one or more identifiers failed to unbind - due to the identity server refusing the request or the homeserver - being unable to determine an identity server to unbind from. This - must be `success` if the homeserver has no identifiers to unbind - for the user. - example: success - required: - - id_server_unbind_result - "401": - description: The homeserver requires additional authentication information. - content: - application/json: - schema: - $ref: definitions/auth_response.yaml - "429": - description: This request was rate-limited. - content: - application/json: - schema: - $ref: definitions/errors/rate_limited.yaml - tags: - - Account management /register/available: get: summary: Checks to see if a username is available on the server. diff --git a/data/schemas/oauth2-client-metadata.yaml b/data/schemas/oauth2-client-metadata.yaml new file mode 100644 index 00000000..cb52d025 --- /dev/null +++ b/data/schemas/oauth2-client-metadata.yaml @@ -0,0 +1,140 @@ +# Copyright 2025 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: OAuth 2.0 Client Server Metadata +type: object +description: |- + This definition of the metadata specifies only the fields that are meaningful + in the context of the Matrix specification. All the possible values are + registered in the [OAuth Dynamic Client Registration Metadata registry](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#client-metadata), + and normative definitions of them are available in their respective RFCs. +properties: + client_uri: + type: string + format: uri + description: |- + A URL to a valid web page that SHOULD give the user more information about + the client. + + This URL MUST use the `https` scheme and SHOULD NOT require authentication + to access. It MUST NOT use a user or password in the authority component + of the URI. + + The server MAY reject client registrations if this field is invalid or + missing. + + This URI is a common base for all the other URIs in the metadata: those + MUST be either on the same host or on a subdomain of the host of the + `client_uri`. The port number, path and query components MAY be different. + + For example, if the `client_uri` is `https://example.com/`, then one of + the `redirect_uris` can be `https://example.com/callback` or + `https://app.example.com/callback`, but not `https://app.com/callback`. + client_name: + type: string + description: |- + Human-readable name of the client to be presented to the user. + + This field can be [localized](/client-server-api/#metadata-localization). + logo_uri: + type: string + format: uri + description: |- + URL that references a logo for the client. + + This URL MUST use the `https` scheme. + + This field can be [localized](/client-server-api/#metadata-localization). + tos_uri: + type: string + format: uri + description: |- + URL that points to a human-readable terms of service document for the + client. + + This URL MUST use the `https` scheme and SHOULD NOT require authentication + to access. It MUST NOT use a user or password in the authority component + of the URI. + + If this field is set, the server SHOULD show or link to this URL. + + This field can be [localized](/client-server-api/#metadata-localization). + policy_uri: + type: string + format: uri + description: |- + URL that points to a human-readable policy document for the client. + + This URL MUST use the `https` scheme and SHOULD NOT require authentication + to access. It MUST NOT use a user or password in the authority component + of the URI. + + If this field is set, the server SHOULD show or link to this URL. + + This field can be [localized](/client-server-api/#metadata-localization). + redirect_uris: + type: array + description: |- + Array of redirection URIs for use in redirect-based flows. + + At least one URI is required to use the authorization code grant. + + The server MUST perform [validation on redirect URIs](/client-server-api/#redirect-uri-validation). + items: + type: string + format: uri + description: A redirection URI. + response_types: + type: array + description: |- + Array of the OAuth 2.0 response types that the client may use. + + This MUST include the `code` value to use the authorization code grant. + + The server MUST ignore values that it does not understand. + items: + type: string + description: A response type that the client may use. + grant_types: + type: array + description: |- + Array of the OAuth 2.0 grant types that the client may use. + + This MUST include: + - the `authorization_code` value to use the authorization code grant, + - the `refresh_token` value to use the refresh token grant. + + The server MUST ignore values that it does not understand. + items: + type: string + description: A grant type that the client may use. + token_endpoint_auth_method: + type: string + description: |- + String indicator of the requested authentication method for the token + endpoint. + + The homeserver MUST support the `none` value, as most Matrix clients are + client-side only, do not have a server component, and therefore are public + clients. + application_type: + type: string + description: |- + Kind of the application. + + The homeserver MUST support the `web` and `native` values to be able to + perform [redirect URI validation](/client-server-api/#redirect-uri-validation). + + Defaults to `web` if omitted. +required: + - client_uri diff --git a/layouts/shortcodes/json-schema.html b/layouts/shortcodes/json-schema.html new file mode 100644 index 00000000..632ed03d --- /dev/null +++ b/layouts/shortcodes/json-schema.html @@ -0,0 +1,46 @@ +{{/* + + This template is used to render the fields of a JSON schema that is not an + event. + + It expects to be passed a `name` parameter, which is the name of a file + under /data/schemas. The file extension is omitted. + + For example: + + {{% json-schema name="oauth2-client-metadata" %}} + +*/}} + +{{ $schema := index .Site.Data "schemas" .Params.name }} +{{ $path := delimit (slice "schemas" .Params.name) "/" }} + +{{ $schema = partial "json-schema/resolve-refs" (dict "schema" $schema "path" $path) }} +{{ $schema = partial "json-schema/resolve-allof" $schema }} + +
+ +
+ + +

+ {{ $schema.title }} +

+
+ +
+ +{{ if $schema.description -}} + {{ $schema.description | markdownify -}} +{{ end -}} + +{{ $schema = merge $schema (dict "title" "") -}} + +{{ $additional_types := partial "json-schema/resolve-additional-types" (dict "schema" $schema) -}} +{{ range $additional_types -}} + {{ partial "openapi/render-object-table" . -}} +{{ end -}} + +
+ +