mirror of
https://github.com/anticensority/runet-censorship-bypass.git
synced 2024-11-24 02:13:43 +03:00
Handle update errors in popup, add ip lookup method, fix rollbacks (change API)
This commit is contained in:
parent
aa20f220ee
commit
9ef8939127
|
@ -49,15 +49,41 @@
|
||||||
|
|
||||||
_currentPacProviderKey: 'Оба_и_на_свитчах',
|
_currentPacProviderKey: 'Оба_и_на_свитчах',
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
get currentPacProviderKey() { return this._currentPacProviderKey },
|
get currentPacProviderKey() { return this._currentPacProviderKey },
|
||||||
set currentPacProviderKey(newKey) {
|
set currentPacProviderKey(newKey) {
|
||||||
|
|
||||||
if (newKey && !this.pacProviders[newKey])
|
this.mustBeKey(newKey);
|
||||||
throw new IllegalArgumentException('No provider for key:' + newKey);
|
|
||||||
this._currentPacProviderKey = newKey;
|
this._currentPacProviderKey = newKey;
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
get pacProvider() { return this.pacProviders[this.currentPacProviderKey] },
|
getPacProvider(key) {
|
||||||
|
|
||||||
|
if(key) {
|
||||||
|
this.mustBeKey(key);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
key = this.currentPacProviderKey;
|
||||||
|
}
|
||||||
|
return this.pacProviders[key];
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Is it the first time extension installed? Do something, e.g. initiate PAC sync.
|
Is it the first time extension installed? Do something, e.g. initiate PAC sync.
|
||||||
|
@ -106,19 +132,28 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
syncWithPacProvider(cb) {
|
syncWithPacProvider(key, cb) {
|
||||||
|
|
||||||
cb = asyncLogGroup('Syncing with PAC provider...', cb);
|
if( !key || typeof(key) === 'function' ) {
|
||||||
if (!this.pacProvider) {
|
cb = key;
|
||||||
|
key = this.currentPacProviderKey;
|
||||||
|
}
|
||||||
|
cb = asyncLogGroup('Syncing with PAC provider ' + key + '...', cb);
|
||||||
|
|
||||||
|
if (key === null) {
|
||||||
|
// No pac provider set.
|
||||||
return cb({clarification:{message:'Сперва выберите PAC-провайдера.'}});
|
return cb({clarification:{message:'Сперва выберите PAC-провайдера.'}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pacProvider = this.getPacProvider(key);
|
||||||
|
|
||||||
const pacSetPromise = new Promise(
|
const pacSetPromise = new Promise(
|
||||||
(resolve, reject) => setPacScriptFromProvider(
|
(resolve, reject) => setPacScriptFromProvider(
|
||||||
this.pacProvider,
|
pacProvider,
|
||||||
(err, res) => {
|
(err, res) => {
|
||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
|
this.currentPacProviderKey = key;
|
||||||
this.lastPacUpdateStamp = Date.now();
|
this.lastPacUpdateStamp = Date.now();
|
||||||
this.ifFirstInstall = false;
|
this.ifFirstInstall = false;
|
||||||
this.setAlarms();
|
this.setAlarms();
|
||||||
|
@ -132,7 +167,7 @@
|
||||||
|
|
||||||
const ipsPromise = new Promise(
|
const ipsPromise = new Promise(
|
||||||
(resolve, reject) => updatePacProxyIps(
|
(resolve, reject) => updatePacProxyIps(
|
||||||
this.pacProvider,
|
pacProvider,
|
||||||
(ipsError) => {
|
(ipsError) => {
|
||||||
|
|
||||||
if (ipsError && ipsError.clarification) {
|
if (ipsError && ipsError.clarification) {
|
||||||
|
@ -186,28 +221,15 @@
|
||||||
|
|
||||||
installPac(key, cb) {
|
installPac(key, cb) {
|
||||||
|
|
||||||
console.log('Installing PAC');
|
console.log('Installing PAC...');
|
||||||
if(typeof(key) === 'function') {
|
if (!key) {
|
||||||
cb = key;
|
throw new Error('Key must be defined.');
|
||||||
key = undefined;
|
|
||||||
}
|
}
|
||||||
|
if (this.currentProviderKey !== key) {
|
||||||
const oldKey = this.currentPacProviderKey;
|
return this.syncWithPacProvider(key, cb);
|
||||||
if(key || key !== oldKey) {
|
|
||||||
this.currentPacProviderKey = key;
|
|
||||||
const _cb = cb;
|
|
||||||
cb = (err, res) => {
|
|
||||||
|
|
||||||
if (err && !(err.clarification && err.clarification.ifNotCritical)) {
|
|
||||||
console.log('Rollback privider key.');
|
|
||||||
this.currentPacProviderKey = oldKey;
|
|
||||||
}
|
}
|
||||||
_cb(err, res);
|
console.log(key + ' already installed.');
|
||||||
|
cb();
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
this.syncWithPacProvider(cb);
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -223,7 +245,7 @@
|
||||||
if (err) {
|
if (err) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
}
|
}
|
||||||
this.currentPacProviderKey = undefined;
|
this.currentPacProviderKey = null;
|
||||||
this.pushToStorage(cb);
|
this.pushToStorage(cb);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -236,16 +258,12 @@
|
||||||
// ON EACH LAUNCH, STARTUP, RELOAD, UPDATE, ENABLE
|
// ON EACH LAUNCH, STARTUP, RELOAD, UPDATE, ENABLE
|
||||||
chrome.storage.local.get(null, (oldStorage) => {
|
chrome.storage.local.get(null, (oldStorage) => {
|
||||||
|
|
||||||
console.log('Init on storage:', oldStorage);
|
checkChromeError();
|
||||||
antiCensorRu.ifFirstInstall = Object.keys(oldStorage).length === 0;
|
/*
|
||||||
|
Event handlers that ALWAYS work (even if installation is not done or failed).
|
||||||
if (!antiCensorRu.ifFirstInstall) {
|
E.g. install window may fail to open or be closed by user accidentally.
|
||||||
// LAUNCH, RELOAD, UPDATE
|
In such case extension _should_ try to work on default parameters.
|
||||||
antiCensorRu._currentPacProviderKey = oldStorage._currentPacProviderKey;
|
*/
|
||||||
antiCensorRu.lastPacUpdateStamp = oldStorage.lastPacUpdateStamp || antiCensorRu.lastPacUpdateStamp;
|
|
||||||
console.log( 'Last PAC update was on', new Date(antiCensorRu.lastPacUpdateStamp).toLocaleString('ru-RU') );
|
|
||||||
}
|
|
||||||
|
|
||||||
chrome.alarms.onAlarm.addListener(
|
chrome.alarms.onAlarm.addListener(
|
||||||
(alarm) => {
|
(alarm) => {
|
||||||
|
|
||||||
|
@ -265,19 +283,28 @@
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (antiCensorRu.ifFirstInstall) {
|
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 {
|
||||||
// INSTALL
|
// INSTALL
|
||||||
console.log('Installing...');
|
console.log('Installing...');
|
||||||
chrome.runtime.openOptionsPage();
|
return chrome.runtime.openOptionsPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!antiCensorRu.pacProvider) {
|
if (!antiCensorRu.getPacProvider()) {
|
||||||
return console.log('No PAC provider set. Do nothing.');
|
|
||||||
/*
|
/*
|
||||||
In case of UPDATE:
|
In case of UPDATE:
|
||||||
1. new providers will still be shown.
|
1. new providers will still be shown.
|
||||||
2. new version won't be pushed to storage
|
2. new version won't be pushed to storage
|
||||||
*/
|
*/
|
||||||
|
return console.log('No PAC provider set. Do nothing.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -52,29 +52,6 @@ window.tabWithError2ip = {}; // For errors only: Error? -> Check this IP!
|
||||||
|
|
||||||
chrome.tabs.onRemoved.addListener( (tabId) => { onTabUpdate(tabId); delete window.tabWithError2ip[tabId] } );
|
chrome.tabs.onRemoved.addListener( (tabId) => { onTabUpdate(tabId); delete window.tabWithError2ip[tabId] } );
|
||||||
|
|
||||||
let previousUpdateTitleFinished = Promise.resolve();
|
|
||||||
|
|
||||||
function isProxiedAndInformed(requestDetails) {
|
|
||||||
|
|
||||||
if (
|
|
||||||
!( window.antiCensorRu.pacProvider && window.antiCensorRu.pacProvider.proxyIps && window.antiCensorRu.pacProvider.proxyIps[ requestDetails.ip ] )
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ifMainFrame = requestDetails.type === 'main_frame';
|
|
||||||
|
|
||||||
previousUpdateTitleFinished = previousUpdateTitleFinished.then(
|
|
||||||
() => new Promise(
|
|
||||||
(resolve) => {
|
|
||||||
const cb = () => updateTitle( requestDetails, resolve );
|
|
||||||
return ifMainFrame ? afterTabUpdated(requestDetails.tabId, cb) : cb();
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
function updateTitle(requestDetails, cb) {
|
function updateTitle(requestDetails, cb) {
|
||||||
|
|
||||||
chrome.browserAction.getTitle(
|
chrome.browserAction.getTitle(
|
||||||
|
@ -82,7 +59,7 @@ window.tabWithError2ip = {}; // For errors only: Error? -> Check this IP!
|
||||||
(title) => {
|
(title) => {
|
||||||
|
|
||||||
const ifTitleSetAlready = /\n/.test(title);
|
const ifTitleSetAlready = /\n/.test(title);
|
||||||
const proxyHost = window.antiCensorRu.pacProvider.proxyIps[ requestDetails.ip ];
|
const proxyHost = window.antiCensorRu.getPacProvider().proxyIps[ requestDetails.ip ];
|
||||||
|
|
||||||
const hostname = new URL( requestDetails.url ).hostname;
|
const hostname = new URL( requestDetails.url ).hostname;
|
||||||
|
|
||||||
|
@ -96,7 +73,7 @@ window.tabWithError2ip = {}; // For errors only: Error? -> Check this IP!
|
||||||
|
|
||||||
chrome.browserAction.setBadgeText({
|
chrome.browserAction.setBadgeText({
|
||||||
tabId: requestDetails.tabId,
|
tabId: requestDetails.tabId,
|
||||||
text: ifMainFrame ? '1' : '%1'
|
text: requestDetails.type === 'main_frame' ? '1' : '%1'
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -143,6 +120,28 @@ window.tabWithError2ip = {}; // For errors only: Error? -> Check this IP!
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let previousUpdateTitleFinished = Promise.resolve();
|
||||||
|
|
||||||
|
function isProxiedAndInformed(requestDetails) {
|
||||||
|
|
||||||
|
if ( !(requestDetails.ip && antiCensorRu.isProxied( requestDetails.ip )) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ifMainFrame = requestDetails.type === 'main_frame';
|
||||||
|
|
||||||
|
previousUpdateTitleFinished = previousUpdateTitleFinished.then(
|
||||||
|
() => new Promise(
|
||||||
|
(resolve) => {
|
||||||
|
const cb = () => updateTitle( requestDetails, resolve );
|
||||||
|
return ifMainFrame ? afterTabUpdated(requestDetails.tabId, cb) : cb();
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
chrome.webRequest.onResponseStarted.addListener(
|
chrome.webRequest.onResponseStarted.addListener(
|
||||||
|
|
|
@ -9,9 +9,10 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
li {
|
li, footer {
|
||||||
display: block;
|
display: block;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
word-break: keep-all;
|
||||||
}
|
}
|
||||||
li > * {
|
li > * {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
@ -49,8 +50,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="status">Загрузка...</div>
|
<div id="status">Загрузка...</div>
|
||||||
<footer>
|
<footer>
|
||||||
<input type="button" value="Готово" class="close-button">
|
<input type="button" value="Готово" class="close-button"> <a href="../debug/index.html" style="text-decoration: none; margin-left: 1em;">Отладка</a>
|
||||||
<a href="../debug/index.html" style="float: right; text-decoration: none">Отладка</a>
|
|
||||||
</footer>
|
</footer>
|
||||||
<script src="./index.js"></script>
|
<script src="./index.js"></script>
|
||||||
<script src="./keep-links-clickable.js"></script>
|
<script src="./keep-links-clickable.js"></script>
|
||||||
|
|
|
@ -61,66 +61,29 @@ chrome.runtime.getBackgroundPage( (backgroundPage) => {
|
||||||
|
|
||||||
// RADIOS
|
// RADIOS
|
||||||
|
|
||||||
const currentRadio = () => {
|
const currentProviderRadio = () => {
|
||||||
|
|
||||||
const id = antiCensorRu.currentPacProviderKey || 'none';
|
const id = antiCensorRu.currentPacProviderKey || 'none';
|
||||||
return document.querySelector('#'+id);
|
return document.querySelector('#'+id);
|
||||||
|
|
||||||
}
|
}
|
||||||
const checkChosenProvider = () => currentRadio().checked = true;
|
const checkChosenProvider = () => currentProviderRadio().checked = true;
|
||||||
const triggerChosenProvider = () => currentRadio().click();
|
|
||||||
|
|
||||||
const ul = document.querySelector('#list-of-providers');
|
const showError = (err) => {
|
||||||
const _firstChild = ul.firstChild;
|
|
||||||
for( const providerKey of Object.keys(antiCensorRu.pacProviders).sort() ) {
|
|
||||||
const li = document.createElement('li');
|
|
||||||
li.innerHTML = '<input type="radio" name="pacProvider" id="' + providerKey + '"> <label for="' + providerKey + '">'+providerKey + '</label> <a href class="link-button checked-radio-panel">[обновить]</a>';
|
|
||||||
li.querySelector('.link-button').onclick = () => { triggerChosenProvider(); return false; };
|
|
||||||
ul.insertBefore( li, _firstChild );
|
|
||||||
}
|
|
||||||
|
|
||||||
const radios = [].slice.apply( document.querySelectorAll('[name=pacProvider]') );
|
|
||||||
for(const radio of radios) {
|
|
||||||
radio.onclick = function(event) {
|
|
||||||
|
|
||||||
const pacKey = event.target.id;
|
|
||||||
if (pacKey === 'none') {
|
|
||||||
return antiCensorRu.clearPac();
|
|
||||||
}
|
|
||||||
|
|
||||||
const enableDisableInputs = function () {
|
|
||||||
|
|
||||||
const inputs = document.querySelectorAll('input');
|
|
||||||
for ( let i = 0; i < inputs.length; i++ ) {
|
|
||||||
inputs[i].disabled = !inputs[i].disabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
enableDisableInputs();
|
|
||||||
setStatusTo('Установка...');
|
|
||||||
antiCensorRu.installPac(pacKey, (err) => {
|
|
||||||
|
|
||||||
backgroundPage.console.log('Popup callback...');
|
|
||||||
if (!err) {
|
|
||||||
setStatusTo('PAC-скрипт установлен.');
|
|
||||||
checkChosenProvider();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const ifNotCritical = err.clarification && err.clarification.ifNotCritical;
|
|
||||||
|
|
||||||
let message = '';
|
|
||||||
let clarification = err.clarification;
|
let clarification = err.clarification;
|
||||||
do {
|
const ifNotCritical = clarification && clarification.ifNotCritical;
|
||||||
message = message +' '+ (clarification && clarification.message || err.message || '');
|
let message = err.message || '';
|
||||||
clarification = clarification && clarification.prev;
|
|
||||||
} while( clarification );
|
while( clarification ) {
|
||||||
|
message = (clarification && (clarification.message + ' ')) + message;
|
||||||
|
clarification = clarification.prev;
|
||||||
|
}
|
||||||
message = message.trim();
|
message = message.trim();
|
||||||
setStatusTo(
|
setStatusTo(
|
||||||
`<span style="color:red">${ifNotCritical ? 'Некритичная ошибка.' : 'Ошибка!'}</span>
|
`<span style="color:red">${ifNotCritical ? 'Некритичная ошибка.' : 'Ошибка!'}</span>
|
||||||
<br/>
|
<br/>
|
||||||
<span style="font-size: 0.9em; color: darkred">${message}</span>
|
<span style="font-size: 0.9em; color: darkred">${message}</span>
|
||||||
<button>Сообщить автору</button><br/>
|
|
||||||
<a href class="link-button">[Ещё подробнее]</a>`
|
<a href class="link-button">[Ещё подробнее]</a>`
|
||||||
);
|
);
|
||||||
getStatus().querySelector('.link-button').onclick = function() {
|
getStatus().querySelector('.link-button').onclick = function() {
|
||||||
|
@ -136,17 +99,76 @@ chrome.runtime.getBackgroundPage( (backgroundPage) => {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const enableDisableInputs = function () {
|
||||||
|
|
||||||
|
const inputs = document.querySelectorAll('input');
|
||||||
|
for ( let i = 0; i < inputs.length; i++ ) {
|
||||||
|
inputs[i].disabled = !inputs[i].disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const conduct = (beforeStatus, operation, afterStatus, onSuccess) => {
|
||||||
|
|
||||||
|
setStatusTo(beforeStatus);
|
||||||
|
enableDisableInputs();
|
||||||
|
operation((err) => {
|
||||||
|
if (err) {
|
||||||
|
showError(err);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setStatusTo(afterStatus);
|
||||||
|
onSuccess && onSuccess();
|
||||||
}
|
}
|
||||||
enableDisableInputs();
|
enableDisableInputs();
|
||||||
});
|
})
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const ul = document.querySelector('#list-of-providers');
|
||||||
|
const _firstChild = ul.firstChild;
|
||||||
|
for( const providerKey of Object.keys(antiCensorRu.pacProviders).sort() ) {
|
||||||
|
const li = document.createElement('li');
|
||||||
|
li.innerHTML = `<input type="radio" name="pacProvider" id="${providerKey}"> <label for="${providerKey}">${providerKey}</label> <a href class="link-button checked-radio-panel">[обновить]</a>`;
|
||||||
|
li.querySelector('.link-button').onclick = () => { conduct( 'Обновляем...', (cb) => antiCensorRu.syncWithPacProvider(cb), 'Обновлено.' ); return false; };
|
||||||
|
ul.insertBefore( li, _firstChild );
|
||||||
|
}
|
||||||
|
checkChosenProvider();
|
||||||
|
|
||||||
|
const radios = [].slice.apply( document.querySelectorAll('[name=pacProvider]') );
|
||||||
|
for(const radio of radios) {
|
||||||
|
radio.onclick = function(event) {
|
||||||
|
|
||||||
|
if (event.target.id === (antiCensorRu.currentPacProviderKey || 'none')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
const pacKey = event.target.id;
|
||||||
|
if (pacKey === 'none') {
|
||||||
|
conduct(
|
||||||
|
'Отключение...',
|
||||||
|
(cb) => antiCensorRu.clearPac(cb),
|
||||||
|
'Отключено.',
|
||||||
|
checkChosenProvider
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
conduct(
|
||||||
|
'Установка...',
|
||||||
|
(cb) => antiCensorRu.installPac(pacKey, cb),
|
||||||
|
'PAC-скрипт установлен.',
|
||||||
|
checkChosenProvider
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
setStatusTo('');
|
setStatusTo('');
|
||||||
checkChosenProvider();
|
|
||||||
if (antiCensorRu.ifFirstInstall) {
|
if (antiCensorRu.ifFirstInstall) {
|
||||||
triggerChosenProvider();
|
currentProviderRadio().click();
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user