tor-browser

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

browser_storage_permission.js (9961B)


      1 "use strict";
      2 
      3 const { PermissionTestUtils } = ChromeUtils.importESModule(
      4  "resource://testing-common/PermissionTestUtils.sys.mjs"
      5 );
      6 
      7 const BASE_URI = "http://mochi.test:8888/browser/dom/serviceworkers/test/";
      8 const PAGE_URI = BASE_URI + "empty.html";
      9 const SCOPE = PAGE_URI + "?storage_permission";
     10 const SW_SCRIPT = BASE_URI + "empty.js";
     11 
     12 add_setup(async function () {
     13  await SpecialPowers.pushPrefEnv({
     14    set: [
     15      // Until the e10s refactor is complete, use a single process to avoid
     16      // service worker propagation race.
     17      ["dom.ipc.processCount", 1],
     18      ["dom.serviceWorkers.enabled", true],
     19      ["dom.serviceWorkers.testing.enabled", true],
     20    ],
     21  });
     22 
     23  let tab = BrowserTestUtils.addTab(gBrowser, PAGE_URI);
     24  let browser = gBrowser.getBrowserForTab(tab);
     25  await BrowserTestUtils.browserLoaded(browser);
     26 
     27  await SpecialPowers.spawn(
     28    browser,
     29    [{ script: SW_SCRIPT, scope: SCOPE }],
     30    async function (opts) {
     31      let reg = await content.navigator.serviceWorker.register(opts.script, {
     32        scope: opts.scope,
     33      });
     34      let worker = reg.installing || reg.waiting || reg.active;
     35      await new Promise(resolve => {
     36        if (worker.state === "activated") {
     37          resolve();
     38          return;
     39        }
     40        worker.addEventListener("statechange", function onStateChange() {
     41          if (worker.state === "activated") {
     42            worker.removeEventListener("statechange", onStateChange);
     43            resolve();
     44          }
     45        });
     46      });
     47    }
     48  );
     49 
     50  BrowserTestUtils.removeTab(tab);
     51 });
     52 
     53 add_task(async function test_allow_permission() {
     54  PermissionTestUtils.add(
     55    PAGE_URI,
     56    "cookie",
     57    Ci.nsICookiePermission.ACCESS_ALLOW
     58  );
     59 
     60  let tab = BrowserTestUtils.addTab(gBrowser, SCOPE);
     61  let browser = gBrowser.getBrowserForTab(tab);
     62  await BrowserTestUtils.browserLoaded(browser);
     63 
     64  let controller = await SpecialPowers.spawn(browser, [], async function () {
     65    return content.navigator.serviceWorker.controller;
     66  });
     67 
     68  ok(!!controller, "page should be controlled with storage allowed");
     69 
     70  BrowserTestUtils.removeTab(tab);
     71 });
     72 
     73 add_task(async function test_deny_permission() {
     74  PermissionTestUtils.add(
     75    PAGE_URI,
     76    "cookie",
     77    Ci.nsICookiePermission.ACCESS_DENY
     78  );
     79 
     80  let tab = BrowserTestUtils.addTab(gBrowser, SCOPE);
     81  let browser = gBrowser.getBrowserForTab(tab);
     82  await BrowserTestUtils.browserLoaded(browser);
     83 
     84  let controller = await SpecialPowers.spawn(browser, [], async function () {
     85    return content.navigator.serviceWorker.controller;
     86  });
     87 
     88  is(controller, null, "page should be not controlled with storage denied");
     89 
     90  BrowserTestUtils.removeTab(tab);
     91  PermissionTestUtils.remove(PAGE_URI, "cookie");
     92 });
     93 
     94 add_task(async function test_session_permission() {
     95  PermissionTestUtils.add(
     96    PAGE_URI,
     97    "cookie",
     98    Ci.nsICookiePermission.ACCESS_SESSION
     99  );
    100 
    101  let tab = BrowserTestUtils.addTab(gBrowser, SCOPE);
    102  let browser = gBrowser.getBrowserForTab(tab);
    103  await BrowserTestUtils.browserLoaded(browser);
    104 
    105  let controller = await SpecialPowers.spawn(browser, [], async function () {
    106    return content.navigator.serviceWorker.controller;
    107  });
    108 
    109  is(controller, null, "page should be not controlled with session storage");
    110 
    111  BrowserTestUtils.removeTab(tab);
    112  PermissionTestUtils.remove(PAGE_URI, "cookie");
    113 });
    114 
    115 // Test to verify an about:blank iframe successfully inherits the
    116 // parent's controller when storage is blocked between opening the
    117 // parent page and creating the iframe.
    118 add_task(async function test_block_storage_before_blank_iframe() {
    119  PermissionTestUtils.remove(PAGE_URI, "cookie");
    120 
    121  let tab = BrowserTestUtils.addTab(gBrowser, SCOPE);
    122  let browser = gBrowser.getBrowserForTab(tab);
    123  await BrowserTestUtils.browserLoaded(browser);
    124 
    125  let controller = await SpecialPowers.spawn(browser, [], async function () {
    126    return content.navigator.serviceWorker.controller;
    127  });
    128 
    129  ok(!!controller, "page should be controlled with storage allowed");
    130 
    131  let controller2 = await SpecialPowers.spawn(browser, [], async function () {
    132    let f = content.document.createElement("iframe");
    133    content.document.body.appendChild(f);
    134    await new Promise(resolve => (f.onload = resolve));
    135    return !!f.contentWindow.navigator.serviceWorker.controller;
    136  });
    137 
    138  ok(!!controller2, "page should be controlled with storage allowed");
    139 
    140  await SpecialPowers.pushPrefEnv({
    141    set: [
    142      ["network.cookie.cookieBehavior", Ci.nsICookieService.BEHAVIOR_REJECT],
    143    ],
    144  });
    145 
    146  let controller3 = await SpecialPowers.spawn(browser, [], async function () {
    147    let f = content.document.createElement("iframe");
    148    content.document.body.appendChild(f);
    149    await new Promise(resolve => (f.onload = resolve));
    150    return !!f.contentWindow.navigator.serviceWorker.controller;
    151  });
    152 
    153  ok(!!controller3, "page should be controlled with storage allowed");
    154 
    155  await SpecialPowers.popPrefEnv();
    156  BrowserTestUtils.removeTab(tab);
    157 });
    158 
    159 // Test to verify a blob URL iframe successfully inherits the
    160 // parent's controller when storage is blocked between opening the
    161 // parent page and creating the iframe.
    162 add_task(async function test_block_storage_before_blob_iframe() {
    163  PermissionTestUtils.remove(PAGE_URI, "cookie");
    164 
    165  let tab = BrowserTestUtils.addTab(gBrowser, SCOPE);
    166  let browser = gBrowser.getBrowserForTab(tab);
    167  await BrowserTestUtils.browserLoaded(browser);
    168 
    169  let controller = await SpecialPowers.spawn(browser, [], async function () {
    170    return content.navigator.serviceWorker.controller;
    171  });
    172 
    173  ok(!!controller, "page should be controlled with storage allowed");
    174 
    175  let controller2 = await SpecialPowers.spawn(browser, [], async function () {
    176    let b = new content.Blob(["<!DOCTYPE html><html></html>"], {
    177      type: "text/html",
    178    });
    179    let f = content.document.createElement("iframe");
    180    // No need to call revokeObjectURL() since the window will be closed shortly.
    181    f.src = content.URL.createObjectURL(b);
    182    content.document.body.appendChild(f);
    183    await new Promise(resolve => (f.onload = resolve));
    184    return !!f.contentWindow.navigator.serviceWorker.controller;
    185  });
    186 
    187  ok(!!controller2, "page should be controlled with storage allowed");
    188 
    189  await SpecialPowers.pushPrefEnv({
    190    set: [
    191      ["network.cookie.cookieBehavior", Ci.nsICookieService.BEHAVIOR_REJECT],
    192    ],
    193  });
    194 
    195  let controller3 = await SpecialPowers.spawn(browser, [], async function () {
    196    let b = new content.Blob(["<!DOCTYPE html><html></html>"], {
    197      type: "text/html",
    198    });
    199    let f = content.document.createElement("iframe");
    200    // No need to call revokeObjectURL() since the window will be closed shortly.
    201    f.src = content.URL.createObjectURL(b);
    202    content.document.body.appendChild(f);
    203    await new Promise(resolve => (f.onload = resolve));
    204    return !!f.contentWindow.navigator.serviceWorker.controller;
    205  });
    206 
    207  ok(!!controller3, "page should be controlled with storage allowed");
    208 
    209  await SpecialPowers.popPrefEnv();
    210  BrowserTestUtils.removeTab(tab);
    211 });
    212 
    213 // Test to verify a blob worker script does not hit our service
    214 // worker storage assertions when storage is blocked between opening
    215 // the parent page and creating the worker.  Note, we cannot
    216 // explicitly check if the worker is controlled since we don't expose
    217 // WorkerNavigator.serviceWorkers.controller yet.
    218 add_task(async function test_block_storage_before_blob_worker() {
    219  PermissionTestUtils.remove(PAGE_URI, "cookie");
    220 
    221  let tab = BrowserTestUtils.addTab(gBrowser, SCOPE);
    222  let browser = gBrowser.getBrowserForTab(tab);
    223  await BrowserTestUtils.browserLoaded(browser);
    224 
    225  let controller = await SpecialPowers.spawn(browser, [], async function () {
    226    return content.navigator.serviceWorker.controller;
    227  });
    228 
    229  ok(!!controller, "page should be controlled with storage allowed");
    230 
    231  let scriptURL = await SpecialPowers.spawn(browser, [], async function () {
    232    let b = new content.Blob(
    233      ["self.postMessage(self.location.href);self.close()"],
    234      { type: "application/javascript" }
    235    );
    236    // No need to call revokeObjectURL() since the window will be closed shortly.
    237    let u = content.URL.createObjectURL(b);
    238    let w = new content.Worker(u);
    239    return await new Promise(resolve => {
    240      w.onmessage = e => resolve(e.data);
    241    });
    242  });
    243 
    244  ok(scriptURL.startsWith("blob:"), "blob URL worker should run");
    245 
    246  await SpecialPowers.pushPrefEnv({
    247    set: [
    248      ["network.cookie.cookieBehavior", Ci.nsICookieService.BEHAVIOR_REJECT],
    249    ],
    250  });
    251 
    252  let scriptURL2 = await SpecialPowers.spawn(browser, [], async function () {
    253    let b = new content.Blob(
    254      ["self.postMessage(self.location.href);self.close()"],
    255      { type: "application/javascript" }
    256    );
    257    // No need to call revokeObjectURL() since the window will be closed shortly.
    258    let u = content.URL.createObjectURL(b);
    259    let w = new content.Worker(u);
    260    return await new Promise(resolve => {
    261      w.onmessage = e => resolve(e.data);
    262    });
    263  });
    264 
    265  ok(scriptURL2.startsWith("blob:"), "blob URL worker should run");
    266 
    267  await SpecialPowers.popPrefEnv();
    268  BrowserTestUtils.removeTab(tab);
    269 });
    270 
    271 add_task(async function cleanup() {
    272  PermissionTestUtils.remove(PAGE_URI, "cookie");
    273 
    274  let tab = BrowserTestUtils.addTab(gBrowser, PAGE_URI);
    275  let browser = gBrowser.getBrowserForTab(tab);
    276  await BrowserTestUtils.browserLoaded(browser);
    277 
    278  await SpecialPowers.spawn(browser, [SCOPE], async function (uri) {
    279    let reg = await content.navigator.serviceWorker.getRegistration(uri);
    280    let worker = reg.active;
    281    await reg.unregister();
    282    await new Promise(resolve => {
    283      if (worker.state === "redundant") {
    284        resolve();
    285        return;
    286      }
    287      worker.addEventListener("statechange", function onStateChange() {
    288        if (worker.state === "redundant") {
    289          worker.removeEventListener("statechange", onStateChange);
    290          resolve();
    291        }
    292      });
    293    });
    294  });
    295 
    296  BrowserTestUtils.removeTab(tab);
    297 });