async function run()

in src/js/relay.firefox.com/get_profile_data.js [43:332]


  async function run() {
    // Get the api token from the account profile page
    const profileMainElement = document.querySelector("#profile-main");
    const apiToken = profileMainElement.dataset.apiToken;
    await browser.storage.local.set({ apiToken });

    // API URL is ${RELAY_SITE_ORIGIN}/api/v1/
    const { relayApiSource } = await browser.storage.local.get("relayApiSource");

    const apiProfileURL = `${relayApiSource}/profiles/`;
    const relayApiUrlRelayAddresses = `${relayApiSource}/relayaddresses/`;
    const relayApiUrlDomainAddresses = `${relayApiSource}/domainaddresses/`;
    const relayApiUrlRelayNumbers = `${relayApiSource}/relaynumber/`;

    async function apiRequest(url, method = "GET", body = null, opts=null) {

      const cookieString =
        typeof document.cookie === "string" ? document.cookie : "";
      const cookieStringArray = cookieString
        .split(";")
        .map((individualCookieString) => individualCookieString.split("="))
        .map(([cookieKey, cookieValue]) => [
          cookieKey.trim(),
          cookieValue.trim(),
        ]);

      const [_csrfCookieKey, csrfCookieValue] = cookieStringArray.find(
        ([cookieKey, _cookieValue]) => cookieKey === "csrftoken"
      );

      browser.storage.local.set({ csrfCookieValue: csrfCookieValue });


      const headers = new Headers();


      headers.set("X-CSRFToken", csrfCookieValue);
      headers.set("Content-Type", "application/json");
      headers.set("Accept", "application/json");

      if (opts && opts.auth) {
        const apiToken = await browser.storage.local.get("apiToken");
        headers.set("Authorization", `Token ${apiToken.apiToken}`);
      }


      const response = await fetch(url, {
        mode: "same-origin",
        method,
        headers: headers,
        body,
      });

      const answer = await response.json();
      return answer;
    }

    const serverProfileData = await apiRequest(apiProfileURL);

    browser.storage.local.set({
      profileID: parseInt(serverProfileData[0].id, 10),
      server_storage: serverProfileData[0].server_storage,
      has_phone: serverProfileData[0].has_phone,
      has_vpn: serverProfileData[0].has_vpn,
      date_subscribed: serverProfileData[0].date_subscribed
    });

    const siteStorageEnabled = serverProfileData[0].server_storage;

    const relayNumbers = await apiRequest(relayApiUrlRelayNumbers);
    if (Array.isArray(relayNumbers) && relayNumbers.length > 0) {
      browser.storage.local.set({
        relayNumbers: relayNumbers,
      });
    }

    /**
     * Fetch the current list of random masks from the server, while preserving local labels if present
     *
     * @param {{ fetchCustomMasks?: boolean }} options - Set `fetchCustomMasks` to `true` if the user is a Premium user.
     */
    async function refreshLocalLabelCache(options = {}) {
      /** @type {RandomMask[]} */
      const relayAddresses = await apiRequest(relayApiUrlRelayAddresses);
      const domainAddresses = options.fetchCustomMasks
        ? await apiRequest(relayApiUrlDomainAddresses)
        : [];
      await browser.storage.local.set({
        relayAddresses:
          (await applyLocalLabels(relayAddresses))
          .concat(await applyLocalLabels(domainAddresses)),
      });
    }

    /**
     * Copy over locally-stored labels to the given addresses
     *
     * If the user has disabled server-side label storage, the add-on may still
     * store data like labels and the websites an address has been used on
     * locally. When we refresh the address data from the server, we'll want to
     * copy over the labels from our local cache of addresses to the new list
     * we just fetched.
     *
     * @param {RandomMask[]} addresses
     * @returns {Promise<RandomMask[]>}
     */
    async function applyLocalLabels(addresses) {
      if (siteStorageEnabled) {
        return addresses;
      }

      const localAddressCache = (await browser.storage.local.get("relayAddresses")).relayAddresses ?? [];
      return addresses.map(address => {
        const matchingLocalAddress = localAddressCache.find((localAddress) => {
          return (
            localAddress.id === address.id &&
            localAddress.address === address.address &&
            localAddress.domain === address.domain
          );
        });

        return {
          ...address,
          description: matchingLocalAddress?.description ?? address.description,
          generated_for: matchingLocalAddress?.generated_for ?? address.generated_for,
          used_on: matchingLocalAddress?.used_on ?? address.used_on,
        };
      });
    }

    // Check if user is premium
    const isPremiumUser = document.querySelector(
        "firefox-private-relay-addon-data"
      ).dataset.hasPremium === "true";
    browser.storage.local.set({ premium: isPremiumUser });

    // Get FXA Stuff
    const fxaSubscriptionsUrl = document.querySelector(
      "firefox-private-relay-addon-data"
    ).dataset.fxaSubscriptionsUrl;
    const aliasesUsedVal = document.querySelector(
      "firefox-private-relay-addon-data"
    ).dataset.aliasesUsedVal;
    const emailsForwardedVal = document.querySelector(
      "firefox-private-relay-addon-data"
    ).dataset.emailsForwardedVal;
    const emailsBlockedVal = document.querySelector(
      "firefox-private-relay-addon-data"
    ).dataset.emailsBlockedVal;
    const emailTrackersRemovedVal = document.querySelector(
      "firefox-private-relay-addon-data"
    ).dataset.emailTrackersRemovedVal;
    const premiumSubdomainSet = document.querySelector(
      "firefox-private-relay-addon-data"
    ).dataset.premiumSubdomainSet;

    browser.storage.local.set({
      fxaSubscriptionsUrl,
      aliasesUsedVal,
      emailsForwardedVal,
      emailsBlockedVal,
      emailTrackersRemovedVal,
      premiumSubdomainSet,
    });

    // Loop through an array of aliases and see if any of them have descriptions, generated_for, or used_on set.
    function aliasesHaveStoredMetadata(aliases) {
      for (const alias of aliases) {
        if (
          typeof alias.description === "string" &&
          alias.description.length > 0
        ) {
          return true;
        }

        if (typeof alias.generated_for === "string" && alias.generated_for.length > 0) {
          return true;
        }

        if (typeof alias.used_on === "string" && alias.used_on.length > 0) {
          return true;
        }
      }
    }

    // Loop through local storage aliases and sync any metadata they have with the server dataset
    async function sendMetaDataToServer(aliases) {
      for (const alias of aliases) {
        const body = {
          description: alias.description ?? "",
          generated_for: alias.generated_for ?? "",
          used_on: alias.used_on ?? "",
        };

        if (body.description.length > 0 || body.generated_for.length > 0 || body.used_on.length > 0) {
          const endpoint = alias.mask_type === "custom" ? relayApiUrlDomainAddresses : relayApiUrlRelayAddresses;
          await apiRequest(`${endpoint}${alias.id}/`, "PATCH", JSON.stringify(body), {auth: true});
        }
      }
    }

    // Loop through the temp array that is about to be synced with the server dataset and
    // be sure it matches the local storage metadata dataset
    function getAliasesWithUpdatedMetadata(updatedAliases, prevAliases) {
      return prevAliases.map(prevAlias => {
        const updatedAlias = updatedAliases.find(otherAlias => otherAlias.id === prevAlias.id) ?? { description: "", generated_for: "", used_on: ""};
        return {
          ...prevAlias,
          description: updatedAlias.description.length > 0 ? updatedAlias.description : prevAlias.description,
          generated_for: updatedAlias.generated_for.length > 0 ? updatedAlias.generated_for : prevAlias.generated_for,
          used_on: updatedAlias.used_on.length > 0 ? updatedAlias.used_on : prevAlias.used_on,
        };
      }
    )}

    if (siteStorageEnabled) {
      // Sync alias data from server page.
      // If local storage items exist AND have label metadata stored, sync it to the server.
      const remoteCopyOfServerMasks = await browser.runtime.sendMessage({
        method: "getAliasesFromServer",
        options: { fetchCustomMasks: isPremiumUser },
      });

      // let usage: This data may be overwritten when merging the local storage dataset with the server set.
      let localCopyOfServerMasks = remoteCopyOfServerMasks;

      // Check/cache local storage
      const { relayAddresses } = await browser.storage.local.get("relayAddresses");

      if (
        relayAddresses &&
        relayAddresses.length > 0 &&
        aliasesHaveStoredMetadata(relayAddresses) && // Make sure there is meta data in the local dataset
        !aliasesHaveStoredMetadata(localCopyOfServerMasks) // Make sure there is no meta data in the server dataset
      ) {
        await sendMetaDataToServer(relayAddresses);
        localCopyOfServerMasks = getAliasesWithUpdatedMetadata(
          localCopyOfServerMasks,
          relayAddresses
        );
      }

      browser.storage.local.set({ relayAddresses: localCopyOfServerMasks });
    } else {
      const { relayAddresses: existingLocalStorageRelayAddresses } = await browser.storage.local.get(
        "relayAddresses"
      );
      if (!existingLocalStorageRelayAddresses || existingLocalStorageRelayAddresses.length === 0) {
        await refreshLocalLabelCache({ fetchCustomMasks: isPremiumUser });
      }
    }

    document.querySelector(
      "firefox-private-relay-addon"
    ).addEventListener("website", async (event) => {
      if (event.detail.type === "labelUpdate") {
        const { relayAddresses } = await browser.storage.local.get("relayAddresses");
        const update = event.detail;
        const oldAddress = relayAddresses.find(existingAddress =>
          existingAddress.id === update.alias.id &&
          existingAddress.address === update.alias.address &&
          existingAddress.domain === update.alias.domain
        );
        const newAddresses = relayAddresses.filter(existingAddress => existingAddress !== oldAddress);
        newAddresses.push({
          ...oldAddress,
          description: update.newLabel,
        });
        await browser.storage.local.set({ relayAddresses: newAddresses });
      }

      if (event.detail.type === "aliasListUpdate") {
        await refreshLocalLabelCache({ fetchCustomMasks: isPremiumUser });
      }

      if (event.detail.type === "subdomainClaimed") {
        browser.storage.local.set({
          premiumSubdomainSet: event.detail.subdomain ?? "None",
        });
      }
    });

    browser.runtime.sendMessage({
      method: "updateAddOnAuthStatus",
      status: true,
    });
    browser.runtime.sendMessage({
      method: "rebuildContextMenuUpgrade",
    });
  }