initial work on popup, which lets the user know which related frames are loading script on the current page

This commit is contained in:
Peter Snyder 2017-10-14 00:41:49 -05:00
parent 8126e1a105
commit f0424dcbdd
7 changed files with 135 additions and 19 deletions

View file

@ -4,6 +4,7 @@
const {packingLib, standards, storageLib} = window.WEB_API_MANAGER; const {packingLib, standards, storageLib} = window.WEB_API_MANAGER;
const rootObject = window.browser || window.chrome; const rootObject = window.browser || window.chrome;
const defaultKey = "(default)";
// Once loaded from storage, will be a mapping from regular expressions // Once loaded from storage, will be a mapping from regular expressions
// (or the default option, "(default)"), to an array of standards // (or the default option, "(default)"), to an array of standards
@ -14,14 +15,42 @@
domainRules = loadedDomainRules; domainRules = loadedDomainRules;
}); });
rootObject.runtime.onMessage.addListener(function (request, sender, tab) { // Manage the state of the browser activity, by displaying the number
const [label, data] = request; // of origins / frames
// Listen for updates to the domain rules from the config page. const updateBrowserActionBadge = function (activeInfo) {
if (label === "rulesUpdate") { const {tabId, windowId} = activeInfo;
domainRules = data; rootObject.tabs.executeScript(
} tabId,
}); {
allFrames: true,
code: "window.location.host"
},
function (allHosts) {
if (rootObject.runtime.lastError) {
rootObject.browserAction.disable(tabId);
return;
}
rootObject.browserAction.enable(tabId);
const numFrames = allHosts
? Array.from(new Set(allHosts)).length.toString()
: "";
rootObject.browserAction.setBadgeText({
text: numFrames,
tabId: tabId
});
}
);
};
rootObject.tabs.onUpdated.addListener(updateBrowserActionBadge);
rootObject.tabs.onActivated.addListener(updateBrowserActionBadge);
rootObject.windows.onFocusChanged.addListener(updateBrowserActionBadge);
// Inject the blocking settings for each visited domain / frame.
const extractHostFromUrl = function (url) { const extractHostFromUrl = function (url) {
const uri = URI(url); const uri = URI(url);
return uri.hostname(); return uri.hostname();
@ -40,6 +69,37 @@
return prev; return prev;
}; };
const whichDomainRuleMatches = function (hostName) {
// of the URL being requested.
const matchingUrlReduceFunctionBound = matchingUrlReduceFunction.bind(undefined, hostName);
const matchingPattern = Object
.keys(domainRules)
.filter((aRule) => aRule !== defaultKey)
.sort()
.reduce(matchingUrlReduceFunctionBound, undefined);
return matchingPattern || defaultKey;
};
// Listen for updates to the domain rules from the config page.
rootObject.runtime.onMessage.addListener(function (request, sender, sendResponse) {
const [label, data] = request;
if (label === "rulesUpdate") {
domainRules = data;
return;
}
if (label === "rulesForDomains") {
const ruleForDomain = data.map(whichDomainRuleMatches);
const mapping = {};
for (let i = 0; i < ruleForDomain.length; i += 1) {
mapping[data[i]] = ruleForDomain[i];
}
sendResponse(mapping);
return;
}
});
const requestFilter = { const requestFilter = {
urls: ["<all_urls>"], urls: ["<all_urls>"],
types: ["main_frame", "sub_frame"] types: ["main_frame", "sub_frame"]
@ -50,18 +110,11 @@
const url = details.url; const url = details.url;
const hostName = extractHostFromUrl(url); const hostName = extractHostFromUrl(url);
const defaultKey = "(default)";
// Decide which set of blocking rules to use, depending on the host // Decide which set of blocking rules to use, depending on the host
// of the URL being requested. // of the URL being requested.
const matchingUrlReduceFunctionBound = matchingUrlReduceFunction.bind(undefined, hostName); const matchingDomainKey = whichDomainRuleMatches(hostName);
const matchingPattern = Object const standardsToBlock = domainRules[matchingDomainKey];
.keys(domainRules)
.filter((aRule) => aRule !== defaultKey)
.sort()
.reduce(matchingUrlReduceFunctionBound, undefined);
const standardsToBlock = domainRules[matchingPattern || defaultKey];
const options = Object.keys(standards); const options = Object.keys(standards);
const packedValues = packingLib.pack(options, standardsToBlock); const packedValues = packingLib.pack(options, standardsToBlock);

View file

@ -2,7 +2,6 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-eval'; object-src 'self'">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Web API Manager Configuration</title> <title>Web API Manager Configuration</title>

BIN
images/uic-128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
images/uic-48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

@ -3,14 +3,21 @@
"name": "WebAPI Manager", "name": "WebAPI Manager",
"version": "0.4", "version": "0.4",
"description": "Improves browser security by restricting page access to parts of the Web API.", "description": "Improves browser security by restricting page access to parts of the Web API.",
"icons": {
"48": "images/uic-48.png",
"128": "images/uic-128.png"
},
"browser_action": {
"default_popup": "popup/popup.html"
},
"permissions": [ "permissions": [
"http://*/*", "https://*/*",
"<all_urls>", "<all_urls>",
"storage", "storage",
"tabs", "tabs",
"webRequest", "webRequest",
"webRequestBlocking", "webRequestBlocking",
"webNavigation" "webNavigation",
"activeTab"
], ],
"content_scripts": [ "content_scripts": [
{ {

37
popup/js/example.js Normal file
View file

@ -0,0 +1,37 @@
(function () {
const rootObject = window.browser || window.chrome;
rootObject.tabs.executeScript(
{
allFrames: true,
code: "window.location.host"
},
function (response) {
const uniqueDomains = Array.from(new Set(response)).sort();
const message = ["rulesForDomains", uniqueDomains];
rootObject.runtime.sendMessage(message, function (response) {
const listGroupElm = document.querySelector("ul.list-group");
const domainNames = Object.keys(response);
domainNames.forEach(function (aDomain) {
const domainRule = response[aDomain];
const liElm = document.createElement("li");
liElm.className = "list-group-item";
const spanElm = document.createElement("span");
spanElm.className = "badge";
const badgeText = document.createTextNode(domainRule);
spanElm.appendChild(badgeText);
liElm.appendChild(spanElm);
const textElm = document.createTextNode(aDomain);
liElm.appendChild(textElm);
listGroupElm.appendChild(liElm);
});
});
}
);
}());

20
popup/popup.html Normal file
View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Frame listing popup</title>
<link href="../config/css/bootstrap.min.css" rel="stylesheet">
<link href="../config/css/bootstrap-theme.min.css" rel="stylesheet">
</head>
<body>
<section>
This page has loaded the followng frames…
<ul class="list-group">
</ul>
</section>
<script src="js/example.js"></script>
</body>
</html>