version 0.4.9
This commit is contained in:
parent
1353e8a110
commit
70a5affd37
11 changed files with 299 additions and 109 deletions
|
@ -1,4 +1,4 @@
|
|||
/* globals UAParser */
|
||||
/* global UAParser */
|
||||
|
||||
'use strict';
|
||||
|
||||
|
@ -544,15 +544,15 @@ const onBeforeSendHeaders = d => {
|
|||
if (platform.toLowerCase().includes('mac')) {
|
||||
platform = 'macOS';
|
||||
}
|
||||
else if (platform.toLowerCase().includes('debian')) {
|
||||
platform = 'Linux';
|
||||
}
|
||||
|
||||
const version = o.userAgentDataBuilder.p?.browser?.major || 107;
|
||||
let name = o.userAgentDataBuilder.p?.browser?.name || 'Google Chrome';
|
||||
if (name === 'Chrome') {
|
||||
name = 'Google Chrome';
|
||||
}
|
||||
else if (name.includes('debian')) {
|
||||
platform = 'Linux';
|
||||
}
|
||||
|
||||
requestHeaders.push({
|
||||
name: 'sec-ch-ua-platform',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"manifest_version": 2,
|
||||
"name": "__MSG_extensionName__",
|
||||
"version": "0.4.8",
|
||||
"version": "0.4.9",
|
||||
"default_locale": "en",
|
||||
"description": "__MSG_extensionDescription__",
|
||||
"permissions": [
|
||||
|
|
|
@ -15,3 +15,5 @@ self.prefs = self.prefs || {
|
|||
platformVersion: '10.0.0'
|
||||
};
|
||||
Object.assign(port.dataset, self.prefs);
|
||||
|
||||
port.dataset.enabled = self.ingored ? false : true;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
const port = document.getElementById('ua-port-fgTd9n');
|
||||
port.remove();
|
||||
console.log(12, port);
|
||||
|
||||
// overwrite navigator.userAgent
|
||||
{
|
||||
|
@ -8,8 +7,8 @@ console.log(12, port);
|
|||
|
||||
Object.defineProperty(Navigator.prototype, 'userAgent', {
|
||||
get: new Proxy(get, {
|
||||
apply() {
|
||||
return port.dataset.ua;
|
||||
apply(target, self, args) {
|
||||
return port.dataset.enabled === 'true' ? port.dataset.ua : Reflect.apply(target, self, args);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
@ -31,8 +30,8 @@ if (port.dataset.uad) {
|
|||
|
||||
Object.defineProperty(self.NavigatorUAData.prototype, 'brands', {
|
||||
get: new Proxy(Object.getOwnPropertyDescriptor(self.NavigatorUAData.prototype, 'brands').get, {
|
||||
apply() {
|
||||
return [{
|
||||
apply(target, self, args) {
|
||||
return port.dataset.enabled === 'true' ? [{
|
||||
brand: port.dataset.name,
|
||||
version: port.dataset.major
|
||||
}, {
|
||||
|
@ -41,35 +40,36 @@ if (port.dataset.uad) {
|
|||
}, {
|
||||
brand: 'Not=A?Brand',
|
||||
version: '24'
|
||||
}];
|
||||
}] : Reflect.apply(target, self, args);
|
||||
}
|
||||
})
|
||||
});
|
||||
Object.defineProperty(self.NavigatorUAData.prototype, 'mobile', {
|
||||
get: new Proxy(Object.getOwnPropertyDescriptor(self.NavigatorUAData.prototype, 'mobile').get, {
|
||||
apply() {
|
||||
return port.dataset.mobile === 'true';
|
||||
apply(target, self, args) {
|
||||
return port.dataset.enabled === 'true' ? port.dataset.mobile === 'true' : Reflect.apply(target, self, args);
|
||||
}
|
||||
})
|
||||
});
|
||||
Object.defineProperty(self.NavigatorUAData.prototype, 'platform', {
|
||||
get: new Proxy(Object.getOwnPropertyDescriptor(self.NavigatorUAData.prototype, 'platform').get, {
|
||||
apply() {
|
||||
return port.dataset.platform;
|
||||
apply(target, self, args) {
|
||||
return port.dataset.enabled === 'true' ? port.dataset.platform : Reflect.apply(target, self, args);
|
||||
}
|
||||
})
|
||||
});
|
||||
self.NavigatorUAData.prototype.toJSON = new Proxy(self.NavigatorUAData.prototype.toJSON, {
|
||||
apply(target, self) {
|
||||
return {
|
||||
apply(target, self, args) {
|
||||
return port.dataset.enabled === 'true' ? {
|
||||
brands: self.brands,
|
||||
mobile: self.mobile,
|
||||
platform: self.platform
|
||||
};
|
||||
} : Reflect.apply(target, self, args);
|
||||
}
|
||||
});
|
||||
self.NavigatorUAData.prototype.getHighEntropyValues = new Proxy(self.NavigatorUAData.prototype.getHighEntropyValues, {
|
||||
apply(target, self, args) {
|
||||
if (port.dataset.enabled === 'true') {
|
||||
const hints = args[0];
|
||||
|
||||
if (!hints || Array.isArray(hints) === false) {
|
||||
|
@ -98,5 +98,7 @@ if (port.dataset.uad) {
|
|||
}
|
||||
return Promise.resolve(r);
|
||||
}
|
||||
return Reflect.apply(target, self, args);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
2
v3/helper/ReadMe.txt
Normal file
2
v3/helper/ReadMe.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
ua-parser.min.js:
|
||||
https://github.com/faisalman/ua-parser-js/releases/tag/1.0.32
|
4
v3/helper/ua-parser.min.js
vendored
Normal file
4
v3/helper/ua-parser.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -10,6 +10,7 @@
|
|||
"webNavigation",
|
||||
"webRequest",
|
||||
"declarativeNetRequest",
|
||||
"declarativeNetRequestFeedback",
|
||||
"contextMenus"
|
||||
],
|
||||
"host_permissions": [
|
||||
|
|
74
v3/policy.js
Normal file
74
v3/policy.js
Normal file
|
@ -0,0 +1,74 @@
|
|||
/* global UAParser */
|
||||
self.importScripts('./helper/ua-parser.min.js');
|
||||
|
||||
const PREFS = {
|
||||
'enabled': true,
|
||||
'mode': 'blacklist',
|
||||
'blacklist-exception-hosts': [],
|
||||
'whitelist-hosts': [],
|
||||
'custom-routing': {
|
||||
'whatismybrowser.com': 'ff'
|
||||
}
|
||||
};
|
||||
|
||||
const policy = {};
|
||||
|
||||
{
|
||||
const cache = new Map();
|
||||
|
||||
policy.parse = d => {
|
||||
const ua = 'Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36';
|
||||
|
||||
if (cache.has(ua)) {
|
||||
return cache.get(ua);
|
||||
}
|
||||
|
||||
return new Promise(resolve => chrome.storage.local.get({
|
||||
'userAgentData': true
|
||||
}, prefs => {
|
||||
const p = (new UAParser(ua)).getResult();
|
||||
|
||||
const r = {
|
||||
ua
|
||||
};
|
||||
r.uad = prefs.userAgentData &&
|
||||
p.browser && p.browser.major && ['Opera', 'Chrome', 'Edge'].includes(p.browser.name);
|
||||
|
||||
if (r.uad) {
|
||||
r.platform = p?.os?.name || 'Windows';
|
||||
if (r.platform.toLowerCase().includes('mac')) {
|
||||
r.platform = 'macOS';
|
||||
}
|
||||
else if (r.platform.toLowerCase().includes('debian')) {
|
||||
r.platform = 'Linux';
|
||||
}
|
||||
|
||||
r.major = p?.browser?.major || 100;
|
||||
|
||||
r.name = p?.browser?.name || 'Google Chrome';
|
||||
if (r.name === 'Chrome') {
|
||||
r.name = 'Google Chrome';
|
||||
}
|
||||
|
||||
r.mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(ua);
|
||||
|
||||
r.architecture = 'x86';
|
||||
|
||||
r.bitness = '64';
|
||||
|
||||
r.platformVersion = '10.0.0';
|
||||
}
|
||||
|
||||
cache.set(ua, r);
|
||||
|
||||
resolve(r);
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
policy.configure = (...methods) => new Promise(resolve => chrome.storage.local.get(PREFS, prefs => {
|
||||
for (const method of methods) {
|
||||
method(prefs);
|
||||
}
|
||||
resolve();
|
||||
}));
|
51
v3/request.js
Normal file
51
v3/request.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
/* global policy */
|
||||
|
||||
const request = {};
|
||||
|
||||
request.network = async prefs => {
|
||||
const p = await policy.parse();
|
||||
|
||||
const condition = {
|
||||
'isUrlFilterCaseSensitive': false,
|
||||
'resourceTypes': Object.values(chrome.declarativeNetRequest.ResourceType)
|
||||
};
|
||||
const one = {
|
||||
'id': 1,
|
||||
'priority': 1,
|
||||
'action': {
|
||||
'type': 'modifyHeaders',
|
||||
'requestHeaders': [{
|
||||
'operation': 'set',
|
||||
'header': 'user-agent',
|
||||
'value': p.ua
|
||||
}]
|
||||
},
|
||||
'condition': {
|
||||
...condition
|
||||
}
|
||||
};
|
||||
const o = {
|
||||
addRules: [one],
|
||||
removeRuleIds: (await chrome.declarativeNetRequest.getDynamicRules()).map(o => o.id)
|
||||
};
|
||||
|
||||
if (prefs.enabled) {
|
||||
if (prefs.mode === 'blacklist') {
|
||||
one.condition.excludedInitiatorDomains = prefs['blacklist-exception-hosts'];
|
||||
}
|
||||
else {
|
||||
if (prefs['whitelist-hosts'].length) {
|
||||
one.condition.initiatorDomains = prefs['whitelist-hosts'];
|
||||
}
|
||||
else {
|
||||
console.info('matching list is empty');
|
||||
o.addRules.length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chrome.declarativeNetRequest.updateDynamicRules(o);
|
||||
};
|
||||
|
||||
chrome.declarativeNetRequest.onRuleMatchedDebug.addListener(d => console.log(d));
|
||||
|
104
v3/scripting.js
Normal file
104
v3/scripting.js
Normal file
|
@ -0,0 +1,104 @@
|
|||
/* global port, policy */
|
||||
|
||||
const scripting = {};
|
||||
|
||||
scripting.page = async prefs => {
|
||||
await chrome.scripting.unregisterContentScripts();
|
||||
|
||||
if (prefs.enabled) {
|
||||
const common = {
|
||||
'allFrames': true,
|
||||
'matchOriginAsFallback': true,
|
||||
'runAt': 'document_start'
|
||||
};
|
||||
if (prefs.mode === 'blacklist') {
|
||||
common.matches = ['*://*/*'];
|
||||
if (prefs['blacklist-exception-hosts'].length) {
|
||||
common.excludeMatches = prefs['blacklist-exception-hosts'].map(h => [`*://${h}/*`, `*://*.${h}/*`]).flat();
|
||||
}
|
||||
}
|
||||
else if (prefs['whitelist-hosts'].length) {
|
||||
common.matches = prefs['whitelist-hosts'].map(h => [`*://${h}/*`, `*://*.${h}/*`]).flat();
|
||||
}
|
||||
|
||||
if (common.matches.length) {
|
||||
await chrome.scripting.registerContentScripts([{
|
||||
...common,
|
||||
'id': 'protected',
|
||||
'js': ['/data/inject/isolated.js'],
|
||||
'world': 'ISOLATED'
|
||||
}, {
|
||||
...common,
|
||||
'id': 'unprotected',
|
||||
'js': ['/data/inject/main.js'],
|
||||
'world': 'MAIN'
|
||||
}]);
|
||||
}
|
||||
else {
|
||||
console.info('matching list is empty');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// web navigation
|
||||
{
|
||||
const onCommitted = async d => {
|
||||
const p = await policy.parse(d);
|
||||
|
||||
if (p) {
|
||||
chrome.scripting.executeScript({
|
||||
target: {
|
||||
tabId: d.tabId,
|
||||
frameIds: [d.frameId]
|
||||
},
|
||||
injectImmediately: true,
|
||||
func: p => {
|
||||
if (typeof port === 'undefined') {
|
||||
self.prefs = p;
|
||||
}
|
||||
else {
|
||||
Object.assign(port.dataset, p);
|
||||
}
|
||||
},
|
||||
args: [p]
|
||||
});
|
||||
}
|
||||
};
|
||||
const onCommittedIgnore = d => {
|
||||
chrome.scripting.executeScript({
|
||||
target: {
|
||||
tabId: d.tabId,
|
||||
frameIds: [d.frameId]
|
||||
},
|
||||
injectImmediately: true,
|
||||
func: () => {
|
||||
if (typeof port === 'undefined') {
|
||||
port.dataset.enabled = false;
|
||||
}
|
||||
else {
|
||||
self.ingored = true;
|
||||
}
|
||||
}
|
||||
}).catch(() => {});
|
||||
};
|
||||
|
||||
scripting.commit = prefs => {
|
||||
if (prefs.enabled && prefs.mode === 'blacklist') {
|
||||
chrome.webNavigation.onCommitted.addListener(onCommitted);
|
||||
if (prefs['blacklist-exception-hosts'].length) {
|
||||
chrome.webNavigation.onCommitted.addListener(onCommittedIgnore, {
|
||||
url: prefs['blacklist-exception-hosts'].map(hostContains => ({
|
||||
hostContains
|
||||
}))
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (prefs['whitelist-hosts'].length) {
|
||||
chrome.webNavigation.onCommitted.addListener(onCommitted, {
|
||||
url: prefs['whitelist-hosts'].map(hostContains => ({
|
||||
hostContains
|
||||
}))
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
86
v3/worker.js
86
v3/worker.js
|
@ -1,72 +1,22 @@
|
|||
const enable = () => chrome.storage.local.get({
|
||||
enabled: true
|
||||
}, async prefs => {
|
||||
await chrome.scripting.unregisterContentScripts();
|
||||
/* global policy, scripting, request */
|
||||
|
||||
if (prefs.enabled) {
|
||||
const common = {
|
||||
'matches': ['*://*/*'],
|
||||
'allFrames': true,
|
||||
'matchOriginAsFallback': true,
|
||||
'runAt': 'document_start'
|
||||
};
|
||||
self.importScripts('./policy.js');
|
||||
self.importScripts('./scripting.js');
|
||||
self.importScripts('./request.js');
|
||||
|
||||
await chrome.scripting.registerContentScripts([{
|
||||
...common,
|
||||
'id': 'protected',
|
||||
'js': ['/data/inject/isolated.js'],
|
||||
'world': 'ISOLATED'
|
||||
}, {
|
||||
...common,
|
||||
'id': 'unprotected',
|
||||
'js': ['/data/inject/main.js'],
|
||||
'world': 'MAIN'
|
||||
}]);
|
||||
}
|
||||
});
|
||||
chrome.runtime.onStartup.addListener(enable);
|
||||
chrome.runtime.onInstalled.addListener(enable);
|
||||
|
||||
const policy = () => ({
|
||||
ua: 'Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36',
|
||||
uad: true,
|
||||
major: 100,
|
||||
name: 'Google Chrome',
|
||||
mobile: false,
|
||||
platform: 'Windows',
|
||||
architecture: 'x86',
|
||||
bitness: '64',
|
||||
platformVersion: '10.0.0'
|
||||
});
|
||||
|
||||
// web navigation
|
||||
const onCommitted = d => {
|
||||
const p = policy(d);
|
||||
|
||||
if (p) {
|
||||
chrome.scripting.executeScript({
|
||||
target: {
|
||||
tabId: d.tabId,
|
||||
frameIds: [d.frameId]
|
||||
},
|
||||
injectImmediately: true,
|
||||
func: p => {
|
||||
/* global port */
|
||||
if (typeof port === 'undefined') {
|
||||
self.prefs = p;
|
||||
}
|
||||
else {
|
||||
Object.assign(port.dataset, p);
|
||||
}
|
||||
},
|
||||
args: [p]
|
||||
});
|
||||
}
|
||||
};
|
||||
chrome.storage.local.get({
|
||||
enabled: true
|
||||
}, prefs => {
|
||||
if (prefs.enabled) {
|
||||
chrome.webNavigation.onCommitted.addListener(onCommitted);
|
||||
// run on each wake up
|
||||
policy.configure(scripting.commit, request.network);
|
||||
|
||||
// run once
|
||||
{
|
||||
const once = () => policy.configure(scripting.page);
|
||||
|
||||
chrome.runtime.onStartup.addListener(once);
|
||||
chrome.runtime.onInstalled.addListener(once);
|
||||
}
|
||||
|
||||
chrome.storage.onChanged.addListener(ps => {
|
||||
if (ps.enabled || ps.mode || ps['blacklist-exception-hosts'] || ps['whitelist-hosts']) {
|
||||
policy.configure(scripting.commit, scripting.page, request.network);
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue