- commit
- 900fced1b4d7bf350aedef3caaae94d08f54a774
- parent
- f238c98c2caac2dc63eb0b1138073aa36997460a
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2022-10-15 11:43
avoid state in background page
Diffstat
| M | manifest.json | 3 | ++- |
| M | src/bg.js | 183 | +++++++++++++++++++++++++++++++++---------------------------- |
2 files changed, 102 insertions, 84 deletions
diff --git a/manifest.json b/manifest.json
@@ -14,7 +14,8 @@ 14 14 "48": "icon.svg" 15 15 }, 16 16 "background": {17 -1 "scripts": ["src/shared.js", "src/bg.js"]-1 17 "scripts": ["src/shared.js", "src/bg.js"], -1 18 "persistent": false 18 19 }, 19 20 "content_scripts": [{ 20 21 "js": ["src/content.js"],
diff --git a/src/bg.js b/src/bg.js
@@ -1,38 +1,45 @@ 1 1 /* global browser shared */ 2 23 -1 var rules = {};4 -1 var requests = {};5 -16 3 var getHostname = function(url) { 7 4 var u = new URL(url); 8 5 return u.hostname; 9 6 }; 10 7 -1 8 var getRules = function() { -1 9 return browser.storage.local.get('rules').then(data => data.rules || {}); -1 10 }; -1 11 -1 12 var getRequests = function() { -1 13 return browser.storage.local.get('requests').then(data => data.requests || {}); -1 14 }; -1 15 11 16 var setRule = function(context, hostname, type, rule) {12 -1 if (hostname === 'first-party') {13 -1 context = '*';14 -1 }15 -1 if (!rules[context]) {16 -1 rules[context] = {};17 -1 }18 -1 if (!rules[context][hostname]) {19 -1 rules[context][hostname] = {};20 -1 }21 -1 if (rule) {22 -1 rules[context][hostname][type] = rule;23 -1 } else {24 -1 delete rules[context][hostname][type];25 -1 if (Object.keys(rules[context][hostname]).length === 0) {26 -1 delete rules[context][hostname];-1 17 return getRules().then(rules => { -1 18 if (hostname === 'first-party') { -1 19 context = '*'; 27 20 }28 -1 if (Object.keys(rules[context]).length === 0) {29 -1 delete rules[context];-1 21 if (!rules[context]) { -1 22 rules[context] = {}; 30 23 }31 -1 }32 -1 browser.storage.local.set({'rules': rules});-1 24 if (!rules[context][hostname]) { -1 25 rules[context][hostname] = {}; -1 26 } -1 27 if (rule) { -1 28 rules[context][hostname][type] = rule; -1 29 } else { -1 30 delete rules[context][hostname][type]; -1 31 if (Object.keys(rules[context][hostname]).length === 0) { -1 32 delete rules[context][hostname]; -1 33 } -1 34 if (Object.keys(rules[context]).length === 0) { -1 35 delete rules[context]; -1 36 } -1 37 } -1 38 return browser.storage.local.set({'rules': rules}); -1 39 }); 33 40 }; 34 4135 -1 var restrictRules = function(context) {-1 42 var restrictRules = function(rules, context) { 36 43 var restricted = {}; 37 44 restricted['*'] = rules['*'] || {}; 38 45 restricted[context] = rules[context] || {}; @@ -40,22 +47,28 @@ var restrictRules = function(context) { 40 47 }; 41 48 42 49 var pushRequest = function(tabId, hostname, type) {43 -1 if (!requests[tabId]) {44 -1 requests[tabId] = {};45 -1 }46 -1 if (!requests[tabId][hostname]) {47 -1 requests[tabId][hostname] = {};48 -1 }49 -1 if (!requests[tabId][hostname][type]) {50 -1 requests[tabId][hostname][type] = 0;51 -1 }52 -1 requests[tabId][hostname][type] += 1;-1 50 return getRequests().then(requests => { -1 51 if (!requests[tabId]) { -1 52 requests[tabId] = {}; -1 53 } -1 54 if (!requests[tabId][hostname]) { -1 55 requests[tabId][hostname] = {}; -1 56 } -1 57 if (!requests[tabId][hostname][type]) { -1 58 requests[tabId][hostname][type] = 0; -1 59 } -1 60 requests[tabId][hostname][type] += 1; -1 61 return browser.storage.local.set({'requests': requests}); -1 62 }); 53 63 }; 54 64 55 65 var clearRequests = function(tabId) {56 -1 if (requests[tabId]) {57 -1 delete requests[tabId];58 -1 }-1 66 return getRequests().then(requests => { -1 67 if (requests[tabId]) { -1 68 delete requests[tabId]; -1 69 } -1 70 return browser.storage.local.set({'requests': requests}); -1 71 }); 59 72 }; 60 73 61 74 var getCurrentTab = function() { @@ -67,36 +80,39 @@ var getCurrentTab = function() { 67 80 68 81 browser.runtime.onMessage.addListener((msg, sender) => { 69 82 if (msg.type === 'get') {70 -1 return getCurrentTab().then(tab => {-1 83 return Promise.all([ -1 84 getCurrentTab(), -1 85 getRules(), -1 86 getRequests(), -1 87 ]).then(([tab, rules, requests]) => { 71 88 var context = msg.data || getHostname(tab.url); 72 89 return { 73 90 context: context,74 -1 rules: restrictRules(context),-1 91 rules: restrictRules(rules, context), 75 92 requests: requests[tab.id] || {}, 76 93 }; 77 94 }); 78 95 } else if (msg.type === 'setRule') {79 -1 setRule(-1 96 return setRule( 80 97 msg.data.context, 81 98 msg.data.hostname, 82 99 msg.data.type, 83 100 msg.data.value,84 -1 );85 -1 return Promise.resolve(restrictRules(msg.data.context));-1 101 ).then(getRules).then(rules => { -1 102 return restrictRules(rules, msg.data.context); -1 103 }); 86 104 } else if (msg.type === 'getAllRules') {87 -1 return Promise.resolve(rules);-1 105 return getRules(); 88 106 } else if (msg.type === 'setAllRules') {89 -1 rules = msg.data;90 -1 browser.storage.local.set({'rules': rules});91 -1 return Promise.resolve();-1 107 return browser.storage.local.set({'rules': msg.data}); 92 108 } else if (msg.type === 'securitypolicyviolation') {93 -1 pushRequest(sender.tab.id, 'inline', msg.data);-1 109 return pushRequest(sender.tab.id, 'inline', msg.data); 94 110 } 95 111 }); 96 112 97 113 browser.tabs.onRemoved.addListener(clearRequests); 98 114 browser.webNavigation.onBeforeNavigate.addListener(details => {99 -1 clearRequests(details.tabId);-1 115 return clearRequests(details.tabId); 100 116 }); 101 117 102 118 browser.webRequest.onBeforeRequest.addListener(details => { @@ -112,49 +128,50 @@ browser.webRequest.onBeforeRequest.addListener(details => { 112 128 var hostname = getHostname(details.url); 113 129 var type = shared.TYPE_MAP[details.type] || 'other'; 114 130115 -1 pushRequest(details.tabId, hostname, type);116 -1117 -1 if (!shared.shouldAllow(rules, context, hostname, type)) {118 -1 if (details.type === 'sub_frame') {119 -1 return {redirectUrl: 'data:,' + encodeURIComponent(details.url)};120 -1 } else {121 -1 return {cancel: true};-1 131 return Promise.all([ -1 132 pushRequest(details.tabId, hostname, type), -1 133 getRules(), -1 134 ]).then(([_, rules]) => { -1 135 if (!shared.shouldAllow(rules, context, hostname, type)) { -1 136 if (details.type === 'sub_frame') { -1 137 return {redirectUrl: 'data:,' + encodeURIComponent(details.url)}; -1 138 } else { -1 139 return {cancel: true}; -1 140 } 122 141 }123 -1 }-1 142 }); 124 143 }, {urls: ['<all_urls>']}, ['blocking']); 125 144 126 145 browser.webRequest.onHeadersReceived.addListener(function(details) {127 -1 var context = getHostname(details.url);128 -1129 -1 var header = type => {130 -1 if (shared.shouldAllow(rules, context, 'inline', type)) {131 -1 return 'Content-Security-Policy-Report-Only';132 -1 } else {133 -1 return 'Content-Security-Policy';134 -1 }135 -1 };-1 146 return getRules().then(rules => { -1 147 var context = getHostname(details.url); -1 148 -1 149 var header = type => { -1 150 if (shared.shouldAllow(rules, context, 'inline', type)) { -1 151 return 'Content-Security-Policy-Report-Only'; -1 152 } else { -1 153 return 'Content-Security-Policy'; -1 154 } -1 155 }; -1 156 -1 157 details.responseHeaders.push({ -1 158 name: header('css'), -1 159 value: "style-src 'self' *", -1 160 }); -1 161 details.responseHeaders.push({ -1 162 name: header('script'), -1 163 value: "script-src 'self' *", -1 164 }); -1 165 details.responseHeaders.push({ -1 166 name: header('media'), -1 167 value: "img-src 'self' *", -1 168 }); 136 169137 -1 details.responseHeaders.push({138 -1 name: header('css'),139 -1 value: "style-src 'self' *",140 -1 });141 -1 details.responseHeaders.push({142 -1 name: header('script'),143 -1 value: "script-src 'self' *",-1 170 return { -1 171 responseHeaders: details.responseHeaders, -1 172 }; 144 173 });145 -1 details.responseHeaders.push({146 -1 name: header('media'),147 -1 value: "img-src 'self' *",148 -1 });149 -1150 -1 return {151 -1 responseHeaders: details.responseHeaders,152 -1 };153 174 }, { 154 175 urls: ['<all_urls>'], 155 176 types: ['main_frame'], 156 177 }, ['blocking', 'responseHeaders']);157 -1158 -1 browser.storage.local.get('rules').then(stored => {159 -1 rules = stored.rules || {};160 -1 });