Search code examples
xcodegoogle-chromesafarisafari-extensionsafari-web-inspector

Safari 14: chrome.permissions.request() not working seamless and tab.url comes blanks always - Extension


I have working cross-platform extension which I converted for Safari using xcrun safari-web-extension-converter PATH. Goal of extension is to bookmark any URL into my website account (https://ourdomain.in).

My extension is perfectly working fine for Chrome but for Safari version, everything works well if user allows access permission for every website.

The issue is, even though I have proper optional_permissions and used chrome.permissions.request() method to ask user-consent for ourdomain.in, and we see user allowed access, still tab.url comes blank for chrome.tabs.onUpdated every time.

Here is the case in detail, when user presses extension button, we are checking user is logged into its account or not by opening our website URL into another tab.

var openSignin = function openSignin() {
    console.log('hey');
    chrome.tabs.create({ url: _config.baseURL + '?extension=1', active: false });
};

When this AUTH tab is loaded, following method will be called as it happens in Chrome which in turn extracts public and private tokens generated when any user logs into our website.

chrome.tabs.onUpdated.addListener(function (tabID, changeInfo, tab) {
    if (tab.status == 'complete' && tab.url.startsWith(_config.baseURL)) {
      chrome.tabs.executeScript(tab.id, { code: 'localStorage.getItem("PUBLIC")' }, function (r) {
       localStorage['PUBLIC'] = JSON.parse(r[0]);
       chrome.tabs.executeScript(tab.id, { code: 'localStorage.getItem("PRIVATE")' }, function (r) {
        localStorage['PRIVATE'] = JSON.parse(r[0]);
        if (localStorage['PRIVATE'] && tab.url === _config.baseURL + '?extension=1') {
         chrome.tabs.remove(tabID);
        }
       });
      });
     }
});

The issue lies here is that until user does not grant for "Always Allow on Every Website" (I mean grant permission for https://ourdomain.in/extension?extension=1), chrome.tabs.onUpdate is giving tab.url = "" and it does not give proper URL value so our conditions don't match and know that particular user is signed in or not.

Following is our manifest.json where I have event used optional_permissions:

{
    "name": "EXT NAME",
    "description": "DESCRIPTION",
    "manifest_version": 2,
    "version": "1.0.181",
    "minimum_chrome_version": "23",
    "offline_enabled": true, 
    "browser_action" : {
        "default_icon" : {
             "64": "logo/icon.png"
        },
        "default_title" : "Add here"
    },
    "background" : {
        "scripts" : [
            "background.js"
        ]
    },
    "content_scripts": [{
            "js": [ "content.js" ],
            "matches": [ "<all_urls>" ]
    }],
    "icons": {
         "16": "logo/icon_small.png",
         "64": "logo/icon.png"
    },
    "permissions" : [
        "https://*.ourdomain.in/*",
        "activeTab",
        "gcm",
        "storage",
        "notifications",
        "identity",
        "contextMenus",
        "tabs",
        "idle"
    ],
    "externally_connectable": {
        "matches": ["https://*.ourdomain.in/*"]
    },

    "optional_permissions": ["activeTab", "tabs", "storage", "contextMenus", "*://*.ourdomain.in/*"],

    "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
    "web_accessible_resources": [
        "corner.css",
        "js/init.js",
        "content.js",
        "js/jquery.min.js",
        "js/taggle.min.js",
        "js/typeahead.bundle.min.js",
        "ext.html.js",
        "assets/*"
    ], 
 "commands": {
         "_execute_browser_action": {
             "suggested_key": {
                 "default": "Ctrl+Shift+S",
                 "mac": "Command+Shift+S"
             },
             "description": "Send a link to DOMAIN!"
         }
     }
}

And following is the code for permission request which is implemented in click event handler of extension button.

chrome.browserAction.onClicked.addListener(function (tab) {
     var reqPerm = {
        permissions: ["activeTab", "tabs", "storage", "contextMenus"],
        origins: ['https://ourdomain.in/']
     };
    
     chrome.permissions.request(reqPerm, function (granted) {
        if (granted) {
            return go(tab.url);
        } else {
            console.log("Requested not granted.");
            chrome.tabs.sendMessage(tabID, { action: 'signin', text: 'Please allow stash.ai to proceed.' });
        }
    });
});

Here I am able to see Privacy dialog and I do press Allow for the Day.

Now if I see in Safari > Preferences > Websites > Stash Extension, I am clearly able to see ourdomain.in -> Allowed which proves prompt worked as expected I believe.

Still when new tab is opened for authentication, the above mentioned code for chrome.tabs.onUpdate is executed and gives tab.url = ''. This definitely works when Allow for Every website is turned on.

And other thing is, when I open https://ourdomain.in, my extension icon still shows disabled and on click of the icon it again asks me for the permission. If on this tab, I do give permission, everything works smooth.

Thus, chrome.permissions.request() is no use if I have to manually give permission from tab.

Please let me know any suggestions here.


Solution

  • The answer was so simple, I have to change my reqPerm like,

    var reqPerm = {
            permissions: ["activeTab", "tabs", "storage", "contextMenus"],
            origins: ['https://ourdomain.in/*']
         };
    

    So every endpoint in ourdomain.in works.