Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSC1958: Widget architecture changes #1958

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 137 additions & 0 deletions proposals/1958-integrations-widget-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# MSC1958: Widget structure alterations
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Add widget_id and parent_url variables.


Widgets are already very powerful in Matrix due to [MSC1236](https://github.com/matrix-org/matrix-doc/issues/1236),
however there are some areas which can be iterated upon.


## Proposal

There are two types of widgets: Account and Room. Account widgets are referred to as "User Widgets"
in MSC1236, however they are renamed here and throughout the integrations API proposals to better
match where they live and who they affect.

#### Account widgets

To recap, account widgets only affect the user which has set them in their own account data. They
cannot be used by other users, and are often used to expand upon the user's experience of a client.
A modern example of an account widget would be the sticker picker: although many people do not realize
it, this is actually a widget powered by the integrations manager. Account widgets currently look
as follows in account data:
```json
{
"type": "m.widgets",
"content": {
"first_widget_arbitrary_id": {
"content": {
"type": "m.stickerpicker",
"url": "https://example.org/stickers.html",
"data": {
"api_url": "https://stickers.example.org"
},
"name": "Stickerpicker"
},
"sender": "@travis:t2l.io",
"state_key": "first_widget_arbitrary_id",
"type": "m.widget",
"id": "first_widget_arbitrary_id"
},
"second_widget_arbitrary_id": {
"content": {
"type": "m.integration_manager",
"url": "https://example.org/integrations.html?my_custom_key=$custom_key",
"data": {
"api_url": "https://integrations.example.org",
"custom_key": "custom_value"
},
"name": "Integration Manager"
},
"sender": "@travis:t2l.io",
"state_key": "second_widget_arbitrary_id",
"type": "m.widget",
"id": "second_widget_arbitrary_id"
}
}
}
```

The changes proposed which differ from MSC1236 are:
* `creatorUserId` and `sender` become optional and can be assumed to be the current user.
* `state_key` becomes optional and can be assumed to be the `id`.
* `type` on a widget event becomes optional and should be assumed to be `m.widget`.
* The template variables supported become `$matrix_user_id`, `$matrix_display_name`, `$matrix_avatar_url`.
`$matrix_room_id` doesn't make sense for account widgets, and should not be provided. Custom keys must
additionally be supported.
* In cases where the user has multiple `m.stickerpicker` widgets, similar ordering rules apply for showing
`m.integration_manager` widgets: lexigraphically sort the widgets by `id` and show them in tabs, or pick
one arbitrarily and use that as the canonical widget. MSC1236 does not define any behaviour. Integration
manager ordering is defined by [MSC1957](https://github.com/matrix-org/matrix-doc/pull/1957).
* `m.stickerpicker` widgets are required to have a `data` object containing an `api_url`. This is relevant
for [MSC1959 - Sticker picker API](https://github.com/matrix-org/matrix-doc/pull/1959). For backwards
compatibility with widgets which don't have this property, clients should try to determine the integration
manager API URL for the widget or continue ignoring the property's existence (showing an iframe instead).

To further clarify: Widgets should no longer be receiving a `scalar_token` via query params. If they need
to authenticate the user, they are able to use
[MSC1960 - OpenID information exchange for widgets](https://github.com/matrix-org/matrix-doc/pull/1960).

#### Room widgets

As a reminder, room widgets are widgets which are defined in room state and visible/accesible to members
of the room. This includes interacting with the widget. Typically these kinds of widgets are shared notepads,
video conferences, or dashboards however there is no restriction for what could be contained here.

This proposal does not alter MSC1236 with respect to room widgets, however it does add some clarifications
on top:
* Like account widgets, room widgets should no longer be receiving a `scalar_token` and instead should be
using [MSC1960 - OpenID information exchange for widgets](https://github.com/matrix-org/matrix-doc/pull/1960).
* Although not mentioned in MSC1236, clients are permitted to build widgets into their app if they like. For
example, a Jitsi widget could translate to built-in call support instead of embedding an iframe. This is
the one of the rationales for including specific `data` on widgets.

#### Widget titles

Widgets already have a `name` component which best describes what it is ("Etherpad", "Jitsi Conference", etc).
In practice there is a `title` attribute which can be specified in `data` to have a secondary title next to
the widget's name. It is proposed that the `title` be moved to the same level as the `name`, otherwise behaving
the same as in practice: if present, it should show up next to the widget's name. If not set or an empty string,
it should not be shown.

*Note*: In the wild there is a widget title API endpoint that goes along with the `title` property, however
the author is excluding the API from this proposal for doubts of its usefulness and the security concerns with
getting it into the integrations API as proposed. The API is currently called against the integration manager
if the widget is missing a title and a title can be displayed, however with multiple integration managers and
untrusted widgets being proposed it is unclear whether the client should be making this API call anymore. The
security concern comes with the need for authorization on the API endpoint, which means the client would need
to register with a likely unknown integration manager, effectively sending the user's ID over too. Clients could
implement additional prompts however the concern becomes one of user experience where the title would be causing
permission request dialogs for ultimately unimportant information.

#### Extension: Theme and client identification support

When filling out template variables in widgets, clients SHOULD support `$matrix_client_id` and `$matrix_client_theme`
as variables. `$matrix_client_id` is a namespaced identifier which the widget/integration manager can use to
identify the client is talking to. For example, this may be `im.vector.riot.web` or `com.github.quaternion`.
`$matrix_client_theme` is the stringified name of the theme the client is running, if available. For example,
`dark` or `light`. Clients which do not want to disclose the information should not replace the variables,
leaving them as-is.


## Potential issues

This proposal alters the existing required fields for widgets, potentially introducing complexity into
applications which already rely on the fields. These applications are encouraged to follow the fallback
advice provided in the proposal.

The exclusion of a widget title API endpoint may not be the best option in the current landscape. Although
the author's own integration manager implementation does not make use of the API in a significant way, other
integration managers might. It is unclear to the author how other managers make use of the existing API.


## Security considerations

Token security is achieved by simply never providing it to the widgets. Some integration managers currently
rely on the token being provided to restrict access to particular assets like the widget's script itself. The
author proposes that those implementations make use of
[MSC1960 - OpenID information exchange for widgets](https://github.com/matrix-org/matrix-doc/pull/1960)
through minimal scripts which acquire a token, set appropriate cookies/headers, and load the remaining resources
afterwards.