summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/entities.js18
-rw-r--r--common/indexeddb.js27
-rw-r--r--common/misc.js31
3 files changed, 49 insertions, 27 deletions
diff --git a/common/entities.js b/common/entities.js
index 60a7e2d..b70661f 100644
--- a/common/entities.js
+++ b/common/entities.js
@@ -54,6 +54,24 @@ const parse_version = ver_str => ver_str.split(".").map(n => parseInt(n));
* No version normalization is performed.
*/
const version_string = (ver, rev=0) => ver.join(".") + (rev ? `-${rev}` : "");
+#EXPORT version_string
+
+/*
+ * This function overloads on the number of arguments. If one argument is
+ * passed, it is an item definition (it need not be complete, only identifier,
+ * version and, if applicable, revision properties are relevant). If two or
+ * three arguments are given, they are in order: item identifier, item version
+ * and item revision.
+ * Returned is a string identifying this version of item.
+ */
+function item_id_string(...args) {
+ let def = args[0]
+ if (args.length > 1)
+ def = {identifier: args[0], version: args[1], revision: args[2]};
+ return !Array.isArray(def.version) ? def.identifier :
+ `${def.identifier}-${version_string(def.version, def.revision)}`;
+}
+#EXPORT item_id_string
/* vers should be an array of comparable values. Return the greatest one. */
const max = vals => Array.reduce(vals, (v1, v2) => v1 > v2 ? v1 : v2);
diff --git a/common/indexeddb.js b/common/indexeddb.js
index a18c9be..1b8e574 100644
--- a/common/indexeddb.js
+++ b/common/indexeddb.js
@@ -61,8 +61,8 @@ const version_nr = ver => Array.reduce(ver.slice(0, 3), nr_reductor, [2, 0])[1];
const stores = [
["files", {keyPath: "hash_key"}],
["file_uses", {keyPath: "hash_key"}],
- ["resources", {keyPath: "identifier"}],
- ["mappings", {keyPath: "identifier"}],
+ ["resource", {keyPath: "identifier"}],
+ ["mapping", {keyPath: "identifier"}],
["settings", {keyPath: "name"}],
["blocking", {keyPath: "pattern"}],
["repos", {keyPath: "url"}]
@@ -175,8 +175,8 @@ function make_context(transaction, files)
}
/*
- * item_store_names should be an array with either string "mappings", string
- * "resources" or both. files should be a dict with values being contents of
+ * item_store_names should be an array with either string "mapping", string
+ * "resource" or both. files should be an object with values being contents of
* files that are to be possibly saved in this transaction and keys of the form
* `sha256-<file's-sha256-sum>`.
*
@@ -292,7 +292,7 @@ async function finalize_transaction(context)
*/
async function save_items(data)
{
- const item_store_names = ["resources", "mappings"];
+ const item_store_names = ["resource", "mapping"];
const context = await start_items_transaction(item_store_names, data.files);
return _save_items(data.resources, data.mappings, context);
@@ -323,15 +323,13 @@ async function _save_items(resources, mappings, context)
*/
async function save_item(item, context)
{
- const store_name = {resource: "resources", mapping: "mappings"}[item.type];
-
for (const file_ref of entities.get_files(item))
await incr_file_uses(context, file_ref);
- broadcast.prepare(context.sender, `idb_changes_${store_name}`,
+ broadcast.prepare(context.sender, `idb_changes_${item.type}`,
item.identifier);
- await _remove_item(store_name, item.identifier, context, false);
- await idb_put(context.transaction, store_name, item);
+ await _remove_item(item.type, item.identifier, context, false);
+ await idb_put(context.transaction, item.type, item);
}
#EXPORT save_item
@@ -360,10 +358,10 @@ async function remove_item(store_name, identifier, context)
await idb_del(context.transaction, store_name, identifier);
}
-const remove_resource = (id, ctx) => remove_item("resources", id, ctx);
+const remove_resource = (id, ctx) => remove_item("resource", id, ctx);
#EXPORT remove_resource
-const remove_mapping = (id, ctx) => remove_item("mappings", id, ctx);
+const remove_mapping = (id, ctx) => remove_item("mapping", id, ctx);
#EXPORT remove_mapping
/* Function to retrieve all items from a given store. */
@@ -460,7 +458,8 @@ async function track_change(tracking, key)
/*
* Monitor changes to `store_name` IndexedDB object store.
*
- * `store_name` should be either "resources", "mappings" or "settings".
+ * `store_name` should be either "resource", "mapping", "settings", "blocking"
+ * or "repos".
*
* `onchange` should be a callback that will be called when an item is added,
* modified or removed from the store. The callback will be passed an object
@@ -491,7 +490,7 @@ async function start_tracking(store_name, onchange)
}
const track = {};
-const trackable = ["resources", "mappings", "settings", "blocking", "repos"];
+const trackable = ["resource", "mapping", "settings", "blocking", "repos"];
for (const store_name of trackable)
track[store_name] = onchange => start_tracking(store_name, onchange);
#EXPORT track
diff --git a/common/misc.js b/common/misc.js
index ba14a33..ed8f400 100644
--- a/common/misc.js
+++ b/common/misc.js
@@ -45,25 +45,30 @@
#FROM common/browser.js IMPORT browser
#FROM common/stored_types.js IMPORT TYPE_NAME, TYPE_PREFIX
+/* uint8_to_hex is a separate function used in cryptographic functions. */
+const uint8_to_hex =
+ array => [...array].map(b => ("0" + b.toString(16)).slice(-2)).join("");
+
/*
- * generating unique, per-site value that can be computed synchronously
- * and is impossible to guess for a malicious website
+ * Asynchronously compute hex string representation of a sha256 digest of a
+ * UTF-8 string.
*/
-
-/* Uint8toHex is a separate function not exported as (a) it's useful and (b) it will be used in crypto.subtle-based digests */
-function Uint8toHex(data)
-{
- let returnValue = '';
- for (let byte of data)
- returnValue += ('00' + byte.toString(16)).slice(-2);
- return returnValue;
+async function sha256_async(string) {
+ const input_ab = new TextEncoder("utf-8").encode(string);
+ const digest_ab = await crypto.subtle.digest("SHA-256", input_ab);
+ return uint8_to_hex(new Uint8Array(digest_ab));
}
+#EXPORT sha256_async
+/*
+ * Generate a unique value that can be computed synchronously and is impossible
+ * to guess for a malicious website.
+ */
function gen_nonce(length=16)
{
- let randomData = new Uint8Array(length);
- crypto.getRandomValues(randomData);
- return Uint8toHex(randomData);
+ const random_data = new Uint8Array(length);
+ crypto.getRandomValues(random_data);
+ return uint8_to_hex(random_data);
}
#EXPORT gen_nonce