/
storage.js
163 lines (146 loc) · 5.22 KB
/
storage.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
Licensed per https://github.com/privacy-tech-lab/gpc-optmeowt/blob/main/LICENSE.md
privacy-tech-lab, https://privacytechlab.org/
*/
/*
storage.js
================================================================================
storage.js handles OptMeowt's reads/writes of data to some local location
If the domainlist is being handled, then cookies are added/removed here too
*/
import { openDB } from "idb";
import { storageCookies } from "./storageCookies.js";
import { reloadDynamicRules } from "../common/editRules.js";
import { saveAs } from "file-saver";
/******************************************************************************/
/************************** Enumerated settings *****************************/
/******************************************************************************/
// In general, these functions should be use with async / await for
// syntactic sweetness & synchronous data handling
// i.e., await storage.set(stores.settings, extensionMode.enabled, 'MODE')
// TODO: Make this an enum
const stores = Object.freeze({
settings: "SETTINGS",
domainlist: "DOMAINLIST",
analysis: "ANALYSIS",
});
/******************************************************************************/
/************************* Main Storage Functions ***************************/
/******************************************************************************/
const dbPromise = openDB("extensionDB", 1, {
upgrade: function dbPromiseInternal(db) {
db.createObjectStore(stores.domainlist);
db.createObjectStore(stores.settings);
db.createObjectStore(stores.analysis);
},
});
const storage = {
async get(store, key) {
return (await dbPromise).get(store, key);
},
async getAll(store) {
return (await dbPromise).getAll(store);
},
async getAllKeys(store) {
return (await dbPromise).getAllKeys(store);
},
// returns an object containing the given store
async getStore(store) {
const storeValues = await storage.getAll(store);
const storeKeys = await storage.getAllKeys(store);
let storeCopy = {};
let key;
for (let index in storeKeys) {
key = storeKeys[index];
storeCopy[key] = storeValues[index];
}
return storeCopy;
},
async set(store, value, key) {
return new Promise(async (resolve, reject) => {
// placing or deleting opt out cookies for a given domain key
// We know that `key` will be a domain, i.e. a string
if (store === stores.domainlist) {
if (value === null) {
storageCookies.addCookiesForGivenDomain(key);
} else {
storageCookies.deleteCookiesForGivenDomain(key);
}
}
(await dbPromise).put(store, value, key).then(resolve());
});
},
async delete(store, key) {
// deleting opt out cookies for a given domain key
// We know that `key` will be a domain, i.e. a string
if (store === stores.domainlist) {
storageCookies.deleteCookiesForGivenDomain(key);
}
return (await dbPromise).delete(store, key);
},
async clear(store) {
return (await dbPromise).clear(store);
},
};
/******************************************************************************/
/********************* Importing/Exporting Domain List **********************/
/******************************************************************************/
async function handleDownload() {
const DOMAINLIST = await storage.getStore(stores.domainlist);
let MANIFEST = chrome.runtime.getManifest();
if ("$BROWSER" == "firefox") {
MANIFEST.version = "2.0";
}
let data = {
VERSION: MANIFEST.version,
DOMAINLIST: DOMAINLIST,
};
let blob = new Blob([JSON.stringify(data, null, 4)], {
type: "text/plain;charset=utf-8",
});
saveAs(blob, "OptMeowt_backup.json");
}
/**
* Sets-up the process for importing a saved domainlist backup
*/
async function startUpload() {
document.getElementById("upload-domainlist").value = "";
document.getElementById("upload-domainlist").click();
}
/**
* Imports and updates the domainlist in local storage with an imported backup
*/
async function handleUpload() {
await storage.clear(stores.domainlist);
const file = this.files[0];
const fr = new FileReader();
fr.onload = function (e) {
const UPLOADED_DATA = JSON.parse(e.target.result);
let version = UPLOADED_DATA.VERSION;
let domainlist = UPLOADED_DATA.DOMAINLIST;
version = version.split(".");
let domainlist_keys = Object.keys(domainlist);
let domainlist_vals = Object.values(domainlist);
for (let i = 0; i < domainlist_keys.length; i++) {
try {
storage.set(stores.domainlist, domainlist_vals[i], domainlist_keys[i]);
} catch (error) {
alert("Error loading list");
}
}
// hardcode if it is the new version
if (Number(version[0]) >= 3) {
reloadDynamicRules();
updateRemovalScript();
} else {
chrome.runtime.sendMessage({
msg: "FORCE_RELOAD",
});
}
};
fr.readAsText(file);
}
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
export { handleDownload, startUpload, handleUpload, stores, storage };