30

We currently have an extension in the Chrome Web Store with many users. We currently request access to foo.site.com but now we'd like to update our permissions so that we can get bar.site.com.

As I understand it now, if we push a new update (new extension version to the Chrome Web Store) requiring these two permissions, existing users will have their extension disabled until they manually re-enable. New users who download the extension after the update will be fine and have both permissions. However, disabling our current users is not an option.

Any way to get around this?

We've looked into optional permissions, which would solve the issue for existing users (we would just ask them to click a button to upgrade the permissions and be on our way). However for new users, they would not only have to install the extension but also accept the optional permissions which sucks. Is there any way for new users to accept all the permission (optional and required) at install time?

user1731468
  • 864
  • 2
  • 9
  • 30
aloo
  • 5,331
  • 7
  • 55
  • 94
  • 4
    You didn't really read the question did you. – aloo Nov 30 '12 at 21:13
  • 2
    I was addressing this: `However, disabling our current users is not an option. Any way to get around this?` – Brian Driscoll Dec 03 '12 at 13:30
  • 3
    It seems like a useful feature to be able to declare some optional_permissions to be requested at install time for new users. File it at http://crbug.com/new? You might also consider whether it would make sense to turn all of your permissions into optional_permissions so you can request them once after install, or whether the beta activeTab permission (http://developer.chrome.com/beta/extensions/activeTab.html) would work instead of always getting access to bar.site.com. – Jeffrey Yasskin Dec 10 '12 at 00:55

4 Answers4

8

Yes, there is solution. You set the new permissions as optional, and then you request the permission before the user using the new feature. The is work 100%.

This is what you add to your manifest:

"permissions": ["tabs","http://*/*","https://*/*"],

After that you can use:

chrome.permissions.request 

and

chrome.permissions.contains
kettlepot
  • 10,574
  • 28
  • 71
  • 100
Aminadav Glickshtein
  • 23,232
  • 12
  • 77
  • 117
  • 1
    For new users they would have to accept the permissions to install the extension and accept another set of permissions to – aloo Feb 05 '13 at 00:39
  • @Gabriele However, chrome.permissions.request must be called inside a "user gesture", right? What user gesture have you used for this? What if I want it to happen whenever user loads a certain webpage? – Keven Wang Oct 01 '14 at 21:40
  • In my case I have a small settings panel that is injected right in the page. When you toggle it, it'll ask for permission. I think it was a bit more complicated than that and it required using messages. The extension I made is called HN Special and you can find it on GitHub. Try googling it :) – kettlepot Oct 01 '14 at 21:42
  • 2
    Is there a way that, my old users get only optional permission popup, but new users only get it once when they are installing extension and not twice - once on installation, and when using these optional features. – Nakul Jan 16 '15 at 14:09
5

Facing the same issue with my extension, I came about this post searching for the same question. There is an update that seems acceptable in some cases. According to: https://support.google.com/chrome_webstore/answer/1054246 and the example on http://developer.chrome.com/extensions/permission_warnings.html

Seems that updating your permissions will in fact disable your extension, however it will prompt the user about your change and allow an easy "re-enable".

It might not be acceptable in your scenario, however in my case the win of new users with the added permission by default trumps the risk of existing user not re-enabling. As this is drastically better to the way it was before where your existing users were not aware of the extension being disabled...

I know this post is old, but as it is the top Google result for this question thought an update be good for future reference...

maximbr
  • 401
  • 6
  • 7
  • 2
    Is there a way that, my old users get only optional permission popup, but new users only get it once when they are installing extension and not twice - once on installation, and when using these optional features. – Nakul Jan 17 '15 at 06:21
  • @Nakul you can use `chrome.permissions.contains` to check if permission is already granted or yet to be asked separately. – Akansh Jun 20 '17 at 19:50
5

Since chrome 16 you can set optional_permission at install time and ask for elevated permission at run time. See https://developer.chrome.com/extensions/permissions

in manifest.json:

  {
    "name": "My extension",
    ...
    "optional_permissions": [ "tabs", "http://bar.site.com/" ],
    ...
  }

in popup.json:

    document.querySelector('#my-button').addEventListener('click', function(event) {
    // Permissions must be requested from inside a user gesture, like a button's
    // click handler.
    chrome.permissions.request({
      permissions: ['tabs'],
      origins: ['http://bar.site.com/']
    }, function(granted) {
      // The callback argument will be true if the user granted the permissions.
      if (granted) {
        doSomething();
      } else {
        doSomethingElse();
      }
    });
  });
David Dehghan
  • 22,159
  • 10
  • 107
  • 95
1

There is a way (using optional permissions) to add new extension permissions without disabling the extension for the existing users, while also ensuring new users get prompted to accept both required and optional permissions after installation.

Optional permissions can be requested using chrome.permissions.request API, but it functions only if the request is preceded by a user action. The simplest way to fulfill this requirement and still provide a seamless user experience is to check for the permissions in the background page and request the optional permissions in a popup at runtime.

Permission request can be made in the background page right after loading the extension (after installation and subsequent browser launches). Any existing user missing any of the permissions will be prompted to accept the permission after relaunching the browser.

The following example includes:

  • The background page JavaScript (background_page.js)
  • Notification popup html file (notification_popup.html)
  • Notification popup JavaScript (notification_popup.js)

You will also need declare the "optional_permissions" in manifest.json for the example to work. The example will work with both a Chrome Extension and a Firefox Add-on.

background_page.js

var brwsr = null;
if (typeof chrome != "undefined") {
    brwsr = chrome;
}
else{
    brwsr = browser;
}
var opt_perms = brwsr.runtime.getManifest().optional_permissions; 
var requiredOptionalPermissions = {}
if(typeof opt_perms!="undefined" && opt_perms.length>0){
    var perms = []
    var origins = []
    var re = new RegExp("^(http|https)://", "i");
    for(var i=0; i<opt_perms.length; i++){
        if(opt_perms[i]==="<all_urls>"|| re.test(opt_perms[i])){
            origins.push(opt_perms[i])
        }
        else{
            perms.push(opt_perms[i])
        }
    }
    if(perms.length>0){
        requiredOptionalPermissions.permissions = perms
    }
    if(origins.length>0){
        requiredOptionalPermissions.origins = origins
    }
}
var requiresPermission = ()=>{
// add your code here
}
// check if optional permission exists and request if not
var runFunctionsRequiringOptPermissions = function(requiredPermissions={}, userGesture=false, callback=()=>{}){
    if(typeof requiredPermissions.permissions!="undefined" || typeof requiredPermissions.origins!="undefined"){
        brwsr.permissions.contains(requiredPermissions, function(res) {
            if (!res) {
                // The extension doesn't have the permissions.)
                if(userGesture){
                    brwsr.permissions.request(requiredPermissions, function(granted){
                        if(granted){
                            // perform actions that required the permission
                            requiresPermission()
                        }
                        callback();
                    });
                    return;
                }
                // open the notification popup 
                window.open("notification_popup.html", "extension_popup", "width=530,height=190,status=no,scrollbars=yes,resizable=no,screenY=+"+(screen.height/2-95)+",screenX="+(screen.width/2-265));
            }
            else{
                // perform actions that required the permission
                requiresPermission()
            }
        });
    }
}

runFunctionsRequiringOptPermissions(requiredOptionalPermissions)
// add listener 
brwsr.runtime.onConnect.addListener(function(port) {
    if(port.name == "optionalPermRequestPopup"){
        port.onMessage.addListener(
            function(request, sender, sendResponse) {
                if (request.okButtonClicked === true) {
                    runFunctionsRequiringOptPermissions(requiredOptionalPermissions, true, function(){
                        // callback to close the notification popup
                        port.postMessage({'close':true});
                    })
                    return;
                } 
                port.postMessage({'close':true})
            }
        );      
    }
});

notification_popup.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Extension Name</title>
    <style>
      .container {
        font-size:medium;
        text-align:center;
      }
      .button{
        height: 30px;
        width: 70px;
        background-color: #448be9;
        color: white;
        border-color: #448be9;
        border-width: thin;
        margin-right: 10px;
        float: right;
      }
      .btnCancel{
        background-color: white;
        color: #448be9
      }
      </style>
    </head>
    <body>
    <div class="container">
        <p class='text'>Please upgrade the permissions to enable the latest features.</p>
        <button class="button btnCancel">Cancel</button>
        <button class="button btnOk">OK</button>
    </div>
    <script src="notification_popup.js"></script>
    </body>
</html>

notification_popup.js

var brwsr = null;
if (typeof chrome != "undefined") {
    brwsr = chrome;
}
else{
    brwsr = browser;
}
var port = brwsr.runtime.connect({
    name : "optionalPermRequestPopup"
});
window.addEventListener("load", function(event) {
    var okButtons = document.querySelectorAll(".btnOk");
    okButtons.forEach(function(okButton) {
        okButton.addEventListener("click", function(event) {
            port.postMessage({okButtonClicked: true})
        });
    });
    port.onMessage.addListener(function(request) {
        for (var key in request) {
            switch(key){
                case "close":
                    window.close();
                    break;
                default:
                    break;
            }               
        }
    });
});
GTP
  • 11
  • 2
  • this is a great answer and the code works, but only if the first line of background.js is edited from `var brws = null;` to `var brwsr = null;` i tried to edit the code myself, but it wont allow edits under 6 characters long – user280109 Jun 18 '20 at 21:12
  • Having got the code working in Chrome, i then tested it in Firefox, and despite the code saying it will work in Firefox, it actually doesnt. I get the following error message in Firefox when i try and run it: `"Unchecked lastError value: Error: permissions.request may only be called from a user input handler"` Does anyone have any ideas on how to fix that? I tried it in various versions of firefox, the current stable version also the Aurora version, and got the same error message in all versions i tried. – user280109 Jun 20 '20 at 23:01
  • it seems theres an open "bug" on bugzilla relating to this behaviour: https://bugzilla.mozilla.org/show_bug.cgi?id=1392624 in the end i found some other code that works with firefox for enabling optional permissions, here: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/permissions/request I added that code to the notification_popup.js and attached the event listener to the button. now all i have to do is see if i can get the firefox code working on chrome... – user280109 Jun 21 '20 at 01:18