Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b5e1296a7a | |||
| e80704c534 |
68
main.js
68
main.js
@@ -6,6 +6,16 @@ const cheerio = require('cheerio');
|
|||||||
const { ElectronBlocker, adsAndTrackingLists } = require('@cliqz/adblocker-electron');
|
const { ElectronBlocker, adsAndTrackingLists } = require('@cliqz/adblocker-electron');
|
||||||
const { autoUpdater } = require('electron-updater');
|
const { autoUpdater } = require('electron-updater');
|
||||||
|
|
||||||
|
// Disable Trusted Types CSP enforcement engine-wide.
|
||||||
|
// YouTube sends `Content-Security-Policy: require-trusted-types-for 'script'`,
|
||||||
|
// which blocks the cliqz adblocker's scriptlet injection (it uses plain
|
||||||
|
// `script.text = ...`) → 52+ console errors and broken anti-adblock neutralizers.
|
||||||
|
// Stripping the CSP header via webRequest doesn't work — the adblocker's own
|
||||||
|
// onHeadersReceived hook overwrites ours (Electron allows only one listener
|
||||||
|
// per session). Disabling the Blink feature is the cleanest fix; safe in a
|
||||||
|
// kiosk single-user context.
|
||||||
|
app.commandLine.appendSwitch('disable-blink-features', 'TrustedDOMTypes');
|
||||||
|
|
||||||
const CONFIG_PATH = path.join(os.homedir(), '.ESH-Media.json');
|
const CONFIG_PATH = path.join(os.homedir(), '.ESH-Media.json');
|
||||||
const BLOCKER_CACHE_PATH = path.join(os.homedir(), '.ESH-Media-adblock-v3.bin');
|
const BLOCKER_CACHE_PATH = path.join(os.homedir(), '.ESH-Media-adblock-v3.bin');
|
||||||
const DEFAULT_TRUSTED_DOMAINS = [
|
const DEFAULT_TRUSTED_DOMAINS = [
|
||||||
@@ -101,7 +111,27 @@ function getBlocker() {
|
|||||||
|
|
||||||
function enableBlockingInSession(sess) {
|
function enableBlockingInSession(sess) {
|
||||||
getBlocker()
|
getBlocker()
|
||||||
.then(b => { b.enableBlockingInSession(sess); console.log('[adblock] enabled for session'); })
|
.then(b => {
|
||||||
|
b.enableBlockingInSession(sess);
|
||||||
|
// Remove the cliqz preload script that the blocker just registered on this
|
||||||
|
// session. The preload injects inline <script> elements (via createTextNode +
|
||||||
|
// appendChild) to neutralize anti-adblock scripts, but:
|
||||||
|
// • Strict-CSP sites (kinogo via Cloudflare, etc.) reject inline scripts
|
||||||
|
// without a matching nonce → "Refused to execute inline script".
|
||||||
|
// • Trusted-Types sites (YouTube, Gmail) reject `script.appendChild(text)`
|
||||||
|
// → "HTMLScriptElement was directly modified" (52 errors).
|
||||||
|
// We keep the adblocker's network blocking and CSP filtering (via the still-
|
||||||
|
// attached webRequest hooks), losing only the niche scriptlet/cosmetic-DOM
|
||||||
|
// injection layer that breaks more sites than it helps.
|
||||||
|
const before = sess.getPreloads();
|
||||||
|
const after = before.filter(p => !/adblocker-electron-preload/i.test(p));
|
||||||
|
if (after.length !== before.length) {
|
||||||
|
sess.setPreloads(after);
|
||||||
|
console.log('[adblock] enabled for session (preload script disabled)');
|
||||||
|
} else {
|
||||||
|
console.log('[adblock] enabled for session');
|
||||||
|
}
|
||||||
|
})
|
||||||
.catch(e => console.warn('[adblock] failed to enable:', e.message));
|
.catch(e => console.warn('[adblock] failed to enable:', e.message));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1228,39 +1258,9 @@ app.whenReady().then(async () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Strip Trusted Types directives from CSP for sites that enforce them
|
// (Trusted Types now handled engine-wide via --disable-blink-features
|
||||||
// (YouTube, Gmail, etc.). The cliqz adblocker injects inline scriptlets to
|
// command-line switch at file top. webRequest.onHeadersReceived strip
|
||||||
// neutralize anti-adblock tricks; those injections use plain script.text
|
// was tried in 1.0.6 but the cliqz adblocker overwrites the listener.)
|
||||||
// assignment which TT blocks → "An HTMLScriptElement was directly modified
|
|
||||||
// and will not be executed" (52+ console errors on YouTube). Without TT
|
|
||||||
// the adblocker's scripts run and YouTube works normally.
|
|
||||||
const TT_STRIP_HOSTS = [
|
|
||||||
'youtube.com', 'youtu.be', 'youtubekids.com',
|
|
||||||
'google.com', 'gmail.com', 'mail.google.com',
|
|
||||||
];
|
|
||||||
const stripTrustedTypes = (sess) => {
|
|
||||||
sess.webRequest.onHeadersReceived(
|
|
||||||
{ urls: ['https://*/*'] },
|
|
||||||
(details, callback) => {
|
|
||||||
let host = '';
|
|
||||||
try { host = new URL(details.url).hostname; } catch {}
|
|
||||||
const match = TT_STRIP_HOSTS.some(d => host === d || host.endsWith('.' + d));
|
|
||||||
const headers = details.responseHeaders;
|
|
||||||
if (!match || !headers) return callback({});
|
|
||||||
for (const k of Object.keys(headers)) {
|
|
||||||
if (/^content-security-policy(-report-only)?$/i.test(k)) {
|
|
||||||
headers[k] = headers[k].map(v => v
|
|
||||||
.replace(/require-trusted-types-for[^;]*;?\s*/gi, '')
|
|
||||||
.replace(/trusted-types[^;]*;?\s*/gi, ''));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
callback({ responseHeaders: headers });
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
stripTrustedTypes(session.defaultSession);
|
|
||||||
stripTrustedTypes(getProxySession());
|
|
||||||
stripTrustedTypes(getDirectSession());
|
|
||||||
|
|
||||||
// Apply proxy from config before blocker tries to download filter lists
|
// Apply proxy from config before blocker tries to download filter lists
|
||||||
loadTrustedDomainsFromDisk();
|
loadTrustedDomainsFromDisk();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ESH-Media",
|
"name": "ESH-Media",
|
||||||
"version": "1.0.6",
|
"version": "1.0.8",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Reference in New Issue
Block a user