Compare commits

..

128 Commits

Author SHA1 Message Date
ilyaigpetrov
d86cf384af Bump 0.0.1.66 2024-07-30 15:39:06 +05:00
ilyaigpetrov
e1c95a3ece Add exact versions for reviewers 2024-07-30 15:38:19 +05:00
ilyaigpetrov
edabf14dd5 Add reference about why have to ask for consent 2024-07-15 23:41:37 +05:00
ilyaigpetrov
2f5d425f34 Autoclose the consent screen after user choice. Show consent screen only in FireFox 2024-07-15 23:40:31 +05:00
ilyaigpetrov
1c38137200
Remove the text about Mozilla ban 2024-06-15 11:57:19 +05:00
ilyaigpetrov
99b68ec8d0
Add a link to releases page for FireFox 2024-06-11 21:54:40 +05:00
ilyaigpetrov
0cc47d43a9
Mention that Mozilla blocks access for Russian IPs 2024-06-09 21:03:15 +05:00
Polycarbohydrate
a583e5ecb3 Fix English grammatical errors and add a translation. Merge PR #244
* Update README.md

* Fix minor punctuation mistakes

* Fix articles and other minor grammar mistakes

* Fix minor spelling mistakes

---------

Co-authored-by: ilyaigpetrov <ilyaigpetrov@gmail.com>
2024-05-13 21:17:41 +05:00
ilyaigpetrov
884b4f0fbc Fix spelling mistakes 2024-05-13 18:23:28 +05:00
ilyaigpetrov
770c4ab47d Bump 0.0.1.65 2024-05-13 18:22:24 +05:00
ilyaigpetrov
c5d9ca3254 Bump 0.0.1.64 2024-04-24 20:27:34 +05:00
ilyaigpetrov
27ad6944e0 Add consent screen 2024-04-24 20:15:14 +05:00
ilyaigpetrov
a589568bf9 Fix obsolete button title 2024-04-24 20:12:36 +05:00
ilyaigpetrov
b3585293a7 Replace the expired antizapret.info with rublacklist/roskomsvoboda registry of blocked sites 2024-03-29 22:25:22 +05:00
ilyaigpetrov
fd45db7dcc Rename the file for reviwers 2024-03-29 22:25:22 +05:00
ilyaigpetrov
65eb930682 Update AntiZapret urls 2024-03-29 22:25:22 +05:00
ilyaigpetrov
d3156175d8 Remove remnants of rebrand.ly shortened urls 2024-03-29 22:25:22 +05:00
ilyaigpetrov
c0862ecfff Bump 0.0.1.63 2024-03-29 22:25:22 +05:00
ilyaigpetrov
75d30ba467 Bump 0.0.1.62 2023-05-05 19:19:31 +05:00
ilyaigpetrov
a7e93d8383 Bump 0.0.1.61 2023-05-05 19:00:22 +05:00
ilyaigpetrov
b3096c8d83 Fix buggy update logic 2023-05-05 18:39:21 +05:00
ilyaigpetrov
ae930da8b3 Get rid of rebrand.ly everywhere in the code 2023-05-05 00:07:37 +05:00
ilyaigpetrov
451691ef2a Upgrade webpack 2023-05-04 23:37:28 +05:00
ilyaigpetrov
6e8943ca1c Bump 0.0.1.60 2023-04-26 05:31:12 +05:00
ilyaigpetrov
61f22e08be Replace 2 shortened links to resolved versions 2023-04-26 05:30:34 +05:00
ilyaigpetrov
b45a78e654 Bump 0.0.1.59 2023-04-26 05:25:17 +05:00
ilyaigpetrov
08e1b41780 Add another source for AntiZapret. Add AZ proxy for twitter to block-informer. Replace some rebrand.ly links (blocked on TSPU) 2023-04-26 05:16:43 +05:00
ilyaigpetrov
e5fb9d11dd Bump 0.0.1.58 2023-04-26 05:13:56 +05:00
ilyaigpetrov
689f9266f7 Add one more source for AntiZapret. Delete old update code. Move notes for reviewers from README to a separate file 2023-04-25 22:59:20 +05:00
ilyaigpetrov
6858c56534 Revert "Add Alt+P hotkey stub"
This reverts commit 3d72acc6dd.
2023-04-11 19:56:44 +05:00
ilyaigpetrov
7f9fb4f972
Update README.md 2022-10-02 18:45:41 +05:00
ilyaigpetrov
0e803bd08f
Replace some rebrandly links with direct links 2022-09-15 18:34:45 +05:00
ilyaigpetrov
6ef5807971
Add a link to the issue with alternative install methods (the default one is blocked for WebStore) 2022-09-14 16:21:53 +00:00
ilyaigpetrov
97adb7f3f4
Remove a maxim and a belief under "Why I do this" 2022-06-25 14:41:08 +00:00
ilyaigpetrov
db8dfbfd50
Remove Open Collective from GitHub FUNDING 2022-05-19 20:22:36 +05:00
ilyaigpetrov
3d72acc6dd Add Alt+P hotkey stub 2022-03-09 21:43:08 +05:00
ilyaigpetrov
0d7678ff50 Bump 0.0.1.57 2022-03-09 20:32:01 +05:00
ilyaigpetrov
edf6fc8b5f
Update README.md 2022-02-19 19:56:30 +05:00
ilyaigpetrov
0951e83dd1
Update README.md 2022-02-13 13:08:58 +00:00
ilyaigpetrov
79049bed25
Update README.md 2022-02-13 13:08:27 +00:00
ilyaigpetrov
951a5e9248 Update some deps for better security 2021-11-28 13:25:51 +00:00
ilyaigpetrov
6634f72580 Bump 0.0.1.56 2021-11-08 16:20:23 +00:00
ilyaigpetrov
aac0182738 Restrict min version for FireFox. r/ /%20/g in an url. Add link to the generator to README 2021-11-08 16:19:44 +00:00
ilyaigpetrov
8f00516d44 Merge branch 'work-even-if-dns-fails' into development 2021-09-15 16:30:18 +00:00
ilyaigpetrov
1265a3ad79 Bump 0.0.1.55 2021-09-15 16:29:37 +00:00
ilyaigpetrov
93aa084de9 Fix the bug with non-descriptive warnings. Make DNS errors non-critical 2021-09-15 16:27:23 +00:00
ilyaigpetrov
cb0d991e94 A fix for yandex browser(startsWith applied to undefined) 2021-09-12 09:03:49 +00:00
ilyaigpetrov
b77be60946 Trying to trace bug with non-descriptive warnings 2021-09-12 07:41:15 +00:00
ilyaigpetrov
1aec32de3e Add backup url for antizapret pac-script 2021-08-31 15:58:16 +00:00
ilyaigpetrov
86d07b79c3 make extension robust to dns failures (test0) 2021-08-27 16:19:50 +00:00
ilyaigpetrov
5b3e6f1f51 Break dns url for testing, don't fail on dns failure
In this commit all dns errors a swallowed during install
2021-08-27 15:28:03 +00:00
ilyaigpetrov
ce22337928 Bump 0.0.1.54 2021-08-27 14:06:11 +00:00
ilyaigpetrov
c0e5609d44 Give WARP SOCKS5 priority, WARP HTTPS doens't work in FireFox 2021-07-01 09:06:13 +00:00
ilyaigpetrov
c496fe1030 Merge branch 'development' of github.com:anticensority/runet-censorship-bypass into development 2021-07-01 08:36:58 +00:00
ilyaigpetrov
034c08828f Inform FireFox user about WARP proxying via block-informer (https proxy fails) 2021-07-01 08:36:20 +00:00
ilyaigpetrov
1c479a4e47 Inform FireFox user about WARP proxying (https proxy fails) 2021-06-26 16:51:46 +00:00
ilyaigpetrov
6e24ee0454 Opts page was too narrow, risk and make wider 2021-06-26 16:47:28 +00:00
ilyaigpetrov
e1bdf654f2 Merge branch 'warp-integration' into development 2021-06-26 16:07:01 +00:00
ilyaigpetrov
e73766ae24 Add WARP integration 2021-06-26 16:06:10 +00:00
ilyaigpetrov
5164559fc6 Bump 0.0.1.53 2021-06-25 14:40:53 +00:00
ilyaigpetrov
e344b987c5 Upgrade 'Tested on' versions in the README 2021-05-30 14:57:18 +00:00
ilyaigpetrov
05903e32b3 Merge branch 'fetch-with-retries' into development 2021-05-28 15:28:17 +00:00
ilyaigpetrov
f43eafaf8a Fix retries bug (test4)
Change args scheme in calls of the modified function
2021-05-26 16:53:56 +00:00
ilyaigpetrov
b5154f6453 Add retries (finished, test0) 2021-05-24 17:30:43 +00:00
ilyaigpetrov
699bef6fea Add retries (not tested) 2021-05-22 17:38:32 +00:00
ilyaigpetrov
da7701393e Merge branch 'ffx-layout-fix' into development 2021-05-18 15:45:31 +00:00
ilyaigpetrov
235f6e4b47 Merge branch 'whitelist' into development 2021-05-18 15:45:21 +00:00
ilyaigpetrov
0c5dc8eb26 Fix popup layout widening horizontally. Fix #18 2021-05-18 15:44:05 +00:00
ilyaigpetrov
57a2a8c1ac Add whitelisting for sites to be proxied 2021-05-17 17:12:45 +00:00
ilyaigpetrov
d3caee1483 Start adding whitelist capability 2021-05-15 17:46:14 +00:00
ilyaigpetrov
e4a936c5f1 Fix cases when currentTab.url is falsy (reported for Yandex browser) 2021-03-13 14:37:29 +00:00
ilyaigpetrov
414e2547f3 Upgrade dependencies 2021-02-28 10:56:49 +00:00
ilyaigpetrov
04be2d6164 Bump 0.0.1.52 2021-01-25 10:05:44 +00:00
ilyaigpetrov
e51673f268 Fix migration error from 1.49 2021-01-25 07:20:53 +00:00
ilyaigpetrov
d56a7e7366 Bump 0.0.1.51 2021-01-24 15:21:25 +00:00
ilyaigpetrov
0b13cb1dd0 Fix 2 bugs in exceptions handling 2021-01-18 13:58:30 +00:00
ilyaigpetrov
14f32b4d13 Migrate all exceptions to wildcarded state 2021-01-17 17:02:59 +00:00
ilyaigpetrov
9ef236d604 Hanlde wildcard when assigning a weight to an exception 2021-01-15 17:28:55 +00:00
ilyaigpetrov
7dae51db8c Return to a step back when wildcard is present in the key (not in the value) 2021-01-15 16:59:32 +00:00
ilyaigpetrov
796681ae5a Make proxy's 'No' settable in UI. Refactor 2021-01-14 16:40:04 +00:00
ilyaigpetrov
ccda45a57c Keep objects in mods.in/ex(cluded). Refactor 2021-01-12 17:29:18 +00:00
ilyaigpetrov
e95c186de1 Handle *. in UI for exceptions 2021-01-12 16:00:29 +00:00
ilyaigpetrov
df3ea9e6ad Allow non-wildcard exceptions (no migration or interface yet) 2021-01-12 15:46:32 +00:00
ilyaigpetrov
38e2bb2f3c Refactor one line 2021-01-12 14:18:46 +00:00
ilyaigpetrov
35668f620b Fix broken migration for <=0.0.1.48 2021-01-10 16:43:47 +00:00
ilyaigpetrov
1371dc01cd Merge branch 'production' into development 2020-12-23 14:40:04 +00:00
ilyaigpetrov
95bfd3ae9e Merge branch 'development' into production 2020-12-23 14:37:39 +00:00
ilyaigpetrov
f93e01bb8a Merge firefox-60 to development 2020-12-23 14:36:16 +00:00
ilyaigpetrov
b3997f48ac Bump 0.0.1.50 2020-12-07 17:47:03 +00:00
ilyaigpetrov
1a0c168458 Bump 0.0.1.49 2020-12-07 16:54:51 +00:00
ilyaigpetrov
c566fcecb5 Migrate storage for <=0.0.1.48. Fix ffx bugs 2020-12-07 16:52:09 +00:00
ilyaigpetrov
aa727d9329 Fix chrome.proxy.settings shims for FireFox
Yet it still downloads pac-script twice
2020-12-06 16:43:29 +00:00
ilyaigpetrov
53571f6228 Add chrome.proxy.settings shims for FireFox 2020-12-05 16:28:30 +00:00
ilyaigpetrov
eb996931ae Fix a bug thrown after waking pc up
Handle a case when all pac-script urls fwail
2020-11-09 12:03:45 +00:00
ilyaigpetrov
63f5e6fd08 Bump 0.0.1.48 2020-11-09 07:57:45 +00:00
ilyaigpetrov
fe2e986bfe Turn off TUNN CONN FAILED for chrome. Fix proxy settings setter bug 2020-11-07 15:29:57 +00:00
ilyaigpetrov
da06ea4aac Bump 0.0.47 2020-11-01 12:07:10 +00:00
ilyaigpetrov
e60b8cc96c Truncate long log output to save RAM 2020-11-01 11:07:59 +00:00
ilyaigpetrov
c8e7d7f427 Move promise rejection handler into later promise. Fix #74 2020-11-01 11:01:03 +00:00
ilyaigpetrov
65f712d0a1
Update README.md 2020-10-19 09:37:13 +00:00
ilyaigpetrov
71d1aff6cd
Update README.md 2020-10-19 09:35:53 +00:00
ilyaigpetrov
5287510263 Make ffx blink on TUNNEL CONN FAILED (but popup doesn't show error) 2020-10-18 16:27:57 +00:00
ilyaigpetrov
a12621635b Bump 0.0.1.46 2020-10-18 16:27:25 +00:00
ilyaigpetrov
fb9aa707a6 Add a note for reviewers 2020-10-17 13:44:57 +00:00
ilyaigpetrov
e3c595a447 Don't open new tab if no access to private windows. Rephrase 2020-10-17 13:36:29 +00:00
ilyaigpetrov
73485e8be4 Open howto when extension needs access to private windows 2020-10-17 10:25:16 +00:00
ilyaigpetrov
99a4ff9d24 Don't clear settings that are not set by us 2020-10-16 17:54:20 +00:00
ilyaigpetrov
97ba2697da Clean before the build 2020-10-16 17:19:56 +00:00
ilyaigpetrov
0ffefd7cfc Get rid of obsolete firefox scripts 2020-10-16 17:02:22 +00:00
ilyaigpetrov
747ad70497 Bump 0.0.1.45 2020-10-16 17:01:09 +00:00
ilyaigpetrov
3f0cebebad Bump 0.0.1.44 2020-10-16 17:00:27 +00:00
ilyaigpetrov
4985ef6526 Get rid of obfuscated string constants 2020-10-16 16:01:04 +00:00
ilyaigpetrov
5278c65c90 Use data-url instead of blob. Remove debug logs. Remove ccahiha. 2020-10-16 15:00:09 +00:00
ilyaigpetrov
94aefc8ddc Provide more build/install details for reviewers 2020-10-16 14:13:11 +00:00
ilyaigpetrov
fccc2611b2 Make start command to build for production 2020-10-16 14:07:19 +00:00
ilyaigpetrov
4e870d5b87
Update README.md 2020-10-16 14:06:23 +00:00
ilyaigpetrov
17989f4735 Fix muted errors
New bug spotted: "GETed with success" is logged twice for
proxy.pac.
2020-10-13 16:27:50 +00:00
ilyaigpetrov
ea85cf941b Merge branch 'development' into production 2020-10-08 08:20:11 +00:00
ilyaigpetrov
0a0df56dbe Merge branch 'development' into production 2019-10-25 16:19:13 +00:00
ilyaigpetrov
97b6c2cdc3 Merge branch 'development' into production 2019-09-30 12:25:18 +00:00
ilyaigpetrov
4e736bf403 Merge branch 'development' into production 2019-09-07 16:37:10 +00:00
ilyaigpetrov
af7a5a24bc Merge branch 'development' into production 2019-08-16 16:34:28 +00:00
ilyaigpetrov
4704585c1a Merge branch 'development' into production 2019-08-12 17:09:31 +05:00
ilyaigpetrov
e9420a68c9 Merge branch 'development' into production 2019-05-20 01:18:43 -05:00
ilyaigpetrov
cbd377b33b Merge branch 'development' into production 2019-05-11 06:21:07 -05:00
ilyaigpetrov
f37539a19c Merge branch 'development' into production 2019-05-04 12:36:34 -05:00
Ilya Ig. Petrov
e6d5be6e56 Merge branch 'development' into production 2019-04-15 07:54:34 +00:00
Ilya Ig. Petrov
66d89a3b97 Merge branch 'development' into production 2018-08-01 17:32:51 +05:00
41 changed files with 19023 additions and 6963 deletions

4
.github/FUNDING.yml vendored
View File

@ -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/Поддержать

View File

@ -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 on Open Collective](https://opencollective.com/anticensority/backers/badge.svg)](#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>

View File

@ -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.

View File

@ -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

View File

@ -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"
}
}

View File

@ -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);
}
}
}

View File

@ -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 {

View File

@ -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();
},

View File

@ -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);
};
}

View File

@ -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.

View File

@ -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.
**/
}));
})();
}

View File

@ -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,
},

View File

@ -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.

View File

@ -1 +0,0 @@
Files of this directory must be copied into final build without modifications.

View File

@ -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>."
}
}

View File

@ -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>."
}
}

View File

@ -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"

View File

@ -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>

View File

@ -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

View File

@ -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 = 'Успешно сохранено!';

View File

@ -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",

View File

@ -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);

View File

@ -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) }/>
})
}

View File

@ -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>

View File

@ -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 );

View File

@ -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>

View File

@ -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>
);
}

View File

@ -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);

View File

@ -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;

View File

@ -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>

View File

@ -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);
}
}
}

View File

@ -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; })();
});

View File

@ -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) {

View File

@ -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>']},
);
}

View File

@ -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