mirror of
				https://github.com/mozilla/gecko-dev.git
				synced 2025-11-04 02:09:05 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			151 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 | 
						|
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
 | 
						|
 | 
						|
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
 | 
						|
 | 
						|
const lazy = {};
 | 
						|
 | 
						|
ChromeUtils.defineESModuleGetters(lazy, {
 | 
						|
  ClientID: "resource://gre/modules/ClientID.sys.mjs",
 | 
						|
  ContextualIdentityService:
 | 
						|
    "resource://gre/modules/ContextualIdentityService.sys.mjs",
 | 
						|
});
 | 
						|
 | 
						|
const RECOMMENDATION_ENABLED = "browser.discovery.enabled";
 | 
						|
const TELEMETRY_ENABLED = "datareporting.healthreport.uploadEnabled";
 | 
						|
const TAAR_COOKIE_NAME = "taarId";
 | 
						|
 | 
						|
export const Discovery = {
 | 
						|
  set enabled(val) {
 | 
						|
    val = !!val;
 | 
						|
    if (val && !lazy.gTelemetryEnabled) {
 | 
						|
      throw Error("unable to turn on recommendations");
 | 
						|
    }
 | 
						|
    Services.prefs.setBoolPref(RECOMMENDATION_ENABLED, val);
 | 
						|
  },
 | 
						|
 | 
						|
  get enabled() {
 | 
						|
    return lazy.gTelemetryEnabled && lazy.gRecommendationEnabled;
 | 
						|
  },
 | 
						|
 | 
						|
  reset() {
 | 
						|
    return DiscoveryInternal.update(true);
 | 
						|
  },
 | 
						|
 | 
						|
  update() {
 | 
						|
    return DiscoveryInternal.update();
 | 
						|
  },
 | 
						|
};
 | 
						|
 | 
						|
XPCOMUtils.defineLazyPreferenceGetter(
 | 
						|
  lazy,
 | 
						|
  "gRecommendationEnabled",
 | 
						|
  RECOMMENDATION_ENABLED,
 | 
						|
  false,
 | 
						|
  Discovery.update
 | 
						|
);
 | 
						|
XPCOMUtils.defineLazyPreferenceGetter(
 | 
						|
  lazy,
 | 
						|
  "gTelemetryEnabled",
 | 
						|
  TELEMETRY_ENABLED,
 | 
						|
  false,
 | 
						|
  Discovery.update
 | 
						|
);
 | 
						|
XPCOMUtils.defineLazyPreferenceGetter(
 | 
						|
  lazy,
 | 
						|
  "gCachedClientID",
 | 
						|
  "toolkit.telemetry.cachedClientID",
 | 
						|
  "",
 | 
						|
  Discovery.reset
 | 
						|
);
 | 
						|
XPCOMUtils.defineLazyPreferenceGetter(
 | 
						|
  lazy,
 | 
						|
  "gContainersEnabled",
 | 
						|
  "browser.discovery.containers.enabled",
 | 
						|
  false,
 | 
						|
  Discovery.reset
 | 
						|
);
 | 
						|
 | 
						|
Services.obs.addObserver(Discovery.update, "contextual-identity-created");
 | 
						|
 | 
						|
const DiscoveryInternal = {
 | 
						|
  get sites() {
 | 
						|
    delete this.sites;
 | 
						|
    this.sites = Services.prefs
 | 
						|
      .getCharPref("browser.discovery.sites", "")
 | 
						|
      .split(",");
 | 
						|
    return this.sites;
 | 
						|
  },
 | 
						|
 | 
						|
  getContextualIDs() {
 | 
						|
    // There is never a zero id, this is just for use in update.
 | 
						|
    let IDs = [0];
 | 
						|
    if (lazy.gContainersEnabled) {
 | 
						|
      lazy.ContextualIdentityService.getPublicIdentities().forEach(identity => {
 | 
						|
        IDs.push(identity.userContextId);
 | 
						|
      });
 | 
						|
    }
 | 
						|
    return IDs;
 | 
						|
  },
 | 
						|
 | 
						|
  async update(reset = false) {
 | 
						|
    if (reset || !Discovery.enabled) {
 | 
						|
      for (let site of this.sites) {
 | 
						|
        Services.cookies.remove(site, TAAR_COOKIE_NAME, "/", {});
 | 
						|
        lazy.ContextualIdentityService.getPublicIdentities().forEach(
 | 
						|
          identity => {
 | 
						|
            let { userContextId } = identity;
 | 
						|
            Services.cookies.remove(site, TAAR_COOKIE_NAME, "/", {
 | 
						|
              userContextId,
 | 
						|
            });
 | 
						|
          }
 | 
						|
        );
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (Discovery.enabled) {
 | 
						|
      // If the client id is not cached, wait for the notification that it is
 | 
						|
      // cached.  This will happen shortly after startup in TelemetryController.sys.mjs.
 | 
						|
      // When that happens, we'll get a pref notification for the cached id,
 | 
						|
      // which will call update again.
 | 
						|
      if (!lazy.gCachedClientID) {
 | 
						|
        return;
 | 
						|
      }
 | 
						|
      let id = await lazy.ClientID.getClientIdHash();
 | 
						|
      for (let site of this.sites) {
 | 
						|
        // This cookie gets tied down as much as possible.  Specifically,
 | 
						|
        // SameSite, Secure, HttpOnly and non-PrivateBrowsing.
 | 
						|
        for (let userContextId of this.getContextualIDs()) {
 | 
						|
          let originAttributes = { privateBrowsingId: 0 };
 | 
						|
          if (userContextId > 0) {
 | 
						|
            originAttributes.userContextId = userContextId;
 | 
						|
          }
 | 
						|
          if (
 | 
						|
            Services.cookies.cookieExists(
 | 
						|
              site,
 | 
						|
              "/",
 | 
						|
              TAAR_COOKIE_NAME,
 | 
						|
              originAttributes
 | 
						|
            )
 | 
						|
          ) {
 | 
						|
            continue;
 | 
						|
          }
 | 
						|
          Services.cookies.add(
 | 
						|
            site,
 | 
						|
            "/",
 | 
						|
            TAAR_COOKIE_NAME,
 | 
						|
            id,
 | 
						|
            true, // secure
 | 
						|
            true, // httpOnly
 | 
						|
            true, // session
 | 
						|
            Date.now(),
 | 
						|
            originAttributes,
 | 
						|
            Ci.nsICookie.SAMESITE_LAX,
 | 
						|
            Ci.nsICookie.SCHEME_HTTPS
 | 
						|
          );
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  },
 | 
						|
};
 |