1
0
mirror of https://github.com/kkapsner/CanvasBlocker synced 2024-12-22 21:00:23 +01:00
CanvasBlocker/lib/frame.js

209 lines
6.1 KiB
JavaScript
Raw Normal View History

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
2019-03-12 22:24:23 +01:00
(function(require){
"use strict";
2017-11-07 00:36:44 +01:00
const settings = require("./settings");
2019-04-08 00:06:25 +02:00
const {preIntercept: intercept} = require("./intercept");
const {ask} = require("./askForPermission");
2019-05-17 00:36:34 +02:00
const {sha256String: hashing} = require("./hash");
2019-04-08 00:06:25 +02:00
const {check: originalCheck, checkStack: originalCheckStack} = require("./check");
2019-04-07 23:09:02 +02:00
const {getWrapped} = require("./modifiedAPIFunctions");
const extension = require("./extension");
2019-05-22 23:37:23 +02:00
const iframeProtection = require("./iframeProtection");
const logging = require("./logging");
const {error, warning, message, notice, verbose, setPrefix: setLogPrefix} = logging;
setLogPrefix("frame script");
// Variable to "unload" the script
var enabled = true;
message("starting", location.href);
function check(message){
if (enabled){
return originalCheck(message);
}
else {
return {type: [], mode: "allow"};
}
}
function checkStack(stack){
if (enabled){
return originalCheckStack(stack);
}
else {
return true;
}
}
function askWrapper(data){
return ask(data, {
_: extension.getTranslation,
prefs
});
}
2017-07-16 00:25:19 +02:00
2019-05-17 00:36:34 +02:00
let extensionSecret;
function computeExtensionSecret(){
function hashString(string){
return hashing(new Uint16Array(
string.split("").map(function(c){
return c.charCodeAt(0);
})
));
}
const now = new Date();
const lastTenMinutes = Math.floor(now.getMinutes() / 10) * 10;
const nextRun = new Date(
now.getFullYear(), now.getMonth(), now.getDate(),
now.getHours(), lastTenMinutes + 10, 0, 0
);
window.setTimeout(
computeExtensionSecret,
nextRun .getTime() - now.getTime()
);
let string =
extension.extensionID +
`${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()} ${now.getHours()}:${lastTenMinutes}`;
extensionSecret = [hashString("input" + string), hashString(string + "output")];
}
computeExtensionSecret();
message("open port to background script");
var port = browser.runtime.connect();
if (window === window.top){
message("Is top level window -> tab had navigation -> clear page action");
port.postMessage({"canvasBlocker-clear-page-action": true});
}
var tabId;
port.onMessage.addListener(function(data){
2017-11-07 00:36:44 +01:00
message("Got data from port", data);
if (data.hasOwnProperty("tabId")){
notice("my tab id is", data.tabId);
tabId = data.tabId;
}
if (data.hasOwnProperty("cookieStoreId")){
notice("my tab cookie store id is", data.cookieStoreId);
const {persistent: persistentRnd} = require("./randomSupplies");
persistentRnd.setCookieStoreId(data.cookieStoreId);
}
const persistentRndName = "persistent" + (extension.inIncognitoContext? "Incognito": "") + "Rnd";
if (data.hasOwnProperty(persistentRndName)){
const persistentRndValue = data[persistentRndName];
notice("got persistent random data", persistentRndValue);
2019-04-08 00:06:25 +02:00
const {persistent: persistentRnd} = require("./randomSupplies");
Object.keys(persistentRndValue).forEach(function(domain){
verbose("random data for", domain, persistentRndValue[domain]);
persistentRnd.setDomainRnd(domain, persistentRndValue[domain]);
});
}
});
var notifications = [];
var notificationCounter = {};
var sentAPIs = {};
function notify(data){
if (!settings.ignoredAPIs[data.api]){
if (settings.storeNotificationData){
notifications.push(data);
}
2019-04-30 23:42:21 +02:00
if (!notificationCounter[data.messageId]){
notificationCounter[data.messageId] = {
count: 0,
api: data.api
};
}
notificationCounter[data.messageId].count += 1;
if (!sentAPIs[data.api]){
sentAPIs[data.api] = true;
port.postMessage({"canvasBlocker-notify": data});
}
}
}
function prefs(...args){
return settings.get(...args);
}
2017-06-25 22:33:12 +02:00
var interceptedWindows = new WeakMap();
function interceptWindow(window){
try {
var href = window.location.href;
var wrappedTry = getWrapped(window);
}
catch (e){
// we are unable to read the location due to SOP
// therefore we also can not intercept anything.
warning("NOT intercepting window due to SOP", window);
return false;
}
const wrappedWindow = wrappedTry;
2019-05-17 00:36:34 +02:00
if (!enabled || interceptedWindows.get(wrappedWindow)){
return false;
}
if (wrappedWindow.matchMedia(extensionSecret[0]) === extensionSecret[1]){
interceptedWindows.set(wrappedWindow, true);
2017-10-10 21:11:50 +02:00
return false;
}
message("intercepting window", window);
2017-06-25 22:33:12 +02:00
intercept(
{subject: window},
{check, checkStack, ask: askWrapper, notify, prefs}
);
message("prepare to intercept (i)frames.");
2019-05-22 23:37:23 +02:00
function interceptAllFrames(){
const currentLength = window.length;
for (let i = currentLength; i--;){
if (!interceptedWindows.get(wrappedWindow[i])){
interceptWindow(window[i]);
2017-06-25 22:33:12 +02:00
}
2019-05-22 23:37:23 +02:00
}
}
iframeProtection.protect(window, wrappedWindow, interceptWindow, interceptAllFrames);
2017-06-25 22:33:12 +02:00
2019-05-17 00:36:34 +02:00
const matchMediaDescriptor = Object.getOwnPropertyDescriptor(wrappedWindow, "matchMedia");
const originalMatchMedia = matchMediaDescriptor.value;
matchMediaDescriptor.value = exportFunction(function matchMedia(query){
if (query === extensionSecret[0]){
return extensionSecret[1];
}
else {
return arguments.length > 1?
originalMatchMedia.apply(this, wrappedWindow.Array.from(arguments)):
originalMatchMedia.call(this, query);
}
}, window);
Object.defineProperty(wrappedWindow, "matchMedia", matchMediaDescriptor);
interceptedWindows.set(wrappedWindow, true);
2017-06-25 22:33:12 +02:00
return true;
2017-10-03 15:35:31 +02:00
}
2017-06-25 22:33:12 +02:00
message("register listener for messages from background script");
extension.message.on(function(data){
2017-06-25 22:33:12 +02:00
if (data["canvasBlocker-unload"]){
enabled = false;
}
if (
data.hasOwnProperty("canvasBlocker-sendNotifications") &&
data["canvasBlocker-sendNotifications"] === tabId
){
notice("sending notifications:", notifications);
extension.message.send({
sender: tabId,
url: window.location.href,
"canvasBlocker-notificationCounter": notificationCounter,
"canvasBlocker-notifications": notifications
});
notice("notifications sent");
}
});
interceptWindow(window);
2019-03-12 22:24:23 +01:00
}(require));