tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Weave.sys.mjs (5723B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
      6 
      7 const lazy = {};
      8 ChromeUtils.defineESModuleGetters(lazy, {
      9  CLIENT_NOT_CONFIGURED: "resource://services-sync/constants.sys.mjs",
     10  FileUtils: "resource://gre/modules/FileUtils.sys.mjs",
     11 });
     12 
     13 XPCOMUtils.defineLazyPreferenceGetter(
     14  lazy,
     15  "syncUsername",
     16  "services.sync.username"
     17 );
     18 
     19 /**
     20 * Sync's XPCOM service.
     21 *
     22 * It is named "Weave" for historical reasons.
     23 *
     24 * It's worth noting how Sync is lazily loaded. We register a timer that
     25 * loads Sync a few seconds after app startup. This is so Sync does not
     26 * adversely affect application start time.
     27 *
     28 * If Sync is not configured, no extra Sync code is loaded. If an
     29 * external component (say the UI) needs to interact with Sync, it
     30 * should use the promise-base function whenLoaded() - something like the
     31 * following:
     32 *
     33 * // 1. Grab a handle to the Sync XPCOM service.
     34 * let service = Cc["@mozilla.org/weave/service;1"]
     35 *                 .getService(Components.interfaces.nsISupports)
     36 *                 .wrappedJSObject;
     37 *
     38 * // 2. Use the .then method of the promise.
     39 * service.whenLoaded().then(() => {
     40 *   // You are free to interact with "Weave." objects.
     41 *   return;
     42 * });
     43 *
     44 * And that's it!  However, if you really want to avoid promises and do it
     45 * old-school, then
     46 *
     47 * // 1. Get a reference to the service as done in (1) above.
     48 *
     49 * // 2. Check if the service has been initialized.
     50 * if (service.ready) {
     51 *   // You are free to interact with "Weave." objects.
     52 *   return;
     53 * }
     54 *
     55 * // 3. Install "ready" listener.
     56 * Services.obs.addObserver(function onReady() {
     57 *   Services.obs.removeObserver(onReady, "weave:service:ready");
     58 *
     59 *   // You are free to interact with "Weave." objects.
     60 * }, "weave:service:ready", false);
     61 *
     62 * // 4. Trigger loading of Sync.
     63 * service.ensureLoaded();
     64 */
     65 export function WeaveService() {
     66  this.wrappedJSObject = this;
     67  this.ready = false;
     68 }
     69 
     70 WeaveService.prototype = {
     71  classID: Components.ID("{74b89fb0-f200-4ae8-a3ec-dd164117f6de}"),
     72 
     73  QueryInterface: ChromeUtils.generateQI([
     74    "nsIObserver",
     75    "nsISupportsWeakReference",
     76  ]),
     77 
     78  get Weave() {
     79    const { Weave } = ChromeUtils.importESModule(
     80      "resource://services-sync/main.sys.mjs"
     81    );
     82    return Weave;
     83  },
     84 
     85  ensureLoaded() {
     86    // Side-effect of accessing the service is that it is instantiated.
     87    this.Weave.Service;
     88  },
     89 
     90  whenLoaded() {
     91    if (this.ready) {
     92      return Promise.resolve();
     93    }
     94    let onReadyPromise = new Promise(resolve => {
     95      Services.obs.addObserver(function onReady() {
     96        Services.obs.removeObserver(onReady, "weave:service:ready");
     97        resolve();
     98      }, "weave:service:ready");
     99    });
    100    this.ensureLoaded();
    101    return onReadyPromise;
    102  },
    103 
    104  init() {
    105    // Force Weave service to load if it hasn't triggered from overlays
    106    this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
    107    this.timer.initWithCallback(
    108      {
    109        notify: () => {
    110          let isConfigured = false;
    111          // We only load more if it looks like Sync is configured.
    112          if (this.enabled) {
    113            // We have an associated FxAccount. So, do a more thorough check.
    114            // This will import a number of modules and thus increase memory
    115            // accordingly. We could potentially copy code performed by
    116            // this check into this file if our above code is yielding too
    117            // many false positives.
    118            var { Weave } = ChromeUtils.importESModule(
    119              "resource://services-sync/main.sys.mjs"
    120            );
    121            isConfigured =
    122              Weave.Status.checkSetup() != lazy.CLIENT_NOT_CONFIGURED;
    123          }
    124          if (isConfigured) {
    125            this.ensureLoaded();
    126          }
    127        },
    128      },
    129      10000,
    130      Ci.nsITimer.TYPE_ONE_SHOT
    131    );
    132  },
    133 
    134  /**
    135   * Whether Sync appears to be enabled.
    136   *
    137   * This returns true if we have an associated FxA account and Sync is enabled.
    138   *
    139   * It does *not* perform a robust check to see if the client is working.
    140   * For that, you'll want to check Weave.Status.checkSetup().
    141   */
    142  get enabled() {
    143    return (
    144      !!lazy.syncUsername &&
    145      Services.prefs.getBoolPref("identity.fxaccounts.enabled")
    146    );
    147  },
    148 };
    149 
    150 export function AboutWeaveLog() {}
    151 AboutWeaveLog.prototype = {
    152  classID: Components.ID("{d28f8a0b-95da-48f4-b712-caf37097be41}"),
    153 
    154  QueryInterface: ChromeUtils.generateQI([
    155    "nsIAboutModule",
    156    "nsISupportsWeakReference",
    157  ]),
    158 
    159  getURIFlags() {
    160    return 0;
    161  },
    162 
    163  newChannel(aURI, aLoadInfo) {
    164    let dir = lazy.FileUtils.getDir("ProfD", ["weave", "logs"]);
    165    try {
    166      dir.create(Ci.nsIFile.DIRECTORY_TYPE, lazy.FileUtils.PERMS_DIRECTORY);
    167    } catch (ex) {
    168      if (ex.result != Cr.NS_ERROR_FILE_ALREADY_EXISTS) {
    169        throw ex;
    170      }
    171      // Ignore the exception due to a directory that already exists.
    172    }
    173    let uri = Services.io.newFileURI(dir);
    174    let channel = Services.io.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
    175 
    176    channel.originalURI = aURI;
    177 
    178    // Ensure that the about page has the same privileges as a regular directory
    179    // view. That way links to files can be opened. make sure we use the correct
    180    // origin attributes when creating the principal for accessing the
    181    // about:sync-log data.
    182    let principal = Services.scriptSecurityManager.createContentPrincipal(
    183      uri,
    184      aLoadInfo.originAttributes
    185    );
    186 
    187    channel.owner = principal;
    188    return channel;
    189  },
    190 };