Revision cf838016
Added by koszko over 1 year ago
| background/patterns_query_manager.js | ||
|---|---|---|
| 4 | 4 |
* Function: Instantiate the Pattern Tree data structure, filled with mappings |
| 5 | 5 |
* from IndexedDB. |
| 6 | 6 |
* |
| 7 |
* Copyright (C) 2021,2022 Wojtek Kosior |
|
| 7 |
* Copyright (C) 2021, 2022 Wojtek Kosior
|
|
| 8 | 8 |
* |
| 9 | 9 |
* This program is free software: you can redistribute it and/or modify |
| 10 | 10 |
* it under the terms of the GNU General Public License as published by |
| ... | ... | |
| 110 | 110 |
pqt.register(tree, object.pattern, "~allow", object.allow + 0); |
| 111 | 111 |
} |
| 112 | 112 |
|
| 113 |
#IF MOZILLA || MV3 |
|
| 114 | 113 |
const id = kind === "mappings" ? object.identifier : object.pattern; |
| 115 | 114 |
currently_registered.set(id, object); |
| 116 |
#ENDIF |
|
| 117 | 115 |
} |
| 118 | 116 |
|
| 119 | 117 |
function changed(kind, change) {
|
| ... | ... | |
| 126 | 124 |
pqt.deregister(tree, change.key, "~allow"); |
| 127 | 125 |
} |
| 128 | 126 |
|
| 129 |
#IF MOZILLA || MV3 |
|
| 130 | 127 |
currently_registered.delete(change.key); |
| 131 |
#ENDIF |
|
| 132 | 128 |
} |
| 133 | 129 |
|
| 134 | 130 |
if (change.new_val !== undefined) |
| background/webrequest.js | ||
|---|---|---|
| 113 | 113 |
if (details.type !== "xmlhttprequest") |
| 114 | 114 |
return {cancel: true};
|
| 115 | 115 |
|
| 116 |
if (details.url.startsWith(redirect_url_template)) |
|
| 117 |
return; |
|
| 118 |
|
|
| 116 | 119 |
#IF DEBUG |
| 117 | 120 |
console.debug(`Settings queried using XHR for '${details.url}'.`);
|
| 118 | 121 |
#ENDIF |
| ... | ... | |
| 130 | 133 |
return {cancel: true};
|
| 131 | 134 |
} |
| 132 | 135 |
|
| 133 |
const policy = decide_policy(tree, details.url, default_allow, secret);
|
|
| 136 |
const policy = decide_policy(tree, queried_url, default_allow, secret);
|
|
| 134 | 137 |
if (!policy.error) {
|
| 135 | 138 |
const encoded_policy = encodeURIComponent(JSON.stringify(policy)); |
| 136 | 139 |
return {redirectUrl: redirect_url_template + encoded_policy};
|
| 137 | 140 |
} |
| 138 | 141 |
} |
| 139 | 142 |
|
| 140 |
console.warn(`Bad request! Expected ${browser.runtime.getURL("dummy")}?url=<valid_urlencoded_url>. Got ${request_url}. This might be the result of page fingerprinting the browser.`);
|
|
| 143 |
console.warn(`Bad request! Expected ${browser.runtime.getURL("dummy")}?url=<valid_urlencoded_url>. Got ${details.url}. This might be the result of page fingerprinting the browser.`);
|
|
| 141 | 144 |
|
| 142 | 145 |
return {cancel: true};
|
| 143 | 146 |
} |
| common/broadcast.js | ||
|---|---|---|
| 119 | 119 |
{
|
| 120 | 120 |
if (conn.type === "sender") |
| 121 | 121 |
flush(conn); |
| 122 |
setTimeout(conn.port.disconnect()); |
|
| 122 |
setTimeout(() => conn.port.disconnect());
|
|
| 123 | 123 |
} |
| 124 | 124 |
#EXPORT close |
| common/browser.js | ||
|---|---|---|
| 3 | 3 |
* |
| 4 | 4 |
* Function: Export the browser API object. |
| 5 | 5 |
* |
| 6 |
* Copyright (C) 2021 Wojtek Kosior |
|
| 6 |
* Copyright (C) 2021, 2022 Wojtek Kosior
|
|
| 7 | 7 |
* |
| 8 | 8 |
* This program is free software: you can redistribute it and/or modify |
| 9 | 9 |
* it under the terms of the CC0 1.0 Universal License as published by |
| ... | ... | |
| 21 | 21 |
|
| 22 | 22 |
#ELIF CHROMIUM |
| 23 | 23 |
|
| 24 |
/* Use promises for sendMessage(). */ |
|
| 25 |
function response_cb(resolve, reject, response) {
|
|
| 26 |
if (arguments.length < 3) |
|
| 27 |
reject(chrome.runtime.lastError); |
|
| 28 |
else |
|
| 29 |
resolve(response); |
|
| 30 |
} |
|
| 31 |
|
|
| 32 |
function replacement_sendMessage(old_sendMessage, ...args) {
|
|
| 33 |
let callbacks, prom = new Promise((...cbs) => callbacks = cbs); |
|
| 34 |
old_sendMessage(...args, resp => response_cb(...callbacks, resp)); |
|
| 35 |
return prom; |
|
| 36 |
} |
|
| 37 |
|
|
| 38 |
for (const api_object of [chrome.tabs, chrome.runtime].filter(a => a)) {
|
|
| 39 |
const old_sendMessage = api_object.sendMessage; |
|
| 40 |
api_object.sendMessage = |
|
| 41 |
(...args) => replacement_sendMessage(old_sendMessage, ...args); |
|
| 42 |
} |
|
| 43 |
|
|
| 24 | 44 |
#EXPORT chrome AS browser |
| 25 | 45 |
|
| 26 | 46 |
#ENDIF |
| content/content.js | ||
|---|---|---|
| 45 | 45 |
|
| 46 | 46 |
#FROM common/browser.js IMPORT browser |
| 47 | 47 |
#FROM common/misc.js IMPORT is_privileged_url |
| 48 |
#FROM common/policy.js IMPORT decide_policy |
|
| 48 |
#FROM common/policy.js IMPORT decide_policy, fallback_policy
|
|
| 49 | 49 |
#FROM content/policy_enforcing.js IMPORT enforce_blocking |
| 50 | 50 |
|
| 51 |
#IF CHROMIUM && MV2 |
|
| 52 |
function synchronously_get_policy(url) |
|
| 53 |
{
|
|
| 54 |
const encoded_url = encodeURIComponent(url); |
|
| 55 |
const request_url = `${browser.runtime.getURL("dummy")}?url=${encoded_url}`;
|
|
| 56 |
|
|
| 57 |
try {
|
|
| 58 |
var xhttp = new XMLHttpRequest(); |
|
| 59 |
xhttp.open("GET", request_url, false);
|
|
| 60 |
xhttp.send(); |
|
| 61 |
} catch(e) {
|
|
| 62 |
console.error("Failure to synchronously fetch policy for url.", e);
|
|
| 63 |
return fallback_policy(); |
|
| 64 |
} |
|
| 65 |
|
|
| 66 |
try {
|
|
| 67 |
const policy = /^[^?]*\?settings=(.*)$/.exec(xhttp.responseURL)[1]; |
|
| 68 |
return JSON.parse(decodeURIComponent(policy)); |
|
| 69 |
} catch(e) {
|
|
| 70 |
console.error("Failure to process synchronously fetched policy for url.", e);
|
|
| 71 |
return fallback_policy() |
|
| 72 |
} |
|
| 73 |
} |
|
| 74 |
#ENDIF |
|
| 75 |
|
|
| 51 | 76 |
let already_run = false, resolve_page_info, |
| 52 | 77 |
page_info_prom = new Promise(cb => resolve_page_info = cb); |
| 53 | 78 |
|
| ... | ... | |
| 60 | 85 |
return true; |
| 61 | 86 |
} |
| 62 | 87 |
|
| 88 |
#IF MOZILLA || MV3 |
|
| 63 | 89 |
globalThis.haketilo_content_script_main = async function() {
|
| 90 |
#ELSE |
|
| 91 |
async function main() {
|
|
| 92 |
#ENDIF |
|
| 64 | 93 |
if (already_run) |
| 65 | 94 |
return; |
| 66 | 95 |
|
| ... | ... | |
| 72 | 101 |
browser.runtime.onMessage.addListener(on_page_info_request); |
| 73 | 102 |
repo_query_cacher.start(); |
| 74 | 103 |
|
| 75 |
const policy = decide_policy(globalThis.haketilo_pattern_tree, |
|
| 76 |
document.URL, |
|
| 77 |
globalThis.haketilo_default_allow, |
|
| 78 |
globalThis.haketilo_secret); |
|
| 104 |
#IF MOZILLA || MV3 |
|
| 105 |
try {
|
|
| 106 |
var policy = decide_policy(globalThis.haketilo_pattern_tree, |
|
| 107 |
document.URL, |
|
| 108 |
globalThis.haketilo_default_allow, |
|
| 109 |
globalThis.haketilo_secret); |
|
| 110 |
} catch(e) {
|
|
| 111 |
console.error(e); |
|
| 112 |
var policy = fallback_policy(); |
|
| 113 |
} |
|
| 114 |
#ELSE |
|
| 115 |
const policy = synchronously_get_policy(document.URL); |
|
| 116 |
#ENDIF |
|
| 117 |
|
|
| 79 | 118 |
const page_info = Object.assign({url: document.URL}, policy);
|
| 80 | 119 |
["csp", "nonce"].forEach(prop => delete page_info[prop]); |
| 81 | 120 |
|
| ... | ... | |
| 108 | 147 |
resolve_page_info(page_info); |
| 109 | 148 |
} |
| 110 | 149 |
|
| 150 |
#IF MOZILLA || MV3 |
|
| 111 | 151 |
function main() {
|
| 112 | 152 |
if (globalThis.haketilo_pattern_tree !== undefined) |
| 113 | 153 |
globalThis.haketilo_content_script_main(); |
| 114 | 154 |
} |
| 155 |
#ENDIF |
|
| 115 | 156 |
|
| 116 | 157 |
#IF !UNIT_TEST |
| 117 | 158 |
main(); |
| content/repo_query_cacher.js | ||
|---|---|---|
| 42 | 42 |
* proprietary program, I am not going to enforce this in court. |
| 43 | 43 |
*/ |
| 44 | 44 |
|
| 45 |
#FROM common/browser.js IMPORT browser |
|
| 46 |
|
|
| 45 | 47 |
/* |
| 46 | 48 |
* Map URLs to objects containing parsed responses, error info or promises |
| 47 | 49 |
* resolving to those. |
| manifest.json | ||
|---|---|---|
| 79 | 79 |
"open_in_tab": true, |
| 80 | 80 |
"browser_style": false |
| 81 | 81 |
}, |
| 82 |
#IF CHROMIUM && MV2 |
|
| 82 | 83 |
#COPY_FILE dummy |
| 83 | 84 |
"web_accessible_resources": ["dummy"], |
| 85 |
#ENDIF |
|
| 84 | 86 |
"background": {
|
| 85 | 87 |
"persistent": true, |
| 86 | 88 |
"scripts": [ |
Also available in: Unified diff
restore chromium support