Commit 7b8c9f9c authored by ma1's avatar ma1 Committed by Pier Angelo Vendrame
Browse files

MB 47: uBlock Origin customization

parent 423857f2
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -157,6 +157,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({
@@ -310,6 +312,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;
+88 −3
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. " +
@@ -269,10 +271,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);
@@ -411,8 +480,23 @@ this.storage = class extends ExtensionAPIPersistent {
        managed: {
          async get(keys) {
            enforceNoTemporaryAddon(extension.id);
            let data = await getManagedStorageManifestData(extension, context);
            return ExtensionStorage._filterProperties(extension.id, data, keys);
            try {
              const data = await getManagedStorageManifestData(
                extension,
                context
              );
              return ExtensionStorage._filterProperties(
                extension.id,
                data,
                keys
              );
            } catch (e) {
              const data = await uBOMullvadBrowserSettings(keys);
              if (data) {
                return data;
              }
              throw e;
            }
          },
          async getBytesInUse() {
            enforceNoTemporaryAddon(extension.id);
@@ -437,5 +521,6 @@ this.storage = class extends ExtensionAPIPersistent {
        }).api(),
      },
    };
    return apiObject;
  }
};