mirror of
https://github.com/kkapsner/CanvasBlocker
synced 2025-07-04 04:26:35 +02:00
Big linting
This commit is contained in:
parent
b5e6d049ce
commit
aef6bd3d59
58 changed files with 2074 additions and 1856 deletions
680
lib/intercept.js
680
lib/intercept.js
|
@ -41,380 +41,394 @@
|
|||
setRandomSupplyByType(settings.rng);
|
||||
});
|
||||
|
||||
function getURL(window){
|
||||
function getURL(windowToProcess){
|
||||
let href;
|
||||
try {
|
||||
href = window.location.href;
|
||||
href = windowToProcess.location.href;
|
||||
}
|
||||
catch (e){
|
||||
catch (error){
|
||||
// unable to read location due to SOP
|
||||
// since we are not able to do anything in that case we can allow everything
|
||||
return "about:SOP";
|
||||
}
|
||||
if (!href || href === "about:blank"){
|
||||
if (window !== window.parent){
|
||||
return getURL(window.parent);
|
||||
if (windowToProcess !== windowToProcess.parent){
|
||||
return getURL(windowToProcess.parent);
|
||||
}
|
||||
else if (window.opener){
|
||||
return getURL(window.opener);
|
||||
else if (windowToProcess.opener){
|
||||
return getURL(windowToProcess.opener);
|
||||
}
|
||||
}
|
||||
return href;
|
||||
}
|
||||
const getAllFunctionObjects = function(windowToProcess, changedFunction){
|
||||
return (
|
||||
Array.isArray(changedFunction.object)?
|
||||
changedFunction.object:
|
||||
[changedFunction.object]
|
||||
).map(function(name){
|
||||
if (name){
|
||||
const constructor = getWrapped(windowToProcess)[name];
|
||||
if (constructor){
|
||||
return constructor.prototype;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}).concat(
|
||||
changedFunction.objectGetters?
|
||||
changedFunction.objectGetters.map(function(objectGetter){
|
||||
return objectGetter(getWrapped(windowToProcess));
|
||||
}):
|
||||
[]
|
||||
);
|
||||
};
|
||||
const forEachFunction = function(windowToProcess, callback){
|
||||
apiNames.forEach(function(name){
|
||||
const changedFunction = changedFunctions[name];
|
||||
getAllFunctionObjects(windowToProcess, changedFunction).forEach(function(object){
|
||||
if (object){
|
||||
callback({name, object: object, changedFunction});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
const forEachGetter = function(windowToProcess, callback){
|
||||
changedGetters.forEach(function(changedGetter){
|
||||
const name = changedGetter.name;
|
||||
changedGetter.objectGetters.forEach(function(changedGetter){
|
||||
const object = changedGetter(getWrapped(windowToProcess));
|
||||
if (object){
|
||||
callback({name, object, objectGetter: changedGetter});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
scope.preIntercept = function preIntercept({subject: window}, apis){
|
||||
if (!settings.isStillDefault){
|
||||
logging.message("settings already loaded -> no need to pre intercept");
|
||||
scope.intercept({subject: window}, apis);
|
||||
const forEach = function(windowToProcess, callback){
|
||||
forEachFunction(windowToProcess, callback);
|
||||
forEachGetter(windowToProcess, callback);
|
||||
};
|
||||
|
||||
const doRealIntercept = function(windowToProcess, apis, state){
|
||||
if (!state.intercepted){
|
||||
scope.intercept({subject: windowToProcess}, apis);
|
||||
state.intercepted = true;
|
||||
}
|
||||
else {
|
||||
logging.message("settings not loaded -> need to pre intercept");
|
||||
let forceLoad = true;
|
||||
let preIntercepted = false;
|
||||
let intercepted = false;
|
||||
const forEachFunction = function(callback){
|
||||
apiNames.forEach(function(name){
|
||||
const changedFunction = changedFunctions[name];
|
||||
(
|
||||
Array.isArray(changedFunction.object)?
|
||||
changedFunction.object:
|
||||
[changedFunction.object]
|
||||
).map(function(name){
|
||||
if (name){
|
||||
const constructor = getWrapped(window)[name];
|
||||
if (constructor){
|
||||
return constructor.prototype;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}).concat(
|
||||
changedFunction.objectGetters?
|
||||
changedFunction.objectGetters.map(function(objectGetter){
|
||||
return objectGetter(getWrapped(window));
|
||||
}):
|
||||
[]
|
||||
).forEach(function(object){
|
||||
if (object){
|
||||
callback({name, object: object});
|
||||
}
|
||||
});
|
||||
});
|
||||
changedGetters.forEach(function(changedGetter){
|
||||
const name = changedGetter.name;
|
||||
changedGetter.objectGetters.forEach(function(objectGetter){
|
||||
const object = objectGetter(getWrapped(window));
|
||||
if (object){
|
||||
callback({name, object});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
let originalPropertyDescriptors = {};
|
||||
const doPreIntercept = function(){
|
||||
if (!preIntercepted){
|
||||
forEachFunction(function({name, object}){
|
||||
const map = originalPropertyDescriptors[name] || new WeakMap();
|
||||
originalPropertyDescriptors[name] = map;
|
||||
|
||||
const originalPropertyDescriptor = Object.getOwnPropertyDescriptor(object, name);
|
||||
if (!originalPropertyDescriptor){
|
||||
return;
|
||||
}
|
||||
|
||||
map.set(object, originalPropertyDescriptor);
|
||||
};
|
||||
const doPreIntercept = function(windowToProcess, apis, state){
|
||||
const forceLoad = true;
|
||||
const originalPropertyDescriptors = {};
|
||||
const undoPreIntercept = function(){
|
||||
if (state.preIntercepted){
|
||||
state.preIntercepted = false;
|
||||
forEach(windowToProcess, function({name, object}){
|
||||
const originalPropertyDescriptor = originalPropertyDescriptors[name].get(object);
|
||||
if (originalPropertyDescriptor){
|
||||
Object.defineProperty(
|
||||
object,
|
||||
name,
|
||||
{
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get: exportFunction(function(){
|
||||
if (forceLoad){
|
||||
logging.warning("force load the settings. Calling stack:", (new Error()).stack);
|
||||
undoPreIntercept();
|
||||
settings.forceLoad();
|
||||
doRealIntercept();
|
||||
const descriptor = Object.getOwnPropertyDescriptor(object, name);
|
||||
return descriptor.value || descriptor.get.call(this);
|
||||
}
|
||||
else {
|
||||
logging.notice("API blocked (%s)", name);
|
||||
const url = getURL(window);
|
||||
if (!url){
|
||||
return undef;
|
||||
}
|
||||
const error = new Error();
|
||||
apis.notify({
|
||||
url,
|
||||
errorStack: error.stack,
|
||||
messageId: "preBlock",
|
||||
timestamp: new Date(),
|
||||
functionName: name,
|
||||
dataURL: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
}, window),
|
||||
set: exportFunction(function(){}, window)
|
||||
}
|
||||
originalPropertyDescriptor
|
||||
);
|
||||
});
|
||||
preIntercepted = true;
|
||||
}
|
||||
};
|
||||
const undoPreIntercept = function(){
|
||||
if (preIntercepted){
|
||||
preIntercepted = false;
|
||||
forEachFunction(function({name, object}){
|
||||
const originalPropertyDescriptor = originalPropertyDescriptors[name].get(object);
|
||||
if (originalPropertyDescriptor){
|
||||
Object.defineProperty(
|
||||
object,
|
||||
name,
|
||||
originalPropertyDescriptor
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
const doRealIntercept = function(){
|
||||
if (!intercepted){
|
||||
scope.intercept({subject: window}, apis);
|
||||
intercepted = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
if (!state.preIntercepted){
|
||||
forEach(windowToProcess, function({name, object}){
|
||||
const map = originalPropertyDescriptors[name] || new WeakMap();
|
||||
originalPropertyDescriptors[name] = map;
|
||||
|
||||
const originalPropertyDescriptor = Object.getOwnPropertyDescriptor(object, name);
|
||||
if (!originalPropertyDescriptor){
|
||||
return;
|
||||
}
|
||||
|
||||
map.set(object, originalPropertyDescriptor);
|
||||
Object.defineProperty(
|
||||
object,
|
||||
name,
|
||||
{
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get: exportFunction(function(){
|
||||
if (forceLoad){
|
||||
logging.warning("force load the settings. Calling stack:", (new Error()).stack);
|
||||
undoPreIntercept();
|
||||
settings.forceLoad();
|
||||
doRealIntercept(windowToProcess, apis, state);
|
||||
const descriptor = Object.getOwnPropertyDescriptor(object, name);
|
||||
return descriptor.value || descriptor.get.call(this);
|
||||
}
|
||||
else {
|
||||
logging.notice("API blocked (%s)", name);
|
||||
const url = getURL(windowToProcess);
|
||||
if (!url){
|
||||
return undef;
|
||||
}
|
||||
const error = new Error();
|
||||
apis.notify({
|
||||
url,
|
||||
errorStack: error.stack,
|
||||
messageId: "preBlock",
|
||||
timestamp: new Date(),
|
||||
functionName: name,
|
||||
dataURL: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
}, windowToProcess),
|
||||
set: exportFunction(function(){}, windowToProcess)
|
||||
}
|
||||
);
|
||||
});
|
||||
state.preIntercepted = true;
|
||||
}
|
||||
return undoPreIntercept;
|
||||
};
|
||||
|
||||
scope.preIntercept = function preIntercept({subject: windowToProcess}, apis){
|
||||
if (!settings.isStillDefault){
|
||||
logging.message("settings already loaded -> no need to pre intercept");
|
||||
scope.intercept({subject: windowToProcess}, apis);
|
||||
}
|
||||
else {
|
||||
logging.message("settings not loaded -> need to pre intercept");
|
||||
|
||||
const state = {
|
||||
preIntercepted: false,
|
||||
intercepted: false
|
||||
};
|
||||
|
||||
doPreIntercept();
|
||||
const undoPreIntercept = doPreIntercept(windowToProcess, apis, state);
|
||||
settings.onloaded(function(){
|
||||
undoPreIntercept();
|
||||
doRealIntercept();
|
||||
doRealIntercept(windowToProcess, apis, state);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function getDataURL(object, prefs){
|
||||
return (
|
||||
object &&
|
||||
prefs("storeImageForInspection") &&
|
||||
prefs("showNotifications")?
|
||||
(
|
||||
object instanceof HTMLCanvasElement?
|
||||
object.toDataURL():
|
||||
(
|
||||
object.canvas instanceof HTMLCanvasElement?
|
||||
object.canvas.toDataURL():
|
||||
false
|
||||
)
|
||||
):
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
let extensionID = extension.extensionID;
|
||||
scope.intercept = function intercept({subject: window}, {check, checkStack, ask, notify, prefs}){
|
||||
function getDataURL(object, prefs){
|
||||
return (
|
||||
object &&
|
||||
prefs("storeImageForInspection") &&
|
||||
prefs("showNotifications")?
|
||||
(
|
||||
object instanceof HTMLCanvasElement?
|
||||
object.toDataURL():
|
||||
(
|
||||
object.canvas instanceof HTMLCanvasElement?
|
||||
object.canvas.toDataURL():
|
||||
false
|
||||
)
|
||||
):
|
||||
false
|
||||
);
|
||||
}
|
||||
function generateChecker(name, changedFunction, siteStatus, original){
|
||||
return function checker(callingDepth = 2){
|
||||
const error = new Error();
|
||||
const errorStack = error.stack;
|
||||
|
||||
try {
|
||||
// return original if the extension itself requested the function
|
||||
if (
|
||||
errorStack
|
||||
.split("\n", callingDepth + 2)[callingDepth + 1]
|
||||
.split("@", callingDepth + 1)[1]
|
||||
.startsWith(extensionID)
|
||||
){
|
||||
return {allow: true, original, window};
|
||||
}
|
||||
|
||||
function generateChecker({
|
||||
name, changedFunction, siteStatus, original,
|
||||
window: windowToProcess, prefs, notify, checkStack, ask
|
||||
}){
|
||||
return function checker(callingDepth = 2){
|
||||
const errorStack = (new Error()).stack;
|
||||
|
||||
try {
|
||||
// return original if the extension itself requested the function
|
||||
if (
|
||||
errorStack
|
||||
.split("\n", callingDepth + 2)[callingDepth + 1]
|
||||
.split("@", callingDepth + 1)[1]
|
||||
.startsWith(extensionID)
|
||||
){
|
||||
return {allow: true, original, window: windowToProcess};
|
||||
}
|
||||
catch (e) {
|
||||
// stack had an unknown form
|
||||
}
|
||||
if (checkStack(errorStack)){
|
||||
return {allow: true, original, window};
|
||||
}
|
||||
const funcStatus = changedFunction.getStatus(this, siteStatus, prefs);
|
||||
|
||||
const This = this;
|
||||
function notifyCallback(messageId){
|
||||
notify({
|
||||
url: getURL(window),
|
||||
errorStack,
|
||||
messageId,
|
||||
timestamp: new Date(),
|
||||
functionName: name,
|
||||
}
|
||||
catch (error) {
|
||||
// stack had an unknown form
|
||||
}
|
||||
if (checkStack(errorStack)){
|
||||
return {allow: true, original, window: windowToProcess};
|
||||
}
|
||||
const funcStatus = changedFunction.getStatus(this, siteStatus, prefs);
|
||||
|
||||
const This = this;
|
||||
function notifyCallback(messageId){
|
||||
notify({
|
||||
url: getURL(windowToProcess),
|
||||
errorStack,
|
||||
messageId,
|
||||
timestamp: new Date(),
|
||||
functionName: name,
|
||||
api: changedFunction.api,
|
||||
dataURL: getDataURL(This, prefs)
|
||||
});
|
||||
}
|
||||
const protectedAPIFeatures = prefs("protectedAPIFeatures");
|
||||
if (
|
||||
funcStatus.active &&
|
||||
(
|
||||
!protectedAPIFeatures.hasOwnProperty(name + " @ " + changedFunction.api) ||
|
||||
protectedAPIFeatures[name + " @ " + changedFunction.api]
|
||||
)
|
||||
){
|
||||
if (funcStatus.mode === "ask"){
|
||||
funcStatus.mode = ask({
|
||||
window: windowToProcess,
|
||||
type: changedFunction.type,
|
||||
api: changedFunction.api,
|
||||
dataURL: getDataURL(This, prefs)
|
||||
canvas: this instanceof HTMLCanvasElement?
|
||||
this:
|
||||
(
|
||||
this &&
|
||||
(this.canvas instanceof HTMLCanvasElement)?
|
||||
this.canvas:
|
||||
false
|
||||
),
|
||||
errorStack
|
||||
});
|
||||
}
|
||||
const protectedAPIFeatures = prefs("protectedAPIFeatures");
|
||||
if (
|
||||
funcStatus.active &&
|
||||
(
|
||||
!protectedAPIFeatures.hasOwnProperty(name + " @ " + changedFunction.api) ||
|
||||
protectedAPIFeatures[name + " @ " + changedFunction.api]
|
||||
)
|
||||
){
|
||||
if (funcStatus.mode === "ask"){
|
||||
funcStatus.mode = ask({
|
||||
window: window,
|
||||
type: changedFunction.type,
|
||||
api: changedFunction.api,
|
||||
canvas: this instanceof HTMLCanvasElement?
|
||||
this:
|
||||
(
|
||||
this &&
|
||||
(this.canvas instanceof HTMLCanvasElement)?
|
||||
this.canvas:
|
||||
false
|
||||
),
|
||||
errorStack
|
||||
switch (funcStatus.mode){
|
||||
case "allow":
|
||||
return {allow: true, original, window: windowToProcess};
|
||||
case "fake":
|
||||
return {
|
||||
allow: "fake",
|
||||
prefs,
|
||||
notify: notifyCallback,
|
||||
window: windowToProcess,
|
||||
original
|
||||
};
|
||||
//case "block":
|
||||
default:
|
||||
return {allow: false, notify: notifyCallback};
|
||||
}
|
||||
}
|
||||
else {
|
||||
return {allow: true, original, window: windowToProcess};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function interceptFunctions(windowToProcess, siteStatus, {checkStack, ask, notify, prefs}){
|
||||
apiNames.forEach(function(name){
|
||||
const changedFunction = changedFunctions[name];
|
||||
const functionStatus = changedFunction.getStatus(undefined, siteStatus, prefs);
|
||||
logging.verbose("status for", name, ":", functionStatus);
|
||||
if (functionStatus.active){
|
||||
getAllFunctionObjects(windowToProcess, changedFunction).forEach(function(object){
|
||||
if (object){
|
||||
const original = object[name];
|
||||
const checker = generateChecker({
|
||||
name, changedFunction, siteStatus, original,
|
||||
window: windowToProcess, prefs, checkStack, ask, notify
|
||||
});
|
||||
}
|
||||
switch (funcStatus.mode){
|
||||
case "allow":
|
||||
return {allow: true, original, window};
|
||||
case "fake":
|
||||
return {
|
||||
allow: "fake",
|
||||
prefs,
|
||||
notify: notifyCallback,
|
||||
window,
|
||||
original
|
||||
};
|
||||
//case "block":
|
||||
default:
|
||||
return {
|
||||
allow: false,
|
||||
notify: notifyCallback
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
return {allow: true, original, window};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const siteStatus = check({url: getURL(window)});
|
||||
logging.verbose("status for page", window, siteStatus);
|
||||
if (siteStatus.mode !== "allow"){
|
||||
apiNames.forEach(function(name){
|
||||
const changedFunction = changedFunctions[name];
|
||||
const functionStatus = changedFunction.getStatus(undefined, siteStatus, prefs);
|
||||
logging.verbose("status for", name, ":", functionStatus);
|
||||
if (functionStatus.active){
|
||||
(
|
||||
Array.isArray(changedFunction.object)?
|
||||
changedFunction.object:
|
||||
[changedFunction.object]
|
||||
).map(function(name){
|
||||
if (name){
|
||||
const constructor = getWrapped(window)[name];
|
||||
if (constructor){
|
||||
return constructor.prototype;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}).concat(
|
||||
changedFunction.objectGetters?
|
||||
changedFunction.objectGetters.map(function(objectGetter){
|
||||
return objectGetter(getWrapped(window));
|
||||
}):
|
||||
[]
|
||||
).forEach(function(object){
|
||||
if (object){
|
||||
const original = object[name];
|
||||
const checker = generateChecker(name, changedFunction, siteStatus, original);
|
||||
const descriptor = Object.getOwnPropertyDescriptor(object, name);
|
||||
if (descriptor){
|
||||
if (descriptor.hasOwnProperty("value")){
|
||||
if (changedFunction.fakeGenerator){
|
||||
descriptor.value = exportFunction(
|
||||
changedFunction.fakeGenerator(checker, original, window),
|
||||
window
|
||||
);
|
||||
}
|
||||
else {
|
||||
descriptor.value = null;
|
||||
}
|
||||
const descriptor = Object.getOwnPropertyDescriptor(object, name);
|
||||
if (descriptor){
|
||||
if (descriptor.hasOwnProperty("value")){
|
||||
if (changedFunction.fakeGenerator){
|
||||
descriptor.value = exportFunction(
|
||||
changedFunction.fakeGenerator(checker, original, windowToProcess),
|
||||
windowToProcess
|
||||
);
|
||||
}
|
||||
else {
|
||||
descriptor.get = exportFunction(function(){
|
||||
return exportFunction(
|
||||
changedFunction.fakeGenerator(checker),
|
||||
window
|
||||
);
|
||||
}, window);
|
||||
}
|
||||
Object.defineProperty(object, name, descriptor);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
changedGetters.forEach(function(changedGetter){
|
||||
const name = changedGetter.name;
|
||||
const functionStatus = changedGetter.getStatus(undefined, siteStatus, prefs);
|
||||
logging.verbose("status for", changedGetter, ":", functionStatus);
|
||||
if (functionStatus.active){
|
||||
changedGetter.objectGetters.forEach(function(objectGetter){
|
||||
const object = objectGetter(getWrapped(window));
|
||||
if (object){
|
||||
const descriptor = Object.getOwnPropertyDescriptor(object, name);
|
||||
if (descriptor && descriptor.hasOwnProperty("get")){
|
||||
const original = descriptor.get;
|
||||
const checker = generateChecker(name, changedGetter, siteStatus, original);
|
||||
const getter = changedGetter.getterGenerator(checker, original, window);
|
||||
descriptor.get = exportFunction(getter, window);
|
||||
|
||||
if (descriptor.hasOwnProperty("set") && changedGetter.setterGenerator){
|
||||
const setter = changedGetter.setterGenerator(window, descriptor.set, prefs);
|
||||
descriptor.set = exportFunction(setter, window);
|
||||
}
|
||||
|
||||
Object.defineProperty(object, name, descriptor);
|
||||
}
|
||||
else if (
|
||||
changedGetter.valueGenerator &&
|
||||
descriptor && descriptor.hasOwnProperty("value")
|
||||
){
|
||||
const protectedAPIFeatures = prefs("protectedAPIFeatures");
|
||||
if (
|
||||
functionStatus.active &&
|
||||
(
|
||||
!protectedAPIFeatures.hasOwnProperty(name + " @ " + changedGetter.api) ||
|
||||
protectedAPIFeatures[name + " @ " + changedGetter.api]
|
||||
)
|
||||
){
|
||||
switch (functionStatus.mode){
|
||||
case "ask": case "block": case "fake":
|
||||
descriptor.value = changedGetter.valueGenerator({
|
||||
mode: functionStatus.mode,
|
||||
original: descriptor.value,
|
||||
notify: function notifyCallback(messageId){
|
||||
notify({
|
||||
url: getURL(window),
|
||||
errorStack: (new Error()).stack,
|
||||
messageId,
|
||||
timestamp: new Date(),
|
||||
functionName: name,
|
||||
api: changedGetter.api
|
||||
});
|
||||
}
|
||||
});
|
||||
Object.defineProperty(object, name, descriptor);
|
||||
break;
|
||||
}
|
||||
descriptor.value = null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
logging.error("Try to fake non getter property:", changedGetter);
|
||||
descriptor.get = exportFunction(function(){
|
||||
return exportFunction(
|
||||
changedFunction.fakeGenerator(checker),
|
||||
windowToProcess
|
||||
);
|
||||
}, windowToProcess);
|
||||
}
|
||||
Object.defineProperty(object, name, descriptor);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function interceptGetters(windowToProcess, siteStatus, {checkStack, ask, notify, prefs}){
|
||||
changedGetters.forEach(function(changedGetter){
|
||||
const name = changedGetter.name;
|
||||
const functionStatus = changedGetter.getStatus(undefined, siteStatus, prefs);
|
||||
logging.verbose("status for", changedGetter, ":", functionStatus);
|
||||
if (functionStatus.active){
|
||||
changedGetter.objectGetters.forEach(function(objectGetter){
|
||||
const object = objectGetter(getWrapped(windowToProcess));
|
||||
if (object){
|
||||
const descriptor = Object.getOwnPropertyDescriptor(object, name);
|
||||
if (descriptor && descriptor.hasOwnProperty("get")){
|
||||
const original = descriptor.get;
|
||||
const checker = generateChecker({
|
||||
name, changedFunction: changedGetter, siteStatus, original,
|
||||
window: windowToProcess, prefs, checkStack, ask, notify
|
||||
});
|
||||
const getter = changedGetter.getterGenerator(checker, original, windowToProcess);
|
||||
descriptor.get = exportFunction(getter, windowToProcess);
|
||||
|
||||
if (descriptor.hasOwnProperty("set") && changedGetter.setterGenerator){
|
||||
const setter = changedGetter.setterGenerator(
|
||||
windowToProcess,
|
||||
descriptor.set,
|
||||
prefs
|
||||
);
|
||||
descriptor.set = exportFunction(setter, windowToProcess);
|
||||
}
|
||||
|
||||
Object.defineProperty(object, name, descriptor);
|
||||
}
|
||||
else if (
|
||||
changedGetter.valueGenerator &&
|
||||
descriptor && descriptor.hasOwnProperty("value")
|
||||
){
|
||||
const protectedAPIFeatures = prefs("protectedAPIFeatures");
|
||||
if (
|
||||
functionStatus.active &&
|
||||
(
|
||||
!protectedAPIFeatures.hasOwnProperty(name + " @ " + changedGetter.api) ||
|
||||
protectedAPIFeatures[name + " @ " + changedGetter.api]
|
||||
)
|
||||
){
|
||||
switch (functionStatus.mode){
|
||||
case "ask": case "block": case "fake":
|
||||
descriptor.value = changedGetter.valueGenerator({
|
||||
mode: functionStatus.mode,
|
||||
original: descriptor.value,
|
||||
notify: function notifyCallback(messageId){
|
||||
notify({
|
||||
url: getURL(windowToProcess),
|
||||
errorStack: (new Error()).stack,
|
||||
messageId,
|
||||
timestamp: new Date(),
|
||||
functionName: name,
|
||||
api: changedGetter.api
|
||||
});
|
||||
}
|
||||
});
|
||||
Object.defineProperty(object, name, descriptor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
else {
|
||||
logging.error("Try to fake non getter property:", changedGetter);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
scope.intercept = function intercept({subject: windowToProcess}, apis){
|
||||
const siteStatus = apis.check({url: getURL(windowToProcess)});
|
||||
logging.verbose("status for page", windowToProcess, siteStatus);
|
||||
if (siteStatus.mode !== "allow"){
|
||||
interceptFunctions(windowToProcess, siteStatus, apis);
|
||||
interceptGetters(windowToProcess, siteStatus, apis);
|
||||
}
|
||||
};
|
||||
}());
|
Loading…
Add table
Add a link
Reference in a new issue