Warning
We have decided not to follow through with the proposed solution in this
design doc. We care a lot about a nice upgrade path for when better
browser integration becomes available. Encouraging the #taler://
fragment
based integration might lead merchant frontends to only support this type
of integration.
Instead, the following path will be taken:
webRequest
permission that allows "Taler: "
header based
browser integration will become opt-in."Taler: "
header.taler://
URI described in this document
will not be supported, as allowing presence detection might
encourage merchants to treat mobile / detached wallets as 2nd class
citizens.A new and improved mechanism for the integration of GNU Taler wallets with web browsers is proposed. The mechanism is meant for browsers that support the WebExtension API, but do not have native support for GNU Taler.
The new approach allows the wallet extension to be installed without excessive, “scary” permissions, while being simpler and still flexible.
The current browser integration of the GNU Taler wallet relies heavily being able to hook into various browser mechanisms via the following mechanisms:
webRequest
handler that is run for every request the browser
makes, and looks at the status code and the presence of a “Taler:
” HTTP header.This has multiple problems:
We first have to accept the fundamental limitation that a WebExtension is not able to read a page’s HTTP request headers without intrusive permissions. Instead, we need to rely on the content and/or URL of the fallback page that is being rendered by the merchant backend.
To be compatible with mobile wallets, merchants and banks must always render a fallback
page that includes the same taler://
URI.
Using the only the activeTab
permission, we can access a page’s content
while and only while the user is opening the popup (or a page action).
The extension should look at the DOM and search for taler://
links.
If such a link as been found, the popup should display an appropriate
dialog to the user (e.g. “Pay with GNU Taler on the current page.”).
Using manual triggering is not the best user experience, but works on every Website
that displays a taler://
link.
Note
Using additional permissions, we could also offer:
taler://pay
linkstaler://
link.It’s not clear if this improves the user experience though.
This mechanism improves the user experience, but requires extra support from merchants
and broader permissions, namely the tabs
permission. This permission
is shown as “can read your history”, which sounds relatively intrusive.
We might decide to make this mechanism opt-in.
The extension uses the tabs
permission to listen to changes to the
URL displayed in the currently active tab. It then parses the fragment,
which can contain a taler://
URI, such as:
https://shop.taler.net/checkout#taler://pay/backend.shop.taler.net/-/-/2020.099-03C5F644XCNMR
The fragment is processed the same way a “Taler: ” header is processed.
For examle, a taler://pay/...
fragment navigates to an in-wallet page
and shows a payment request to the user.
To support fragment-based detection of the wallet, a special
taler://check-presence/${redir}
URL can be used to cause a navigation to
${redir}
if the wallet is installed. The redirect URL can be absolute or
relative to the current page and can contain a fragment.
For example:
https://shop.taler.net/checkout#taler://check-presence/taler-installed
-> (when wallet installed)
https://shop.taler.net/taler-installed
To preserve correct browser history navigation, the wallet does not initiate the redirect if
the tab’s URL changes from ${redir}
back to the page with the check-presence
fragment.
The fragment-based triggering does not work well on single-page apps: It interferes with the SPA’s routing, as it requires a change to the navigation location’s fragment.
The only way to communicate with a WebExtension is by knowing its extension ID. However, we want to allow users to build their own version of the WebExtension, and extensions are assigned different IDs in different browsers. We thus need a mechanism to obtain the wallet extension ID in order to asynchronously communicate with it.
To allow the Website to obtain this extension ID, we can extend the redirection URL
of the taler://check-presence
fragment to allow a placeholder for the extension ID.
https://shop.taler.net/checkout#taler://check-presence/#taler-installed-${extid}
-> (when wallet installed)
https://shop.taler.net/checkout#taler-installed-12345ASDFG
Warning
This allows fingerprinting, and thus should be an opt-in feature. The wallet could also ask the user every time to allow a page to obtain the
Note
To avoid navigating away from an SPA to find out the extension ID, the SPA can open a new tab/window and communicate the updated extension ID back to original SPA page.
Once the Website has obtained the extension ID, it can use the runtime.connect()
function
to establish a communication channel to the extension.
taler://
URIs :-)taler://
. For a better user experience,
there should also be some way to check whether some particular URI scheme
has a handler.