mirror of
https://github.com/anticensority/runet-censorship-bypass.git
synced 2025-04-22 18:22:00 +03:00
Compare commits
128 Commits
0.0.1.43-t
...
developmen
Author | SHA1 | Date | |
---|---|---|---|
|
d86cf384af | ||
|
e1c95a3ece | ||
|
edabf14dd5 | ||
|
2f5d425f34 | ||
|
1c38137200 | ||
|
99b68ec8d0 | ||
|
0cc47d43a9 | ||
|
a583e5ecb3 | ||
|
884b4f0fbc | ||
|
770c4ab47d | ||
|
c5d9ca3254 | ||
|
27ad6944e0 | ||
|
a589568bf9 | ||
|
b3585293a7 | ||
|
fd45db7dcc | ||
|
65eb930682 | ||
|
d3156175d8 | ||
|
c0862ecfff | ||
|
75d30ba467 | ||
|
a7e93d8383 | ||
|
b3096c8d83 | ||
|
ae930da8b3 | ||
|
451691ef2a | ||
|
6e8943ca1c | ||
|
61f22e08be | ||
|
b45a78e654 | ||
|
08e1b41780 | ||
|
e5fb9d11dd | ||
|
689f9266f7 | ||
|
6858c56534 | ||
|
7f9fb4f972 | ||
|
0e803bd08f | ||
|
6ef5807971 | ||
|
97adb7f3f4 | ||
|
db8dfbfd50 | ||
|
3d72acc6dd | ||
|
0d7678ff50 | ||
|
edf6fc8b5f | ||
|
0951e83dd1 | ||
|
79049bed25 | ||
|
951a5e9248 | ||
|
6634f72580 | ||
|
aac0182738 | ||
|
8f00516d44 | ||
|
1265a3ad79 | ||
|
93aa084de9 | ||
|
cb0d991e94 | ||
|
b77be60946 | ||
|
1aec32de3e | ||
|
86d07b79c3 | ||
|
5b3e6f1f51 | ||
|
ce22337928 | ||
|
c0e5609d44 | ||
|
c496fe1030 | ||
|
034c08828f | ||
|
1c479a4e47 | ||
|
6e24ee0454 | ||
|
e1bdf654f2 | ||
|
e73766ae24 | ||
|
5164559fc6 | ||
|
e344b987c5 | ||
|
05903e32b3 | ||
|
f43eafaf8a | ||
|
b5154f6453 | ||
|
699bef6fea | ||
|
da7701393e | ||
|
235f6e4b47 | ||
|
0c5dc8eb26 | ||
|
57a2a8c1ac | ||
|
d3caee1483 | ||
|
e4a936c5f1 | ||
|
414e2547f3 | ||
|
04be2d6164 | ||
|
e51673f268 | ||
|
d56a7e7366 | ||
|
0b13cb1dd0 | ||
|
14f32b4d13 | ||
|
9ef236d604 | ||
|
7dae51db8c | ||
|
796681ae5a | ||
|
ccda45a57c | ||
|
e95c186de1 | ||
|
df3ea9e6ad | ||
|
38e2bb2f3c | ||
|
35668f620b | ||
|
1371dc01cd | ||
|
95bfd3ae9e | ||
|
f93e01bb8a | ||
|
b3997f48ac | ||
|
1a0c168458 | ||
|
c566fcecb5 | ||
|
aa727d9329 | ||
|
53571f6228 | ||
|
eb996931ae | ||
|
63f5e6fd08 | ||
|
fe2e986bfe | ||
|
da06ea4aac | ||
|
e60b8cc96c | ||
|
c8e7d7f427 | ||
|
65f712d0a1 | ||
|
71d1aff6cd | ||
|
5287510263 | ||
|
a12621635b | ||
|
fb9aa707a6 | ||
|
e3c595a447 | ||
|
73485e8be4 | ||
|
99a4ff9d24 | ||
|
97ba2697da | ||
|
0ffefd7cfc | ||
|
747ad70497 | ||
|
3f0cebebad | ||
|
4985ef6526 | ||
|
5278c65c90 | ||
|
94aefc8ddc | ||
|
fccc2611b2 | ||
|
4e870d5b87 | ||
|
17989f4735 | ||
|
ea85cf941b | ||
|
0a0df56dbe | ||
|
97b6c2cdc3 | ||
|
4e736bf403 | ||
|
af7a5a24bc | ||
|
4704585c1a | ||
|
e9420a68c9 | ||
|
cbd377b33b | ||
|
f37539a19c | ||
|
e6d5be6e56 | ||
|
66d89a3b97 |
4
.github/FUNDING.yml
vendored
4
.github/FUNDING.yml
vendored
|
@ -2,11 +2,11 @@
|
|||
|
||||
github: # ilyaigpetrov
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: anticensority
|
||||
open_collective:
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: https://rebrand.ly/ac-donate
|
||||
custom: https://github.com/anticensority/runet-censorship-bypass/wiki/Поддержать
|
||||
|
|
34
README.md
34
README.md
|
@ -1,7 +1,7 @@
|
|||
If you __unstar__, please, [leave us a note](https://github.com/anticensority/runet-censorship-bypass/issues) why you do so.
|
||||
|
||||
[d1]: https://img.shields.io/badge/Поддержать-❤-green.svg
|
||||
[d2]: https://rebrand.ly/ac-donate
|
||||
[d2]: https://github.com/anticensority/runet-censorship-bypass/wiki/Поддержать
|
||||
|
||||
[![Поддержать][d1]][d2]
|
||||
[](#backers)
|
||||
|
@ -9,29 +9,37 @@ If you __unstar__, please, [leave us a note](https://github.com/anticensority/ru
|
|||
|
||||
# Russian Anticensorship on PAC-Scripts
|
||||
|
||||
This repo contains a chrome extension to bypass censorship in Russia: [WebStore](https://chrome.google.com/webstore/detail/npgcnondjocldhldegnakemclmfkngch)
|
||||
This repo contains an extension for Chromium and FireFox that helps to bypass censorship in Russia: [WebStore](https://chrome.google.com/webstore/detail/npgcnondjocldhldegnakemclmfkngch)
|
||||
| [Sources](./extensions/chromium/runet-censorship-bypass).
|
||||
This extension uses pac scripts, one of which (anticensority) is generated by this [pac-generator].
|
||||
|
||||
[pac-generator]: https://github.com/anticensority/pac-script-generator
|
||||
|
||||
## Install / Установка
|
||||
|
||||
1. [Chrome Web Store](https://chrome.google.com/webstore/detail/обход-блокировок-рунета/npgcnondjocldhldegnakemclmfkngch)
|
||||
2. [Chrome Web Store (MINI)](https://chrome.google.com/webstore/detail/обход-блокировок-рунета-м/gnknjnebjldmkpmlhjipalimhjofpgho)
|
||||
3. [Microsoft Edge Add-ons](https://microsoftedge.microsoft.com/addons/detail/обход-блокировок-рунета/ajgpnodjpffiagcfmifildjpoaeiobfh)
|
||||
4. [Microsoft Edge Add-ons (MINI)](https://microsoftedge.microsoft.com/addons/detail/обход-блокировок-рунета-м/cjppllmpmkpjfchbaoebeneghcbmlibj)
|
||||
5. [FireFox Add-ons](https://addons.mozilla.org/ru/firefox/addon/обход-блокировок-рунета/).
|
||||
6. Opera: сначала [установщик расширений из WebStore](https://addons.opera.com/ru/extensions/details/install-chrome-extensions/) (от команды Opera), затем см. пункты 1 и 2 выше.
|
||||
7. Пакеты для автономной (offline) установки / Packages for offline installation: https://github.com/anticensority/runet-censorship-bypass/releases.
|
||||
|
||||
Из-за блокировок адресов Google расширение может не устанавливаться из WebStore. Подробности и способы установки см. https://github.com/anticensority/runet-censorship-bypass/wiki/Автономная-установка-расширения.
|
||||
|
||||
## Why I do This
|
||||
|
||||
I believe __information mustn't be blocked based on political or other subjective views__.
|
||||
|
||||
My maxim is _"Your freedom ends when it starts to confine the freedom of others"_.
|
||||
|
||||
See [my other arguments against censorship (ru)](https://rebrand.ly/ac-arguments)
|
||||
See [my arguments against censorship (ru)](https://github.com/anticensority/runet-censorship-bypass/wiki/Почему-мы-это-делаем%3F-Аргументы-против-цензуры).
|
||||
|
||||
Looking at how Russian government [distorts TV](https://therussianreader.wordpress.com/2015/11/22/russian-truckers-strike-dagestan/) and blocks [critics of Putin](https://www.reuters.com/article/us-russia-internet-idUSBREA2C21L20140313),
|
||||
I decided to write an anticensorship extension for Chromium before they strike me first.
|
||||
I decided to write an anti-censorship extension for Chromium before they strike me first.
|
||||
|
||||
## How it Works
|
||||
|
||||
0. PAC script is a JavaScript file, triggered on every URL request, which says browser which proxy to use if any for this particular URL.
|
||||
1. The Chrome Extension sets PAC script in browser settings and keeps it synced with PAC script on the server (offering Antizapret (hosted on a dedicated server) or Anticensority (hosted on GitHub)).
|
||||
2. On every request PAC script checks if host is blocked or if its IP is blocked.
|
||||
3. If address is blocked PAC script returns proxy server to the browser. Antizapret PAC-script uses its own proxy servers and Anticensority PAC-script uses local Tor.
|
||||
0. PAC script is a JavaScript file, triggered on every URL request, which tells the browser which proxy to use if any for this particular URL.
|
||||
1. The Chrome Extension sets the PAC-script in browser settings and keeps it synced with the PAC script on the server. It offers Antizapret (hosted on a dedicated server) or Anticensority (hosted on GitHub) built-in PAC scripts for the user choice.
|
||||
2. On every request the PAC script checks if the host is blocked or if its IP is blocked.
|
||||
3. If an address is blocked, the PAC script returns the proxy server to the browser. The Antizapret PAC script uses its own proxy servers and the Anticensority PAC-script uses local Tor.
|
||||
4. PAC scripts on servers are updated periodically from https://github.com/zapret-info/z-i.
|
||||
|
||||
## Contributors
|
||||
|
@ -61,5 +69,3 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
|
|||
<a href="https://opencollective.com/anticensority/sponsor/7/website" target="_blank"><img src="https://opencollective.com/anticensority/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/anticensority/sponsor/8/website" target="_blank"><img src="https://opencollective.com/anticensority/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/anticensority/sponsor/9/website" target="_blank"><img src="https://opencollective.com/anticensority/sponsor/9/avatar.svg"></a>
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
# Install
|
||||
|
||||
Tested on NodeJS versoin: 12.
|
||||
Tested on:
|
||||
|
||||
NodeJS: v16.1.0.
|
||||
NPM: 7.11.2.
|
||||
OS: Linux Mint 20 Xfce Edition.
|
||||
|
||||
```
|
||||
npm install
|
||||
|
@ -9,15 +13,19 @@ npm install
|
|||
cd -
|
||||
|
||||
# For debugging:
|
||||
npm start
|
||||
npm start
|
||||
# Use your build/extension-beta
|
||||
|
||||
# For production:
|
||||
npm run release
|
||||
npm start
|
||||
# Use your build/extension-full or build/extension-mini
|
||||
```
|
||||
|
||||
# Release
|
||||
# For Reviewers
|
||||
|
||||
See ./src/extension-common/FOR_REVIEWERS.md.
|
||||
|
||||
# Release Instructions
|
||||
|
||||
1. `npm run release`
|
||||
2. `vim src/templates-data.js` and bump version.
|
||||
|
|
|
@ -46,7 +46,7 @@ const templatePlugin = (context) => through.obj(function(file, encoding, cb) {
|
|||
|
||||
const clean = function(cb) {
|
||||
|
||||
//return del.sync('./build');
|
||||
del.sync('./build');
|
||||
return cb();
|
||||
|
||||
};
|
||||
|
@ -97,7 +97,7 @@ const copyBeta = function(cb) {
|
|||
|
||||
};
|
||||
|
||||
const buildAll = gulp.parallel(copyMini, copyFull, copyBeta);
|
||||
const buildAll = gulp.series(clean, gulp.parallel(copyMini, copyFull, copyBeta));
|
||||
const buildBeta = copyBeta;
|
||||
|
||||
module.exports = {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,24 +8,24 @@
|
|||
"test": "mocha --recursive ./src/**/test/*",
|
||||
"subpages": "cd ./src/extension-common/pages/options/ && npm run build && cd -",
|
||||
"subpages:dev": "cd ./src/extension-common/pages/options/ && npm run build:dev:nocomp && cd -",
|
||||
"start": "npm run subpages:dev && npm run gulp buildAll",
|
||||
"release": "npm run subpages && npm run gulp buildAll"
|
||||
"start": "npm run release",
|
||||
"release": "npm run subpages && npx gulp -- buildAll"
|
||||
},
|
||||
"author": "Ilya Ig. Petrov",
|
||||
"license": "GPLv3",
|
||||
"devDependencies": {
|
||||
"chai": "^3.5.0",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-google": "^0.7.1",
|
||||
"gulp-changed": "^3.2.0",
|
||||
"mocha": "^3.5.3",
|
||||
"sinon-chrome": "^2.3.1",
|
||||
"chai": "^4.3.0",
|
||||
"eslint": "^7.19.0",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"gulp-changed": "^4.0.2",
|
||||
"mocha": "^8.2.1",
|
||||
"sinon-chrome": "^3.0.1",
|
||||
"symlink-to": "^0.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"del": "^3.0.0",
|
||||
"del": "^6.0.0",
|
||||
"gulp": "^4.0.2",
|
||||
"plugin-error": "^1.0.1",
|
||||
"through2": "^3.0.0"
|
||||
"through2": "^4.0.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
console.log('Extension started.');
|
||||
|
||||
{
|
||||
|
||||
const IF_DEBUG = true;
|
||||
|
@ -39,15 +41,18 @@
|
|||
|
||||
},
|
||||
|
||||
lastError: undefined,
|
||||
|
||||
checkChromeError() {
|
||||
|
||||
// Chrome API calls your cb in a context different from the point of API
|
||||
// method invokation.
|
||||
const err = chrome.runtime.lastError || chrome.extension.lastError;
|
||||
const err = chrome.runtime.lastError || chrome.extension.lastError || self.lastError;
|
||||
if (!err) {
|
||||
return;
|
||||
}
|
||||
console.warn('API returned error:', err);
|
||||
delete self.lastError;
|
||||
return new Error(err.message); // Add stack.
|
||||
|
||||
},
|
||||
|
@ -153,6 +158,32 @@
|
|||
|
||||
},
|
||||
|
||||
promisedLocalStorage: {
|
||||
get(key) {
|
||||
return new Promise((resolve) => (
|
||||
chrome.storage.local.get(
|
||||
key,
|
||||
window.utils.getOrDie((storage) => resolve(key ? storage[key] : storage)),
|
||||
)
|
||||
));
|
||||
},
|
||||
set(items) {
|
||||
return new Promise((resolve) => (
|
||||
chrome.storage.local.set(items, resolve)
|
||||
));
|
||||
},
|
||||
remove(keys) {
|
||||
return new Promise((resolve) => (
|
||||
chrome.storage.local.remove(keys, resolve)
|
||||
));
|
||||
},
|
||||
clear() {
|
||||
return new Promise((resolve) => (
|
||||
chrome.storage.local.clear(resolve)
|
||||
));
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* Possible values for levelOfControl:
|
||||
*
|
||||
|
@ -230,6 +261,15 @@
|
|||
|
||||
},
|
||||
|
||||
openAndFocus(url) {
|
||||
|
||||
chrome.tabs.create(
|
||||
{url: url},
|
||||
(tab) => chrome.windows.update(tab.windowId, {focused: true})
|
||||
);
|
||||
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
const max = 2**16;
|
||||
|
@ -240,9 +280,20 @@
|
|||
|
||||
const compareVersions = (a, b) => versionToInt(a) - versionToInt(b);
|
||||
|
||||
const ifFirefox = navigator.userAgent.toLowerCase().includes('firefox');
|
||||
|
||||
let give;
|
||||
const promise = !ifFirefox ? Promise.resolve() : new Promise((resolve) => {
|
||||
give = resolve;
|
||||
});
|
||||
|
||||
window.apis = {
|
||||
consent: {
|
||||
promise,
|
||||
give,
|
||||
},
|
||||
platform: {
|
||||
ifFirefox: navigator.userAgent.toLowerCase().includes('firefox'),
|
||||
ifFirefox,
|
||||
},
|
||||
version: {
|
||||
ifMini: false,
|
||||
|
@ -252,43 +303,4 @@
|
|||
},
|
||||
};
|
||||
|
||||
// Shims for FireFox
|
||||
|
||||
if (!chrome.proxy.settings) {
|
||||
|
||||
const ffxStore = window.utils.createStorage('firefox-only');
|
||||
|
||||
|
||||
chrome.proxy.settings = {
|
||||
get: (_, cb) => {
|
||||
|
||||
let currentSettings = ffxStore('proxySettings') || {};
|
||||
currentSettings.levelOfControl = 'controlled_by_this_extension'; // May be lie, but this field is required.
|
||||
cb && cb(currentSettings);
|
||||
|
||||
},
|
||||
onChange: {
|
||||
addListener: () => {},
|
||||
},
|
||||
set: (details, cb) => {
|
||||
|
||||
browser.proxy.unregister();
|
||||
browser.proxy.register('./default.pac.js');
|
||||
|
||||
|
||||
// browser.proxy.onProxyError.addListener((...err) => { console.log('ERROR IN PAC:', ...err) });
|
||||
|
||||
browser.runtime.sendMessage(details, {toProxyScript: true});
|
||||
ffxStore('proxySettings', details);
|
||||
cb && cb();
|
||||
|
||||
},
|
||||
};
|
||||
const proxySettings = ffxStore('proxySettings');
|
||||
if (proxySettings) {
|
||||
chrome.proxy.settings.set(proxySettings);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -53,15 +53,6 @@
|
|||
|
||||
};
|
||||
|
||||
const openAndFocus = function openAndFocus(url) {
|
||||
|
||||
chrome.tabs.create(
|
||||
{url: url},
|
||||
(tab) => chrome.windows.update(tab.windowId, {focused: true})
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
const ifPrefix = 'if-on-';
|
||||
const extName = chrome.runtime.getManifest().name;
|
||||
const extVersion = window.apis.version.build;
|
||||
|
@ -75,8 +66,8 @@
|
|||
const errors = err ? {[type]: err} : this.idToError;
|
||||
const json = JSON.stringify(errors, errorJsonReplacer, 0);
|
||||
|
||||
openAndFocus(
|
||||
'https://rebrand.ly/ac-error/?json=' + encodeURIComponent(json) +
|
||||
window.utils.openAndFocus(
|
||||
'https://anticensority.github.io/error/?json=' + encodeURIComponent(json) +
|
||||
(type ? '&type=' + encodeURIComponent(type) : '') +
|
||||
'&version=' + chrome.runtime.getManifest().version +
|
||||
'&useragent=' + encodeURIComponent(navigator.userAgent) +
|
||||
|
@ -242,7 +233,7 @@
|
|||
|
||||
chrome.notifications.clear(notId);
|
||||
if(notId === 'no-control') {
|
||||
return openAndFocus(
|
||||
return window.utils.openAndFocus(
|
||||
window.utils.messages.searchSettingsForUrl('proxy')
|
||||
);
|
||||
}
|
||||
|
@ -291,7 +282,7 @@
|
|||
handlers.mayNotify(
|
||||
noCon,
|
||||
chrome.i18n.getMessage('noControl'),
|
||||
chrome.i18n.getMessage('which'),
|
||||
chrome.i18n.getMessage('WhichQ'),
|
||||
{icon: 'no-control-128.png', ifSticky: false}
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
);
|
||||
}
|
||||
|
||||
console.log('GETed with success:', url, Date.now() - start);
|
||||
console.log('GETed with success:', url.substr(0, 100), Date.now() - start);
|
||||
textCb();
|
||||
|
||||
},
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
'use strict';
|
||||
|
||||
if (window.apis.platform.ifFirefox) {
|
||||
|
||||
const prefix = 'firefox-only';
|
||||
|
||||
const originalSet = chrome.proxy.settings.set.bind( chrome.proxy.settings );
|
||||
chrome.proxy.settings.set = function(details, cb) {
|
||||
const pac = window.utils.getProp(details, 'value.pacScript') || {};
|
||||
if (!(pac && pac.data)) {
|
||||
return originalSet(details, cb);
|
||||
}
|
||||
|
||||
const blob = new Blob([pac.data], { type : 'application/x-ns-proxy-autoconfig' });
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
originalSet({
|
||||
value: {
|
||||
proxyType: 'autoConfig',
|
||||
autoConfigUrl: blobUrl,
|
||||
},
|
||||
}, window.utils.chromified( async (err) => {
|
||||
if (err) {
|
||||
window.utils.lastError = err;
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
await window.utils.promisedLocalStorage.set({ [`${prefix}-pac-data`]: pac.data });
|
||||
cb();
|
||||
}));
|
||||
};
|
||||
|
||||
const originalGet = chrome.proxy.settings.get.bind( chrome.proxy.settings );
|
||||
chrome.proxy.settings.get = function(details, cb) {
|
||||
originalGet(details, window.utils.chromified(async (err, originalDetails) => {
|
||||
if (err) {
|
||||
window.utils.lastError = err;
|
||||
cb(originalDetails);
|
||||
return;
|
||||
}
|
||||
let pacData = await window.utils.promisedLocalStorage.get(`${prefix}-pac-data`);
|
||||
if (!pacData || !Object.keys(pacData).length) {
|
||||
cb(originalDetails);
|
||||
return;
|
||||
}
|
||||
cb(Object.assign(
|
||||
originalDetails,
|
||||
{
|
||||
value: {
|
||||
mode: 'pac_script',
|
||||
pacScript: {
|
||||
data: pacData,
|
||||
},
|
||||
},
|
||||
}
|
||||
));
|
||||
}));
|
||||
};
|
||||
|
||||
const originalClear = chrome.proxy.settings.clear.bind( chrome.proxy.settings );
|
||||
chrome.proxy.settings.clear = async function(details, cb) {
|
||||
await window.utils.promisedLocalStorage.remove(`${prefix}-pac-data`);
|
||||
originalClear(details, cb);
|
||||
};
|
||||
}
|
|
@ -101,12 +101,19 @@
|
|||
dflt: false,
|
||||
category: 'ownProxies',
|
||||
label: 'использовать СВОЙ локальный Tor',
|
||||
desc: 'Установите <a href="https://rebrand.ly/ac-tor">Tor</a> на свой компьютер и используйте его как прокси-сервер. <a href="https://rebrand.ly/ac-tor">ВАЖНО</a>',
|
||||
desc: 'Установите <a href="https://github.com/anticensority/runet-censorship-bypass/wiki/Расширение-и-TOR">Tor</a> на свой компьютер и используйте его как прокси-сервер. <a href="https://github.com/anticensority/runet-censorship-bypass/wiki/Расширение-и-TOR#важно">ВАЖНО</a>.',
|
||||
order: 5,
|
||||
},
|
||||
ifUseLocalWarp: {
|
||||
dflt: false,
|
||||
category: 'ownProxies',
|
||||
label: 'использовать WARP как прокси',
|
||||
desc: 'Использовать СВОЙ локальный CloudFlare WARP (<a href="https://one.one.one.one">https://one.one.one.one</a>) в качестве прокси.',
|
||||
order: 5.5,
|
||||
},
|
||||
exceptions: {
|
||||
category: 'exceptions',
|
||||
dflt: null,
|
||||
category: 'exceptions',
|
||||
},
|
||||
ifMindExceptions: {
|
||||
dflt: true,
|
||||
|
@ -115,11 +122,22 @@
|
|||
desc: 'Учитывать сайты, добавленные вручную. Только для своих прокси-серверов! Без своих прокси работать не будет.',
|
||||
order: 6,
|
||||
},
|
||||
whitelist: {
|
||||
dflt: [],
|
||||
category: 'exceptions',
|
||||
},
|
||||
ifMindWhitelist: {
|
||||
dflt: false,
|
||||
category: 'exceptions',
|
||||
label: 'Ограничиться только <a href="../exceptions/index.html">белым списком</a>',
|
||||
desc: 'Разрешить расширению работать только с адресами из белого списка.',
|
||||
order: 6.5,
|
||||
},
|
||||
customProxyStringRaw: {
|
||||
dflt: '',
|
||||
category: 'ownProxies',
|
||||
label: 'использовать СВОИ прокси',
|
||||
url: 'https://rebrand.ly/ac-own-proxy',
|
||||
url: 'https://github.com/anticensority/runet-censorship-bypass/wiki/Свои-прокси-в-расширении',
|
||||
order: 7,
|
||||
},
|
||||
ifUseOwnProxiesOnlyForOwnSites: {
|
||||
|
@ -142,7 +160,7 @@
|
|||
dflt: false,
|
||||
category: 'ownProxies',
|
||||
label: 'подменять DIRECT на',
|
||||
desc: 'Использовать в PAC-скрипте указанную строку для запросов напрямую (вместо директивы DIRECT). Данная строка не проверяется на требования к шифрованию связи до прокси! Строка должна соответствовать формату возвращаемого значения PAC-скрипта, который подобен <a href="https://rebrand.ly/ac-own-proxies#user-content-Формат">формату своих прокси</a>.',
|
||||
desc: 'Использовать в PAC-скрипте указанную строку для запросов напрямую (вместо директивы DIRECT). Данная строка не проверяется на требования к шифрованию связи до прокси! Строка должна соответствовать формату возвращаемого значения PAC-скрипта, который подобен <a href="https://github.com/anticensority/runet-censorship-bypass/wiki/Свои-прокси-в-расширении#формат">формату своих прокси</a>.',
|
||||
order: 9,
|
||||
},
|
||||
|
||||
|
@ -157,7 +175,6 @@
|
|||
return acc;
|
||||
|
||||
}, {});
|
||||
|
||||
};
|
||||
|
||||
const getCurrentConfigs = function getCurrentConfigs(ifRaw = false) {
|
||||
|
@ -220,7 +237,8 @@
|
|||
});
|
||||
|
||||
const self = {};
|
||||
Object.assign(self, getDefaults(), mods);
|
||||
const gdft = getDefaults();
|
||||
Object.assign(self, gdft, mods);
|
||||
self.ifNoMods = ifNoMods;
|
||||
|
||||
let customProxyArray = [];
|
||||
|
@ -234,6 +252,10 @@
|
|||
customProxyArray = customProxyArray.filter( (pStr) => /^HTTPS\s/.test(pStr) );
|
||||
}
|
||||
}
|
||||
if (self.ifUseLocalWarp) {
|
||||
self.warpPoints = ['SOCKS5 localhost:40000', 'HTTPS localhost:40000'];
|
||||
customProxyArray.push(...self.warpPoints);
|
||||
}
|
||||
if (self.ifUseLocalTor) {
|
||||
self.torPoints = ['SOCKS5 localhost:9150', 'SOCKS5 localhost:9050'];
|
||||
customProxyArray.push(...self.torPoints);
|
||||
|
@ -298,7 +320,8 @@
|
|||
self.included = [];
|
||||
self.excluded = [];
|
||||
for(const host of Object.keys(self.exceptions)) {
|
||||
if (self.exceptions[host]) {
|
||||
const ifProxy = self.exceptions[host] || false;
|
||||
if (ifProxy) {
|
||||
self.included.push(host);
|
||||
} else {
|
||||
self.excluded.push(host);
|
||||
|
@ -307,9 +330,9 @@
|
|||
['included', 'excluded'].forEach((who) => {
|
||||
|
||||
self[who] = self[who]
|
||||
.map( (s) => s.split('').reverse() )
|
||||
.map( (domain) => domain.split('').reverse() )
|
||||
.sort()
|
||||
.map( (a) => a.reverse().join('') );
|
||||
.map( (rDomain) => rDomain.reverse().join('') );
|
||||
|
||||
});
|
||||
if (self.included.length && !self.filteredCustomsString) {
|
||||
|
@ -343,18 +366,32 @@
|
|||
/******/
|
||||
/******/ const originalFindProxyForURL = FindProxyForURL;
|
||||
/******/ let tmp = function(url, host) {
|
||||
/******/
|
||||
/******/ const dotHost = '.' + host;
|
||||
${
|
||||
function() {
|
||||
let generatedPac = `
|
||||
/******/ if (${pacMods.ifMindWhitelist && pacMods.whitelist.length}) {
|
||||
/******/ const ifWhitelisted =
|
||||
/******/ ${JSON.stringify(pacMods.whitelist)}.some((whiteHost) => {
|
||||
/******/ const ifWild = whiteHost.startsWith('*');
|
||||
/******/ if (ifWild) {
|
||||
/******/ return dotHost.endsWith(whiteHost.substr(1));
|
||||
/******/ }
|
||||
/******/ return host === whiteHost;
|
||||
/******/ })
|
||||
/******/ if (!ifWhitelisted) {
|
||||
/******/ return 'DIRECT';
|
||||
/******/ }
|
||||
/******/ }`;
|
||||
|
||||
let res = pacMods.ifProhibitDns ? `
|
||||
generatedPac += pacMods.ifProhibitDns ? `
|
||||
/******/
|
||||
/******/ global.dnsResolve = function(host) { return null; };
|
||||
/******/
|
||||
/******/` : '';
|
||||
if (pacMods.ifProxyHttpsUrlsOnly) {
|
||||
|
||||
res += `
|
||||
generatedPac += `
|
||||
/******/
|
||||
/******/ if (!url.startsWith("https")) {
|
||||
/******/ return "DIRECT";
|
||||
|
@ -364,7 +401,7 @@
|
|||
}
|
||||
if (pacMods.ifUseLocalTor) {
|
||||
|
||||
res += `
|
||||
generatedPac += `
|
||||
/******/
|
||||
/******/ if (host.endsWith(".onion")) {
|
||||
/******/ return "${pacMods.torPoints.join('; ')}";
|
||||
|
@ -372,12 +409,12 @@
|
|||
/******/
|
||||
/******/ `;
|
||||
}
|
||||
res += `
|
||||
generatedPac += `
|
||||
/******/
|
||||
/******/ const directIfAllowed = ${pacMods.ifProxyOrDie ? '""/* Not allowed. */' : '"DIRECT"'};
|
||||
/******/`;
|
||||
if (pacMods.filteredCustomsString) {
|
||||
res += `
|
||||
generatedPac += `
|
||||
/******/
|
||||
/******/ const filteredCustomProxies = "${pacMods.filteredCustomsString}";
|
||||
/******/`;
|
||||
|
@ -386,11 +423,11 @@
|
|||
const ifIncluded = pacMods.included && pacMods.included.length;
|
||||
const ifExcluded = pacMods.excluded && pacMods.excluded.length;
|
||||
const ifManualExceptions = ifIncluded || ifExcluded;
|
||||
const finalExceptions = {};
|
||||
let finalExceptions = {};
|
||||
if (pacMods.ifProxyMoreDomains) {
|
||||
pacMods.moreDomains.reduce((acc, tld) => {
|
||||
finalExceptions = pacMods.moreDomains.reduce((acc, tld) => {
|
||||
|
||||
acc[tld] = true;
|
||||
acc['*.' + tld] = true;
|
||||
return acc;
|
||||
|
||||
}, finalExceptions);
|
||||
|
@ -401,21 +438,33 @@
|
|||
const ifExceptions = Object.keys(finalExceptions).length;
|
||||
|
||||
if (ifExceptions) {
|
||||
res += `
|
||||
generatedPac += `
|
||||
/******/
|
||||
/******/ /* EXCEPTIONS START */
|
||||
/******/ const dotHost = '.' + host;
|
||||
/******/ const isHostInDomain = (domain) => dotHost.endsWith('.' + domain);
|
||||
/******/ const domainReducer = (maxWeight, [domain, ifIncluded]) => {
|
||||
// TODO: handle wildcards.
|
||||
/******/ const isHostInDomain = (domain, ifWild) => {
|
||||
if (ifWild) {
|
||||
return dotHost.endsWith(domain.substr(1));
|
||||
}
|
||||
return domain === host;
|
||||
}
|
||||
/******/ const domainReducer = (maxWeight, [domain, ifProxy]) => {
|
||||
/******/
|
||||
/******/ if (!isHostInDomain(domain)) {
|
||||
const ifWild = domain.startsWith('*.');
|
||||
/******/ if (!isHostInDomain(domain, ifWild)) {
|
||||
/******/ return maxWeight;
|
||||
/******/ }
|
||||
/******/ const newWeightAbs = domain.length;
|
||||
let len = domain.length;
|
||||
if (ifWild) {
|
||||
len = len === 0 ? len : (len - 2)*2 - 1;
|
||||
} else {
|
||||
len = len*2;
|
||||
}
|
||||
/******/ const newWeightAbs = len;
|
||||
/******/ if (newWeightAbs < Math.abs(maxWeight)) {
|
||||
/******/ return maxWeight;
|
||||
/******/ }
|
||||
/******/ return newWeightAbs*(ifIncluded ? 1 : -1);
|
||||
/******/ return newWeightAbs*(ifProxy ? 1 : -1);
|
||||
/******/
|
||||
/******/ };
|
||||
/******/
|
||||
|
@ -434,7 +483,7 @@ ${ pacMods.filteredCustomsString
|
|||
/******/ /* EXCEPTIONS END */
|
||||
`;
|
||||
}
|
||||
res += `
|
||||
generatedPac += `
|
||||
/******/ const pacScriptProxies = originalFindProxyForURL(url, host)${
|
||||
/******/ pacMods.ifProxyOrDie
|
||||
? '.replace(/DIRECT/g, "")'
|
||||
|
@ -445,12 +494,12 @@ ${ pacMods.filteredCustomsString
|
|||
!pacMods.filteredCustomsString &&
|
||||
pacMods.ifUsePacScriptProxies
|
||||
) {
|
||||
return res + `
|
||||
return generatedPac + `
|
||||
/******/ return [pacScriptProxies, directIfAllowed]
|
||||
.filter((p) => p).join("; ") || "DIRECT";`;
|
||||
}
|
||||
|
||||
return res + `
|
||||
return generatedPac + `
|
||||
/******/ let pacProxyArray = pacScriptProxies.split(/(?:\\s*;\\s*)+/g).filter( (p) => p );
|
||||
/******/ const ifNoProxies = pacProxyArray${pacMods.ifProxyOrDie ? '.length === 0' : '.every( (p) => /^DIRECT$/i.test(p) )'};
|
||||
/******/ if (ifNoProxies) {
|
||||
|
@ -541,11 +590,9 @@ ${
|
|||
|
||||
).then((details) => {
|
||||
|
||||
console.log('DEEETAILS:', details); // TODO:
|
||||
if (
|
||||
details && details.levelOfControl === 'controlled_by_this_extension'
|
||||
) {
|
||||
console.log('TODODOODODODOD:', details); // TODO:
|
||||
const pac = window.utils.getProp(details, 'value.pacScript');
|
||||
if (pac && pac.data) {
|
||||
return chrome.proxy.settings.set(details, chromified(cb));
|
||||
|
@ -553,7 +600,6 @@ ${
|
|||
}
|
||||
|
||||
kitchenState(ifIncontinence, true);
|
||||
console.log('TYYYYPE ERRROR');
|
||||
cb(null, null, new TypeError(
|
||||
'Не найдено активного PAC-скрипта! Изменения будут применены при возвращении контроля настроек прокси или установке нового PAC-скрипта.'
|
||||
));
|
||||
|
@ -627,52 +673,21 @@ ${
|
|||
const originalSet = chrome.proxy.settings.set.bind( chrome.proxy.settings );
|
||||
|
||||
chrome.proxy.settings.set = function(details, cb) {
|
||||
|
||||
const pac = window.utils.getProp(details, 'value.pacScript') || {};
|
||||
const autoConfigUrl = window.utils.getProp(details, 'value.autoConfigUrl');
|
||||
const ifNothingToCook = !(pac && pac.data || autoConfigUrl);
|
||||
if (ifNothingToCook) {
|
||||
return originalSet(details, cb);
|
||||
const pac = window.utils.getProp(details, 'value.pacScript');
|
||||
if (!(pac && pac.data)) {
|
||||
return originalSet(details, window.utils.timeouted(cb));
|
||||
}
|
||||
const getPacData = (cb) =>
|
||||
pac.data ? cb(null, pac.data) : window.apis.httpLib.get(autoConfigUrl, cb);
|
||||
|
||||
getPacData((err, pacData) => {
|
||||
if (err) {
|
||||
cb(err);
|
||||
return;
|
||||
}
|
||||
const pacMods = getCurrentConfigs();
|
||||
const cookedData = pacKitchen.cook( pacData, pacMods );
|
||||
|
||||
if (window.apis.platform.ifFirefox) {
|
||||
const autoConfigUrl = URL.createObjectURL(new Blob([cookedData], {
|
||||
type: 'application/x-ns-proxy-autoconfig',
|
||||
}));
|
||||
originalSet({
|
||||
value: {
|
||||
proxyType: 'autoConfig',
|
||||
autoConfigUrl,
|
||||
},
|
||||
}, chromified(cb));
|
||||
return;
|
||||
}
|
||||
|
||||
details.value.pacScript.data = cookedData;
|
||||
originalSet({value: details.value}, (/* No args. */) => {
|
||||
const pacMods = getCurrentConfigs();
|
||||
pac.data = pacKitchen.cook( pac.data, pacMods );
|
||||
originalSet({value: details.value}, window.utils.chromified((err) => {
|
||||
|
||||
if (!err) {
|
||||
kitchenState(ifIncontinence, null);
|
||||
cb && cb();
|
||||
}
|
||||
window.utils.lastError = err;
|
||||
cb && cb();
|
||||
|
||||
});
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
pacKitchen.checkIncontinence();
|
||||
chrome.proxy.settings.onChange.addListener(
|
||||
timeouted(
|
||||
pacKitchen.checkIncontinence.bind(pacKitchen)
|
||||
)
|
||||
);
|
||||
|
||||
} // Private namespace ends.
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
const timeouted = window.utils.timeouted;
|
||||
|
||||
const clarifyThen = window.apis.errorsLib.clarifyThen;
|
||||
const clarify = window.apis.errorsLib.clarify;
|
||||
const Warning = window.apis.errorsLib.Warning;
|
||||
|
||||
const httpLib = window.apis.httpLib;
|
||||
|
@ -59,25 +60,64 @@
|
|||
|
||||
};
|
||||
|
||||
const tryPromiseSeveralTimesAsync = (createPromise, timeoutsInSec) =>
|
||||
createPromise().then(
|
||||
(res) => Promise.resolve(res),
|
||||
(err) => {
|
||||
console.log('Promise failed, are there any retries?');
|
||||
const outSec = timeoutsInSec.shift();
|
||||
if (outSec === undefined) {
|
||||
console.log('No retries left.');
|
||||
return Promise.reject(err);
|
||||
}
|
||||
console.log('Retrying in', outSec, 'sec');
|
||||
/*
|
||||
const alarmName = 'try-promise=several-times-async';
|
||||
const res = new Promise((resolve) => {
|
||||
chrome.alarms.onAlarm.addListener((alarmInfo) => {
|
||||
if (alarmInfo.name === alarmName) {
|
||||
console.log('Time to retry.');
|
||||
resolve(tryPromiseSeveralTimesAsync(createPromise, timeoutsInSec));
|
||||
}
|
||||
});
|
||||
});
|
||||
chrome.alarms.create(alarmName, { delayInMinutes: outSec/60 });
|
||||
return res;
|
||||
*/
|
||||
return new Promise((resolve) =>
|
||||
window.setTimeout(() => resolve(tryPromiseSeveralTimesAsync(createPromise, timeoutsInSec)), outSec*1000),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
const doWithoutProxyAsync = (createPromise) => new Promise((resolve, reject) => {
|
||||
console.log('Doing without proxy...');
|
||||
chrome.proxy.settings.get({}, chromified((getErr, settings) => {
|
||||
if (getErr) {
|
||||
reject(getErr);
|
||||
return;
|
||||
}
|
||||
const ifWeAreInControl = window.utils.areSettingsControlledFor(settings);
|
||||
if (!ifWeAreInControl) {
|
||||
resolve(createPromise());
|
||||
return;
|
||||
}
|
||||
delete settings.levelOfControl;
|
||||
const setProxyAsync = () => new Promise((setResolve, setReject) =>
|
||||
const setProxyAsync = () => new Promise((setResolve, setReject) => {
|
||||
|
||||
console.log('Restoring chrome proxy settings...');
|
||||
chrome.proxy.settings.set(
|
||||
settings,
|
||||
chromified((err) => err ? setReject(err) : setResolve()),
|
||||
),
|
||||
);
|
||||
);
|
||||
});
|
||||
console.log('Clearing chrome proxy settings...');
|
||||
chrome.proxy.settings.clear({}, chromified((clearErr) => {
|
||||
if (clearErr) {
|
||||
reject(clearErr);
|
||||
return;
|
||||
}
|
||||
return createPromise().then((actionResult) => setProxyAsync().then(() => resolve(actionResult)));
|
||||
createPromise().then((actionResult) => setProxyAsync().then(() => resolve(actionResult)), reject);
|
||||
}));
|
||||
}));
|
||||
});
|
||||
|
@ -86,41 +126,41 @@
|
|||
pacData = mandatory(), cb = throwIfError,
|
||||
) {
|
||||
|
||||
console.log('Clearing chrome proxy settings...');
|
||||
chrome.proxy.settings.clear({}, chromified((clearErr) => {
|
||||
const config = {
|
||||
mode: 'pac_script',
|
||||
pacScript: {
|
||||
mandatory: false,
|
||||
data: pacData,
|
||||
},
|
||||
};
|
||||
console.log('Setting chrome proxy settings...');
|
||||
chrome.proxy.settings.set( { value: config }, chromified((err) => {
|
||||
|
||||
if (clearErr) {
|
||||
return cb(clearErr);
|
||||
}
|
||||
const config = {
|
||||
mode: 'pac_script',
|
||||
pacScript: {
|
||||
mandatory: false,
|
||||
data: pacData,
|
||||
},
|
||||
};
|
||||
console.log('Setting chrome proxy settings...');
|
||||
chrome.proxy.settings.set( { value: config }, chromified((err) => {
|
||||
|
||||
if (err) {
|
||||
return cb(err);
|
||||
if (err) {
|
||||
if (err.message === 'proxy.settings requires private browsing permission.') {
|
||||
clarifyThen(
|
||||
chrome.i18n.getMessage('AllowExtensionToRunInPrivateWindows'),
|
||||
cb,
|
||||
)(err);
|
||||
return;
|
||||
}
|
||||
handlers.updateControlState( () => {
|
||||
return cb(err);
|
||||
}
|
||||
handlers.updateControlState( () => {
|
||||
|
||||
if ( !handlers.ifControlled ) {
|
||||
if ( !handlers.ifControlled ) {
|
||||
|
||||
console.warn('Failed, other extension is in control.');
|
||||
return cb(
|
||||
new Error( window.utils.messages.whichExtensionHtml() ),
|
||||
);
|
||||
console.warn('Failed, other extension is in control.');
|
||||
return cb(
|
||||
new Error( window.utils.messages.whichExtensionHtml() ),
|
||||
);
|
||||
|
||||
}
|
||||
console.log('Successfuly set PAC in proxy settings..');
|
||||
cb();
|
||||
}
|
||||
console.log('Successfuly set PAC in proxy settings.');
|
||||
cb();
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
}));
|
||||
}));
|
||||
};
|
||||
|
||||
|
@ -137,7 +177,7 @@
|
|||
};
|
||||
|
||||
const setPacScriptFromProviderAsync = function setPacScriptFromProviderAsync(
|
||||
provider, lastModifiedStr = mandatory(), cb = throwIfError,
|
||||
provider, lastModifiedStr, ifUnattended = mandatory(), cb = throwIfError,
|
||||
) {
|
||||
|
||||
const pacUrl = provider.pacUrls[0];
|
||||
|
@ -172,27 +212,34 @@
|
|||
|
||||
}
|
||||
|
||||
console.log('Clearing chrome proxy settings...');
|
||||
const pacDataPromise = doWithoutProxyAsync(
|
||||
doWithoutProxyAsync(
|
||||
// Employ all urls, the latter are fallbacks for the former.
|
||||
() =>
|
||||
provider.pacUrls.reduce(
|
||||
() => {
|
||||
const tryAllUrlsAsync = () => provider.pacUrls.reduce(
|
||||
(promise, url) => promise.catch(
|
||||
() => new Promise(
|
||||
(resolve, reject) => httpLib.get(
|
||||
url,
|
||||
(newErr, pacData) => newErr ? reject(newErr) : resolve(pacData),
|
||||
(newErr, pacData) =>
|
||||
newErr ? reject(newErr) : resolve(pacData),
|
||||
),
|
||||
),
|
||||
),
|
||||
Promise.reject(),
|
||||
),
|
||||
);
|
||||
|
||||
pacDataPromise.then(
|
||||
|
||||
);
|
||||
return (ifUnattended
|
||||
? tryPromiseSeveralTimesAsync(tryAllUrlsAsync, [20, 40, 60])
|
||||
: tryAllUrlsAsync()
|
||||
).catch(
|
||||
(err) => Promise.reject(clarify(
|
||||
err,
|
||||
chrome.i18n.getMessage('FailedToDownloadPacScriptFromAddresses') + ': [ '
|
||||
+ provider.pacUrls.join(' , ') + ' ].',
|
||||
)),
|
||||
);
|
||||
},
|
||||
).then(
|
||||
(pacData) => {
|
||||
|
||||
setPacAsync(
|
||||
pacData,
|
||||
(err, res) => cb(
|
||||
|
@ -200,15 +247,8 @@
|
|||
Object.assign(res || {}, {lastModified: lastModifiedStr}),
|
||||
),
|
||||
);
|
||||
|
||||
},
|
||||
|
||||
clarifyThen(
|
||||
chrome.i18n.getMessage('FailedToDownloadPacScriptFromAddresses') + ': [ '
|
||||
+ provider.pacUrls.join(' , ') + ' ].',
|
||||
cb,
|
||||
),
|
||||
|
||||
cb,
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -226,15 +266,20 @@
|
|||
? \`Основной PAC-скрипт от автора проекта «Антизапрет».
|
||||
Охватывет меньше сайтов.
|
||||
Блокировка определяется по доменному имени и при необходимости по IP.
|
||||
<br/> <a href="https://rebrand.ly/ac-pacs">Сравнение PAC-скриптов</a>.
|
||||
<br/> <a href="https://github.com/anticensority/runet-censorship-bypass/wiki/PAC-скрипты:-различия">Сравнение PAC-скриптов</a>.
|
||||
\`
|
||||
: \`The main PAC-script from the author of project "Antizapret"\.
|
||||
Covers fewer sites.
|
||||
Block is detected based on a domain name and, if necessary, on an IP.
|
||||
<br/> <a href="https://rebrand.ly/ac-pacs">Comparison of PAC-scripts (ru)</a>.
|
||||
<br/> <a href="https://github.com/anticensority/runet-censorship-bypass/wiki/PAC-скрипты:-различия">Comparison of PAC-scripts (ru)</a>.
|
||||
\`,
|
||||
order: 0,
|
||||
pacUrls: ['https://antizapret.prostovpn.org/proxy.pac'],
|
||||
pacUrls: [
|
||||
'https://e.cen.rodeo:8443/proxy.pac',
|
||||
'https://antizapret.prostovpn.org:8443/proxy.pac',
|
||||
'https://antizapret.prostovpn.org:18443/proxy.pac',
|
||||
'https://antizapret.prostovpn.org/proxy.pac',
|
||||
],
|
||||
},
|
||||
Антицензорити: {
|
||||
distinctKey: 'Anticensority',
|
||||
|
@ -244,13 +289,13 @@
|
|||
Охватывает больше сайтов.
|
||||
Блокировка определятся по доменному имени или IP адресу.
|
||||
Подходит для провайдеров, блокирующих все сайты на одном IP.
|
||||
<br/> <a href="https://rebrand.ly/ac-pacs">Сравнение PAC-скриптов</a>.
|
||||
<br/> <a href="https://github.com/anticensority/runet-censorship-bypass/wiki/PAC-скрипты:-различия">Сравнение PAC-скриптов</a>.
|
||||
\`
|
||||
: \`Alternative PAC-script from the author of this extension.
|
||||
Covers more sites.
|
||||
Block is detected based on a domain name and on an IP address.
|
||||
Better fits providers that block all sites on one IP.
|
||||
<br/> <a href="https://rebrand.ly/ac-pacs">Comparison of PAC-scripts (ru)</a>.
|
||||
<br/> <a href="https://github.com/anticensority/runet-censorship-bypass/wiki/PAC-скрипты:-различия">Comparison of PAC-scripts (ru)</a>.
|
||||
\`,
|
||||
order: 1,
|
||||
|
||||
|
@ -374,22 +419,23 @@
|
|||
}
|
||||
}
|
||||
|
||||
chrome.storage.local.clear(
|
||||
chrome.storage.local.remove(
|
||||
'antiCensorRu',
|
||||
() => chrome.storage.local.set(
|
||||
onlySettable,
|
||||
{ antiCensorRu: onlySettable },
|
||||
chromified(cb),
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
},
|
||||
|
||||
syncWithPacProviderAsync(
|
||||
key = this.currentPacProvierKey, cb = throwIfError) {
|
||||
|
||||
if( typeof(key) === 'function' ) {
|
||||
cb = key;
|
||||
key = this.getCurrentPacProviderKey();
|
||||
syncWithPacProviderAsync(opts = {}, cb = throwIfError) {
|
||||
const optsDefaults = Object.freeze({ key: this.getCurrentPacProviderKey(), ifUnattended: false });
|
||||
if( typeof(opts) === 'function' ) {
|
||||
cb = opts;
|
||||
opts = {};
|
||||
}
|
||||
let { key, ifUnattended } = { ...optsDefaults, ...opts };
|
||||
cb = asyncLogGroup('Syncing with PAC provider ' + key + '...', cb);
|
||||
|
||||
if (key === null) {
|
||||
|
@ -403,6 +449,7 @@
|
|||
(resolve, reject) => setPacScriptFromProviderAsync(
|
||||
pacProvider,
|
||||
this.getLastModifiedForKey(key),
|
||||
ifUnattended,
|
||||
(err, res, ...warns) => {
|
||||
|
||||
if (!err) {
|
||||
|
@ -419,22 +466,35 @@
|
|||
)
|
||||
);
|
||||
|
||||
const ipsErrorPromise = new Promise(
|
||||
const updateIpsAsync = () => new Promise(
|
||||
(resolve, reject) => updatePacProxyIps(
|
||||
resolve,
|
||||
(err, res, ...warns) => {
|
||||
if (err) {
|
||||
reject([err, ...warns]);
|
||||
return;
|
||||
}
|
||||
resolve([err, res, ...warns]);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
Promise.all([pacSetPromise, ipsErrorPromise]).then(
|
||||
([[pacErr, pacRes, ...pacWarns], ipsErr]) => {
|
||||
const ipsPromise = !ifUnattended
|
||||
? updateIpsAsync()
|
||||
: tryPromiseSeveralTimesAsync(updateIpsAsync, [20, 40, 60]);
|
||||
|
||||
if (pacErr && ipsErr) {
|
||||
Promise.all([pacSetPromise, ipsPromise]).then(
|
||||
([[pacErr, pacRes, ...pacWarns], [ipsErr, ipsRes, ...ipsWarns]]) => {
|
||||
|
||||
if (pacErr) {
|
||||
return cb(pacErr, pacRes);
|
||||
}
|
||||
const warns = pacWarns;
|
||||
if (ipsErr) {
|
||||
warns.push(ipsErr);
|
||||
}
|
||||
if (ipsWarns.length) {
|
||||
warns.push(...ipsWarns);
|
||||
}
|
||||
this.pushToStorageAsync(
|
||||
(pushErr) => cb(pacErr || pushErr, null, ...warns),
|
||||
);
|
||||
|
@ -486,7 +546,7 @@
|
|||
throw new Error('Key must be defined.');
|
||||
}
|
||||
if (this.currentProviderKey !== key) {
|
||||
return this.syncWithPacProviderAsync(key, cb);
|
||||
return this.syncWithPacProviderAsync({ key }, cb);
|
||||
}
|
||||
console.log(key + ' already installed.');
|
||||
cb();
|
||||
|
@ -518,12 +578,25 @@
|
|||
};
|
||||
|
||||
// ON EACH LAUNCH, STARTUP, RELOAD, UPDATE, ENABLE
|
||||
chrome.storage.local.get(null, chromified( async (err, oldStorage) => {
|
||||
|
||||
if (err) {
|
||||
throw err;
|
||||
(async () => {
|
||||
let ifConsentGiven = await window.utils.promisedLocalStorage.get('ifConsentGiven');
|
||||
if (!ifConsentGiven) {
|
||||
window.utils.openAndFocus('/pages/consent/index.html');
|
||||
await window.apis.consent.promise;
|
||||
ifConsentGiven = true
|
||||
await window.utils.promisedLocalStorage.set({ ifConsentGiven });
|
||||
}
|
||||
|
||||
let oldAntiCensorRu = await window.utils.promisedLocalStorage.get('antiCensorRu') || {};
|
||||
|
||||
const otherKeys = [
|
||||
'pac-kitchen-if-incontinence',
|
||||
'pac-kitchen-mods',
|
||||
'ip-to-host',
|
||||
'handlers-pac-error',
|
||||
'handlers-ext-error',
|
||||
'handlers-no-control',
|
||||
];
|
||||
/*
|
||||
Event handlers that ALWAYS work (even if installation is not done
|
||||
or failed).
|
||||
|
@ -540,7 +613,7 @@
|
|||
'Periodic PAC update triggered:',
|
||||
new Date().toLocaleString('ru-RU'),
|
||||
);
|
||||
antiCensorRu.syncWithPacProviderAsync(() => {/* swallow */});
|
||||
antiCensorRu.syncWithPacProviderAsync({ ifUnattended: true }, () => { /* Swallow. */ });
|
||||
}
|
||||
|
||||
})
|
||||
|
@ -557,24 +630,25 @@
|
|||
console.log('Keep cooked...');
|
||||
await new Promise((resolve) => window.apis.pacKitchen.keepCookedNowAsync(resolve));
|
||||
|
||||
console.log('Storage on init:', oldStorage);
|
||||
antiCensorRu.ifFirstInstall = Object.keys(oldStorage).length === 0;
|
||||
//console.log('Storage on init:', oldAntiCensorRu);
|
||||
antiCensorRu.ifFirstInstall = Object.keys(oldAntiCensorRu).length === 0;
|
||||
|
||||
if (antiCensorRu.ifFirstInstall) {
|
||||
// INSTALL
|
||||
console.log('Installing...');
|
||||
handlers.switch('on', 'ext-error');
|
||||
return chrome.runtime.openOptionsPage();
|
||||
chrome.runtime.openOptionsPage();
|
||||
return;
|
||||
}
|
||||
|
||||
// LAUNCH, RELOAD, UPDATE
|
||||
// Use old or migrate to default.
|
||||
antiCensorRu._currentPacProviderKey =
|
||||
oldStorage._currentPacProviderKey || null;
|
||||
oldAntiCensorRu._currentPacProviderKey || null;
|
||||
antiCensorRu.lastPacUpdateStamp =
|
||||
oldStorage.lastPacUpdateStamp || antiCensorRu.lastPacUpdateStamp;
|
||||
oldAntiCensorRu.lastPacUpdateStamp || antiCensorRu.lastPacUpdateStamp;
|
||||
antiCensorRu._currentPacProviderLastModified =
|
||||
oldStorage._currentPacProviderLastModified
|
||||
oldAntiCensorRu._currentPacProviderLastModified
|
||||
|| antiCensorRu._currentPacProviderLastModified;
|
||||
console.log(
|
||||
'Last PAC update was on',
|
||||
|
@ -592,11 +666,11 @@
|
|||
|
||||
await new Promise(async (resolve) => {
|
||||
|
||||
const ifUpdating = antiCensorRu.version !== oldStorage.version;
|
||||
const ifUpdating = antiCensorRu.version !== oldAntiCensorRu.version;
|
||||
if (!ifUpdating) {
|
||||
|
||||
// LAUNCH, RELOAD, ENABLE
|
||||
antiCensorRu.pacProviders = oldStorage.pacProviders;
|
||||
antiCensorRu.pacProviders = oldAntiCensorRu.pacProviders;
|
||||
console.log('Extension launched, reloaded or enabled.');
|
||||
return resolve();
|
||||
|
||||
|
@ -611,56 +685,16 @@
|
|||
|
||||
});
|
||||
|
||||
console.log('Updating from', oldStorage.version, 'to', antiCensorRu.version);
|
||||
console.log('Updating from', oldAntiCensorRu.version, 'to', antiCensorRu.version);
|
||||
try {
|
||||
if (window.apis.version.isLeq(oldStorage.version, '0.0.1.5')) {
|
||||
|
||||
// Change semicolons to semicolons followed by newlines in proxy string (raw).
|
||||
const migrateProxies = (oldStr) => oldStr.replace(/;\\r?\\n?/g, ';\\n');
|
||||
const modsMutated = window.apis.pacKitchen.getPacModsRaw();
|
||||
if (modsMutated) {
|
||||
modsMutated['customProxyStringRaw'] = migrateProxies(modsMutated['customProxyStringRaw']);
|
||||
await new Promise(
|
||||
(resolve) => window.apis.pacKitchen.keepCookedNowAsync(modsMutated, resolve),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
if (window.apis.version.isLeq(oldStorage.version, '0.0.1.25')) {
|
||||
|
||||
console.log('Switch to Antizapret automatically, only from Anitcensority without own proxies.');
|
||||
const provKey = antiCensorRu.getCurrentPacProviderKey();
|
||||
if (provKey !== 'Антицензорити' && provKey !== 'Антизапрет') {
|
||||
console.log('Current provider', provKey, '!== Anticensority or Antizapret');
|
||||
return; // Not Anticensority.
|
||||
}
|
||||
const pacMods = window.apis.pacKitchen.getPacMods();
|
||||
if (pacMods.filteredCustomsString) {
|
||||
console.log('Proxies found:', pacMods.filteredCustomsString);
|
||||
return; // Own proxies or Tor are used.
|
||||
}
|
||||
antiCensorRu.setCurrentPacProviderKey('Антизапрет');
|
||||
antiCensorRu.setLastModified(0);
|
||||
await new Promise((resolveSwitch) =>
|
||||
|
||||
antiCensorRu.syncWithPacProviderAsync((err, res, warns) => {
|
||||
|
||||
if (warns) {
|
||||
console.log(warns);
|
||||
}
|
||||
if (err) {
|
||||
console.log(
|
||||
'Ungraceful update from 1.25: couldn\\'t fetch Antizapret:',
|
||||
);
|
||||
console.error(err);
|
||||
} else {
|
||||
console.log('Update from 1.25 applied successfully.');
|
||||
}
|
||||
resolveSwitch();
|
||||
|
||||
}),
|
||||
);
|
||||
|
||||
if (window.apis.version.isLeq(oldAntiCensorRu.version, '0.0.1.62')) {
|
||||
window.apis.antiCensorRu.pacProviders['Антизапрет'].pacUrls = [
|
||||
'https://e.cen.rodeo:8443/proxy.pac',
|
||||
'https://antizapret.prostovpn.org:8443/proxy.pac',
|
||||
'https://antizapret.prostovpn.org:18443/proxy.pac',
|
||||
'https://antizapret.prostovpn.org/proxy.pac',
|
||||
];
|
||||
console.log('Successfully updated to 0.0.1.63.');
|
||||
}
|
||||
} catch (e) {
|
||||
// Log update error.
|
||||
|
@ -691,6 +725,6 @@
|
|||
* Add storage.lastPacUpdateStamp.
|
||||
**/
|
||||
|
||||
}));
|
||||
})();
|
||||
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
order: 0,
|
||||
},
|
||||
|
||||
hostTracker: {
|
||||
googleCache: {
|
||||
title: 'Из кэша Google',
|
||||
getUrl: (blockedUrl) => 'http://webcache.googleusercontent.com/search?q=cache:' + blockedUrl,
|
||||
order: 1,
|
||||
|
@ -27,19 +27,19 @@
|
|||
|
||||
otherUnblock: {
|
||||
title: 'Разблокировать по-другому',
|
||||
getUrl: (blockedUrl) => ('https://rebrand.ly/ac-unblock#' + blockedUrl),
|
||||
getUrl: (blockedUrl) => ('https://anticensority.github.io/unblock#' + blockedUrl),
|
||||
order: 3,
|
||||
},
|
||||
|
||||
antizapretInfo: {
|
||||
title: 'Сайт в реестре блокировок?',
|
||||
getUrl: (blockedUrl) => 'https://antizapret.info/index.php?search=' + new URL(blockedUrl).hostname,
|
||||
getUrl: (blockedUrl) => 'https://reestr.rublacklist.net/?q=' + new URL(blockedUrl).hostname,
|
||||
order: 4,
|
||||
},
|
||||
|
||||
support: {
|
||||
title: 'Документация / Помощь / Поддержка',
|
||||
getUrl: (blockedUrl) => 'https://git.io/ac-wiki',
|
||||
getUrl: (blockedUrl) => 'https://github.com/anticensority/runet-censorship-bypass/wiki',
|
||||
order: 99,
|
||||
},
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
# For Reviewers
|
||||
|
||||
## Prerequirements
|
||||
|
||||
* You need a globally installed `gulp-cli@3.0.0`.
|
||||
See https://gulpjs.com/docs/en/getting-started/quick-start#install-the-gulp-command-line-utility.
|
||||
* Node v21.7.3
|
||||
* NPM 10.5.0
|
||||
|
||||
## Steps
|
||||
|
||||
Steps to reproduce the same zip:
|
||||
```
|
||||
npm ci
|
||||
cd src/extension-common/pages/options/
|
||||
npm ci
|
||||
cd -
|
||||
npm start
|
||||
# See ./build/extension-full
|
||||
cd ./build/extension-full
|
||||
zip -r runet-censorship-bypass-full.zip ./*
|
||||
```
|
||||
|
||||
## Minified Files
|
||||
|
||||
### Ace Editor
|
||||
|
||||
https://ace.c9.io -> https://github.com/ajaxorg/ace -> Building Ace -> "The ace-builds repository endeavours to maintain the latest build" -> https://github.com/ajaxorg/ace-builds/ -> Select tag of 1.2.5, open https://github.com/ajaxorg/ace-builds/tree/v1.2.5/src-min and download the files you want to check.
|
||||
|
||||
|
||||
```
|
||||
mkdir downloaded
|
||||
cd downloaded
|
||||
wget https://raw.githubusercontent.com/ajaxorg/ace-builds/v1.2.5/src-min/ace.js
|
||||
wget https://raw.githubusercontent.com/ajaxorg/ace-builds/v1.2.5/src-min/ext-searchbox.js
|
||||
wget https://raw.githubusercontent.com/ajaxorg/ace-builds/v1.2.5/src-min/mode-javascript.js
|
||||
wget https://raw.githubusercontent.com/ajaxorg/ace-builds/v1.2.5/src-min/worker-javascript.js
|
||||
|
||||
downloaded$ for i in ./*; do md5sum "$i"; done
|
||||
2b9a1157bb3ba711a0402b6751d9ac71 ./ace.js
|
||||
1f73efaff2853571af0e701c5e9a15ee ./ext-searchbox.js
|
||||
e5eebd85c4e66667c28f124e6a07e3ed ./mode-javascript.js
|
||||
f0d1342102d16ab7abe319b2683d10ea ./worker-javascript.js
|
||||
```
|
||||
|
||||
## PAC-Script AntiZapret
|
||||
|
||||
https://antizapret.prostovpn.org/proxy.pac (old) and https://e.cen.rodeo:8443/proxy.pac (new) are generated by https://bitbucket.org/anticensority/antizapret-pac-generator-light/, reviewers may find justifications related to this PAC-script in that repo.
|
|
@ -1 +0,0 @@
|
|||
Files of this directory must be copied into final build without modifications.
|
|
@ -87,7 +87,7 @@
|
|||
"message": "Error"
|
||||
},
|
||||
"Non_critical_error": {
|
||||
"message": "Non-critical error"
|
||||
"message": "Non-critical error. Don't worry: it works"
|
||||
},
|
||||
"Donate": {
|
||||
"message": "Donate"
|
||||
|
@ -136,5 +136,8 @@
|
|||
},
|
||||
"noOwnProxiesError": {
|
||||
"message": "Proxying of OWN sites is possible only via OWN proxies. No own proxies found that satisfy your requirements."
|
||||
},
|
||||
"AllowExtensionToRunInPrivateWindows": {
|
||||
"message": "For the extension to work it is required to allow it to run in private windows, see <a href='https://github.com/anticensority/runet-censorship-bypass/wiki/Как-разрешить-запуск-расширения-в-приватных-окнах-|-How-to-allow-extension-to-run-in-private-windows'>a HOWTO</a>."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
"message": "Ошибка"
|
||||
},
|
||||
"Non_critical_error": {
|
||||
"message": "Некритичная ошибка"
|
||||
"message": "Некритичная ошибка. Всё хорошо, продолжаем работу"
|
||||
},
|
||||
"Donate": {
|
||||
"message": "Поддержать"
|
||||
|
@ -136,5 +136,8 @@
|
|||
},
|
||||
"noOwnProxiesError": {
|
||||
"message": "Проксировать СВОИ сайты можно только при наличии СВОИХ прокси. Нет своих прокси, удовлетворяющих вашим требованиям."
|
||||
},
|
||||
"AllowExtensionToRunInPrivateWindows": {
|
||||
"message": "Для работы расширения необходимо разрешить запуск в приватных окнах, см. <a href='https://github.com/anticensority/runet-censorship-bypass/wiki/Как-разрешить-запуск-расширения-в-приватных-окнах-|-How-to-allow-extension-to-run-in-private-windows'>инструкции</a>."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
"proxy"
|
||||
, "alarms"
|
||||
, "storage"
|
||||
, "unlimitedStorage"
|
||||
, "<all_urls>"
|
||||
, "tabs"
|
||||
, "contextMenus"
|
||||
|
@ -21,6 +22,11 @@
|
|||
${extra_permissions}
|
||||
],
|
||||
"minimum_chrome_version": "55.0.0.0",
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"strict_min_version": "91.1.0"
|
||||
}
|
||||
},
|
||||
|
||||
"background": {
|
||||
${persistent}
|
||||
|
@ -30,6 +36,7 @@
|
|||
, "11-error-handlers-api.js"
|
||||
, "12-errors-lib.js"
|
||||
, "13-http-lib.js"
|
||||
, "15-firefox-proxy-settings.js"
|
||||
${scripts_2x}
|
||||
, "35-pac-kitchen-api.js"
|
||||
, "37-sync-pac-script-with-pac-provider-api.js"
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="icon" type="image/x-icon" href="./ribbon-128.ico">
|
||||
<meta charset="utf-8">
|
||||
<title>Согласие на сбор данных / Data Collection Consent</title>
|
||||
<style>
|
||||
p, ol { font-size: 16px }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="margin: 0 auto; max-width: 35rem; text-align: justify; font-family: sans-serif">
|
||||
<img src="./ribbon-128.png">
|
||||
<h1>Согласие на сбор данных / Data Collection Consent</h1>
|
||||
<p>
|
||||
Этот документ написан на двух языках. Английский предпочтительней.
|
||||
</p>
|
||||
<p>
|
||||
This document is written in two languages. English is preferable.
|
||||
</p>
|
||||
<p>
|
||||
Привет! На связи команда разработчиков браузерного расширения «Обход блокировок Рунета».
|
||||
Вы либо только что установили расширение, либо только что обновились до новой версии.
|
||||
По новым правилам мы <a href="https://github.com/anticensority/runet-censorship-bypass/wiki/Зачем-нам-согласие-со-сбором-данных%3F">должны</a>
|
||||
получить от вас согласие на сбор ваших данных и передачу их
|
||||
третьим лицам.
|
||||
</p>
|
||||
<p>
|
||||
Hi! It's "Runet Censorship Bypass" browser extension developers team.
|
||||
You have just installed the extension or just updated to a new version.
|
||||
According to the new requirements we <a href="https://github.com/anticensority/runet-censorship-bypass/wiki/Зачем-нам-согласие-со-сбором-данных%3F">have to</a> get your consent before collecting your data and
|
||||
sharing it with 3rd parties.
|
||||
</p>
|
||||
<p>
|
||||
Сообщаем вам, что после первого запуска расширения и при дальнейшем его использовании
|
||||
настроенные в нём PAC-скрипты и прокси-сервера могут собирать или уже* собирают
|
||||
некоторые ваши данные. Какие именно, зависит от выбранного вами поставщика этих ресурсов,
|
||||
так что рекомендуем ознакомиться с их соответствующей политикой конфиденциальности (Privacy
|
||||
Policy).
|
||||
<br>
|
||||
* Если вы установили и пользовалсись расширением уже некоторое время. Этого экрана согласия не
|
||||
было в старых версиях.
|
||||
</p>
|
||||
<p>
|
||||
We inform you that starting from the first launch of the extension and on further usage chosen
|
||||
PAC-scripts and proxy-servers may collect or are already* collecting some of your data. Which
|
||||
exactly depends on the chosen provider of these resources so we recommend you to get
|
||||
acquainted with their corresponding Privacy Policy.
|
||||
<br>
|
||||
* If you have installed and have been using the extension for some time already. This consent
|
||||
screen wasn't shown in the old versions.
|
||||
</p>
|
||||
<p>
|
||||
При первом запуске и по умолчанию будут использоваться PAC-скрипт и встроенные в него
|
||||
прокси-сервера, предоставляемые <a href="https://antizapret.prostovpn.org:8443">проектом
|
||||
"АнтиЗапрет"</a>, — политику конфиденциальности этого решения см. в
|
||||
<a href="https://antizapret.prostovpn.org:8443/faq.html">FAQ</a> под заголовком "Какие данные
|
||||
собирает сервис и каким образом они используются?".
|
||||
</p>
|
||||
<p>
|
||||
On the first launch and by default the PAC-script and its built-in proxy-servers provided by
|
||||
<a href="https://antizapret.prostovpn.org:8443">project "AntiZapret" (RU)</a> will be used, —
|
||||
see its Privacy Policy in
|
||||
<a href="https://antizapret.prostovpn.org:8443/faq.html">the FAQ (RU)</a> under the title
|
||||
"Какие данные собирает сервис и каким образом они используются?". Its translation to EN is
|
||||
present in the Privacy Policy of the extension.
|
||||
</p>
|
||||
<p>
|
||||
Политику конфиденциальности самого расширения см.
|
||||
<a
|
||||
href="https://github.com/anticensority/runet-censorship-bypass/wiki/Privacy-Policy-|-Политика-конфиденциальности"
|
||||
>здесь (EN)</a>.
|
||||
</p>
|
||||
<p>
|
||||
See the Privacy Policy of this extension
|
||||
<a
|
||||
href="https://github.com/anticensority/runet-censorship-bypass/wiki/Privacy-Policy-|-Политика-конфиденциальности"
|
||||
>here</a>.
|
||||
</p>
|
||||
<p>
|
||||
В расширении представлены кнопки / There are these buttons in the extension:
|
||||
</p>
|
||||
<ol>
|
||||
<li>
|
||||
"Через Google Translate" / "Via Google Translate"
|
||||
</li><li>
|
||||
"Из кэша Google" / "From Google Cache"
|
||||
</li><li>
|
||||
"Из архива archive.org" / "From archive.org archive"
|
||||
</li><li>
|
||||
"Разблокировать по-другому" / "Unblock another way"
|
||||
</li><li>
|
||||
"Сайт в реестре блокировок?" / "Is site in the registry of blockings?"
|
||||
</li>
|
||||
</ol>
|
||||
<p>
|
||||
Все эти кнопки передают URL-адрес текущей вкладки в соответствующие службы. /
|
||||
All these buttons share URL-address of the current tab with corresponding services.
|
||||
</p>
|
||||
<button id="agreeBtn">Разрешаю собирать заявленные данные / Allow claimed data collection
|
||||
</button>
|
||||
<button id="rejectBtn">Нет, удалите расширение / No, delete this extension
|
||||
</button>
|
||||
</div>
|
||||
<script src="./index.js"></script>
|
||||
<script src="../lib/keep-links-clickable.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
chrome.runtime.getBackgroundPage( (backgroundPage) =>
|
||||
backgroundPage.apis.errorHandlers.installListenersOn(
|
||||
window, 'CONSENT', () => {
|
||||
agreeBtn.onclick = () => {
|
||||
backgroundPage.apis.consent.give();
|
||||
window.close();
|
||||
}
|
||||
rejectBtn.onclick = () =>
|
||||
chrome.management.uninstallSelf();
|
||||
},
|
||||
),
|
||||
);
|
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
|
@ -17,7 +17,9 @@ chrome.runtime.getBackgroundPage( (backgroundPage) =>
|
|||
# Сначала идёт список проксируемых сайтов,
|
||||
# затем ==== на отдельной строке,
|
||||
# затем исключённые сайты.
|
||||
# После ещё одной строки с ==== идёт белый список.
|
||||
# Сортировка — с конца строки.
|
||||
# Адреса со звёздочками поддерживаются: *.kasparov.ru, например.
|
||||
|
||||
# ПРОКСИРОВАТЬ:
|
||||
|
||||
|
@ -26,7 +28,16 @@ ${(mods.included || []).join('\n')}
|
|||
===============================
|
||||
# НЕ ПРОКСИРОВАТЬ:
|
||||
|
||||
${(mods.excluded || []).join('\n')}`;
|
||||
${(mods.excluded || []).join('\n')}
|
||||
|
||||
|
||||
===============================
|
||||
# БЕЛЫЙ СПИСОК
|
||||
# Разрешить расширению работать только с этими адресами:
|
||||
|
||||
${(mods.whitelist || []).join('\n')}
|
||||
|
||||
`.trim();
|
||||
|
||||
status.innerText = 'Успешно загружено!';
|
||||
|
||||
|
@ -35,7 +46,7 @@ ${(mods.excluded || []).join('\n')}`;
|
|||
|
||||
saveBtn.onclick = function() {
|
||||
|
||||
let [proxyList, dontProxyList] = editor.value
|
||||
let [proxyList, dontProxyList, whitelist] = editor.value
|
||||
.trim()
|
||||
.replace(/#.*/g, '')
|
||||
.split(/=+/g)
|
||||
|
@ -45,12 +56,14 @@ ${(mods.excluded || []).join('\n')}`;
|
|||
.filter((host) => host)
|
||||
)
|
||||
dontProxyList = dontProxyList || [];
|
||||
whitelist = whitelist || [];
|
||||
|
||||
const exceptions = {};
|
||||
proxyList.forEach((host) => (exceptions[host] = true));
|
||||
dontProxyList.forEach((host) => (exceptions[host] = false));
|
||||
const mods = backgroundPage.apis.pacKitchen.getPacMods();
|
||||
mods.exceptions = exceptions;
|
||||
mods.whitelist = whitelist;
|
||||
backgroundPage.apis.pacKitchen.keepCookedNowAsync(mods, (err) => {
|
||||
if (!err) {
|
||||
status.innerText = 'Успешно сохранено!';
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -12,14 +12,16 @@
|
|||
"concat-stream": "^1.6.2",
|
||||
"csjs-inject": "^1.0.1",
|
||||
"flow-bin": "^0.45.0",
|
||||
"gulp": "^4.0.2",
|
||||
"inferno": "~3.2.0",
|
||||
"inferno-component": "^3.10.1",
|
||||
"inferno-create-element": "^3.10.1",
|
||||
"webpack": "^2.5.1"
|
||||
"webpack": "^5.82.0",
|
||||
"webpack-cli": "^5.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
"check": "flow status",
|
||||
"build:prod": "webpack --define process.env.NODE_ENV=\"'production'\" --env=prod",
|
||||
"build:prod": "webpack --node-env=\"'production'\" --env=prod",
|
||||
"build:dev:nocomp": "NODE_ENV=development webpack --define process.env.NODE_ENV=\"'development'\" --env=dev",
|
||||
"build:dev": "NODE_ENV=development webpack --debug --define process.env.NODE_ENV=\"'development'\" --output-pathinfo --env=dev",
|
||||
"gulp": "cd .. && npm run gulp",
|
||||
|
|
|
@ -266,7 +266,6 @@ export default function getApp(theState) {
|
|||
this.setStatusTo(beforeStatus);
|
||||
this.switchInputs('off');
|
||||
operation((err, res, ...warns) => {
|
||||
|
||||
warns = warns.filter( (w) => w );
|
||||
if (err || warns.length) {
|
||||
this.showErrors(err, ...warns);
|
||||
|
|
|
@ -79,14 +79,14 @@ export default function getExcEditor(theState) {
|
|||
props.currentTab &&
|
||||
props.currentTab.url &&
|
||||
!props.currentTab.url.startsWith('chrome')
|
||||
? new URL(props.currentTab.url).hostname.replace(/^www\./g, '')
|
||||
? '*.' + (new URL(props.currentTab.url).hostname.replace(/^www\./g, ''))
|
||||
: '';
|
||||
|
||||
const pacMods = props.apis.pacKitchen.getPacMods();
|
||||
this.state = {
|
||||
trimmedInputValueOrSpace,
|
||||
sortedListOfOptions: this.modsToOpts(pacMods),
|
||||
isHostHidden: {}
|
||||
hostToIfHidden: {},
|
||||
};
|
||||
this.handleRadioClick = this.handleRadioClick.bind(this);
|
||||
this.handleInputOrClick = this.handleInputOrClick.bind(this);
|
||||
|
@ -96,11 +96,11 @@ export default function getExcEditor(theState) {
|
|||
hideAllOptions() {
|
||||
|
||||
this.setState({
|
||||
isHostHidden: this.state.sortedListOfOptions.reduce(
|
||||
(isHostHidden, [excHost]) => {
|
||||
hostToIfHidden: this.state.sortedListOfOptions.reduce(
|
||||
(hostToIfHidden, [excHost]) => {
|
||||
|
||||
isHostHidden[excHost] = true;
|
||||
return isHostHidden;
|
||||
hostToIfHidden[excHost] = true;
|
||||
return hostToIfHidden;
|
||||
|
||||
},
|
||||
{}),
|
||||
|
@ -110,7 +110,7 @@ export default function getExcEditor(theState) {
|
|||
|
||||
isHostValid(host) {
|
||||
|
||||
const ValidHostnameRegex = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/;
|
||||
const ValidHostnameRegex = /^(?:\*\.)?(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/;
|
||||
if(!ValidHostnameRegex.test(host)) {
|
||||
this.props.funs.showErrors(new TypeError('Должно быть только доменное имя, без протокола, порта и пути. Попробуйте ещё раз.'));
|
||||
return false;
|
||||
|
@ -210,7 +210,9 @@ export default function getExcEditor(theState) {
|
|||
const ifInit = !event;
|
||||
const currentHost = ifTriangleClicked ? '' : (trimmedInput || (ifInit ? '' : ' '));
|
||||
setInputValue(currentHost);
|
||||
this.setState({trimmedInputValueOrSpace: currentHost});
|
||||
this.setState({
|
||||
trimmedInputValueOrSpace: currentHost,
|
||||
});
|
||||
|
||||
// Episode 2.
|
||||
|
||||
|
@ -279,7 +281,7 @@ export default function getExcEditor(theState) {
|
|||
})();
|
||||
|
||||
this.setState({
|
||||
isHostHidden: hidden,
|
||||
hostToIfHidden: hidden,
|
||||
sortedListOfOptions: options,
|
||||
});
|
||||
|
||||
|
@ -301,7 +303,7 @@ export default function getExcEditor(theState) {
|
|||
<div>{chrome.i18n.getMessage('ProxyTheDomainNameBelowQ')}</div>
|
||||
<div id="exc-address-container">
|
||||
<div id="exc-address" class={inputProxyingState !== undefined ? ( inputProxyingState === true ? scopedCss.ifYes : scopedCss.ifNo ) : ''}>
|
||||
<span>*.</span><input placeholder="navalny.com" list="exc-list" id="exc-editor"
|
||||
<input placeholder="*.navalny.com" list="exc-list" id="exc-editor"
|
||||
value={this.state.trimmedInputValueOrSpace}
|
||||
ref={(inputNode) => { this.rawInput = inputNode; }}
|
||||
onKeyDown={this.handleKeyDown.bind(this)}
|
||||
|
@ -321,9 +323,10 @@ export default function getExcEditor(theState) {
|
|||
|
||||
// 1. Option's value may be changed to hide it from the tooltip.
|
||||
// 2. Space is used in matching so even an empty input (replaced with space) has tooltip with prompts.
|
||||
const ifProxy = excState;
|
||||
return <option
|
||||
value={ this.state.isHostHidden[excHost] ? '\n' : excHost + ' ' }
|
||||
label={ excState === true ? labelIfProxied : (excState === false ? labelIfNotProxied : labelIfAuto) }/>
|
||||
value={ this.state.hostToIfHidden[excHost] ? '\n' : excHost + ' ' }
|
||||
label={ ifProxy === true ? labelIfProxied : (ifProxy === false ? labelIfNotProxied : labelIfAuto) }/>
|
||||
|
||||
})
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ export default function getFooter(theState) {
|
|||
|
||||
<footer class={scopedCss.controlRow + ' horFlex nowrap'}>
|
||||
<input type="button" value={chrome.i18n.getMessage('Finish')} disabled={props.ifInputsDisabled} style={{ display: theState.flags.ifInsideEdgeOptionsPage ? 'none' : 'initial' }} onClick={() => window.close()} />
|
||||
<a href="https://rebrand.ly/ac-donate">{chrome.i18n.getMessage('Donate')}</a>
|
||||
<a href="https://github.com/anticensority/runet-censorship-bypass/wiki/Поддержать">{chrome.i18n.getMessage('Donate')}</a>
|
||||
<a data-in-bg="false" href="../troubleshoot/index.html">
|
||||
{chrome.i18n.getMessage('ProblemsQ')}
|
||||
</a>
|
||||
|
|
|
@ -7,8 +7,10 @@ export default function getLastUpdateDate(theState) {
|
|||
|
||||
componentWillMount() {
|
||||
|
||||
this.onStorageChangedHandler = (changes) =>
|
||||
changes.lastPacUpdateStamp.newValue && this.forceUpdate();
|
||||
this.onStorageChangedHandler = (changes) => {
|
||||
const ac = changes.antiCensorRu;
|
||||
return ac && ac.newValue && ac.newValue.lastPacUpdateStamp && this.forceUpdate();
|
||||
};
|
||||
|
||||
chrome.storage.onChanged.addListener( this.onStorageChangedHandler );
|
||||
|
||||
|
|
|
@ -145,9 +145,9 @@ export default function getPacChooser(theState) {
|
|||
<div class={scopedCss.fullLineHeight}>
|
||||
{
|
||||
props.flags.ifMini
|
||||
? (<a class={scopedCss.otherVersion + ' emoji'} href="https://rebrand.ly/ac-versions"
|
||||
? (<a class={scopedCss.otherVersion + ' emoji'} href="https://github.com/anticensority/runet-censorship-bypass/wiki/Различные-версии-расширения"
|
||||
title={chrome.i18n.getMessage("FullVersion")}>🏋</a>)
|
||||
: (<a class={scopedCss.otherVersion + ' emoji'} href="https://rebrand.ly/ac-versions"
|
||||
: (<a class={scopedCss.otherVersion + ' emoji'} href="https://github.com/anticensority/runet-censorship-bypass/wiki/Различные-версии-расширения"
|
||||
title={chrome.i18n.getMessage("VersionForSlowMachines")}>🐌</a>)
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -363,7 +363,7 @@ export default function getProxyEditor(theState) {
|
|||
}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="https://rebrand.ly/ac-protected-proxy">Запароленные прокси?</a>
|
||||
<a href="https://github.com/anticensority/runet-censorship-bypass/wiki/Прокси-и-пароль">Запароленные прокси?</a>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ export default function append(document, { flags }) {
|
|||
document.querySelector('style').innerHTML = `
|
||||
/* GLOBAL VARIABLES */
|
||||
|
||||
:root {
|
||||
body {
|
||||
--ribbon-color: #4169e1;
|
||||
--blue-bg: dodgerblue;
|
||||
--default-grey: #bfbfbf;
|
||||
|
@ -12,18 +12,13 @@ export default function append(document, { flags }) {
|
|||
--cr-icon-selected: #d7d7d7;
|
||||
--cr-popup-border: #bababa;
|
||||
--cr-grey-panel: #f2f2f2;
|
||||
${ flags.ifInsideOptionsPage
|
||||
// Without this prop on the next line
|
||||
// options page width may be jerking
|
||||
// in size when scrolling is showed.
|
||||
? 'width: 20em'
|
||||
: 'max-width: 25em;' }
|
||||
}
|
||||
|
||||
/* BASE ELEMENTS */
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
max-width: 25em;
|
||||
}
|
||||
a, a:visited {
|
||||
color: var(--ribbon-color);
|
||||
|
|
|
@ -42,8 +42,8 @@ chrome.runtime.getBackgroundPage( (bgWindow) =>
|
|||
);
|
||||
// winChrome.runtime.sendMessage({ currentTab, eventName: 'POPUP_OPENED' });
|
||||
|
||||
theState.flags.ifInsideOptionsPage = !currentTab || /.*:\/\/extensions\/\?options=/g.test(currentTab.url) || currentTab.url.startsWith('about:addons');
|
||||
theState.flags.ifInsideEdgeOptionsPage = theState.flags.ifInsideOptionsPage && currentTab.url.startsWith('edge://');
|
||||
theState.flags.ifInsideOptionsPage = !(currentTab && currentTab.url) || /.*:\/\/extensions\/\?options=/g.test(currentTab.url) || currentTab.url.startsWith('about:addons');
|
||||
theState.flags.ifInsideEdgeOptionsPage = theState.flags.ifInsideOptionsPage && currentTab && currentTab.url && currentTab.url.startsWith('edge://');
|
||||
|
||||
theState.currentTab = currentTab;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,12 +10,12 @@
|
|||
<ol>
|
||||
<li><a data-in-bg="false" href class="view-errors">Детали последних ошибок</a></li>
|
||||
<li><a data-in-bg="false" href class="reset-settings">Сбросить настройки</a></li>
|
||||
<li><a data-in-bg="false" href="https://rebrand.ly/ac-support" target="_blank">Файл самопомощи</a></li>
|
||||
<li><a data-in-bg="false" href="https://rebrand.ly/ac-contact">Напишите нам!</a></li>
|
||||
<li><a data-in-bg="false" href="https://github.com/anticensority/runet-censorship-bypass/wiki/Если-расширение-не-работает" target="_blank">Файл самопомощи</a></li>
|
||||
<li><a data-in-bg="false" href="https://groups.google.com/g/anticensority">Напишите нам!</a></li>
|
||||
</ol>
|
||||
<h2>Для продвинутых</h2>
|
||||
<ol>
|
||||
<li><a data-in-bg="false" href="https://rebrand.ly/ac-logs">Как прочитать логи?</a></li>
|
||||
<li><a data-in-bg="false" href="https://github.com/anticensority/runet-censorship-bypass/wiki/Как-прочитать-логи%3F-%28для-продвинутых%29">Как прочитать логи?</a></li>
|
||||
<li><a data-in-bg="false" href="../debug/index.html">Отладка PAC-скрипта</a></li>
|
||||
</ol>
|
||||
<hr/>
|
||||
|
@ -23,12 +23,12 @@
|
|||
<ol>
|
||||
<li><a data-in-bg="false" href class="view-errors">Details of last errors</a></li>
|
||||
<li><a data-in-bg="false" href class="reset-settings">Reset settings</a></li>
|
||||
<li><a data-in-bg="false" href="https://rebrand.ly/ac-support" target="_blank">Troubleshoot guide (ru)</a></li>
|
||||
<li><a data-in-bg="false" href="https://rebrand.ly/ac-contact">Write to us!</a></li>
|
||||
<li><a data-in-bg="false" href="https://github.com/anticensority/runet-censorship-bypass/wiki/Если-расширение-не-работает" target="_blank">Troubleshoot guide (ru)</a></li>
|
||||
<li><a data-in-bg="false" href="https://groups.google.com/g/anticensority">Write to us!</a></li>
|
||||
</ol>
|
||||
<h2>Advanced</h2>
|
||||
<ol>
|
||||
<li><a data-in-bg="false" href="https://rebrand.ly/ac-logs">How to read logs?</a></li>
|
||||
<li><a data-in-bg="false" href="https://github.com/anticensority/runet-censorship-bypass/wiki/Как-прочитать-логи%3F-%28для-продвинутых%29">How to read logs?</a></li>
|
||||
<li><a data-in-bg="false" href="../debug/index.html">PAC-script debugging</a></li>
|
||||
</ol>
|
||||
<script src="./index.js"></script>
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
{
|
||||
|
||||
if (!chrome.proxy.settings) {
|
||||
|
||||
const ffxStore = window.utils.createStorage('firefox-only');
|
||||
|
||||
|
||||
chrome.proxy.settings = {
|
||||
get: (_, cb) => {
|
||||
|
||||
let currentSettings = ffxStore('proxySettings') || {};
|
||||
currentSettings.levelOfControl = 'controlled_by_this_extension'; // May be lie, but this field is required.
|
||||
cb && cb(currentSettings);
|
||||
|
||||
},
|
||||
onChange: {
|
||||
addListener: () => {},
|
||||
},
|
||||
set: (details, cb) => {
|
||||
|
||||
browser.proxy.unregister();
|
||||
browser.proxy.register('./default.pac.js');
|
||||
|
||||
|
||||
// browser.proxy.onProxyError.addListener((...err) => { console.log('ERROR IN PAC:', ...err) });
|
||||
|
||||
browser.runtime.sendMessage(details, {toProxyScript: true});
|
||||
ffxStore('proxySettings', details);
|
||||
cb && cb();
|
||||
|
||||
},
|
||||
};
|
||||
const proxySettings = ffxStore('proxySettings');
|
||||
if (proxySettings) {
|
||||
chrome.proxy.settings.set(proxySettings);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
var coolFind = () => {};
|
||||
this.FindProxyForURL = function (...args) {
|
||||
return coolFind(...args);
|
||||
};
|
||||
|
||||
const dnsResolve = this.dnsResolve || (() => null); // Welcome to hell! Someone forgot dns.
|
||||
|
||||
browser.runtime.onMessage.addListener((details) => {
|
||||
const pacData =
|
||||
details && details.value && details.value.pacScript && details.value.pacScript.data;
|
||||
if (!pacData) {
|
||||
throw new Error('Never install empty PAC scripts!');
|
||||
}
|
||||
coolFind = (function() { eval(pacData); return FindProxyForURL; })();
|
||||
|
||||
});
|
||||
|
|
@ -69,21 +69,24 @@
|
|||
|
||||
const reinit = function reinit() {
|
||||
|
||||
/* Don't use directly, please.
|
||||
Encoded to counter abuse.
|
||||
*/
|
||||
privates._strToHostObj = [
|
||||
/* Please, don't use proxies directly (without PAC-script). */
|
||||
'n.thenewone.lol',
|
||||
's.thenewone.lol',
|
||||
// antizapret.prostovpn.org:
|
||||
'\x70\x72\x6f\x78\x79\x2e\x61\x6e\x74\x69\x7a\x61\x70\x72\x65\x74\x2e\x70\x72\x6f\x73\x74\x6f\x76\x70\x6e\x2e\x6f\x72\x67', // Antizapret old.
|
||||
'\x63\x63\x61\x68\x69\x68\x61\x2e\x61\x6e\x74\x69\x7a\x61\x70\x72\x65\x74\x2e\x70\x72\x6f\x73\x74\x6f\x76\x70\x6e\x2e\x6f\x72\x67', // Antizapret for ranges.
|
||||
'\x70\x72\x6f\x78\x79\x2d\x73\x73\x6c\x2e\x61\x6e\x74\x69\x7a\x61\x70\x72\x65\x74\x2e\x70\x72\x6f\x73\x74\x6f\x76\x70\x6e\x2e\x6f\x72\x67', // Antizapret SSL.
|
||||
'\x70\x72\x6f\x78\x79\x2d\x6e\x6f\x73\x73\x6c\x2e\x61\x6e\x74\x69\x7a\x61\x70\x72\x65\x74\x2e\x70\x72\x6f\x73\x74\x6f\x76\x70\x6e\x2e\x6f\x72\x67', // Antizapret w/o SSL.
|
||||
'proxy.antizapret.prostovpn.org',
|
||||
'proxy-ssl.antizapret.prostovpn.org',
|
||||
'proxy-nossl.antizapret.prostovpn.org',
|
||||
'proxy-fbtw-ssl.antizapret.prostovpn.org',
|
||||
].reduce((acc, hostname) => Object.assign(acc, { [hostname]: { host: hostname }}), {
|
||||
// Defaults:
|
||||
localhost: { host: 'localhost' },
|
||||
});
|
||||
|
||||
privates._ipToHostObj = {};
|
||||
privates._ipToHostObj = {
|
||||
'127.0.0.1': { host: 'localhost' },
|
||||
'0.0.0.0': { host: 'localhost' },
|
||||
};
|
||||
|
||||
// Persisted.
|
||||
const ipToHost = _state(ip2host);
|
||||
|
@ -109,7 +112,7 @@
|
|||
const getIpsFor = function getIpsFor(host, cb = mandatory()) {
|
||||
|
||||
if (host.trim() === 'localhost') {
|
||||
return cb(null, ['127.0.0.1', '::1']);
|
||||
return cb(null, ['127.0.0.1', '0.0.0.0', '::1']);
|
||||
}
|
||||
const types = [1, 28];
|
||||
const promises = types.map(
|
||||
|
@ -231,12 +234,11 @@
|
|||
getIpsFor(hostStr, (err, ips, ...warns) => {
|
||||
|
||||
console.log('Got IPs + err?:', ips, err);
|
||||
if (!err) {
|
||||
resolveIps(ips);
|
||||
} else {
|
||||
if (err) {
|
||||
reject([err, null, ...warns]);
|
||||
return;
|
||||
}
|
||||
|
||||
resolveIps(ips);
|
||||
});
|
||||
|
||||
}).then(
|
||||
|
@ -258,7 +260,9 @@
|
|||
|
||||
_updateAllAsync(cb = mandatory()) {
|
||||
|
||||
const hostArr = Object.keys(privates._strToHostObj);
|
||||
const hostArr = Object.keys(privates._strToHostObj)
|
||||
.filter((hostStr) => hostStr !== 'localhost');
|
||||
|
||||
console.log('Update all:', hostArr);
|
||||
|
||||
const promises = hostArr.map(
|
||||
|
@ -271,29 +275,18 @@
|
|||
);
|
||||
Promise.all( promises ).then( (cbsRes) => {
|
||||
|
||||
const errors = cbsRes.map( ([err]) => err ).filter( (err) => err );
|
||||
let newError;
|
||||
const ifAllErrors = cbsRes.length === errors.length;
|
||||
if (errors.length) {
|
||||
if (ifAllErrors) {
|
||||
newError = errors.shift();
|
||||
} else {
|
||||
newError = errors;
|
||||
}
|
||||
newError = clarify(
|
||||
newError,
|
||||
let ipErrors = cbsRes.map( ([err]) => err ).filter( (err) => err );
|
||||
let warns = [];
|
||||
if (ipErrors.length) {
|
||||
warns = [clarify(
|
||||
ipErrors,
|
||||
'Не удалось получить один или несколько IP адресов для' +
|
||||
' прокси-серверов. Иконка для уведомления об обходе' +
|
||||
' блокировок может не отображаться.'
|
||||
);
|
||||
if (ifAllErrors) {
|
||||
return cb(newError);
|
||||
}
|
||||
}
|
||||
cb(null, null, newError);
|
||||
|
||||
)];
|
||||
} else {}
|
||||
cb(null, null, ...warns);
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
_replaceAllAsync(hostArr = mandatory(), cb) {
|
||||
|
|
|
@ -4,9 +4,13 @@
|
|||
|
||||
const timeouted = window.utils.timeouted;
|
||||
|
||||
const proxySideErrors = [
|
||||
'net::ERR_TUNNEL_CONNECTION_FAILED',
|
||||
];
|
||||
const isProxied = (requestDetails) => false;
|
||||
const isProxySideError = (details) =>
|
||||
/* About !main_frame: Main frame websocket errors are followed by webnavigation errors
|
||||
which chrome-internals code resets the state of the popup.
|
||||
*/
|
||||
details.error === 'net::ERR_TUNNEL_CONNECTION_FAILED' && details.type !== 'main_frame' && isProxied(details) ||
|
||||
details.error === 'NS_ERROR_CONNECTION_REFUSED' && Boolean(details.proxyInfo);
|
||||
|
||||
const urlToA = (url) => new URL(url).host.link(
|
||||
encodeURIComponent(url),
|
||||
|
@ -14,9 +18,7 @@
|
|||
|
||||
const isProxyErrorHandledAsync = async (details) => {
|
||||
|
||||
if (!proxySideErrors.includes(details.error) || details.type === 'main_frame') {
|
||||
// Main frame websocket errors are followed by webnavigation errors
|
||||
// which chrome-internals code resets the state of the popup.
|
||||
if (!isProxySideError(details)) {
|
||||
return;
|
||||
}
|
||||
let fromPageHref = '';
|
||||
|
@ -66,7 +68,7 @@
|
|||
)
|
||||
);
|
||||
|
||||
const popupPrefix = chrome.runtime.getURL(`/pages/options/index.html?status=<span style="color: red">🔥 Прокси-сервер отказался обслуживать запрос к `);
|
||||
const popupPrefix = chrome.runtime.getURL(`/pages/options/index.html?status=<span style="color: red">🔥 Прокси-сервер отказался обслуживать запрос к%20`);
|
||||
if (decodeURIComponent(oldPopup).startsWith(popupPrefix)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -164,5 +166,4 @@
|
|||
timeouted(isProxyErrorHandledAsync),
|
||||
{urls: ['<all_urls>']},
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
@ -2,15 +2,13 @@
|
|||
|
||||
const pacUrls = [
|
||||
// GitHub.io (anticensority), cached:
|
||||
'\x68\x74\x74\x70\x73\x3a\x2f\x2f\x61\x6e\x74\x69\x63\x65\x6e\x73\x6f\x72\x69\x74\x79\x2e\x67\x69\x74\x68\x75\x62\x2e\x69\x6f\x2f\x67\x65\x6e\x65\x72\x61\x74\x65\x64\x2d\x70\x61\x63\x2d\x73\x63\x72\x69\x70\x74\x73\x2f\x61\x6e\x74\x69\x63\x65\x6e\x73\x6f\x72\x69\x74\x79\x2e\x70\x61\x63',
|
||||
'https://anticensority.github.io/generated-pac-scripts/anticensority.pac',
|
||||
// GitHub repo (anticensority), cached:
|
||||
'\x68\x74\x74\x70\x73\x3a\x2f\x2f\x72\x61\x77\x2e\x67\x69\x74\x68\x75\x62\x75\x73\x65\x72\x63\x6f\x6e\x74\x65\x6e\x74\x2e\x63\x6f\x6d\x2f\x61\x6e\x74\x69\x63\x65\x6e\x73\x6f\x72\x69\x74\x79\x2f\x67\x65\x6e\x65\x72\x61\x74\x65\x64\x2d\x70\x61\x63\x2d\x73\x63\x72\x69\x70\x74\x73\x2f\x6d\x61\x73\x74\x65\x72\x2f\x61\x6e\x74\x69\x63\x65\x6e\x73\x6f\x72\x69\x74\x79\x2e\x70\x61\x63',
|
||||
// First official, shortened, not cached:
|
||||
'https://rebrand.ly/ac-chrome-anticensority-pac',
|
||||
'https://raw.githubusercontent.com/anticensority/generated-pac-scripts/master/anticensority.pac',
|
||||
];
|
||||
|
||||
const commonContext = {
|
||||
version: '1.43',
|
||||
version: '1.66',
|
||||
anticensorityPacUrls: [
|
||||
...pacUrls,
|
||||
],
|
||||
|
@ -57,7 +55,6 @@ exports.contexts.beta = Object.assign({}, commonContext, {
|
|||
anticensorityPacUrls: [
|
||||
'https://raw.githubusercontent.com/anticensority/for-testing/master/anticensority.pac',
|
||||
'https://anticensority.github.io/for-testing/anticensority.pac',
|
||||
'https://rebrand.ly/ac-beta-pac',
|
||||
],
|
||||
version: '1.14',
|
||||
versionSuffix: '',
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user