diff --git a/changelogs/application_service/newsfragments/1744.clarification b/changelogs/application_service/newsfragments/1744.clarification new file mode 100644 index 00000000..908c48ab --- /dev/null +++ b/changelogs/application_service/newsfragments/1744.clarification @@ -0,0 +1 @@ +Clarify that the `/login` and `/register` endpoints should fail when using the `m.login.application_service` login type without a valid `as_token`. diff --git a/changelogs/client_server/newsfragments/1735.feature b/changelogs/client_server/newsfragments/1735.feature new file mode 100644 index 00000000..1d764142 --- /dev/null +++ b/changelogs/client_server/newsfragments/1735.feature @@ -0,0 +1 @@ +Add support for multi-stream VoIP, as per [MSC3077](https://github.com/matrix-org/matrix-spec-proposals/pull/3077). \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1748.clarification b/changelogs/client_server/newsfragments/1748.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/client_server/newsfragments/1748.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. diff --git a/changelogs/internal/newsfragments/1718.clarification b/changelogs/internal/newsfragments/1718.clarification new file mode 100644 index 00000000..5b89875a --- /dev/null +++ b/changelogs/internal/newsfragments/1718.clarification @@ -0,0 +1 @@ +Add some clarifications around implementation requirements for MSCs diff --git a/changelogs/internal/newsfragments/1745.clarification b/changelogs/internal/newsfragments/1745.clarification new file mode 100644 index 00000000..acd85892 --- /dev/null +++ b/changelogs/internal/newsfragments/1745.clarification @@ -0,0 +1 @@ +Factor out all the common parameters of the various `/relations` apis. diff --git a/changelogs/internal/newsfragments/1751.clarification b/changelogs/internal/newsfragments/1751.clarification new file mode 100644 index 00000000..50c50693 --- /dev/null +++ b/changelogs/internal/newsfragments/1751.clarification @@ -0,0 +1 @@ +Add support for `$ref` URIs containing fragments in OpenAPI definitions and JSON schemas. diff --git a/content/application-service-api.md b/content/application-service-api.md index f3db06cf..a7526e64 100644 --- a/content/application-service-api.md +++ b/content/application-service-api.md @@ -436,6 +436,12 @@ an application service-defined namespace will receive the same `M_EXCLUSIVE` error code, but only if the application service has defined the namespace as `exclusive`. +If `/register` or `/login` is called with the `m.login.application_service` +login type, but without a valid `as_token`, the endpoints will return an error +with the `M_MISSING_TOKEN` or `M_UNKNOWN_TOKEN` error code and 401 as the HTTP +status code. This is the same behavior as invalid auth in the client-server API +(see [Using access tokens](/client-server-api/#using-access-tokens)). + #### Pinging {{% added-in v="1.7" %}} diff --git a/content/client-server-api/modules/sso_login.md b/content/client-server-api/modules/sso_login.md index 95a3e23a..1a46c84d 100644 --- a/content/client-server-api/modules/sso_login.md +++ b/content/client-server-api/modules/sso_login.md @@ -10,7 +10,7 @@ This module allows a Matrix homeserver to delegate user authentication to an external authentication server supporting one of these protocols. In this process, there are three systems involved: -- A Matrix client, using the APIs defined this specification, which +- A Matrix client, using the APIs defined in this specification, which is seeking to authenticate a user to a Matrix homeserver. - A Matrix homeserver, implementing the APIs defined in this specification, but which is delegating user authentication to the diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index 102e3dcd..4df0ba13 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -171,18 +171,31 @@ In response to an incoming invite, a client may do one of several things: ##### Streams -Clients are expected to send one stream with one track of kind `audio` (creating a -voice call). They can optionally send a second track in the same stream of kind -`video` (creating a video call). +Clients may send more than one stream in a VoIP call. The streams should be +differentiated by including metadata in the [`m.call.invite`](/client-server-api/#mcallinvite), +[`m.call.answer`](/client-server-api/#mcallanswer) and [`m.call.negotiate`](/client-server-api/#mcallnegotiate) +events, using the `sdp_stream_metadata` property. -Clients implementing this specification use the first stream and will ignore -any streamless tracks. Note that in the JavaScript WebRTC API, this means -`addTrack()` must be passed two parameters: a track and a stream, not just a -track, and in a video call the stream must be the same for both audio and video -track. +`sdp_stream_metadata` maps from the `id` of a stream in the session description, +to metadata about that stream. Currently only one property is defined for the +metadata. This is `purpose`, which should be a string indicating the purpose of +the stream. The following `purpose`s are defined: -A client may send other streams and tracks but the behaviour of the other party -with respect to presenting such streams and tracks is undefined. +* `m.usermedia` - stream that contains the webcam and/or microphone tracks +* `m.screenshare` - stream with the screen-sharing tracks + +If `sdp_stream_metadata` is present and an incoming stream is not listed in it, +the stream should be ignored. If a stream has a `purpose` of an unknown type, it +should also be ignored. + +For backwards compatibility, if `sdp_stream_metadata` is not present in the +initial [`m.call.invite`](/client-server-api/#mcallinvite) or [`m.call.answer`](/client-server-api/#mcallanswer) +event sent by the other party, the client should assume that this property is +not supported by the other party. It means that multiple streams cannot be +differentiated: the client should only use the first incoming stream and +shouldn't send more than one stream. + +Clients implementing this specification should ignore any streamless tracks. ##### Invitees The `invitee` field should be added whenever the call is intended for one diff --git a/content/proposals.md b/content/proposals.md index dac520c9..b58a98be 100644 --- a/content/proposals.md +++ b/content/proposals.md @@ -380,9 +380,18 @@ As part of the proposal process the Spec Core Team will require evidence of the MSC working in order for it to move into FCP. This can usually be a branch/pull request to whichever implementation of choice that proves the MSC works in practice, though in some cases the MSC itself will be -small enough to be considered proven. Where it's unclear if an MSC will -require an implementation proof, ask in -[\#matrix-spec:matrix.org](https://matrix.to/#/#matrix-spec:matrix.org). +small enough to be considered proven. Implementations do not need to be +merged or released, but must be of sufficient quality to show that the +MSC works. Where it's unclear if an MSC will require an implementation +proof, ask in [\#matrix-spec:matrix.org](https://matrix.to/#/#matrix-spec:matrix.org). +Proposals may require both server-side and client-side implementations. + +Proposals that have not yet been implemented will have the +`needs-implementation` label. After an implementation has been made, add a +comment in the GitHub issue indicating so. After an implementation has been +made, we will check it to verify that it implements the MSC. Proposals that +have implementations that have not yet been checked will have the +`implementation-needs-checking` label. ### Early release of an MSC/idea diff --git a/data/api/client-server/relations.yaml b/data/api/client-server/relations.yaml index 255a8061..c43ea2f3 100644 --- a/data/api/client-server/relations.yaml +++ b/data/api/client-server/relations.yaml @@ -33,89 +33,13 @@ paths: security: - accessToken: [] parameters: - - in: path - name: roomId - description: The ID of the room containing the parent event. - required: true - example: "!636q39766251:matrix.org" - schema: - type: string - - in: path - name: eventId - description: The ID of the parent event whose child events are to be returned. - required: true - example: $asfDuShaf7Gafaw - schema: - type: string - - in: query - name: from - description: |- - The pagination token to start returning results from. If not supplied, results - start at the most recent topological event known to the server. - - Can be a `next_batch` or `prev_batch` token from a previous call, or a returned - `start` token from [`/messages`](/client-server-api/#get_matrixclientv3roomsroomidmessages), - or a `next_batch` token from [`/sync`](/client-server-api/#get_matrixclientv3sync). - required: false - example: page2_token - schema: - type: string - - in: query - name: to - description: |- - The pagination token to stop returning results at. If not supplied, results - continue up to `limit` or until there are no more events. - - Like `from`, this can be a previous token from a prior call to this endpoint - or from `/messages` or `/sync`. - required: false - example: page3_token - schema: - type: string - - in: query - name: limit - description: |- - The maximum number of results to return in a single `chunk`. The server can - and should apply a maximum value to this parameter to avoid large responses. - - Similarly, the server should apply a default value when not supplied. - required: false - example: 20 - schema: - type: integer - - in: query - name: dir - x-addedInMatrixVersion: "1.4" - description: |- - Optional (default `b`) direction to return events from. If this is set to `f`, events - will be returned in chronological order starting at `from`. If it - is set to `b`, events will be returned in *reverse* chronological - order, again starting at `from`. - schema: - type: string - enum: - - b - - f - - in: query - name: recurse - x-addedInMatrixVersion: "1.10" - required: false - description: |- - Whether to additionally include events which only relate indirectly to the - given event, ie. events related to the root events via one or more direct relationships. - - If set to `false`, only events which have direct a relation with the given - event will be included. - - If set to `true`, all events which relate to the given event, or relate to - events that relate to the given event, will be included. - - It is recommended that at least 3 levels of relationships are traversed. - Implementations may perform more but should be careful to not infinitely recurse. - - The default value is `false`. - schema: - type: boolean + - $ref: '#/components/parameters/roomId' + - $ref: '#/components/parameters/eventId' + - $ref: '#/components/parameters/from' + - $ref: '#/components/parameters/to' + - $ref: '#/components/parameters/limit' + - $ref: '#/components/parameters/dir' + - $ref: '#/components/parameters/recurse' responses: # note: this endpoint deliberately does not support rate limiting, therefore a # 429 error response is not included. @@ -127,66 +51,24 @@ paths: content: application/json: schema: - type: object - properties: - chunk: - title: ChildEventsChunk - type: array - description: The child events of the requested event, ordered topologically - most-recent first. - items: - allOf: - - $ref: definitions/client_event.yaml - next_batch: - type: string - description: |- - An opaque string representing a pagination token. The absence of this token - means there are no more results to fetch and the client should stop paginating. - prev_batch: - type: string - description: |- - An opaque string representing a pagination token. The absence of this token - means this is the start of the result set, i.e. this is the first batch/page. - recursion_depth: - type: integer - description: |- - If the `recurse` parameter was supplied by the client, this response field is - mandatory and gives the actual depth to which the server recursed. The the client - did not specify the `recurse` parameter, this field must be absent. - required: - - chunk + allOf: + - $ref: '#/components/schemas/response' + - type: object + properties: + chunk: + title: ChildEventsChunk + type: array + description: The child events of the requested event, ordered topologically + most-recent first. + items: + $ref: definitions/client_event.yaml + required: + - chunk examples: response: - value: { - "chunk": [ - { - "room_id": "!636q39766251:matrix.org", - "$ref": "../../event-schemas/examples/m.room.message$m.text.yaml", - "content": { - "m.relates_to": { - "rel_type": "org.example.my_relation", - "event_id": "$asfDuShaf7Gafaw" - } - } - } - ], - "next_batch": "page2_token", - "prev_batch": "page1_token" - } + $ref: '#/components/examples/response' "404": - description: |- - The parent event was not found or the user does not have permission to read - this event (it might be contained in history that is not accessible to the user). - content: - application/json: - schema: - $ref: definitions/errors/error.yaml - examples: - response: - value: { - "errcode": "M_NOT_FOUND", - "error": "Event not found." - } + $ref: '#/components/responses/404' tags: - Event relationships # The same as above, with added `/{relType}` @@ -208,97 +90,14 @@ paths: security: - accessToken: [] parameters: - - in: path - name: roomId - description: The ID of the room containing the parent event. - required: true - example: "!636q39766251:matrix.org" - schema: - type: string - - in: path - name: eventId - description: The ID of the parent event whose child events are to be returned. - required: true - example: $asfDuShaf7Gafaw - schema: - type: string - - in: path - name: relType - description: The [relationship type](/client-server-api/#relationship-types) to - search for. - required: true - example: org.example.my_relation - schema: - type: string - - in: query - name: from - description: |- - The pagination token to start returning results from. If not supplied, results - start at the most recent topological event known to the server. - - Can be a `next_batch` or `prev_batch` token from a previous call, or a returned - `start` token from [`/messages`](/client-server-api/#get_matrixclientv3roomsroomidmessages), - or a `next_batch` token from [`/sync`](/client-server-api/#get_matrixclientv3sync). - required: false - example: page2_token - schema: - type: string - - in: query - name: to - description: |- - The pagination token to stop returning results at. If not supplied, results - continue up to `limit` or until there are no more events. - - Like `from`, this can be a previous token from a prior call to this endpoint - or from `/messages` or `/sync`. - required: false - example: page3_token - schema: - type: string - - in: query - name: limit - description: |- - The maximum number of results to return in a single `chunk`. The server can - and should apply a maximum value to this parameter to avoid large responses. - - Similarly, the server should apply a default value when not supplied. - required: false - example: 20 - schema: - type: integer - - in: query - name: dir - x-addedInMatrixVersion: "1.4" - description: |- - Optional (default `b`) direction to return events from. If this is set to `f`, events - will be returned in chronological order starting at `from`. If it - is set to `b`, events will be returned in *reverse* chronological - order, again starting at `from`. - schema: - type: string - enum: - - b - - f - - in: query - name: recurse - x-addedInMatrixVersion: "1.10" - required: false - description: |- - Whether to additionally include events which only relate indirectly to the - given event, ie. events related to the root events via one or more direct relationships. - - If set to `false`, only events which have direct a relation with the given - event will be included. - - If set to `true`, all events which relate to the given event, or relate to - events that relate to the given event, will be included. - - It is recommended that at least 3 levels of relationships are traversed. - Implementations may perform more but should be careful to not infinitely recurse. - - The default value is `false`. - schema: - type: boolean + - $ref: '#/components/parameters/roomId' + - $ref: '#/components/parameters/eventId' + - $ref: '#/components/parameters/relType' + - $ref: '#/components/parameters/from' + - $ref: '#/components/parameters/to' + - $ref: '#/components/parameters/limit' + - $ref: '#/components/parameters/dir' + - $ref: '#/components/parameters/recurse' responses: # note: this endpoint deliberately does not support rate limiting, therefore a # 429 error response is not included. @@ -310,68 +109,26 @@ paths: content: application/json: schema: - type: object - properties: - chunk: - title: ChildEventsChunk - type: array - description: |- - The child events of the requested event, ordered topologically - most-recent first. The events returned will match the `relType` - supplied in the URL. - items: - allOf: - - $ref: definitions/client_event.yaml - next_batch: - type: string - description: |- - An opaque string representing a pagination token. The absence of this token - means there are no more results to fetch and the client should stop paginating. - prev_batch: - type: string - description: |- - An opaque string representing a pagination token. The absence of this token - means this is the start of the result set, i.e. this is the first batch/page. - recursion_depth: - type: integer - description: |- - If the `recurse` parameter was supplied by the client, this response field is - mandatory and gives the actual depth to which the server recursed. The the client - did not specify the `recurse` parameter, this field must be absent. - required: - - chunk + allOf: + - $ref: '#/components/schemas/response' + - type: object + properties: + chunk: + title: ChildEventsChunk + type: array + description: |- + The child events of the requested event, ordered topologically + most-recent first. The events returned will match the `relType` + supplied in the URL. + items: + $ref: definitions/client_event.yaml + required: + - chunk examples: response: - value: { - "chunk": [ - { - "room_id": "!636q39766251:matrix.org", - "$ref": "../../event-schemas/examples/m.room.message$m.text.yaml", - "content": { - "m.relates_to": { - "rel_type": "org.example.my_relation", - "event_id": "$asfDuShaf7Gafaw" - } - } - } - ], - "next_batch": "page2_token", - "prev_batch": "page1_token" - } + $ref: '#/components/examples/response' "404": - description: |- - The parent event was not found or the user does not have permission to read - this event (it might be contained in history that is not accessible to the user). - content: - application/json: - schema: - $ref: definitions/errors/error.yaml - examples: - response: - value: { - "errcode": "M_NOT_FOUND", - "error": "Event not found." - } + $ref: '#/components/responses/404' tags: - Event relationships # The same as above, with added `/{eventType}` @@ -394,28 +151,9 @@ paths: security: - accessToken: [] parameters: - - in: path - name: roomId - description: The ID of the room containing the parent event. - required: true - example: "!636q39766251:matrix.org" - schema: - type: string - - in: path - name: eventId - description: The ID of the parent event whose child events are to be returned. - required: true - example: $asfDuShaf7Gafaw - schema: - type: string - - in: path - name: relType - description: The [relationship type](/client-server-api/#relationship-types) to - search for. - required: true - example: org.example.my_relation - schema: - type: string + - $ref: '#/components/parameters/roomId' + - $ref: '#/components/parameters/eventId' + - $ref: '#/components/parameters/relType' - in: path name: eventType description: |- @@ -427,75 +165,11 @@ paths: example: m.room.message schema: type: string - - in: query - name: from - description: |- - The pagination token to start returning results from. If not supplied, results - start at the most recent topological event known to the server. - - Can be a `next_batch` or `prev_batch` token from a previous call, or a returned - `start` token from [`/messages`](/client-server-api/#get_matrixclientv3roomsroomidmessages), - or a `next_batch` token from [`/sync`](/client-server-api/#get_matrixclientv3sync). - required: false - example: page2_token - schema: - type: string - - in: query - name: to - description: |- - The pagination token to stop returning results at. If not supplied, results - continue up to `limit` or until there are no more events. - - Like `from`, this can be a previous token from a prior call to this endpoint - or from `/messages` or `/sync`. - required: false - example: page3_token - schema: - type: string - - in: query - name: limit - description: |- - The maximum number of results to return in a single `chunk`. The server can - and should apply a maximum value to this parameter to avoid large responses. - - Similarly, the server should apply a default value when not supplied. - required: false - example: 20 - schema: - type: integer - - in: query - name: dir - x-addedInMatrixVersion: "1.4" - description: |- - Optional (default `b`) direction to return events from. If this is set to `f`, events - will be returned in chronological order starting at `from`. If it - is set to `b`, events will be returned in *reverse* chronological - order, again starting at `from`. - schema: - type: string - enum: - - b - - f - - in: query - name: recurse - x-addedInMatrixVersion: "1.10" - required: false - description: |- - Whether to additionally include events which only relate indirectly to the - given event, ie. events related to the root events via one or more direct relationships. - - If set to `false`, only events which have direct a relation with the given - event will be included. - - If set to `true`, all events which relate to the given event, or relate to - events that relate to the given event, will be included. - - It is recommended that at least 3 levels of relationships are traversed. - Implementations may perform more but should be careful to not infinitely recurse. - - The default value is `false`. - schema: - type: boolean + - $ref: '#/components/parameters/from' + - $ref: '#/components/parameters/to' + - $ref: '#/components/parameters/limit' + - $ref: '#/components/parameters/dir' + - $ref: '#/components/parameters/recurse' responses: # note: this endpoint deliberately does not support rate limiting, therefore a # 429 error response is not included. @@ -507,68 +181,26 @@ paths: content: application/json: schema: - type: object - properties: - chunk: - title: ChildEventsChunk - type: array - description: |- - The child events of the requested event, ordered topologically most-recent - first. The events returned will match the `relType` and `eventType` supplied - in the URL. - items: - allOf: - - $ref: definitions/client_event.yaml - next_batch: - type: string - description: |- - An opaque string representing a pagination token. The absence of this token - means there are no more results to fetch and the client should stop paginating. - prev_batch: - type: string - description: |- - An opaque string representing a pagination token. The absence of this token - means this is the start of the result set, i.e. this is the first batch/page. - recursion_depth: - type: integer - description: |- - If the `recurse` parameter was supplied by the client, this response field is - mandatory and gives the actual depth to which the server recursed. The the client - did not specify the `recurse` parameter, this field must be absent. - required: - - chunk + allOf: + - $ref: '#/components/schemas/response' + - type: object + properties: + chunk: + title: ChildEventsChunk + type: array + description: |- + The child events of the requested event, ordered topologically most-recent + first. The events returned will match the `relType` and `eventType` supplied + in the URL. + items: + $ref: definitions/client_event.yaml + required: + - chunk examples: response: - value: { - "chunk": [ - { - "room_id": "!636q39766251:matrix.org", - "$ref": "../../event-schemas/examples/m.room.message$m.text.yaml", - "content": { - "m.relates_to": { - "rel_type": "org.example.my_relation", - "event_id": "$asfDuShaf7Gafaw" - } - } - } - ], - "next_batch": "page2_token", - "prev_batch": "page1_token" - } + $ref: '#/components/examples/response' "404": - description: |- - The parent event was not found or the user does not have permission to read - this event (it might be contained in history that is not accessible to the user). - content: - application/json: - schema: - $ref: definitions/errors/error.yaml - examples: - response: - value: { - "errcode": "M_NOT_FOUND", - "error": "Event not found." - } + $ref: '#/components/responses/404' tags: - Event relationships servers: @@ -586,3 +218,156 @@ servers: components: securitySchemes: $ref: definitions/security.yaml + parameters: + roomId: + in: path + name: roomId + description: The ID of the room containing the parent event. + required: true + example: "!636q39766251:matrix.org" + schema: + type: string + eventId: + in: path + name: eventId + description: The ID of the parent event whose child events are to be returned. + required: true + example: $asfDuShaf7Gafaw + schema: + type: string + from: + in: query + name: from + description: |- + The pagination token to start returning results from. If not supplied, results + start at the most recent topological event known to the server. + + Can be a `next_batch` or `prev_batch` token from a previous call, or a returned + `start` token from [`/messages`](/client-server-api/#get_matrixclientv3roomsroomidmessages), + or a `next_batch` token from [`/sync`](/client-server-api/#get_matrixclientv3sync). + required: false + example: page2_token + schema: + type: string + to: + in: query + name: to + description: |- + The pagination token to stop returning results at. If not supplied, results + continue up to `limit` or until there are no more events. + + Like `from`, this can be a previous token from a prior call to this endpoint + or from `/messages` or `/sync`. + required: false + example: page3_token + schema: + type: string + limit: + in: query + name: limit + description: |- + The maximum number of results to return in a single `chunk`. The server can + and should apply a maximum value to this parameter to avoid large responses. + + Similarly, the server should apply a default value when not supplied. + required: false + example: 20 + schema: + type: integer + dir: + in: query + name: dir + x-addedInMatrixVersion: "1.4" + description: |- + Optional (default `b`) direction to return events from. If this is set to `f`, events + will be returned in chronological order starting at `from`. If it + is set to `b`, events will be returned in *reverse* chronological + order, again starting at `from`. + schema: + type: string + enum: + - b + - f + relType: + in: path + name: relType + description: The [relationship type](/client-server-api/#relationship-types) to + search for. + required: true + example: org.example.my_relation + schema: + type: string + recurse: + in: query + name: recurse + x-addedInMatrixVersion: "1.10" + required: false + description: |- + Whether to additionally include events which only relate indirectly to the + given event, ie. events related to the root events via one or more direct relationships. + + If set to `false`, only events which have direct a relation with the given + event will be included. + + If set to `true`, all events which relate to the given event, or relate to + events that relate to the given event, will be included. + + It is recommended that at least 3 levels of relationships are traversed. + Implementations may perform more but should be careful to not infinitely recurse. + + The default value is `false`. + schema: + type: boolean + schemas: + response: + type: object + properties: + next_batch: + type: string + description: |- + An opaque string representing a pagination token. The absence of this token + means there are no more results to fetch and the client should stop paginating. + prev_batch: + type: string + description: |- + An opaque string representing a pagination token. The absence of this token + means this is the start of the result set, i.e. this is the first batch/page. + recursion_depth: + type: integer + description: |- + If the `recurse` parameter was supplied by the client, this response field is + mandatory and gives the actual depth to which the server recursed. The the client + did not specify the `recurse` parameter, this field must be absent. + responses: + "404": + description: |- + The parent event was not found or the user does not have permission to read + this event (it might be contained in history that is not accessible to the user). + content: + application/json: + schema: + $ref: definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_NOT_FOUND", + "error": "Event not found." + } + examples: + response: + value: { + "chunk": [ + { + "room_id": "!636q39766251:matrix.org", + "$ref": "../../event-schemas/examples/m.room.message$m.text.yaml", + "content": { + "m.relates_to": { + "rel_type": "org.example.my_relation", + "event_id": "$asfDuShaf7Gafaw" + } + } + } + ], + "next_batch": "page2_token", + "prev_batch": "page1_token" + } diff --git a/data/event-schemas/examples/m.call.answer.yaml b/data/event-schemas/examples/m.call.answer.yaml index 78b48878..8a627360 100644 --- a/data/event-schemas/examples/m.call.answer.yaml +++ b/data/event-schemas/examples/m.call.answer.yaml @@ -8,6 +8,14 @@ "answer": { "type" : "answer", "sdp" : "v=0\r\no=- 6584580628695956864 2 IN IP4 127.0.0.1[...]" + }, + "sdp_stream_metadata": { + "271828182845": { + "purpose": "m.screenshare" + }, + "314159265358": { + "purpose": "m.usermedia" + } } } } diff --git a/data/event-schemas/examples/m.call.invite.yaml b/data/event-schemas/examples/m.call.invite.yaml index 45600001..9547854b 100644 --- a/data/event-schemas/examples/m.call.invite.yaml +++ b/data/event-schemas/examples/m.call.invite.yaml @@ -9,6 +9,14 @@ "offer": { "type" : "offer", "sdp" : "v=0\r\no=- 6584580628695956864 2 IN IP4 127.0.0.1[...]" + }, + "sdp_stream_metadata": { + "271828182845": { + "purpose": "m.screenshare" + }, + "314159265358": { + "purpose": "m.usermedia" + } } } } diff --git a/data/event-schemas/examples/m.call.negotiate.yaml b/data/event-schemas/examples/m.call.negotiate.yaml index fabb6add..aaf9daf2 100644 --- a/data/event-schemas/examples/m.call.negotiate.yaml +++ b/data/event-schemas/examples/m.call.negotiate.yaml @@ -9,6 +9,14 @@ "description": { "type" : "offer", "sdp" : "v=0\r\no=- 6584580628695956864 2 IN IP4 127.0.0.1[...]" + }, + "sdp_stream_metadata": { + "271828182845": { + "purpose": "m.screenshare" + }, + "314159265358": { + "purpose": "m.usermedia" + } } } } diff --git a/data/event-schemas/schema/components/sdp_stream_metadata.yaml b/data/event-schemas/schema/components/sdp_stream_metadata.yaml new file mode 100644 index 00000000..f16b4cbd --- /dev/null +++ b/data/event-schemas/schema/components/sdp_stream_metadata.yaml @@ -0,0 +1,27 @@ +type: object +x-addedInMatrixVersion: "1.10" +description: |- + Metadata describing the [streams](/client-server-api/#streams) that will be + sent. + + This is a map of stream ID to metadata about the stream. +additionalProperties: + type: object + title: StreamMetadata + description: Metadata describing a stream. + properties: + purpose: + type: string + enum: + - m.usermedia + - m.screenshare + description: |- + The purpose of the stream. + + The possible values are: + + * `m.usermedia`: Stream that contains the webcam and/or microphone + tracks. + * `m.screenshare`: Stream with the screen-sharing tracks. + required: + - purpose diff --git a/data/event-schemas/schema/m.call.answer.yaml b/data/event-schemas/schema/m.call.answer.yaml index 163690be..15e07202 100644 --- a/data/event-schemas/schema/m.call.answer.yaml +++ b/data/event-schemas/schema/m.call.answer.yaml @@ -27,6 +27,9 @@ } }, "required": ["type", "sdp"] + }, + "sdp_stream_metadata": { + "$ref": "components/sdp_stream_metadata.yaml" } }, "required": ["answer"] diff --git a/data/event-schemas/schema/m.call.invite.yaml b/data/event-schemas/schema/m.call.invite.yaml index 72020b26..c688d7b3 100644 --- a/data/event-schemas/schema/m.call.invite.yaml +++ b/data/event-schemas/schema/m.call.invite.yaml @@ -35,7 +35,10 @@ "invitee": { "type": "string", "description": "The ID of the user being called. If omitted, any user in the room can answer.", - "x-addedInMatrixVersion": "1.7", + "x-addedInMatrixVersion": "1.7" + }, + "sdp_stream_metadata": { + "$ref": "components/sdp_stream_metadata.yaml" } }, "required": ["offer", "lifetime"] diff --git a/data/event-schemas/schema/m.call.negotiate.yaml b/data/event-schemas/schema/m.call.negotiate.yaml index b2b47c1d..e1a14f6f 100644 --- a/data/event-schemas/schema/m.call.negotiate.yaml +++ b/data/event-schemas/schema/m.call.negotiate.yaml @@ -63,6 +63,8 @@ properties: type: integer description: The time in milliseconds that the negotiation is valid for. Once the negotiation age exceeds this value, clients should discard it. + sdp_stream_metadata: + $ref: components/sdp_stream_metadata.yaml required: - description - lifetime diff --git a/layouts/partials/events/example.html b/layouts/partials/events/example.html index 181de88f..90752fbd 100644 --- a/layouts/partials/events/example.html +++ b/layouts/partials/events/example.html @@ -1,13 +1,18 @@ {{/* - Renders an event example. Resolves `$ref`s, serializes as JSON, and ensures + Renders an event example. Resolves `$ref`s, serializes as JSON, and ensures that it can be included in HTML. - This partial is called with the example event object as its context. + Parameters: + + * `schema`: the schema of the example + * `name`: the name of the example */}} -{{ $example_content := partial "json-schema/resolve-refs" (dict "schema" . "path" "event-schemas/examples") }} +{{ $path := delimit (slice "event-schemas/examples" .name) "/" }} + +{{ $example_content := partial "json-schema/resolve-refs" (dict "schema" .schema "path" $path) }} {{ $example_json := jsonify (dict "indent" " ") $example_content }} {{ $example_json = replace $example_json "\\u003c" "<" }} {{ $example_json = replace $example_json "\\u003e" ">" | safeHTML }} diff --git a/layouts/partials/events/render-event.html b/layouts/partials/events/render-event.html index 70752721..71ba60bd 100644 --- a/layouts/partials/events/render-event.html +++ b/layouts/partials/events/render-event.html @@ -77,7 +77,7 @@ */}} {{ if $desired_example_name }} {{ if eq $example_name $desired_example_name }} - {{ partial "events/example" $example }} + {{ partial "events/example" (dict "schema" $example "name" $example_name) }} {{ end }} {{/* If `$desired_example_name` is not given, we will include any @@ -86,7 +86,7 @@ the event name includes a "$". */}} {{ else if eq $event_name $example_name }} - {{ partial "events/example" $example }} + {{ partial "events/example" (dict "schema" $example "name" $example_name) }} {{/* If `$desired_example_name` is not given, we will include any examples whose first part (before "$") matches the event name @@ -96,7 +96,7 @@ {{ $pieces := split $example_name "$" }} {{ $example_base_name := index $pieces 0 }} {{ if eq $event_name $example_base_name }} - {{ partial "events/example" $example }} + {{ partial "events/example" (dict "schema" $example "name" $example_name) }} {{ end }} {{ end }} {{ end }} diff --git a/layouts/partials/json-schema/resolve-refs.html b/layouts/partials/json-schema/resolve-refs.html index 1d99201d..9a36e413 100644 --- a/layouts/partials/json-schema/resolve-refs.html +++ b/layouts/partials/json-schema/resolve-refs.html @@ -1,7 +1,10 @@ {{/* Resolves the `$ref` JSON schema keyword, by recursively replacing - it with the object it points to. + it with the object it points to, given: + + * `schema`: the schema where the references should be resolved + * `path`: the path of the file containing the schema This template uses [`Scratch`](https://gohugo.io/functions/scratch/) rather than a normal `dict` because with `dict` you can't replace key values: @@ -20,8 +23,12 @@ {{ $scratch.Set "result_map" dict }} {{ $ref_value := index $schema "$ref"}} - {{ if $ref_value}} - {{ $full_path := path.Join $path $ref_value }} + {{ if $ref_value }} + {{ $uri := urls.Parse $path }} + {{ $ref_uri := urls.Parse $ref_value }} + {{ $full_uri := $uri.ResolveReference $ref_uri }} + + {{ $full_path := strings.TrimPrefix "/" $full_uri.Path }} {{/* Apparently Hugo doesn't give us a nice way to split the extension off a filename. */}} @@ -30,11 +37,18 @@ {{ $ref := index site.Data $pieces }} + {{/* If there is a fragment, follow the JSON Pointer */}} + {{ if $full_uri.Fragment }} + {{ $fragment := strings.TrimPrefix "/" $full_uri.Fragment }} + {{ $pieces := split $fragment "/" }} + {{ $ref = index $ref $pieces }} + {{ end }} + {{ $new_path := (path.Split $full_path).Dir}} {{ $result_map := partial "json-schema/resolve-refs" (dict "schema" $ref "path" $new_path)}} {{ if $result_map}} {{ $scratch.Set "result_map" $result_map }} - {{end }} + {{ end }} {{ end }} diff --git a/layouts/partials/openapi/render-parameters.html b/layouts/partials/openapi/render-parameters.html index 925b0197..ecabfc05 100644 --- a/layouts/partials/openapi/render-parameters.html +++ b/layouts/partials/openapi/render-parameters.html @@ -5,6 +5,7 @@ * `parameters`: OpenAPI data specifying the parameters * `type`: the type of parameters to render: "header, ""path", "query" * `caption`: caption to use for the table + * `path`: the path where this definition was found, to enable us to resolve "$ref" This template renders a single table containing parameters of the given type. @@ -13,7 +14,9 @@ {{ $parameters := .parameters }} {{ $type := .type }} {{ $caption := .caption }} +{{ $path := .path }} +{{ $parameters = partial "json-schema/resolve-refs" (dict "schema" $parameters "path" $path) }} {{ $parameters_of_type := where $parameters "in" $type }} {{ with $parameters_of_type }} @@ -32,5 +35,4 @@ {{/* and render the parameters */}} {{ partial "openapi/render-object-table" (dict "title" $caption "properties" $param_dict) }} - {{ end }} diff --git a/layouts/partials/openapi/render-request.html b/layouts/partials/openapi/render-request.html index 3d4b0381..5ef55c64 100644 --- a/layouts/partials/openapi/render-request.html +++ b/layouts/partials/openapi/render-request.html @@ -26,9 +26,9 @@ {{ if $parameters }}