Is it possible for a webextension/addon to request permission for a specific website at runtime?

677 Views Asked by At

I am trying to develop a WebExtension that accesses a user-defined API whose URL I do not know in advance. (More specifically, it manages their Ghost publications, whose APIs would be hosted on the same domains as the publications themselves). Hence, I need to let users enter their API URL and access that throughout the addon.

The simplest way to do this would be to request the <all_urls> host permission (basically like *://**). But instead of such sweeping permissions, I was wondering if there's a more finegrained way of requesting permission just for the specific URL I need?

I know that the optional_permissions setting lets an addon request additional permissions at runtime if those permissions are specified in advance in the manifest. From this w3cub page:

Type Mandatory Example
Array No "optional_permissions": ["*://developer.mozilla.org/*", "webRequest"]

Use the optional_permissions key to list permissions that you want to ask for at runtime, after your extension has been installed.

However, this seems to require a hard-coded permission (*://developer.mozilla.org/*) that's requested at runtime. What I need is a user-defined permission that can be requested in the same manner. Is there any way I can go about implementing this?

1

There are 1 best solutions below

0
On BEST ANSWER

From the list of use-cases for optional permissions on the Mozilla docs:

  • The extension may need host permissions, but not know at install time which host permissions it needs. For example, the list of hosts may be a user setting. In this scenario, asking for a more specific range of hosts at runtime, can be an alternative to asking for "<all_urls>" at install time.

The way to do it is to include <all_urls> in the optional_permissions setting of your manifest.json like this:

"optional_permissions": [
    "<all_urls>",
    "webRequest",
    "geoLocation"
],

In this example, we're also requesting the webRequest and geoLocation permissions; this is to demonstrate the two different kinds of permission you can request.

Then, in your code, instead of requesting <all_urls>, just request the URLs that you actually want to access:

browser.permissions.request({
    permissions: ["webRequest", "geoLocation"],
    origins: ["https://example.com/*"]
})

As you can see, the request is neatly separated into an option for more API permissions and another for the different websites (origins) you want to access.

A more complete example can be found on the docs for permissions.request docs. (You can also find a working sample webextension here, but it doesn't include host permissions, only API ones).