#166 Handle userScripts API permissions change
Closed: Fixed by polcak. Opened by gioma1.

TLDR: in Chromium 138 and above we need to change the messaging around requiring additional permissions / settings for wrapper injection from asking the developer mode to asking the new userScripts permissions. The affected code in common.css, helpers.js, options.html and popup.html can be easily found by looking for the string "devmode".

Announcement from Google:

We have an upcoming change to how Chrome extensions utilize the chrome.userScripts API. We are transitioning from using the global Developer Mode toggle for enabling this API to a new toggle per developer feedback. This toggle remains an additional step to the extension being granted the userScripts permission.

New Per-Extension "Allow User Scripts" Toggle

In milestone 138, instead of relying on the global Developer Mode toggle, users will be able to manage the chrome.userScripts API permission on a per-extension basis. This new toggle will be accessible on the extension detail page (chrome://extensions/?id=).

chrome.userScripts API with the new toggle disabled is now undefined

In addition, to check the availability of the User Scripts API, extensions previously had to attempt to access chrome.userScripts. This threw an error if developer mode was disabled. From Chrome 138, the behavior aligns with other APIs and the API is undefined if unavailable.

// Before Chrome 138 and the Developer Mode toggle disabled:
chrome.userScripts;
// Output (throws error): The 'userScripts' API is only available for users in developer mode.
// After Chrome 138 and the new toggle is disabled:
chrome.userScripts;
// Output: returns `undefined`

Transition Period, Migration and Documentation Update

During this transition period, any versions prior to the above milestone will continue using the Developer Mode toggle and those at or above the release milestone will use the new per-extension "Allow User Scripts" toggle. This means that while users update both toggles will exist (depending on the Chrome version of the user) as the feature rolls out. We will be updating the developer documentation for the chrome.userScripts API to clearly explain both methods of enabling the API so both can be referred to.

When the new toggle rolls out it does a one-time migration of any existing extensions to reduce user disruption. The logic for this is: if the userScripts permission is granted to the extension and the Developer Mode toggle is on then the new toggle will be set to on, otherwise the new toggle will be set to off. Any new extensions installed after the migration will default with the new toggle set to off.

See the release schedule for dates on when this change will reach stable.

Detecting the New Toggle in Your Code

To help you adapt your extension and potentially provide a smoother user onboarding experience during this transition period, you can use the following JavaScript check to determine which toggle mechanism is currently active:

let version = Number(navigator.userAgent.match(/(Chrome|Chromium)\/([0-9]+)/)?.[2]);
if (version > 138) {
  // Allow User Scripts toggle will be used.
} else {
  // Developer Mode toggle will be used.
}

Early Testing Opportunity

Developers who wish to experiment with the new per-extension Allow User Scripts toggle can do so by launching Chrome with the following command-line flag:

--enable-features=UserScriptUserExtensionToggle

This will allow you to preview and test the new behavior before it becomes the default.

We believe this change will provide users with more granular control over extension capabilities and enhance the overall security and transparency of Chrome extensions. We encourage you to familiarize yourselves with these upcoming changes and update your extensions accordingly.


Hello, thank you for kicking this.

So 138 should be the next release, so we need to act quickly. @gioma1, should I work on the code?

I am a little bit confused because in the TLDR summary, it looks like there will be a new permission that the users would need to provide consistently with other permissions but later it looks like the users need to change a toggle after they install JShelter.

The issue does not contain any URL, can you at least provide URLs that you think we should add to the user-facing texts?

So 138 should be the next release, so we need to act quickly. @gioma1, should I work on the code?

Yes please, if it's possible to you. Otherwise let me know and I'll try to find the time for a patch.

it looks like there will be a new permission that the users would need to provide consistently with other permissions but later it looks like the users need to change a toggle after they install JShelter.

My understanding is that it's exactly the same as the developer option, i.e. you need to enable the toggle independently from the initial permissions dialog, BUT that the toggle appears in the extensions management page only after you grant the userScripts permission:

"After your extension receives the permission to use the userScripts API, users must enable a specific toggle to allow your extension to use the API. The specific toggle required, and the API's behavior when disabled, vary by Chrome version."

The issue does not contain any URL, can you at least provide URLs that you think we should add to the user-facing texts?

In the announcement they said they were going to update the docs, and here they did (the previous link should still work for the other toggle):

https://developer.chrome.com/docs/extensions/reference/api/userScripts/index.md#chrome_versions_138_and_newer_allow_user_scripts_toggle

I experimented with --enable-features=UserScriptUserExtensionToggle and also reviewed the code around:

https://pagure.io/JShelter/webextension/blob/main/f/common/helpers.js#_297

and it seems to me that the code is robust to handle the switch without a need to rewrite.

So the only needed change is rephrasing the message shown to the user. We do not have facilities to change or show a string based on the browser version so I took an easy way how to display a string that is more meaningful to the user.

This will be a part of 0.20.3 soon to be released.

I am not closing the issue right now as I wrote the code in a way to be easily removed and changed once all or most users migrate to 138 or later. Such change can happen in say September 2025 or later.

What should be done:

  • Revert https://pagure.io/JShelter/webextension/c/c69b4cbf0dfa63be3090a1ae8740dbb285273dfe?branch=main and https://pagure.io/JShelter/webextension/c/ca7ef88efb741777466a40a65267f0ec1f1237eb?branch=main
  • Change https://pagure.io/JShelter/webextension/blob/697c276d428be3b291b733e44fb7f1be7bd95144/f/common/popup.html#_34 and https://pagure.io/JShelter/webextension/blob/697c276d428be3b291b733e44fb7f1be7bd95144/f/common/options.html#_62 to use MV3AllowUserScriptsRequired and remove https://pagure.io/JShelter/webextension/blob/e02a66b760c3e3c48f66689c755259095ae4181a/f/common/_locales/en/messages.json#_1327 from all translations.

Fix completed in 0.22, commit id 12c85c5c

Metadata Update from @polcak:
- Issue close_status updated to: Fixed
- Issue status updated to: Closed (was: Open)

Metadata