/
editRules.js
140 lines (130 loc) · 3.96 KB
/
editRules.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
/*
Licensed per https://github.com/privacy-tech-lab/gpc-optmeowt/blob/main/LICENSE.md
privacy-tech-lab, https://privacytechlab.org/
*/
import { storage, stores } from "../background/storage.js";
/*
editRules.js
================================================================================
editRules.js is an internal API for adding/removing GPC-exclusion dynamic rules
*/
/**
* Gets fresh rule ID for new DeclarativeNetRequest dynamic rule
* Pulls from already set dynamic rules as opposed to domainlist values
*
* NOTE: Does not 'reserve' the ID. If it isn't used on the client side,
* getFreshId() will spit out the same val next call.
* @returns {Promise<(number|null)>} - number of fresh ID, null if non available
*/
export async function getFreshId() {
const MAX_RULES =
chrome.declarativeNetRequest.MAX_NUMBER_OF_DYNAMIC_AND_SESSION_RULES;
const rules = await chrome.declarativeNetRequest.getDynamicRules();
let freshId = null;
let usedRuleIds = [];
for (let i in rules) {
usedRuleIds.push(rules[i]["id"]);
}
usedRuleIds.sort((a, b) => {
return a - b;
}); // Necessary for next for loop
// Make sure the ID starts at 1 (I think 0 is reserved?)
for (let i = 1; i < MAX_RULES; i++) {
if (i !== usedRuleIds[i - 1]) {
freshId = i; // We have found the first nonzero, unused id
break;
}
}
return freshId;
}
/**
* Deletes GPC-exclusion rule from rule set
* Does NOT remove from domainlist
* (see declarativeNetRequest)
* @param {number} id - rule id
*/
export async function deleteDynamicRule(id) {
let UpdateRuleOptions = { removeRuleIds: [id] };
await chrome.declarativeNetRequest.updateDynamicRules(UpdateRuleOptions);
}
/**
* Deletes all GPC-exclusion dynamic rules
* (see declarativeNetRequest)
*/
export async function deleteAllDynamicRules() {
let MAX_RULES =
chrome.declarativeNetRequest.MAX_NUMBER_OF_DYNAMIC_AND_SESSION_RULES;
let UpdateRuleOptions = { removeRuleIds: [...Array(MAX_RULES).keys()] };
await chrome.declarativeNetRequest.updateDynamicRules(UpdateRuleOptions);
}
/**
* Adds domain as a rule to be excluded from receiving GPC signals
* Note id should be fresh, o/w it will overwrite existing rule
* (see getFreshId, declarativeNetRequest)
* @param {number} id - rule id
* @param {string} domain - domain to associate with id
*/
export async function addDynamicRule(id, domain) {
let UpdateRuleOptions = {
addRules: [
{
id: id,
priority: 2,
action: {
type: "modifyHeaders",
requestHeaders: [
{ header: "Sec-GPC", operation: "remove" },
{ header: "DNT", operation: "remove" },
],
},
condition: {
urlFilter: domain,
resourceTypes: [
"main_frame",
"sub_frame",
"stylesheet",
"script",
"image",
"font",
"object",
"xmlhttprequest",
"ping",
"csp_report",
"media",
"websocket",
"webtransport",
"webbundle",
"other",
],
},
},
],
removeRuleIds: [id],
};
await chrome.declarativeNetRequest.updateDynamicRules(UpdateRuleOptions);
return;
}
/**
* Deletes all rules, queries current domainlist, and re-adds all rules
* - Useful when replacing the domainlist via an import/export
* - Remember rules as of v3.0.0 are 'exclusion' rules, i.e. excluded from
* receiving GPC or other opt-outs.
*/
export async function reloadDynamicRules() {
if ("$BROWSER" == "chrome") {
deleteAllDynamicRules();
let domainlist = await storage.getStore(stores.domainlist);
let promises = [];
Object.keys(domainlist).forEach(async (domain) => {
promises.push(
new Promise(async (resolve, reject) => {
let id = domainlist[domain];
if (id) {
await addDynamicRule(id, domain);
}
resolve();
})
);
});
}
}