123 lines
7.5 KiB
Markdown
123 lines
7.5 KiB
Markdown
# MSC2974: Widgets: Re-exchange capabilities
|
|
|
|
Currently [widgets](https://github.com/matrix-org/matrix-doc/pull/2764) are only able to exchange
|
|
capabilities during [their initialization](https://github.com/matrix-org/matrix-doc/pull/2764/files#diff-30e79df7a74998ad207dd3894a975fed94daea20a3a955fd11ade7cf7c96b9f0R366-R371).
|
|
This can be limiting to some widgets which don't generally require a given capability until much
|
|
later in the widget's lifecycle.
|
|
|
|
This proposal attempts to support these sorts of long-lived widgets by still requiring the early
|
|
exchange of capabilities and by altering the specification to allow mid-session capabilities.
|
|
|
|
For reference, the capabilities exchange is one of the first request/response pairs sent over the
|
|
widget API during the widget's initialization. Once the widget has loaded, the client asks the
|
|
widget which capabilities it wants - the widget is then expected to reply with said capabilities
|
|
request. Normally a widget would not be aware of what capabilities it was approved for (upon
|
|
receipt of the widget's request for capabilities the client is meant to prompt the user for
|
|
confirmation), however under [MSC2871](https://github.com/matrix-org/matrix-doc/pull/2871) the
|
|
widget is more aware of what capabilities it ended up being approved for. After the capabilities
|
|
exchange happens, the widget is generally ready to be communicated with normally - this is the
|
|
start of a successful "session".
|
|
|
|
## Proposal
|
|
|
|
The line "Clients MUST NOT re-negotiate capabilities after the session has been established." is
|
|
removed from the specification and instead replaced by the mechanism defined by this proposal.
|
|
|
|
After a session has been established, a widget can request additional capabilities with a newly
|
|
proposed `request_capabilities` `fromWidget` action over the widget API. The shape of this request
|
|
looks very much like what the widget would have already sent back to request the initial set of
|
|
capabilities:
|
|
|
|
```json5
|
|
{
|
|
"api": "fromWidget",
|
|
"requestId": "AAABBB",
|
|
"widgetId": "CCCDDD",
|
|
"action": "request_capabilities",
|
|
"data": {
|
|
"capabilities": ["m.always_on_screen", "com.example.cap"]
|
|
}
|
|
}
|
|
```
|
|
|
|
The client should only prompt the user to approve any additional capabilities that have not been
|
|
approved already. The client should only respond with the standardized error response if the widget
|
|
is being rate limited or some other programming error has occurred. The client responds to the
|
|
widget's request with an acknowledgement (empty `response` object) to avoid the standardized timeout
|
|
causing problems with communication.
|
|
|
|
After the client has prompted the user to approve/deny the additional capabilities, it uses the same
|
|
communication structure established by [MSC2871](https://github.com/matrix-org/matrix-doc/pull/2871)
|
|
to send over the total list of requested and approved capabilities throughout the session. For example,
|
|
if the widget started the session by requesting `com.example.cap.1` and was approved, then when the
|
|
widget was later approved for `com.example.cap.2` the client would inform the widget that it was
|
|
approved for both 1 and 2.
|
|
|
|
This MSC does not currently allow clients to decline capabilities which were already approved. There
|
|
does not appear to be a use case for this at the moment, and the client retains control over ending
|
|
the session if it believes the widget is abusive/malicious (widgets cannot end a session, but a client
|
|
can under the current spec).
|
|
|
|
As a result, clients should not reconfirm already-approved capabilities with the user. The client
|
|
might still show the already-approved capabilities to give additional context to the user.
|
|
|
|
If the widget has made a mistake and requested no new capabilities then the user should not be prompted
|
|
and the widget should be reminded of it's capabilities using [MSC2871](https://github.com/matrix-org/matrix-doc/pull/2871).
|
|
This implies that the original `request_capabilities` request is also successful and does not result in
|
|
an error response. The widget can still be rate limited for making repeated mistakes.
|
|
|
|
Much like the initial capabilities exchange, the client is permitted to approve capabilities which
|
|
"make sense" for the widget without informing the user. Such examples include conference call widgets
|
|
which ask to remain on screen: the client can (and probably should) auto-approve this capability.
|
|
Widgets which expect their capabilities to be automatically approved are generally encouraged to make
|
|
the request while the session is being established rather than with a secondary capabilities request,
|
|
however. Typically widgets which would have their capabilities auto-approved will not need to add
|
|
extra traffic to the session and can instead get the request out of the way early.
|
|
|
|
For the purposes of MSCs and functionality which require behaviour if the capabilities were approved
|
|
(such as sending events from client to widget), this MSC implies that the defined behaviour starts
|
|
once the widget is approved for the relevant capabilities. For example, if the widget starts by asking
|
|
for all message events sent to it and later requests room name state events to be sent too, both
|
|
would be sent to the widget (assuming the user approved both requests).
|
|
|
|
## Potential issues
|
|
|
|
This could result in excessive popups to users as widgets request the bare minimum as they need it.
|
|
Widgets are encouraged to avoid being rate limited by requesting capabilities in bulk where possible.
|
|
Widgets should note that clients might be more strict on rate limits when user interaction is involved
|
|
to ensure that the user experience is not damaged by a widget.
|
|
|
|
Repeated permissions prompts may help promote a user experience where end users do not read the
|
|
capabilities being requested and automatically approve them, such as is common with presenting terms of
|
|
service to typical users. Generally speaking, the first permissions prompt will be read by users as
|
|
a sort of "wait a minute, what is going on" response however secondary prompts may result in the user
|
|
clicking the 'Approve All' button. Clients are encouraged to perform user testing and alter their
|
|
design as needed to avoid this scenario.
|
|
|
|
## Alternatives
|
|
|
|
The widget could request a whole other session to be established, however this is overly disruptive
|
|
to the communications channel that the client and widget will have established. Similarly, widgets
|
|
could present dialogs to the user to request that the user reload the widget to establish a new
|
|
session. It is believed that these are overly disruptive to the user experience.
|
|
|
|
## Security considerations
|
|
|
|
As already mentioned, typical rate limit issues arise when arbitrary widgets can request information
|
|
from the user, particularly in popup form.
|
|
|
|
Also as already mentioned, users may be inclined to approve secondary requests without reviewing the
|
|
actual request. This could lead to a widget appearing innocent by requesting very few capabilities and
|
|
following that up later with many more capabilities. Clients are encouraged to try and avoid this.
|
|
|
|
A third risk is that the widget might repeatedly request declined capabilities until it annoys the
|
|
user into accepting them. This sort of behaviour should result in a rate limit response or the client
|
|
continually denying the widget's capabilities request on behalf of the widget.
|
|
|
|
## Unstable prefix
|
|
|
|
Until this MSC is in a release version of the specification, implementations should use `org.matrix.msc2974`
|
|
in the `supported_versions` request/response to detect support. The `action` becomes
|
|
`org.matrix.msc2974.request_capabilities` under this convention - the capabilities return defined by MSC2871
|
|
is unchanged.
|