add ability to log what specific methods were blocked

This commit is contained in:
Peter Snyder 2017-10-14 23:23:40 -05:00
parent fc4ecef273
commit eefd6bde58
9 changed files with 99 additions and 29 deletions

View file

@ -11,12 +11,14 @@
// (or the default option, "(default)"), to an array of standards // (or the default option, "(default)"), to an array of standards
// that should be blocked on matching domains. // that should be blocked on matching domains.
let domainRules; let domainRules;
let shouldLog;
// The extension depends on this fetch happening before the DOM on any // The extension depends on this fetch happening before the DOM on any
// pages is loaded. The Chrome and Firefox docs *do not* promise this, // pages is loaded. The Chrome and Firefox docs *do not* promise this,
// but in testing this is always the case. // but in testing this is always the case.
storageLib.get(function (loadedDomainRules) { storageLib.get(function (storedValues) {
domainRules = loadedDomainRules; domainRules = storedValues.domainRules;
shouldLog = storedValues.shouldLog;
}); });
// Manage the state of the browser activity, by displaying the number // Manage the state of the browser activity, by displaying the number
@ -66,7 +68,7 @@
// Listen for updates to the domain rules from the config page. // Listen for updates to the domain rules from the config page.
// The two types of messages that are sent to the background page are // The two types of messages that are sent to the background page are
// "rulesUpdate", which comes from the config page, indicating the domain // "stateUpdate", which comes from the config page, indicating the domain
// blocking / matching rules have changed, and the "rulesForDomains" // blocking / matching rules have changed, and the "rulesForDomains"
// message, which comes from the browserAction popup, and is a request // message, which comes from the browserAction popup, and is a request
// for information about "here are the domains of the frames on the // for information about "here are the domains of the frames on the
@ -74,8 +76,9 @@
rootObject.runtime.onMessage.addListener(function (request, ignore, sendResponse) { rootObject.runtime.onMessage.addListener(function (request, ignore, sendResponse) {
const [label, data] = request; const [label, data] = request;
if (label === "rulesUpdate") { if (label === "stateUpdate") {
domainRules = data; domainRules = data.domainRules;
shouldLog = data.shouldLog;
return; return;
} }
@ -127,7 +130,12 @@
details.responseHeaders.push({ details.responseHeaders.push({
name: "Set-Cookie", name: "Set-Cookie",
value: `web-api-manager=${packedValues}` value: `wam-standards=${packedValues}`
});
details.responseHeaders.push({
name: "Set-Cookie",
value: `wam-log=${shouldLog ? "true" : "false"}`
}); });
return { return {

View file

@ -22,8 +22,10 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-xs-4 col-md-4 well"> <div class="col-xs-4 col-md-4">
<domain-rules :domain-names="domainNames" :selected-domain="selectedDomain"></domain-rules> <domain-rules :domain-names="domainNames" :selected-domain="selectedDomain"></domain-rules>
<logging-settings :should-log="shouldLog"></logging-settings>
</div> </div>
<div class="col-xs-8 col-md-8"> <div class="col-xs-8 col-md-8">
@ -37,11 +39,12 @@
<script src="../lib/init.js"></script> <script src="../lib/init.js"></script>
<script src="../content_scripts/dist/defaults.js"></script> <script src="../content_scripts/dist/defaults.js"></script>
<script src="../content_scripts/dist/standards.js"></script> <script src="../content_scripts/dist/standards.js"></script>
<script src="../lib/storage.js"></script> <script src="../lib/storage.js"></script>
<script src="js/lib/vue.js"></script> <script src="js/lib/vue.js"></script>
<script src="js/state.js"></script> <script src="js/state.js"></script>
<script src="js/components/domain-rules.vue.js"></script> <script src="js/components/domain-rules.vue.js"></script>
<script src="js/components/web-api-standards.vue.js"></script> <script src="js/components/web-api-standards.vue.js"></script>
<script src="js/components/logging-settings.vue.js"></script>
<script src="js/config.js"></script> <script src="js/config.js"></script>
</body> </body>
</html> </html>

View file

@ -6,7 +6,7 @@
Vue.component("domain-rules", { Vue.component("domain-rules", {
props: ["domainNames", "selectedDomain"], props: ["domainNames", "selectedDomain"],
template: ` template: `
<div class="domain-rules-container"> <div class="domain-rules-container well">
<div class="radio" v-for="aDomain in domainNames"> <div class="radio" v-for="aDomain in domainNames">
<label> <label>
<input type="radio" <input type="radio"
@ -29,7 +29,7 @@
<input class="form-control" v-model.trim="newDomain" placeholder="*.example.org"> <input class="form-control" v-model.trim="newDomain" placeholder="*.example.org">
</div> </div>
<button type="submit" class="btn btn-default" @click="newDomainSubmitted">Submit</button> <button type="submit" class="btn btn-default btn-block" @click="newDomainSubmitted">Add Rule</button>
</div> </div>
`, `,
data: function () { data: function () {

View file

@ -0,0 +1,26 @@
/*jslint es6: true, this: true*/
/*global window, Vue*/
(function () {
"use strict";
Vue.component("logging-settings", {
props: ["shouldLog"],
template: `
<div class="logging-settings">
<div class="checkbox">
<label>
<input type="checkbox"
v-model="shouldLog"
@change="shouldLogChanged">
Log blocked functionality?
</label>
</div>
</div>
`,
methods: {
shouldLogChanged: function () {
this.$root.$data.setShouldLog(this.shouldLog);
}
}
});
}());

View file

@ -11,9 +11,9 @@
const state = stateLib.generateStateObject(defaultDomain, standards); const state = stateLib.generateStateObject(defaultDomain, standards);
const onSettingsLoaded = function (loadedDomainRules) { const onSettingsLoaded = function (storedSettings) {
state.setDomainRules(loadedDomainRules); state.populateFromStorage(storedSettings);
const vm = new Vue({ const vm = new Vue({
el: doc.body, el: doc.body,
@ -21,18 +21,17 @@
}); });
const updateStoredSettings = function () { const updateStoredSettings = function () {
storageLib.set(state.domainRules, function () { storageLib.set(state.toStorage(), function () {
rootObject.runtime.sendMessage(["rulesUpdate", state.domainRules]); rootObject.runtime.sendMessage(["stateUpdate", state.toStorage()]);
}); });
}; };
vm.$watch("selectedStandards", updateStoredSettings); vm.$watch("selectedStandards", updateStoredSettings);
vm.$watch("domainNames", updateStoredSettings); vm.$watch("domainNames", updateStoredSettings);
vm.$watch("shouldLog", updateStoredSettings);
}; };
const onPageLoad = function () { window.onload = function () {
storageLib.get(onSettingsLoaded); storageLib.get(onSettingsLoaded);
}; };
window.onload = onPageLoad;
}()); }());

View file

@ -4,6 +4,7 @@
"use strict"; "use strict";
const defaultDomain = "(default)"; const defaultDomain = "(default)";
const {packingLib, standards} = window.WEB_API_MANAGER;
const generateStateObject = function (initialDomain, standards) { const generateStateObject = function (initialDomain, standards) {
@ -12,8 +13,21 @@
standards: standards, standards: standards,
domainRules: {}, domainRules: {},
domainNames: [], domainNames: [],
shouldLog: false,
selectedStandards: [], selectedStandards: [],
toStorage: function () {
return {
domainRules: this.domainRules,
shouldLog: this.shouldLog
};
},
populateFromStorage: function (storedValues) {
this.setDomainRules(storedValues.domainRules);
this.setShouldLog(storedValues.shouldLog);
},
setDomainRules: function (newDomainRules) { setDomainRules: function (newDomainRules) {
this.domainRules = newDomainRules; this.domainRules = newDomainRules;
this.domainNames = Object.keys(newDomainRules); this.domainNames = Object.keys(newDomainRules);
@ -47,6 +61,10 @@
this.domainNames = Object.keys(this.domainRules); this.domainNames = Object.keys(this.domainRules);
this.selectedDomain = newDomainRule; this.selectedDomain = newDomainRule;
this.selectedStandards = this.domainRules[newDomainRule]; this.selectedStandards = this.domainRules[newDomainRule];
},
setShouldLog: function (shouldLog) {
this.shouldLog = shouldLog;
} }
}; };

View file

@ -8,18 +8,22 @@
const script = document.createElement('script'); const script = document.createElement('script');
const rootElm = document.head || document.documentElement; const rootElm = document.head || document.documentElement;
const cookieKey = "web-api-manager"; const standardsCookieKey = "wam-standards";
const {packingLib, standards} = window.WEB_API_MANAGER; const {packingLib, standards} = window.WEB_API_MANAGER;
const options = Object.keys(standards); const options = Object.keys(standards);
const packedValues = Cookies.get(cookieKey); const packedValues = Cookies.get(standardsCookieKey);
const standardsToBlock = packingLib.unpack(options, packedValues); const standardsToBlock = packingLib.unpack(options, packedValues);
Cookies.remove(cookieKey); Cookies.remove(standardsCookieKey);
const shouldLogCookieKey = "wam-log";
const shouldLog = Cookies.get(shouldLogCookieKey);
Cookies.remove(shouldLogCookieKey);
const code = ` const code = `
window.WEB_API_MANAGER_PAGE = { window.WEB_API_MANAGER_PAGE = {
standards: ${JSON.stringify(standards)}, standards: ${JSON.stringify(standards)},
toBlock: ${JSON.stringify(standardsToBlock)}, toBlock: ${JSON.stringify(standardsToBlock)},
shouldLog: false shouldLog: ${shouldLog}
}; };
###-INJECTED-PROXY-BLOCKING-CODE-### ###-INJECTED-PROXY-BLOCKING-CODE-###
`; `;

View file

@ -10,6 +10,7 @@
const shouldLog = settings.shouldLog; const shouldLog = settings.shouldLog;
const standardsToBlock = settings.toBlock; const standardsToBlock = settings.toBlock;
const standardDefinitions = settings.standards; const standardDefinitions = settings.standards;
const hostName = window.location.hostname;
const defaultFunction = function () {}; const defaultFunction = function () {};
const funcPropNames = Object.getOwnPropertyNames(defaultFunction); const funcPropNames = Object.getOwnPropertyNames(defaultFunction);
@ -59,9 +60,12 @@
let hasBeenLogged = false; let hasBeenLogged = false;
const logKeyPath = function () { const logKeyPath = function () {
if (keyPath !== undefined && hasBeenLogged === false) {
if (keyPath !== undefined &&
hasBeenLogged === false &&
shouldLog) {
hasBeenLogged = true; hasBeenLogged = true;
console.info(keyPath); console.log("Blocked '" + keyPath + "' on '" + hostName + "'");
} }
}; };
@ -128,6 +132,7 @@
} }
try { try {
if (shouldLog === true) { if (shouldLog === true) {
parentRef[lastPropertyName] = createBlockingProxy(keyPath); parentRef[lastPropertyName] = createBlockingProxy(keyPath);
return true; return true;
@ -136,6 +141,7 @@
parentRef[lastPropertyName] = defaultBlockingProxy; parentRef[lastPropertyName] = defaultBlockingProxy;
return true; return true;
} catch (e) { } catch (e) {
if (shouldLog) { if (shouldLog) {
console.log("Error instrumenting " + keyPath + ": " + e); console.log("Error instrumenting " + keyPath + ": " + e);
} }

View file

@ -4,23 +4,29 @@
"use strict"; "use strict";
const rootObject = window.browser || window.chrome; const rootObject = window.browser || window.chrome;
const webApiManagerKeySettingsKey = "webApiManagerDomainRules"; const webApiManagerKeySettingsKey = "webApiManager";
const storageObject = rootObject.storage; const storageObject = rootObject.storage;
const get = function (callback) { const get = function (callback) {
storageObject.local.get(webApiManagerKeySettingsKey, function (results) { storageObject.local.get(webApiManagerKeySettingsKey, function (results) {
let loadedDomainRules = results && results[webApiManagerKeySettingsKey]; let loadedValues = results && results[webApiManagerKeySettingsKey];
// If there are no currently saved domain rules, then create // If there are no currently saved domain rules, then create
// a stubbed out one, using an empty blocking rule set. // a stubbed out one, using an empty blocking rule set.
if (!loadedDomainRules || Object.keys(loadedDomainRules).length === 0) { if (!loadedValues ||
loadedDomainRules = { !loadedValues.domainRules ||
"(default)": [] Object.keys(loadedValues.domainRules).length === 0) {
loadedValues = {
domainRules: {
"(default)": []
},
shouldLog: false
}; };
} }
callback(loadedDomainRules); callback(loadedValues);
}); });
}; };