Make one click allowlisting module continue working when service workers are suspended
Background
One of the major challenges introduced by MV3 is that service workers (unlike MV2 background pages) may be suspended and restarted at any time. Our existing codebase has all been written assuming we have a long living background page, and so we can do things like hold information that's relevant between events in local variables, or register events asynchronously.
In an MV3 context, our assumptions about how our code will be run are broken. Our extension will break in all sorts of weird ways. We need to identify what those ways are and fix them.
To simplify the process of keeping our code working, making these changes has been broken down by functional area. In this issue, the one click allowlisting module should be made to continue working even if the MV3 service worker is suspended.
In https://gitlab.com/eyeo/adblockplus/abc/webext-sdk/-/merge_requests/404, we added a broad method of testing our normal functionality when the service worker is suspended frequently. This is currently skipped for the one click allowlisting tests, so as part of this issue those tests should be enabled and they should pass.
Use case
One click allowlisting continues to work in MV3, even though in MV3 the browser may suspend the service worker at any time.
What to change
- Enable fuzz tests for one click allowlisting module.
- Review the code in one click allowlisting and fix anything that would stop working if the service worker is suspended (fuzz tests should help to discover these).
- All event listeners that can wake up the service worker must be attached in the first turn of the event loop.
- Events that we emit must be able to have listeners attached in the first turn of the event loop.
- Functionality that currently requires state shared between events must keep working, for example by using a storage API for the state.
Integrator Notes
-
EWE.allowlisting.onUnauthorized
,EWE.allowlisting.setAllowlistingCallback
, andEWE.allowlisting.setAuthorizedKeys
should now all be called in the first turn of the event loop. This is to ensure that the authorized key is available if an allowlisting event activates the service worker. -
EWE.allowlisting.setAuthorizedKeys
still returns a promise, which resolves or rejects when all of the keys have been validated. It is also unchanged in that the keys are NOT updated if ANY of the keys passed in are invalid. However, a difference is that the new keys will take effect immediately. Internally, the signature verification will wait for the new keys to finish being verified before using them (if they're valid) or continuing with the previous set of authorized keys (if the new keys are not valid).