Skip to content

Commit 6344d12

Browse files
committed
Stateless-compatibile TabGuard.
1 parent 95da855 commit 6344d12

File tree

4 files changed

+64
-18
lines changed

4 files changed

+64
-18
lines changed

src/bg/TabGuard.js

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,62 @@
1818
* this program. If not, see <https://www.gnu.org/licenses/>.
1919
*/
2020

21+
// depends on /nscl/common/SessionCache.js
22+
// depends on /nscl/service/TabCache.js
23+
// depends on /nscl/service/TabTies.js
2124

2225
var TabGuard = (() => {
23-
(async () => { await include(["/nscl/service/TabCache.js", "/nscl/service/TabTies.js"]); })();
2426

25-
const anonymizedTabs = new Map();
26-
browser.tabs.onRemoved.addListener(tab => {
27-
anonymizedTabs.delete(tab.id);
27+
let anonymizedTabs = new Map();
28+
browser.tabs.onRemoved.addListener(({id}) => {
29+
if (anonymizedTabs.has(id)) {
30+
anonymizedTabs.delete(id);
31+
session.save();
32+
}
2833
});
2934

30-
const anonymizedRequests = new Set();
35+
const anonymizedRequests = new Set(); // ephemeral, lifespan is webRequest
36+
37+
// Domain groups:
38+
// property keys are domains, property values are domain Sets
39+
// (session-persisted)
40+
41+
let Groups = {
42+
allowed: {},
43+
filtered: {},
44+
};
45+
const forget = () => {
46+
Groups.allowed = {};
47+
Groups.filtered = {};
48+
};
3149

32-
let allowedGroups, filteredGroups;
33-
let forget = () => {
34-
allowedGroups = {};
35-
filteredGroups = {};
50+
const groupsSerDe = (source, callback) => {
51+
const target = {};
52+
for (const [which, group] of Object.entries(source)) {
53+
const targetGroup = {};
54+
for (const [domain, otherDomains] of Object.entries(group)) {
55+
targetGroup[domain] = callback(otherDomains);
56+
}
57+
target[which] = targetGroup;
58+
}
59+
return target;
3660
};
37-
forget();
61+
const session = new SessionCache(
62+
"TabGuard", // storageKey
63+
{
64+
afterLoad(data) { // afterLoad
65+
if (!data) return;
66+
anonymizedTabs = new Map(data.anonymizedTabs);
67+
Groups = groupsSerDe(data.Groups, domainsArray => new Set(domainsArray));
68+
},
69+
beforeSave() {
70+
return {
71+
anonymizedTabs: [...anonymizedTabs],
72+
Groups: groupsSerDe(Groups, domainsSet => [...domainsSet]),
73+
}
74+
},
75+
}
76+
);
3877

3978
function mergeGroups(groups,
4079
{tabDomain, otherDomains}, /* anonymizedTabInfo */
@@ -48,6 +87,7 @@ var TabGuard = (() => {
4887
(groups[d] || (groups[d] = new Set())).add(tabDomain);
4988
}
5089
}
90+
session.save();
5191
}
5292

5393
const AUTH_HEADERS_RX = /^(?:authorization|cookie)/i;
@@ -65,9 +105,10 @@ var TabGuard = (() => {
65105
return flat;
66106
}
67107

68-
let scheduledCuts = new Set();
108+
const scheduledCuts = new Set();
69109

70110
return {
111+
wakening: Promise.all([TabCache.wakening, TabTies.wakening, session.load()]),
71112
forget,
72113
// must be called from a webRequest.onBeforeSendHeaders blocking listener
73114
onSend(request) {
@@ -199,7 +240,7 @@ var TabGuard = (() => {
199240
suspiciousDomains.push(getDomain(tab.url));
200241
}));
201242

202-
const legitDomains = allowedGroups[tabDomain] || new Set();
243+
const legitDomains = Groups.allowed[tabDomain] || new Set();
203244
legitDomains.add(tabDomain);
204245

205246
let otherDomains = new Set(suspiciousDomains.filter(d => d && !legitDomains.has(d)));
@@ -213,11 +254,13 @@ var TabGuard = (() => {
213254
requestHeaders = requestHeaders.filter(h => !AUTH_HEADERS_RX.test(h.name));
214255
debug("[TabGuard] Removing auth headers from %o (%o)", request, requestHeaders);
215256
anonymizedTabs.set(tabId, {tabDomain, otherDomains: [...otherDomains]});
257+
session.save();
258+
216259
anonymizedRequests.add(request.id);
217260
return {requestHeaders};
218261
};
219262

220-
let quietDomains = filteredGroups[tabDomain];
263+
let quietDomains = Groups.filtered[tabDomain];
221264
if (mainFrame) {
222265
const promptOption = ns.sync.TabGuardPrompt;
223266

@@ -238,9 +281,9 @@ var TabGuard = (() => {
238281
if (ret.button !== 0) {
239282
return {cancel: true};
240283
}
241-
const groups = ret.option === 0 ? filteredGroups : allowedGroups;
284+
const groups = ret.option === 0 ? Groups.filtered : Groups.allowed;
242285
mergeGroups(groups, {tabDomain, otherDomains});
243-
return groups === filteredGroups ? filterAuth() : null;
286+
return groups === Groups.filtered ? filterAuth() : null;
244287
})();
245288
}
246289
}
@@ -288,7 +331,7 @@ var TabGuard = (() => {
288331
allow(tabId) {
289332
if (!TabGuard.isAnonymizedTab(tabId)) return;
290333
const info = this.getAnonymizedTabInfo(tabId);
291-
mergeGroups(allowedGroups, info);
334+
mergeGroups(Groups.allowed, info);
292335
}
293336
}
294337
})();

src/bg/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
if (!isTorBrowser) {
8888
await include("/nscl/service/prefetchCSSResources.js");
8989
}
90-
90+
await TabGuard.wakening;
9191
await RequestGuard.start();
9292

9393
try {

src/manifest.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,12 @@
5858
"/nscl/common/DNS.js",
5959
"/nscl/common/AddressMatcherWithDNS.js",
6060
"/nscl/common/iputil.js",
61+
"/nscl/common/SessionCache.js",
6162
"/nscl/service/DocStartInjection.js",
6263
"/nscl/service/LastListener.js",
6364
"/nscl/service/patchWorkers.js",
65+
"/nscl/service/TabCache.js",
66+
"/nscl/service/TabTies.js",
6467
"ui/Prompts.js",
6568
"xss/XSS.js",
6669
"bg/ReportingCSP.js",

src/nscl

Submodule nscl updated from 3ba8d9a to 9705b11

0 commit comments

Comments
 (0)