This commit is contained in:
Raymond Hill 2024-12-02 10:59:16 -05:00
parent 61d6cd803c
commit 3c13d279fd
No known key found for this signature in database
GPG key ID: 25E1490B761470C2
6 changed files with 127 additions and 46 deletions

View file

@ -42,5 +42,14 @@
"managed_schema": "managed_storage.json"
},
"version": "1.0",
"web_accessible_resources": []
"web_accessible_resources": [
{
"resources": [
"/strict-block.html"
],
"matches": [
"<all_urls>"
]
}
]
}

View file

@ -243,7 +243,11 @@
"message": "uBO Lite has prevented the following page from loading:",
"description": "Sentence used in the strict-blocked page"
},
"strictblockBack": {
"strictblockNoParamsPrompt": {
"message": "without parameters",
"description": "Label to be used for the parameter-less URL"
},
"strictblockBack": {
"message": "Go back",
"description": "A button to go back to the previous webpage"
},

View file

@ -39,7 +39,8 @@ import { ubolLog } from './debug.js';
const TRUSTED_DIRECTIVE_BASE_RULE_ID = 8000000;
let dynamicRulesetId = 1;
let dynamicRuleId = 1;
let sessionRuleId = 1;
/******************************************************************************/
@ -82,6 +83,17 @@ function getDynamicRules(...args) {
return getDynamicRules.promise;
}
function getSessionRules(...args) {
if ( getSessionRules.promise !== undefined ) {
return getSessionRules.promise;
}
getSessionRules.promise = dnr.getSessionRules(...args).then(rules => {
getSessionRules.promise = undefined;
return rules;
});
return getSessionRules.promise;
}
/******************************************************************************/
async function pruneInvalidRegexRules(realm, rulesIn) {
@ -143,7 +155,7 @@ async function updateRegexRules(toAdd) {
for ( const rules of regexRulesets ) {
if ( Array.isArray(rules) === false ) { continue; }
for ( const rule of rules ) {
rule.id = dynamicRulesetId++;
rule.id = dynamicRuleId++;
allRules.push(rule);
}
}
@ -181,7 +193,7 @@ async function updateRemoveparamRules(toAdd) {
for ( const rules of removeparamRulesets ) {
if ( Array.isArray(rules) === false ) { continue; }
for ( const rule of rules ) {
rule.id = dynamicRulesetId++;
rule.id = dynamicRuleId++;
allRules.push(rule);
}
}
@ -220,7 +232,7 @@ async function updateRedirectRules(toAdd) {
for ( const rules of redirectRulesets ) {
if ( Array.isArray(rules) === false ) { continue; }
for ( const rule of rules ) {
rule.id = dynamicRulesetId++;
rule.id = dynamicRuleId++;
allRules.push(rule);
}
}
@ -259,7 +271,7 @@ async function updateModifyHeadersRules(toAdd) {
for ( const rules of rulesets ) {
if ( Array.isArray(rules) === false ) { continue; }
for ( const rule of rules ) {
rule.id = dynamicRulesetId++;
rule.id = dynamicRuleId++;
allRules.push(rule);
}
}
@ -275,7 +287,7 @@ async function updateModifyHeadersRules(toAdd) {
/******************************************************************************/
async function updateStrictBlockRules(toAdd) {
async function updateStrictBlockRules(dynamicRules, sessionRules) {
const [
hasOmnipotence,
rulesetDetails,
@ -296,8 +308,6 @@ async function updateStrictBlockRules(toAdd) {
}
const strictBlockRulesets = await Promise.all(toFetch);
const allExcluded = permanentlyExcluded.concat(temporarilyExcluded);
// Strict-block rules can only be enforced with omnipotence
let toStrictBlock = new Set();
if ( hasOmnipotence ) {
@ -305,66 +315,115 @@ async function updateStrictBlockRules(toAdd) {
if ( Array.isArray(hostnames) === false ) { continue; }
toStrictBlock = toStrictBlock.union(new Set(hostnames));
}
} else if ( allExcluded.length !== 0 ) {
localRemove('excludedStrictBlockHostnames');
sessionRemove('excludedStrictBlockHostnames');
allExcluded.length = 0;
} else {
if ( permanentlyExcluded.length !== 0 ) {
localRemove('excludedStrictBlockHostnames');
permanentlyExcluded.length = 0;
}
if ( temporarilyExcluded.length !== 0 ) {
sessionRemove('excludedStrictBlockHostnames');
temporarilyExcluded.length = 0;
}
}
for ( const hn of allExcluded ) {
for ( const hn of permanentlyExcluded ) {
toStrictBlock.delete(hn);
}
if ( toStrictBlock.size === 0 ) { return; }
const ubolOrigin = runtime.getURL('').replace(/\/$/, '');
const rule = {
id: dynamicRulesetId++,
const dynamicRule = {
id: dynamicRuleId++,
action: {
type: 'redirect',
redirect: {
regexSubstitution: `${ubolOrigin}/strict-block.html#\\0`,
regexSubstitution: `${runtime.getURL('/strict-block.html')}#\\0`,
},
},
condition: {
regexFilter: '^https:?//.+',
regexFilter: '^https?://.+',
requestDomains: Array.from(toStrictBlock),
resourceTypes: [ 'main_frame' ],
},
priority: 29,
};
if ( allExcluded.length !== 0 ) {
rule.condition.excludedRequestDomains = allExcluded;
if ( permanentlyExcluded.length !== 0 ) {
dynamicRule.condition.excludedRequestDomains = permanentlyExcluded;
}
toAdd.push(rule);
dynamicRules.push(dynamicRule);
ubolLog(`Add 1 DNR dynamic rule with ${toStrictBlock.size} strict-blocked domains`);
ubolLog(`Add 1 DNR strict-block rules with ${toStrictBlock.size} domains`);
if ( temporarilyExcluded.length === 0 ) { return; }
sessionRules.push({
id: sessionRuleId++,
action: {
type: 'allow',
},
condition: {
requestDomains: temporarilyExcluded,
resourceTypes: [ 'main_frame' ],
},
priority: 29,
});
ubolLog(`Add 1 DNR session rule with ${temporarilyExcluded.length} unstrict-blocked domains`);
}
/******************************************************************************/
async function updateDynamicRules() {
dynamicRulesetId = 1;
const addRules = [];
const [ removeRuleIds ] = await Promise.all([
dynamicRuleId = 1;
sessionRuleId = 1;
const dynamicRules = [];
const sessionRules = [];
const [
dynamicRuleIds,
sessionRuleIds,
] = await Promise.all([
getDynamicRules().then(rules =>
rules.map(rule => rule.id)
.filter(id => id < TRUSTED_DIRECTIVE_BASE_RULE_ID)
),
updateRegexRules(addRules),
updateRemoveparamRules(addRules),
updateRedirectRules(addRules),
updateModifyHeadersRules(addRules),
updateStrictBlockRules(addRules),
getSessionRules().then(rules => rules.map(rule => rule.id)),
updateRegexRules(dynamicRules),
updateRemoveparamRules(dynamicRules),
updateRedirectRules(dynamicRules),
updateModifyHeadersRules(dynamicRules),
updateStrictBlockRules(dynamicRules, sessionRules),
]);
if ( addRules.length === 0 && removeRuleIds.length === 0 ) { return; }
if ( removeRuleIds.length !== 0 ) {
ubolLog(`Remove ${removeRuleIds.length} dynamic DNR rules`);
if ( dynamicRules.length === 0 && dynamicRuleIds.length === 0 ) { return; }
const promises = [];
if ( dynamicRules.length !== 0 || dynamicRuleIds.length !== 0 ) {
promises.push(
dnr.updateDynamicRules({
addRules: dynamicRules,
removeRuleIds: dynamicRuleIds,
}).then(( ) => {
if ( dynamicRuleIds.length !== 0 ) {
ubolLog(`Remove ${dynamicRuleIds.length} dynamic DNR rules`);
}
if ( dynamicRules.length !== 0 ) {
ubolLog(`Add ${dynamicRules.length} dynamic DNR rules`);
}
}).catch(reason => {
console.error(`updateDynamicRules() / ${reason}`);
})
);
}
if ( addRules.length !== 0 ) {
ubolLog(`Add ${addRules.length} dynamic DNR rules`);
if ( sessionRules.length !== 0 || sessionRuleIds.length !== 0 ) {
promises.push(
dnr.updateSessionRules({
addRules: sessionRules,
removeRuleIds: sessionRuleIds,
}).then(( ) => {
if ( sessionRuleIds.length !== 0 ) {
ubolLog(`Remove ${sessionRuleIds.length} session DNR rules`);
}
if ( sessionRules.length !== 0 ) {
ubolLog(`Add ${sessionRules.length} session DNR rules`);
}
}).catch(reason => {
console.error(`updateSessionRules() / ${reason}`);
})
);
}
return dnr.updateDynamicRules({ addRules, removeRuleIds }).catch(reason => {
console.error(`updateDynamicRules() / ${reason}`);
});
return Promise.all(promises);
}
/******************************************************************************/

View file

@ -116,7 +116,7 @@ qs$('#theURL > p > span:first-of-type').append(urlToFragment(toURL.href));
if ( search === '' ) { return false; }
url.search = '';
const li = liFromParam(i18n$('docblockedNoParamsPrompt'), url.href);
const li = liFromParam(i18n$('strictblockNoParamsPrompt'), url.href);
parentNode.appendChild(li);
const params = new self.URLSearchParams(search);
@ -169,8 +169,8 @@ if ( window.history.length > 1 ) {
dom.on('#disableWarning', 'change', ev => {
const checked = ev.target.checked;
dom.cl.toggle('[data-i18n="docblockedBack"]', 'disabled', checked);
dom.cl.toggle('[data-i18n="docblockedClose"]', 'disabled', checked);
dom.cl.toggle('[data-i18n="strictblockBack"]', 'disabled', checked);
dom.cl.toggle('[data-i18n="strictblockClose"]', 'disabled', checked);
});
dom.on('#proceed', 'click', ( ) => {

View file

@ -51,5 +51,14 @@
],
"short_name": "uBO Lite",
"version": "1.0",
"web_accessible_resources": []
"web_accessible_resources": [
{
"resources": [
"/strict-block.html"
],
"matches": [
"<all_urls>"
]
}
]
}

View file

@ -1368,7 +1368,7 @@ async function main() {
if ( platform === 'chromium' ) {
web_accessible_resources.use_dynamic_url = true;
}
manifest.web_accessible_resources = [ web_accessible_resources ];
manifest.web_accessible_resources.push(web_accessible_resources);
// Patch manifest version property
manifest.version = version;