187 lines
No EOL
5.7 KiB
JavaScript
187 lines
No EOL
5.7 KiB
JavaScript
/**
|
|
* Ad Blocker Module
|
|
*
|
|
* Handles ad blocking and web request filtering for Sneedium browser:
|
|
* - Sets up ad blocking with the Ghostery adblocker
|
|
* - Configures web request rules
|
|
* - Prevents access to local resources from remote sites
|
|
*/
|
|
|
|
const { ElectronBlocker } = require('@ghostery/adblocker-electron');
|
|
const fetch = require("cross-fetch");
|
|
|
|
// Blocklist for ad filtering
|
|
const toBlock = [
|
|
"*://*.doubleclick.*",
|
|
"*://s.innovid.com/*",
|
|
"*://partner.googleadservices.com/*",
|
|
"*://*.googlesyndication.com/*",
|
|
"*://*.google-analytics.com/*",
|
|
"*://*.creative.ak.fbcdn.net/*",
|
|
"*://*.adbrite.com/*",
|
|
"*://*.exponential.com/*",
|
|
"*://*.quantserve.com/*",
|
|
"*://*.scorecardresearch.com/*",
|
|
"*://*.zedo.com/*",
|
|
"*://*.a-ads.com/*",
|
|
"*://*.777partner.com/*",
|
|
"*://*.77tracking.com/*",
|
|
"*://*.abc-ads.com/*",
|
|
"*://*.aaxads.com/*",
|
|
"*://*.adizio.com/*",
|
|
"*://*.adjix.com/*",
|
|
"*://*.adjug.com/*",
|
|
"*://*.adjuggler.com/*",
|
|
"*://*.trafficjunky.net/*",
|
|
"*://*.trafficleader.com/*",
|
|
"*://*.trafficrouter.io/*",
|
|
"*://*.monerominer.rocks/*",
|
|
"*://*.2mdn.net/*",
|
|
"*.exe",
|
|
"*.vbs",
|
|
"*://*.googlesyndication.*",
|
|
"*pixels*",
|
|
"*telemetry*",
|
|
"*analytics*",
|
|
"*://ads.*.com*",
|
|
"*ae/us/audience*",
|
|
"*/api/v*/science*",
|
|
"*/api/v*/typing*"
|
|
];
|
|
|
|
// Regex patterns for additional blocking
|
|
const regexPatterns = [
|
|
"r[0-100]+---sn-.*\\.googlevideo\\.com$/g",
|
|
"r[0-100]+-sn-.*\\.googlevideo\\.com$/g"
|
|
];
|
|
|
|
// Local domain tokens for security filtering
|
|
const locals = [
|
|
'0.0.0.0', '127.0.0.1', '192.168', '.local', '.example', '.staging', 'fe80::', '::1'
|
|
];
|
|
|
|
/**
|
|
* Initialize ad blocker and web request filtering
|
|
* @param {Object} session - Electron session to apply blocking to
|
|
* @returns {Object} Functions to control ad blocker
|
|
*/
|
|
function initAdBlocker(session) {
|
|
let blocker = undefined;
|
|
|
|
return {
|
|
enableAdBlocking: () => enableGoodies(session),
|
|
setupWebRequestFilters: () => setupWebRequestFilters(session),
|
|
isLocal
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Enable ad blocking for a session
|
|
* @param {Object} s - Electron session to enable blocking for
|
|
*/
|
|
async function enableGoodies(s) {
|
|
try {
|
|
if (!s) {
|
|
console.log("No session provided to enableGoodies, using default session");
|
|
return;
|
|
}
|
|
|
|
const blocker = await ElectronBlocker.fromLists(fetch, [
|
|
"https://github.com/uBlockOrigin/uAssets/raw/refs/heads/master/filters/ubol-filters.txt",
|
|
'https://easylist.to/easylist/easylist.txt',
|
|
'https://secure.fanboy.co.nz/fanboy-annoyance.txt',
|
|
'https://easylist.to/easylist/easyprivacy.txt',
|
|
'https://easylist-downloads.adblockplus.org/antiadblockfilters.txt',
|
|
'https://raw.githubusercontent.com/hoshsadiq/adblock-nocoin-list/master/nocoin.txt',
|
|
'https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/adblock/pro.plus.txt',
|
|
"https://github.com/yokoffing/filterlists/raw/refs/heads/main/youtube_clear_view.txt",
|
|
"https://pgl.yoyo.org/as/serverlist.php?showintro=0;hostformat=adblock",
|
|
"https://github.com/uBlockOrigin/uAssets/raw/refs/heads/master/filters/unbreak.txt",
|
|
"https://github.com/uBlockOrigin/uAssets/raw/refs/heads/master/filters/quick-fixes.txt",
|
|
"https://github.com/uBlockOrigin/uAssets/raw/refs/heads/master/filters/privacy.txt",
|
|
"https://github.com/uBlockOrigin/uAssets/raw/refs/heads/master/filters/badware.txt",
|
|
"https://github.com/uBlockOrigin/uAssets/raw/refs/heads/master/filters/filters.txt"
|
|
]);
|
|
|
|
blocker.enableBlockingInSession(s);
|
|
console.log("AD blocking enabled successfully");
|
|
return blocker;
|
|
} catch (error) {
|
|
console.error("Error enabling AD blocking:", error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if a URL is for a local resource
|
|
* @param {string} url - URL to check
|
|
* @returns {boolean} Whether URL is for a local resource
|
|
*/
|
|
function isLocal(url) {
|
|
return locals.some(local => url.includes(local));
|
|
}
|
|
|
|
/**
|
|
* Check if a URL should be blocked by our custom rules
|
|
* @param {string} url - URL to check
|
|
* @returns {boolean} Whether URL should be blocked
|
|
*/
|
|
function containsAD(url) {
|
|
// Check against simple pattern list
|
|
for (let i = 0; i < toBlock.length; i++) {
|
|
let regex = toBlock[i].replace(/\*/g, "[^ ]*");
|
|
if (url.match(regex)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Check against regex patterns
|
|
for (let i = 0; i < regexPatterns.length; i++) {
|
|
let regex = regexPatterns[i];
|
|
if (url.match(regex)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Set up web request filters for ad blocking and security
|
|
* @param {Object} session - Electron session to set up filters for
|
|
*/
|
|
function setupWebRequestFilters(session) {
|
|
// Set up web request filter
|
|
session.webRequest.onBeforeRequest((details, callback) => {
|
|
// Block ads
|
|
if (containsAD(details.url)) {
|
|
return callback({cancel: true});
|
|
}
|
|
|
|
try {
|
|
const url = new URL(details.url);
|
|
const hostname = url.hostname;
|
|
const isLocalDomain = isLocal(hostname);
|
|
|
|
// Check if the request is to a local domain
|
|
if (isLocalDomain) {
|
|
// Check if the request is initiated by a remote domain
|
|
const initiator = details.initiator ? new URL(details.initiator).hostname : '';
|
|
const isInitiatorLocal = isLocal(initiator);
|
|
|
|
if (initiator && !isInitiatorLocal) {
|
|
console.log(`[W] Local domain is being accessed by external source (${initiator}), don't allow!`);
|
|
callback({ cancel: true }); // Block request to local domains from remote sources
|
|
return;
|
|
}
|
|
}
|
|
|
|
callback({ cancel: false }); // Allow request
|
|
} catch (error) {
|
|
console.error("Error in web request filter:", error);
|
|
callback({ cancel: false }); // Allow on error
|
|
}
|
|
});
|
|
}
|
|
|
|
module.exports = initAdBlocker;
|