tor-browser

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

ContentPermissionPrompt.sys.mjs (4898B)


      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 const lazy = {};
      6 
      7 ChromeUtils.defineESModuleGetters(lazy, {
      8  Integration: "resource://gre/modules/Integration.sys.mjs",
      9  PermissionUI: "resource:///modules/PermissionUI.sys.mjs",
     10 });
     11 /**
     12 * ContentPermissionIntegration is responsible for showing the user
     13 * simple permission prompts when content requests additional
     14 * capabilities.
     15 *
     16 * While there are some built-in permission prompts, createPermissionPrompt
     17 * can also be overridden by system add-ons or tests to provide new ones.
     18 *
     19 * This override ability is provided by Integration.sys.mjs. See
     20 * PermissionUI.sys.mjs for an example of how to provide a new prompt
     21 * from an add-on.
     22 */
     23 const ContentPermissionIntegration = {
     24  /**
     25   * Creates a PermissionPrompt for a given permission type and
     26   * nsIContentPermissionRequest.
     27   *
     28   * @param {string} type
     29   *        The type of the permission request from content. This normally
     30   *        matches the "type" field of an nsIContentPermissionType, but it
     31   *        can be something else if the permission does not use the
     32   *        nsIContentPermissionRequest model. Note that this type might also
     33   *        be different from the permission key used in the permissions
     34   *        database.
     35   *        Example: "geolocation"
     36   * @param {nsIContentPermissionRequest} request
     37   *        The request for a permission from content.
     38   * @returns {PermissionPrompt?} (see PermissionUI.sys.mjs),
     39   *         or undefined if the type cannot be handled.
     40   */
     41  createPermissionPrompt(type, request) {
     42    switch (type) {
     43      case "geolocation": {
     44        return new lazy.PermissionUI.GeolocationPermissionPrompt(request);
     45      }
     46      case "xr": {
     47        return new lazy.PermissionUI.XRPermissionPrompt(request);
     48      }
     49      case "desktop-notification": {
     50        return new lazy.PermissionUI.DesktopNotificationPermissionPrompt(
     51          request
     52        );
     53      }
     54      case "persistent-storage": {
     55        return new lazy.PermissionUI.PersistentStoragePermissionPrompt(request);
     56      }
     57      case "midi": {
     58        return new lazy.PermissionUI.MIDIPermissionPrompt(request);
     59      }
     60      case "storage-access": {
     61        return new lazy.PermissionUI.StorageAccessPermissionPrompt(request);
     62      }
     63      case "localhost": {
     64        return new lazy.PermissionUI.LocalHostPermissionPrompt(request);
     65      }
     66      case "local-network": {
     67        return new lazy.PermissionUI.LocalNetworkPermissionPrompt(request);
     68      }
     69    }
     70    return undefined;
     71  },
     72 };
     73 
     74 export function ContentPermissionPrompt() {}
     75 
     76 ContentPermissionPrompt.prototype = {
     77  classID: Components.ID("{d8903bf6-68d5-4e97-bcd1-e4d3012f721a}"),
     78 
     79  QueryInterface: ChromeUtils.generateQI(["nsIContentPermissionPrompt"]),
     80 
     81  /**
     82   * This implementation of nsIContentPermissionPrompt.prompt ensures
     83   * that there's only one nsIContentPermissionType in the request,
     84   * and that it's of type nsIContentPermissionType. Failing to
     85   * satisfy either of these conditions will result in this method
     86   * throwing NS_ERRORs. If the combined ContentPermissionIntegration
     87   * cannot construct a prompt for this particular request, an
     88   * NS_ERROR_FAILURE will be thrown.
     89   *
     90   * Any time an error is thrown, the nsIContentPermissionRequest is
     91   * cancelled automatically.
     92   *
     93   * @param {nsIContentPermissionRequest} request
     94   *        The request that we're to show a prompt for.
     95   */
     96  prompt(request) {
     97    if (request.element && request.element.fxrPermissionPrompt) {
     98      // For Firefox Reality on Desktop, switch to a different mechanism to
     99      // prompt the user since fewer permissions are available and since many
    100      // UI dependencies are not availabe.
    101      request.element.fxrPermissionPrompt(request);
    102      return;
    103    }
    104 
    105    let type;
    106    try {
    107      // Only allow exactly one permission request here.
    108      let types = request.types.QueryInterface(Ci.nsIArray);
    109      if (types.length != 1) {
    110        throw Components.Exception(
    111          "Expected an nsIContentPermissionRequest with only 1 type.",
    112          Cr.NS_ERROR_UNEXPECTED
    113        );
    114      }
    115 
    116      type = types.queryElementAt(0, Ci.nsIContentPermissionType).type;
    117      let combinedIntegration = lazy.Integration.contentPermission.getCombined(
    118        ContentPermissionIntegration
    119      );
    120 
    121      let permissionPrompt = combinedIntegration.createPermissionPrompt(
    122        type,
    123        request
    124      );
    125      if (!permissionPrompt) {
    126        throw Components.Exception(
    127          `Failed to handle permission of type ${type}`,
    128          Cr.NS_ERROR_FAILURE
    129        );
    130      }
    131 
    132      permissionPrompt.prompt();
    133    } catch (ex) {
    134      console.error(ex);
    135      request.cancel();
    136      throw ex;
    137    }
    138  },
    139 };