Commit c5333ad1 authored by ma1's avatar ma1 Committed by Beatriz Rizental
Browse files

MB 47: uBlock Origin customization

parent b4cbb438
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -137,6 +137,8 @@ this.storage = class extends ExtensionAPI {
      context
    );

    const isUBO = extension.id === "uBlock0@raymondhill.net";

    // onChangedName is "storage.onChanged", "storage.sync.onChanged", etc.
    function makeOnChangedEventTarget(onChangedName) {
      return new EventManager({
@@ -279,6 +281,11 @@ this.storage = class extends ExtensionAPI {
            selectedBackend = await promiseStorageLocalBackend;
          }

          if (isUBO && args[0] === "cachedManagedStorage") {
            // prevent uBO from caching adminSettings
            return Promise.resolve({});
          }

          // Let the outer try to catch rejections returned by the backend methods.
          const result = await selectedBackend[method](...args);
          return result;
+77 −4
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ XPCOMUtils.defineLazyPreferenceGetter(
  true
);

XPCOMUtils.defineLazyGlobalGetters(this, ["fetch"]);

const enforceNoTemporaryAddon = extensionId => {
  const EXCEPTION_MESSAGE =
    "The storage API will not work with a temporary addon ID. " +
@@ -254,10 +256,77 @@ this.storage = class extends ExtensionAPIPersistent {
  getAPI(context) {
    let { extension } = context;

    const NOP = async () => {};

    let apiObject;
    const isUBO = extension.id === "uBlock0@raymondhill.net";

    let uBOMullvadBrowserSettings = isUBO
      ? async keys => {
          // First thing on startup uBO checks if some adminSettings can be
          // loaded from managed storage, and we exploit this to inject our
          // settings customization.
          // See https://github.com/gorhill/uBlock/search?q=restoreAdminSettings
          if (Array.isArray(keys) && !keys.includes("adminSettings")) {
            return;
          }

          // stop intercepting managed storage for this session
          uBOMullvadBrowserSettings = NOP;

          // deuglify our storage access API
          const storage = {};
          for (let m of ["get", "set"]) {
            storage[m] = async (...args) =>
              apiObject.storage.local.callMethodInParentProcess(m, args);
          }

          // check if settings still need to be customized
          const CURRENT_VERSION = 1;
          const VERSION_KEY = "mullvad-browser/settings-version";
          const version = (await storage.get([VERSION_KEY]))[VERSION_KEY];
          if (version === CURRENT_VERSION) {
            return;
          }

          // the filter lists we want to enable by default
          const EXTRA_FILTERS = [
            "adguard-spyware-url", // strip tracking parameters
            "fanboy-cookiemonster", // hide cookie consent popups
          ];

          // load uBO's default filter lists from the extension's package
          const assetsUrl = context.uri.resolve("assets/assets.json");
          const assets = await (await fetch(assetsUrl)).json();

          // build the default selection ensuring our filter lists are included
          const selectedFilterLists = Object.entries(assets)
            .filter(
              ([key, value]) =>
                (!value.off || EXTRA_FILTERS.includes(key)) &&
                value.content === "filters"
            )
            .map(([key]) => key);
          // we're done for this version (don't mess with user choices anymore)
          await storage.set({ [VERSION_KEY]: CURRENT_VERSION });

          // enforce our list on startup
          return {
            adminSettings: {
              selectedFilterLists,
            },
          };
        }
      : NOP;

    apiObject = {
      storage: {
        local: {
          async callMethodInParentProcess(method, args) {
            if (isUBO && args[0] === "cachedManagedStorage") {
              // prevent uBO from caching adminSettings
              return Promise.resolve({});
            }
            const res = await ExtensionStorageIDB.selectBackend({ extension });
            if (!res.backendEnabled) {
              return ExtensionStorage[method](extension.id, ...args);
@@ -403,9 +472,12 @@ this.storage = class extends ExtensionAPIPersistent {

            let data = await lookup;
            if (!data) {
              return Promise.reject({
              return (
                (await uBOMullvadBrowserSettings(keys)) ||
                Promise.reject({
                  message: "Managed storage manifest not found",
              });
                })
              );
            }
            return ExtensionStorage._filterProperties(extension.id, data, keys);
          },
@@ -421,5 +493,6 @@ this.storage = class extends ExtensionAPIPersistent {
        }).api(),
      },
    };
    return apiObject;
  }
};