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?
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).