Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions lib/jquery-3.4.1.min.js

This file was deleted.

10 changes: 9 additions & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
"48": "icons/icon-48x48.png",
"128": "icons/icon-128x128.png"
},
"applications" : {
"gecko" : {
"id" : "{9a253c57-0e95-4589-be64-365b3602c564}"
}
},
"browser_action": {
"default_icon": {
"16": "icons/icon-16x16.png"
Expand All @@ -21,7 +26,10 @@
},
"content_scripts": [{
"matches" : ["*://*/*"],
"js": ["src/inject/scriptInjector.js"],
"js": [
"src/inject/scriptInjector.js"
,"src/subresourceIntegrity/subresourceIntegrity.js"
],
"all_frames": true,
"run_at": "document_start"
}],
Expand Down
25 changes: 14 additions & 11 deletions src/background/background.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@
<meta charset="utf-8" />
</head>
<body>
<script src="init.js"></script>
<script src="util.js"></script>
<script src="keyvalDB.js"></script>
<script src="match.js"></script>
<script src="requestIdTracker.js"></script>
<script src="tabUrlTracker.js"></script>
<script src="extractMime.js"></script>
<script src="mainStorage.js"></script>
<script src="headerHandling.js"></script>
<script src="requestHandling.js"></script>
<script src="background.js"></script>
<script type="module" src="init.js"></script>
<script type="module" src="util.js"></script>
<script type="module" src="keyvalDB.js"></script>
<script type="module" src="match.js"></script>
<script type="module" src="requestIdTracker.js"></script>
<script type="module" src="tabUrlTracker.js"></script>
<script type="module" src="extractMime.js"></script>
<script type="module" src="mainStorage.js"></script>
<script type="module" src="headerHandling.js"></script>
<script type="module" src="parseHTML.js"></script>
<script type="module" src="htmlWebRequestProcessor.js"></script>
<script type="module" src="removeIntegrity.js"></script>
<script type="module" src="requestHandling.js"></script>
<script type="module" src="background.js"></script>
</body>
</html>
274 changes: 149 additions & 125 deletions src/background/background.js
Original file line number Diff line number Diff line change
@@ -1,143 +1,167 @@
/* globals chrome, bgapp, unescape, match */
{
bgapp.ruleDomains = {};
bgapp.syncFunctions = [];
/* globals chrome, unescape, match */
import {capabilities} from "./init.js"
import {simpleError} from "./util.js"
import {extractMimeType} from "./extractMime.js"
import {mainStorage} from "./mainStorage.js"
import {requestIdTracker} from "./requestIdTracker.js"
import {tabUrlTracker} from "./tabUrlTracker.js"
import {handleRequest} from "./requestHandling.js"
import {makeHeaderHandler} from "./headerHandling.js"

const simpleError = bgapp.util.simpleError;
export let ruleDomains = {};
export let syncFunctions = [];

// Called when the user clicks on the browser action icon.
chrome.browserAction.onClicked.addListener(function() {
// open or focus options page.
const optionsUrl = chrome.runtime.getURL("src/ui/devtoolstab.html");
chrome.tabs.query({}, function(extensionTabs) {
let found = false;
for (let i = 0, len = extensionTabs.length; i < len; i++) {
if (optionsUrl === extensionTabs[i].url) {
found = true;
chrome.tabs.update(extensionTabs[i].id, {selected: true});
break;
}
// Called when the user clicks on the browser action icon.
chrome.browserAction.onClicked.addListener(function() {
// open or focus options page.
const optionsUrl = chrome.runtime.getURL("src/ui/devtoolstab.html");
chrome.tabs.query({}, function(extensionTabs) {
let found = false;
for (let i = 0, len = extensionTabs.length; i < len; i++) {
if (optionsUrl === extensionTabs[i].url) {
found = true;
chrome.tabs.update(extensionTabs[i].id, {selected: true});
break;
}
if (found === false) {
chrome.tabs.create({url: optionsUrl});
}
});
}
if (found === false) {
chrome.tabs.create({url: optionsUrl});
}
});
});

const syncAllInstances = function() {
// Doing this weird dance because I cant figure out how to
// send data from this script to the dev tools script.
// Nothing seems to work (even the examples!).
bgapp.syncFunctions.forEach(function(fn) {
try {
fn();
} catch (e) { /**/ }
});
bgapp.syncFunctions = [];
};
const syncAllInstances = function() {
// Doing this weird dance because I cant figure out how to
// send data from this script to the dev tools script.
// Nothing seems to work (even the examples!).
syncFunctions.forEach(function(fn) {
try {
fn();
} catch (e) { /**/ }
});
syncFunctions = [];
};

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.action === "saveDomain") {
bgapp.mainStorage.put(request.data)
.then(syncAllInstances)
.catch(simpleError);
bgapp.ruleDomains[request.data.id] = request.data;
} else if (request.action === "getDomains") {
bgapp.mainStorage.getAll().then(function(domains) {
sendResponse(domains || []);
}).catch(simpleError);
} else if (request.action === "deleteDomain") {
bgapp.mainStorage.delete(request.id)
.then(syncAllInstances)
.catch(simpleError);
delete bgapp.ruleDomains[request.id];
} else if (request.action === "import") {
let maxId = 0;
for (const id in bgapp.ruleDomains) {
maxId = Math.max(maxId, parseInt(id.substring(1)));
}
maxId++;
Promise.all(request.data.map(function(domainData) {
// dont overwrite any pre-existing domains.
domainData.id = "d" + maxId++;
bgapp.ruleDomains[domainData.id] = domainData;
return bgapp.mainStorage.put(domainData);
}))
const messageEventsProcessors = new Map([
["saveDomain", (request, sender) => {
mainStorage.put(request.data)
.then(syncAllInstances)
.catch(simpleError);
} else if (request.action === "makeGetRequest") {
const xhr = new XMLHttpRequest();
xhr.open("GET", request.url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
sendResponse(xhr.responseText);
}
};
xhr.send();
} else if (request.action === "setSetting") {
localStorage[request.setting] = request.value;
} else if (request.action === "getSetting") {
sendResponse(localStorage[request.setting]);
} else if (request.action === "syncMe") {
bgapp.syncFunctions.push(sendResponse);
} else if (request.action === "match") {
sendResponse(match(request.domainUrl, request.windowUrl).matched);
} else if (request.action === "extractMimeType") {
sendResponse(bgapp.extractMimeType(request.fileName, request.file));
ruleDomains[request.data.id] = request.data;
}],
["getDomains", (request, sender) => {
return mainStorage.getAll().then(function(domains) {
return domains || [];
});
}],
["deleteDomain", (request, sender) => {
mainStorage.delete(request.id)
.then(syncAllInstances)
.catch(simpleError);
delete ruleDomains[request.id];
}],
["import", (request, sender) => {
let maxId = 0;
for (const id in ruleDomains) {
maxId = Math.max(maxId, parseInt(id.substring(1)));
}
maxId++;
Promise.all(request.data.map(function(domainData) {
// dont overwrite any pre-existing domains.
domainData.id = "d" + maxId++;
ruleDomains[domainData.id] = domainData;
return mainStorage.put(domainData);
}))
.then(syncAllInstances)
.catch(simpleError);
}],
["makeGetRequest", (request, sender) => {
return fetch(request.url, {"headers": {"Origin": null}, "referrer": "no-referrer"}).then(e=>e.text());
}],
["setSetting", (request, sender) => {
localStorage[request.setting] = request.value;
}],
["getSetting", (request, sender) => {
return Promise.resolve(localStorage[request.setting]);
}],
["syncMe", (request, sender) => {
return new Promise((resolve, reject) => {
syncFunctions.push(resolve);
});
}],
["match", (request, sender) => {
return Promise.resolve(match(request.domainUrl, request.windowUrl).matched);
}],
["extractMimeType", (request, sender) => {
return Promise.resolve(extractMimeType(request.fileName, request.file));
}],
["getCapabilities", () => {return Promise.resolve(capabilities);}],
]);

// !!!Important!!! Need to return true for sendResponse to work.
return true;
});
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
return messageEventsProcessors.get(request.action)(request, sender);
});

chrome.webRequest.onBeforeRequest.addListener(function(details) {
if (!bgapp.requestIdTracker.has(details.requestId)) {
if (details.tabId > -1) {
let tabUrl = bgapp.tabUrlTracker.getUrlFromId(details.tabId);
if (details.type === "main_frame") {
// a new tab must have just been created.
tabUrl = details.url;
}
if (tabUrl) {
const result = bgapp.handleRequest(details.url, tabUrl, details.tabId, details.requestId);
if (result) {
// make sure we don't try to redirect again.
bgapp.requestIdTracker.push(details.requestId);
}
return result;
}
}

function processOnlyTabTrackedURIs(details, callback){
if (details.tabId > -1) {
let tabUrl = tabUrlTracker.getUrlFromId(details.tabId);
if (details.type === "main_frame") {
// a new tab must have just been created.
tabUrl = details.url;
}
if (tabUrl) {
return callback(details, tabUrl);
}
}, {
urls: ["<all_urls>"]
}, ["blocking"]);
}
}

chrome.webRequest.onHeadersReceived.addListener(bgapp.makeHeaderHandler("response"), {
urls: ["<all_urls>"]
}, ["blocking", "responseHeaders"]);

chrome.webRequest.onBeforeSendHeaders.addListener(bgapp.makeHeaderHandler("request"), {
urls: ["<all_urls>"]
}, ["blocking", "requestHeaders"]);
chrome.webRequest.onBeforeRequest.addListener(function(details) {
processOnlyTabTrackedURIs(details, (details, tabUrl) => {
if (!requestIdTracker.has(details.requestId)) {
const result = handleRequest(details, tabUrl);
if (result) {
// make sure we don't try to redirect again.
requestIdTracker.push(details.requestId);
}
return result;
}
});
}, {
urls: ["<all_urls>"]
}, ["blocking"]);

//init settings
if (localStorage.devTools === undefined) {
localStorage.devTools = "true";
}
if (localStorage.showSuggestions === undefined) {
localStorage.showSuggestions = "true";
}
if (localStorage.showLogs === undefined) {
localStorage.showLogs = "false";
}
const responseHeadersHandler = makeHeaderHandler("response");
chrome.webRequest.onHeadersReceived.addListener((details) => {
responseHeadersHandler(details);
//processOnlyTabTrackedURIs(details, handleBody);
handleBody(details, tabUrlTracker.getUrlFromId(details.tabId));
}, {
urls: ["<all_urls>"]
}, ["blocking", "responseHeaders"]);

// init domain storage
bgapp.mainStorage.getAll().then(function(domains) {
if (domains) {
domains.forEach(function(domainObj) {
bgapp.ruleDomains[domainObj.id] = domainObj;
});
}
}).catch(simpleError);
chrome.webRequest.onBeforeSendHeaders.addListener(makeHeaderHandler("request"), {
urls: ["<all_urls>"]
}, ["blocking", "requestHeaders"]);

//init settings
if (localStorage.devTools === undefined) {
localStorage.devTools = "true";
}
if (localStorage.showSuggestions === undefined) {
localStorage.showSuggestions = "true";
}
if (localStorage.showLogs === undefined) {
localStorage.showLogs = "false";
}

// init domain storage
mainStorage.getAll().then(function(domains) {
if (domains) {
domains.forEach(function(domainObj) {
ruleDomains[domainObj.id] = domainObj;
});
}
}).catch(simpleError);

Loading