Detect whether extension has host permission for active tab

My goal is to simply change the browser action icon to reflect whether the extension has or doesn’t have the host permission to access the current tab.

Currently there doesn’t seem to be a good way to detect whether an extension has permissions to access the currently active tab in the background.

One cannot use browser.permissions.contains() without having the “tabs” permission (“tabs” permission is needed to get the URL of the active tab).

My current workaround works by trying to inject a content script and see if it succeeds or fails:

async function hasHostPermissionForTab(tabId) {
  try {
    return (await browser.scripting.executeScript({
      target: { tabId: tabId },
      injectImmediately: true,
      func: () => true,
    }))[0].result;
  }
  catch(_) {
    return false;
  }
}
1 Like

If your extension

a) doesn’t have the “tabs” permission
b) doesn’t have a host permission for the active tab

then browser.tabs.query({ lastFocusedWindow: true, active: true }) will return a tabs.Tab object without a “url” property.
(I haven’t tried this, so please let us know if it solves your problem)

2 Likes

I haven’t thought about this. Thanks a lot!
Just for completeness I ended up using the following function which also works if the tabs permission is granted (in my case it can be optionally granted so I required the additional check).

async function hasHostPermissionForActiveTab() {
  const [activeTab] = await browser.tabs.query({active: true, currentWindow: true});

  try {
    return activeTab.url
      ? await browser.permissions.contains({
        origins: [activeTab.url]
      })
      : false;
  }
  // catch error that occurs for special urls like about:
  catch {
    return false;
  }
}