tor-browser

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

test_remote_settings_older_than_local.js (4342B)


      1 const PREF_SETTINGS_SERVER = "services.settings.server";
      2 
      3 let server;
      4 let client;
      5 
      6 async function clear_state() {
      7  await client.db.clear();
      8 }
      9 
     10 function setJSONResponse(response, changeset) {
     11  response.setStatusLine(null, 200, "OK");
     12  response.setHeader("Content-Type", "application/json; charset=UTF-8");
     13  response.setHeader("Date", new Date().toUTCString());
     14  response.write(JSON.stringify(changeset));
     15 }
     16 
     17 add_setup(() => {
     18  Services.prefs.setStringPref("services.settings.loglevel", "debug");
     19 
     20  // Set up an HTTP Server
     21  server = new HttpServer();
     22  server.start(-1);
     23 
     24  Services.prefs.setStringPref(
     25    PREF_SETTINGS_SERVER,
     26    `http://localhost:${server.identity.primaryPort}/v1`
     27  );
     28 
     29  client = RemoteSettings("some-cid");
     30 
     31  const bodies = {
     32    // First successful sync at timestamp=333
     33    "/v1/buckets/main/collections/some-cid/changeset?_expected=333": {
     34      timestamp: 333,
     35      metadata: {
     36        signatures: [{ signature: "abc", x5u: "data:text/plain;base64,pem" }],
     37      },
     38      changes: [
     39        { id: "rid2", last_modified: 22 },
     40        { id: "rid1", last_modified: 11 },
     41      ],
     42    },
     43    // Client fetches with _expected=222&_since=333
     44    "/v1/buckets/main/collections/some-cid/changeset?_expected=222&_since=%22333%22":
     45      {
     46        timestamp: 222,
     47        metadata: {
     48          signatures: [{ signature: "ghi", x5u: "data:text/plain;base64,pem" }],
     49        },
     50        changes: [{ id: "rid1", last_modified: 11 }],
     51      },
     52    // Client refetches full collection with _expected=222 after signature fails.
     53    "/v1/buckets/main/collections/some-cid/changeset?_expected=222": {
     54      timestamp: 222,
     55      metadata: {
     56        signatures: [{ signature: "ghi", x5u: "data:text/plain;base64,pem" }],
     57      },
     58      changes: [{ id: "rid1", last_modified: 11 }],
     59    },
     60  };
     61  const handler = (request, response) => {
     62    const body = bodies[`${request.path}?${request.queryString}`];
     63    if (!body) {
     64      const err = new Error(
     65        `Unexpected request ${request.path}?${request.queryString}`
     66      );
     67      console.error(err);
     68      throw err;
     69    }
     70    setJSONResponse(response, body);
     71  };
     72  Object.keys(bodies).map(path =>
     73    server.registerPathHandler(path.split("?")[0], handler)
     74  );
     75 
     76  // In this test suite, the only valid data is the one at timestamp=222 or timestamp=333, but not a mix of the two.
     77  let backup = client._verifier;
     78  client._verifier = {
     79    asyncVerifyContentSignature: serialized => {
     80      return (
     81        serialized ==
     82          '{"data":[{"id":"rid2","last_modified":22}],"last_modified":"444"}' ||
     83        serialized ==
     84          '{"data":[{"id":"rid1","last_modified":11},{"id":"rid2","last_modified":22}],"last_modified":"333"}' ||
     85        serialized ==
     86          '{"data":[{"id":"rid1","last_modified":11}],"last_modified":"222"}'
     87      );
     88    },
     89  };
     90 
     91  registerCleanupFunction(() => {
     92    client._verifier = backup;
     93    server.stop(() => {});
     94    Services.prefs.clearUserPref(PREF_SETTINGS_SERVER);
     95 
     96    Services.prefs.clearUserPref("services.settings.loglevel");
     97  });
     98 });
     99 
    100 add_task(clear_state);
    101 
    102 add_task(async function test_ignores_if_local_signature_is_valid() {
    103  await client.maybeSync(333);
    104  Assert.deepEqual(
    105    [
    106      await client.db.getLastModified(),
    107      (await client.get()).map(({ id }) => id),
    108    ],
    109    [333, ["rid1", "rid2"]]
    110  );
    111 
    112  await client.maybeSync(222);
    113 
    114  // The client should detect that timestamp is older,
    115  // but it ignores it because local data is good.
    116  Assert.deepEqual(
    117    [
    118      await client.db.getLastModified(),
    119      (await client.get()).map(({ id }) => id),
    120    ],
    121    [333, ["rid1", "rid2"]]
    122  );
    123 });
    124 add_task(clear_state);
    125 
    126 add_task(async function test_uses_old_data_if_local_signature_is_invalid() {
    127  // Import some data in the local DB. Signature will be bad.
    128  await client.db.importChanges({}, 333, [{ id: "myid", last_modified: 1234 }]);
    129  Assert.deepEqual(
    130    [
    131      await client.db.getLastModified(),
    132      (await client.get()).map(({ id }) => id),
    133    ],
    134    [333, ["myid"]]
    135  );
    136 
    137  await client.maybeSync(222);
    138 
    139  // The client should detect that timestamp is older,
    140  // but will replace local data with this old data.
    141  Assert.deepEqual(
    142    [
    143      await client.db.getLastModified(),
    144      (await client.get()).map(({ id }) => id),
    145    ],
    146    [222, ["rid1"]]
    147  );
    148 });
    149 add_task(clear_state);