2015-12-20 23:28:41 +03:00
'use strict' ;
/ *
2016-05-08 19:14:08 +03:00
Task 1. Gets IPs for proxies of antizapret / anticenz via dns over https .
2016-02-12 19:00:40 +03:00
These IPs are used in block - informer to inform user when proxy is ON .
Task 2. Downloads PAC proxy script from antizapret / anticenz / my Google Drive and sets it in Chromium settings .
Task 3. Schedules tasks 1 & 2 for every 4 hours .
2015-12-20 23:28:41 +03:00
* /
/ *
In background scripts use window . antiCensorRu public variables .
2016-05-15 16:08:23 +03:00
In pages window . antiCensorRu is not accessible ,
2015-12-20 23:28:41 +03:00
use chrome . runtime . getBackgroundPage ( . . ) ,
2016-05-08 19:14:08 +03:00
extension . getBackgroundPage is deprecated
2015-12-20 23:28:41 +03:00
* /
2016-11-20 15:58:49 +03:00
{ // Private namespace starts.
2015-12-20 23:28:41 +03:00
2016-11-20 15:58:49 +03:00
window . antiCensorRu = {
2015-12-20 23:28:41 +03:00
2016-11-20 15:58:49 +03:00
version : chrome . runtime . getManifest ( ) . version ,
2015-12-20 23:28:41 +03:00
2016-11-20 15:58:49 +03:00
pacProviders : {
Антизапрет : {
pacUrl : 'https://antizapret.prostovpn.org/proxy.pac' ,
proxyHosts : [ 'proxy.antizapret.prostovpn.org' ] ,
proxyIps : {
'195.123.209.38' : 'proxy.antizapret.prostovpn.org' ,
'2a02:27ac::10' : 'proxy.antizapret.prostovpn.org'
}
} ,
Антиценз : {
pacUrl : 'https://config.anticenz.org/proxy.pac' ,
proxyHosts : [ 'gw2.anticenz.org' ] ,
proxyIps : {
'5.196.220.114' : 'gw2.anticenz.org'
}
} ,
О б а _и _на _с витча х : {
//pacUrl: 'https://drive.google.com/uc?export=download&id=0B-ZCVSvuNWf0akpCOURNS2VCTmc', // 0.14
pacUrl : 'https://drive.google.com/uc?export=download&id=0B-ZCVSvuNWf0bzNUR2F4RF8wOU0' , // 0.15
proxyHosts : [ 'proxy.antizapret.prostovpn.org' , 'gw2.anticenz.org' ] ,
proxyIps : {
'195.123.209.38' : 'proxy.antizapret.prostovpn.org' ,
'2a02:27ac::10' : 'proxy.antizapret.prostovpn.org' ,
'5.196.220.114' : 'gw2.anticenz.org'
}
2016-02-08 12:55:41 +03:00
}
2016-01-17 22:27:54 +03:00
} ,
2015-12-20 23:28:41 +03:00
2016-11-20 15:58:49 +03:00
_currentPacProviderKey : 'О б а _и_на _с витча х ' ,
2015-12-20 23:28:41 +03:00
2016-11-24 19:40:57 +03:00
isProxied ( ip ) {
// Executed on each request with ip. Make it as fast as possible.
return this . _currentPacProviderKey && this . pacProviders [ this . _currentPacProviderKey ] . proxyIps . hasOwnProperty ( ip ) ;
// The benefit of removing lookups is little, e.g. this._currentProxyIps && this._currentProxyIps.hasOwnProperty(ip);
} ,
mustBeKey ( key ) {
if ( ! ( key === null || this . pacProviders [ key ] ) ) {
throw new IllegalArgumentException ( 'No provider for key:' + key ) ;
}
} ,
2016-11-20 15:58:49 +03:00
get currentPacProviderKey ( ) { return this . _currentPacProviderKey } ,
set currentPacProviderKey ( newKey ) {
2016-05-15 16:08:23 +03:00
2016-11-24 19:40:57 +03:00
this . mustBeKey ( newKey ) ;
2016-11-20 15:58:49 +03:00
this . _currentPacProviderKey = newKey ;
2016-11-24 19:40:57 +03:00
2016-11-20 15:58:49 +03:00
} ,
2015-12-20 23:28:41 +03:00
2016-11-24 19:40:57 +03:00
getPacProvider ( key ) {
if ( key ) {
this . mustBeKey ( key ) ;
}
else {
key = this . currentPacProviderKey ;
}
return this . pacProviders [ key ] ;
} ,
2015-12-20 23:28:41 +03:00
2016-11-20 15:58:49 +03:00
/ *
Is it the first time extension installed ? Do something , e . g . initiate PAC sync .
* /
ifFirstInstall : false ,
lastPacUpdateStamp : 0 ,
2015-12-20 23:28:41 +03:00
2016-11-20 15:58:49 +03:00
_periodicUpdateAlarmReason : 'Периодичное обновление PAC-скрипта Антизапрет' ,
2015-12-20 23:28:41 +03:00
2016-11-20 15:58:49 +03:00
pushToStorage ( cb ) {
2015-12-20 23:28:41 +03:00
2016-11-20 15:58:49 +03:00
console . log ( 'Pushing to storage...' ) ;
2016-05-15 16:08:23 +03:00
2016-11-20 15:58:49 +03:00
// Copy only settable properties (except functions).
const onlySettable = { } ;
for ( const key of Object . keys ( this ) ) {
if ( Object . getOwnPropertyDescriptor ( this , key ) . writable && typeof ( this [ key ] ) !== 'function' ) {
onlySettable [ key ] = this [ key ] ;
}
2016-05-15 16:08:23 +03:00
}
2016-02-05 19:11:19 +03:00
2016-11-21 20:39:46 +03:00
chrome . storage . local . clear (
2016-11-20 15:58:49 +03:00
( ) => chrome . storage . local . set (
onlySettable ,
chromified ( cb , onlySettable )
)
) ;
2016-02-13 18:53:27 +03:00
2016-11-20 15:58:49 +03:00
} ,
2015-12-20 23:28:41 +03:00
2016-11-20 15:58:49 +03:00
pullFromStorage ( cb ) {
2016-05-15 16:08:23 +03:00
2016-11-20 15:58:49 +03:00
chrome . storage . local . get ( null , ( storage ) => {
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
const err = checkChromeError ( ) ;
if ( ! err ) {
console . log ( 'Pulled from storage:' , storage ) ;
for ( const key of Object . keys ( storage ) ) {
this [ key ] = storage [ key ] ;
}
2016-11-20 14:33:18 +03:00
}
2015-12-20 23:28:41 +03:00
2016-11-20 15:58:49 +03:00
console . log ( 'Synced with storage, any callback?' , ! ! cb ) ;
2016-11-21 20:39:46 +03:00
cb && cb ( err , storage ) ;
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
} ) ;
} ,
2016-01-26 13:38:40 +03:00
2016-11-24 19:40:57 +03:00
syncWithPacProvider ( key , cb ) {
if ( ! key || typeof ( key ) === 'function' ) {
cb = key ;
key = this . currentPacProviderKey ;
}
cb = asyncLogGroup ( 'Syncing with PAC provider ' + key + '...' , cb ) ;
2016-05-15 16:08:23 +03:00
2016-11-24 19:40:57 +03:00
if ( key === null ) {
// No pac provider set.
2016-11-20 15:58:49 +03:00
return cb ( { clarification : { message : 'Сперва выберите PAC-провайдера.' } } ) ;
}
2016-01-26 23:05:21 +03:00
2016-11-24 19:40:57 +03:00
const pacProvider = this . getPacProvider ( key ) ;
2016-11-20 15:58:49 +03:00
const pacSetPromise = new Promise (
( resolve , reject ) => setPacScriptFromProvider (
2016-11-24 19:40:57 +03:00
pacProvider ,
2016-11-20 15:58:49 +03:00
( err , res ) => {
if ( ! err ) {
2016-11-24 19:40:57 +03:00
this . currentPacProviderKey = key ;
2016-11-20 15:58:49 +03:00
this . lastPacUpdateStamp = Date . now ( ) ;
this . ifFirstInstall = false ;
this . setAlarms ( ) ;
}
2016-11-21 20:39:46 +03:00
resolve ( [ err , res ] ) ;
2016-05-15 16:08:23 +03:00
}
2016-11-20 15:58:49 +03:00
)
) ;
2016-04-10 12:39:11 +03:00
2016-11-20 15:58:49 +03:00
const ipsPromise = new Promise (
( resolve , reject ) => updatePacProxyIps (
2016-11-24 19:40:57 +03:00
pacProvider ,
2016-11-20 15:58:49 +03:00
( ipsError ) => {
2016-02-13 18:53:27 +03:00
2016-11-20 15:58:49 +03:00
if ( ipsError && ipsError . clarification ) {
ipsError . clarification . ifNotCritical = true ;
}
2016-11-21 20:39:46 +03:00
resolve ( [ ipsError ] ) ;
2016-11-20 15:58:49 +03:00
}
)
) ;
2016-01-26 23:05:21 +03:00
2016-11-20 15:58:49 +03:00
Promise . all ( [ pacSetPromise , ipsPromise ] ) . then (
( [ [ pacErr , pacRes ] , [ ipsErr ] ] ) => {
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
if ( pacErr && ipsErr ) {
return cb ( pacErr , pacRes ) ;
2016-11-20 14:33:18 +03:00
}
2016-11-20 15:58:49 +03:00
this . pushToStorage (
( pushErr ) => cb ( pacErr || ipsErr || pushErr , pacRes )
) ;
2016-05-15 16:08:23 +03:00
2016-11-21 18:03:02 +03:00
} ,
cb
2016-11-20 15:58:49 +03:00
) ;
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
} ,
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
_pacUpdatePeriodInMinutes : 4 * 60 ,
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
setAlarms ( ) {
let nextUpdateMoment = this . lastPacUpdateStamp + this . _pacUpdatePeriodInMinutes * 60 * 1000 ;
const now = Date . now ( ) ;
if ( nextUpdateMoment < now ) {
nextUpdateMoment = now ;
2016-01-26 23:05:21 +03:00
}
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
console . log ( 'Next PAC update is scheduled on' , new Date ( nextUpdateMoment ) . toLocaleString ( 'ru-RU' ) ) ;
2016-05-08 19:14:08 +03:00
2016-11-20 15:58:49 +03:00
chrome . alarms . create (
this . _periodicUpdateAlarmReason ,
{
when : nextUpdateMoment ,
periodInMinutes : this . _pacUpdatePeriodInMinutes
}
) ;
2016-02-13 18:53:27 +03:00
2016-11-20 15:58:49 +03:00
return nextUpdateMoment === now ; // ifAlarmTriggered. May be changed in the future.
2016-02-13 18:53:27 +03:00
2016-11-20 15:58:49 +03:00
} ,
2016-03-24 19:11:36 +03:00
2016-11-20 15:58:49 +03:00
installPac ( key , cb ) {
2016-02-13 18:53:27 +03:00
2016-11-24 19:40:57 +03:00
console . log ( 'Installing PAC...' ) ;
if ( ! key ) {
throw new Error ( 'Key must be defined.' ) ;
2016-02-13 18:53:27 +03:00
}
2016-11-24 19:40:57 +03:00
if ( this . currentProviderKey !== key ) {
return this . syncWithPacProvider ( key , cb ) ;
2016-11-20 15:58:49 +03:00
}
2016-11-24 19:40:57 +03:00
console . log ( key + ' already installed.' ) ;
cb ( ) ;
2015-12-20 23:28:41 +03:00
2016-11-20 15:58:49 +03:00
} ,
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
clearPac ( cb ) {
2015-12-20 23:28:41 +03:00
2016-11-20 15:58:49 +03:00
cb = asyncLogGroup ( 'Cearing alarms and PAC...' , cb ) ;
chrome . alarms . clearAll (
( ) => chrome . proxy . settings . clear (
{ } ,
( ) => {
2016-05-15 16:08:23 +03:00
2016-11-20 15:58:49 +03:00
const err = checkChromeError ( ) ;
if ( err ) {
return cb ( err ) ;
}
2016-11-24 19:40:57 +03:00
this . currentPacProviderKey = null ;
2016-11-21 20:39:46 +03:00
this . pushToStorage ( cb ) ;
2016-05-15 16:08:23 +03:00
2016-11-20 14:33:18 +03:00
}
2016-11-20 15:58:49 +03:00
)
) ;
}
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
} ;
2015-12-20 23:28:41 +03:00
2016-11-20 15:58:49 +03:00
// ON EACH LAUNCH, STARTUP, RELOAD, UPDATE, ENABLE
chrome . storage . local . get ( null , ( oldStorage ) => {
2015-12-20 23:28:41 +03:00
2016-11-24 19:40:57 +03:00
checkChromeError ( ) ;
/ *
Event handlers that ALWAYS work ( even if installation is not done or failed ) .
E . g . install window may fail to open or be closed by user accidentally .
In such case extension _should _ try to work on default parameters .
* /
2016-11-20 15:58:49 +03:00
chrome . alarms . onAlarm . addListener (
( alarm ) => {
2016-02-08 12:55:41 +03:00
2016-11-20 15:58:49 +03:00
if ( alarm . name === antiCensorRu . _periodicUpdateAlarmReason ) {
console . log ( 'Periodic PAC update triggered:' , new Date ( ) . toLocaleString ( 'ru-RU' ) ) ;
antiCensorRu . syncWithPacProvider ( /* Swallows errors. */ ) ;
}
2016-05-15 16:08:23 +03:00
2016-02-13 18:53:27 +03:00
}
2016-11-20 15:58:49 +03:00
) ;
console . log ( 'Alarm listener installed. We won\'t miss any PAC update.' ) ;
2016-11-16 21:12:53 +03:00
2016-11-20 15:58:49 +03:00
window . addEventListener ( 'online' , ( ) => {
2016-11-16 21:12:53 +03:00
2016-11-20 15:58:49 +03:00
console . log ( 'We are online, checking periodic updates...' ) ;
antiCensorRu . setAlarms ( ) ;
2016-11-16 21:12:53 +03:00
2016-11-20 15:58:49 +03:00
} ) ;
2016-02-13 18:53:27 +03:00
2016-11-24 19:40:57 +03:00
console . log ( 'Storage on init:' , oldStorage ) ;
antiCensorRu . ifFirstInstall = Object . keys ( oldStorage ) . length === 0 ;
if ( ! antiCensorRu . ifFirstInstall ) {
// LAUNCH, RELOAD, UPDATE
antiCensorRu . _currentPacProviderKey = oldStorage . _currentPacProviderKey || null ; // Old or migrate.
antiCensorRu . lastPacUpdateStamp = oldStorage . lastPacUpdateStamp || antiCensorRu . lastPacUpdateStamp ; // Old or migrate to default.
console . log ( 'Last PAC update was on' , new Date ( antiCensorRu . lastPacUpdateStamp ) . toLocaleString ( 'ru-RU' ) ) ;
}
else {
2016-11-20 15:58:49 +03:00
// INSTALL
console . log ( 'Installing...' ) ;
2016-11-24 19:40:57 +03:00
return chrome . runtime . openOptionsPage ( ) ;
2016-11-20 15:58:49 +03:00
}
2016-02-11 23:07:39 +03:00
2016-11-24 19:40:57 +03:00
if ( ! antiCensorRu . getPacProvider ( ) ) {
2016-11-20 15:58:49 +03:00
/ *
In case of UPDATE :
1. new providers will still be shown .
2. new version won ' t be pushed to storage
* /
2016-11-24 19:40:57 +03:00
return console . log ( 'No PAC provider set. Do nothing.' ) ;
2016-11-20 15:58:49 +03:00
}
2016-05-08 19:14:08 +03:00
2016-11-20 15:58:49 +03:00
/ *
1. There is no way to check that chrome . runtime . onInstalled wasn ' t fired except timeout .
Otherwise we could put storage migration code only there .
2. We have to check storage for migration before using it .
Better on each launch then on each pull .
* /
2016-02-12 19:00:40 +03:00
2016-11-20 15:58:49 +03:00
const ifAlarmTriggered = antiCensorRu . setAlarms ( ) ;
2016-02-11 23:07:39 +03:00
2016-11-20 15:58:49 +03:00
if ( antiCensorRu . version === oldStorage . version ) {
// LAUNCH, RELOAD, ENABLE
antiCensorRu . pacProviders = oldStorage . pacProviders ;
return console . log ( 'Extension launched, reloaded or enabled.' ) ;
}
2015-12-20 23:28:41 +03:00
2016-11-20 15:58:49 +03:00
// UPDATE & MIGRATION
console . log ( 'Extension updated.' ) ;
if ( ! ifAlarmTriggered ) {
antiCensorRu . pushToStorage ( /* Swallows errors. */ ) ;
}
2016-05-15 16:08:23 +03:00
2016-11-20 15:58:49 +03:00
/ *
History of Changes to Storage ( Migration Guide )
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
Version 0.0 . 0.10
* Added this . version
* PacProvider . proxyIps changed from { ip - > Boolean } to { ip - > hostname }
Version 0.0 . 0.8 - 9
* Changed storage . ifNotInstalled to storage . ifFirstInstall
* Added storage . lastPacUpdateStamp
* * /
} ) ;
2016-05-15 16:08:23 +03:00
2016-11-20 15:58:49 +03:00
function asyncLogGroup ( ... args ) {
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
const cb = args . pop ( ) || ( ( ) => { } ) ;
console . group . apply ( console , args ) ;
return function ( ... cbArgs ) {
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
console . groupEnd ( ) ;
console . log ( 'Group finished.' ) ;
2016-11-21 20:39:46 +03:00
cb . apply ( this , cbArgs ) ;
2016-11-12 17:35:50 +03:00
2016-11-20 14:33:18 +03:00
}
2015-12-20 23:28:41 +03:00
}
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
function checkChromeError ( betterStack ) {
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
// Chrome API calls your cb in a context different from the point of API method invokation.
const err = chrome . runtime . lastError || chrome . extension . lastError || null ;
if ( err ) {
const args = [ 'API returned error:' , err ] ;
if ( betterStack ) {
args . push ( '\n' + betterStack ) ;
}
console . warn . apply ( console , args ) ;
}
return err ;
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
}
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
function chromified ( cb , ... replaceArgs ) {
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
const stack = ( new Error ( ) ) . stack ;
// Take error first callback and covert it to chrome api callback.
return function ( ... args ) {
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
if ( replaceArgs . length ) {
args = replaceArgs ;
}
const err = checkChromeError ( stack ) ;
2016-11-21 20:39:46 +03:00
cb && cb . call ( this , err , ... args ) ;
2015-12-20 23:28:41 +03:00
2016-11-20 15:58:49 +03:00
} ;
2016-05-15 16:08:23 +03:00
2016-11-20 15:58:49 +03:00
}
2016-05-15 16:08:23 +03:00
2016-11-21 18:03:02 +03:00
function setPac ( pacData , cb ) {
const config = {
mode : 'pac_script' ,
pacScript : {
mandatory : false ,
data : pacData
}
} ;
console . log ( 'Setting chrome proxy settings...' ) ;
chrome . proxy . settings . set ( { value : config } , ( ) => {
const err = checkChromeError ( ) ;
if ( err ) {
return cb ( err ) ;
}
chrome . proxy . settings . get ( { } , ( details ) => {
const ifThis = details . levelOfControl . startsWith ( 'controlled_by_this' ) ;
if ( ! ifThis ) {
console . warn ( 'Failed, other extension is in control.' ) ;
return cb ( { clarification : { message : 'Настройки прокси контролирует другое расширение. <a href="chrome://settings/search#proxy">Какое?</a>' } } ) ;
}
console . log ( 'Successfuly set PAC in proxy settings..' ) ;
2016-11-21 20:39:46 +03:00
cb ( ) ;
2016-11-21 18:03:02 +03:00
} ) ;
} ) ;
}
2016-11-20 15:58:49 +03:00
function httpGet ( url , cb ) {
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
const start = Date . now ( ) ;
2016-11-21 20:39:46 +03:00
fetch ( url ) . then (
2016-11-20 15:58:49 +03:00
( res ) => {
2016-05-15 16:08:23 +03:00
2016-11-20 15:58:49 +03:00
const textCb =
( err ) => cb && res . text ( )
. then ( ( text ) => cb ( err , text ) , cb ) ;
const status = res . status ;
if ( ! ( status >= 200 && status < 300 || status === 304 ) ) {
res . clarification = { message : 'Получен ответ с неудачным HTTP-кодом ' + status + '.' } ;
return textCb ( res ) ;
}
console . log ( 'GETed with success:' , url , Date . now ( ) - start ) ;
2016-11-21 20:39:46 +03:00
textCb ( ) ;
2016-11-20 14:33:18 +03:00
2016-11-20 15:58:49 +03:00
} ,
( err ) => {
2016-01-26 23:05:21 +03:00
2016-11-20 15:58:49 +03:00
err . clarification = { message : 'Что-то не так с сетью, проверьте соединение.' } ;
2016-11-21 20:39:46 +03:00
cb && cb ( err ) ;
2016-05-08 19:14:08 +03:00
2016-11-20 15:58:49 +03:00
}
) ;
2016-05-15 16:08:23 +03:00
}
2016-05-08 19:14:08 +03:00
2016-11-20 15:58:49 +03:00
function getOneDnsRecord ( args , cb ) {
2016-05-08 19:14:08 +03:00
2016-11-20 15:58:49 +03:00
// args: { host:..., type: 'AAAA', filter: ['AAAA'] }
if ( ! ( args . host && args . type && cb ) ) {
throw new Error ( 'Wrong args:' + host + ',' + type ) ;
}
const type2str = {
// https://en.wikipedia.org/wiki/List_of_DNS_record_types
// A, AAAA may be localized (github, e.g.), but you may use ANY
1 : 'A' , // IPv4
28 : 'AAAA' , // IPv6
2 : 'NS' ,
5 : 'CNAME' , // Synonyms, returned by server together with A/AAAA.
255 : 'ANY' // Deprecated on some servers, not recommended
} ;
httpGet (
'https://dns.google.com/resolve?type=' + args . type + '&name=' + args . host ,
( err , res ) => {
if ( res ) {
try {
res = JSON . parse ( res ) ;
console . log ( 'Json parsed.' ) ;
if ( err || res . Status ) {
const msg = [ 'Answer' , 'Comment' , 'Status' ]
. filter ( ( prop ) => res [ prop ] )
. map ( ( prop ) => prop + ': ' + JSON . stringify ( res [ prop ] ) )
. join ( ', \n' ) ;
err . clarification . message += ' Сервер (json): ' + msg ;
err . data = err . data || res ;
2016-05-15 16:08:23 +03:00
}
2016-11-20 15:58:49 +03:00
else {
res = res . Answer || [ ] ;
for ( const record of res ) {
record . type = type2str [ record . type ] ;
}
if ( args . filter ) {
res = res . filter ( ( record ) => args . filter . indexOf ( record . type ) > - 1 ) ;
}
2016-05-08 19:14:08 +03:00
}
}
2016-11-20 15:58:49 +03:00
catch ( e ) {
err = e || err || { clarification : { message : '' } } ;
err . clarification = err . clarification || { message : '' } ;
err . clarification . message += ' Сервер (текст): ' + res ;
err . clarification . message . trim ( ) ;
err . data = err . data || res ;
2016-05-15 16:08:23 +03:00
}
2016-11-20 15:58:49 +03:00
}
2016-11-21 20:39:46 +03:00
cb ( err , res ) ;
2016-05-15 16:08:23 +03:00
}
2016-11-20 15:58:49 +03:00
) ;
} ;
function getDnsRecords ( args , cb ) {
/ *
Example of input :
2016-05-15 16:08:23 +03:00
{
2016-11-20 15:58:49 +03:00
// Required
host : 'proxy.navalny.cia.gov' ,
// Optional
types : {
string : [ 'A' , 'AAAA' ] , // <- Default. Makes one request per each type.
filter : [ 'A' , 'AAAA' ] , // <- Default. E.g., you want to get rid of CNAME type from response.
}
}
Exmple of answer from google :
"Answer" :
[
{
"name" : "apple.com." , // Always matches name in the Question section
"type" : 1 , // A - Standard DNS RR type
"TTL" : 3599 , // Record's time-to-live in seconds
"data" : "17.178.96.59" // Data for A - IP address as text
} ,
...
Exmple of output :
The same as google , but types _may be _ canonical strings ( 'AAAA' , 'A' )
* * /
if ( ! args . host . length ) {
throw new Error ( 'args.host is required: ' + args . host ) ;
}
args . types = Object . assign ( {
string : [ 'A' , 'AAAA' ] ,
filter : [ 'A' , 'AAAA' ]
} , args . types ) ;
const promises = args . types . string . map (
( type ) => new Promise ( ( resolve , reject ) =>
getOneDnsRecord ( { host : args . host , type : type , filter : args . types . filter } , ( err , res ) => err ? reject ( err ) : resolve ( res ) )
)
) ;
Promise . all ( promises ) . then ( ( answers ) => cb ( null , [ ] . concat . apply ( [ ] , answers ) ) , cb ) ;
2016-05-15 16:08:23 +03:00
}
2016-05-08 19:14:08 +03:00
2016-11-20 15:58:49 +03:00
const getIpDnsRecords = ( host , cb ) => getDnsRecords ( { host : host } , cb ) ;
2016-05-15 16:08:23 +03:00
2016-11-20 15:58:49 +03:00
function updatePacProxyIps ( provider , cb ) {
2016-05-15 16:08:23 +03:00
2016-11-20 15:58:49 +03:00
cb = asyncLogGroup ( 'Getting IP for ' + provider . proxyHosts . join ( ', ' ) + '...' , cb ) ;
let failure = {
clarification : { message : 'Н е удалось получить один или несколько IP адресов для прокси-серверов. Иконка для уведомления о б обходе блокировок может не отображаться.' } ,
errors : { }
} ;
let i = 0 ;
provider . proxyHosts . map (
( proxyHost ) => getIpDnsRecords (
proxyHost ,
( err , records ) => {
2016-05-15 16:08:23 +03:00
2016-11-20 15:58:49 +03:00
if ( ! err ) {
provider . proxyIps = provider . proxyIps || { } ;
records . forEach ( ( ans ) => provider . proxyIps [ ans . data ] = proxyHost ) ;
}
else {
failure . errors [ proxyHost ] = err ;
}
2016-01-26 23:05:21 +03:00
2016-11-20 15:58:49 +03:00
if ( ++ i === provider . proxyHosts . length ) {
failure = Object . keys ( failure . errors ) . length ? failure : null ;
2016-11-21 20:39:46 +03:00
cb ( failure , provider . proxyIps ) ;
2016-11-20 15:58:49 +03:00
}
2016-01-17 22:27:54 +03:00
}
2016-11-20 15:58:49 +03:00
)
) ;
}
2015-12-20 23:28:41 +03:00
2016-11-20 15:58:49 +03:00
function setPacScriptFromProvider ( provider , cb ) {
2016-05-15 16:08:23 +03:00
2016-11-20 15:58:49 +03:00
cb = asyncLogGroup ( 'Getting pac script from provider...' , provider . pacUrl , cb ) ;
2016-01-17 22:27:54 +03:00
2016-11-20 15:58:49 +03:00
httpGet (
provider . pacUrl ,
( err , pacData ) => {
2016-05-15 16:08:23 +03:00
2016-11-20 15:58:49 +03:00
if ( err ) {
err . clarification = {
message : 'Н е удалось скачать PAC-скрипт с адреса: ' + provider . pacUrl + '.' ,
prev : err . clarification
} ;
return cb ( err ) ;
}
2016-11-21 18:03:02 +03:00
setPac ( pacData , cb ) ;
2016-11-12 17:35:50 +03:00
2016-11-20 15:58:49 +03:00
}
) ;
}
2016-05-15 16:08:23 +03:00
2016-11-16 19:12:39 +03:00
}
2016-11-20 14:33:18 +03:00
window . addEventListener ( 'error' , ( err ) => {
console . error ( 'Global error' ) ;
} ) ;
window . addEventListener ( 'unhandledrejection' , ( event ) => {
console . warn ( 'Unhandled rejection. Throwing error.' ) ;
event . preventDefault ( ) ;
throw event . reason ;
} ) ;
2016-11-21 18:03:02 +03:00
chrome . proxy . settings . onChange . addListener ( ( details ) => {
2016-11-21 20:39:46 +03:00
console . log ( 'Proxy settings changed.' , details ) ;
const ifOther = details . levelOfControl . startsWith ( 'controlled_by_other' ) ;
2016-11-21 18:03:02 +03:00
} ) ;