Skip to content

Commit 08e3392

Browse files
0.6.0b2
- add popup with button for adding and removing sites from the whitelist - misc bugfixes and streamlining
1 parent 9fbe5b6 commit 08e3392

File tree

8 files changed

+113
-47
lines changed

8 files changed

+113
-47
lines changed

src/bg/classes.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
class Settings {
22
constructor() {
3+
this.ignored = {}; // hostname:unixTimeStamp pairs
34
this.defaults = {
4-
'ignored': {}, // hostname:unixTimeStamp pairs
5-
'ignorePeriod': 7 //-1 = permanent, 0 = session-only, 1+ = X days
5+
'ignorePeriod': 7, //-1 = permanent, 0 = session-only, 1+ = X days
6+
'whitelist': {}
67
};
78
this.loading = (async () => {
8-
let saved = await browser.storage.local.get(this.defaults);
9+
const data = browser.storage.local;
10+
let saved = await data.get(this.defaults);
911
this.all = saved;
10-
await browser.storage.local.set(saved);
12+
await data.set(saved);
13+
if (this.ignorePeriod) data.get().then(r => {
14+
this.ignored = r.ignored;
15+
});
1116
browser.storage.onChanged.addListener((changes, area) => {
1217
console.debug(`HTTPZ: ${area} storage changed`);
1318
for (const i in changes) {
1419
if (changes[i].hasOwnProperty('newValue')) this[i] = changes[i].newValue;
1520
else if (changes[i].hasOwnProperty('oldValue')) delete this[i];
1621
}
22+
if (changes.ignorePeriod) data.set({ignored: this.ignored});
1723
});
1824
console.log('HTTPZ: settings loaded');
1925
delete this.loading;
@@ -30,11 +36,6 @@ class Settings {
3036
set all(obj) {
3137
for (const i in obj) this[i] = obj[i];
3238
}
33-
save() {
34-
this.all.then(r => {
35-
browser.storage.local.set(r);
36-
});
37-
}
3839
}
3940

4041
class DelayableAction {

src/bg/runtime.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1+
const wlSaver = new DelayableAction(10, 60, () => {
2+
browser.storage.local.set({whitelist: settings.whitelist});
3+
});
14
browser.runtime.onMessage.addListener((msg, sender, sendResponse) => {
2-
// triggered by options page script
3-
return settings.all;
5+
if (msg === 'options') return settings.all; // triggered by options page script
6+
// triggered by popup script
7+
if (msg.value) {
8+
wlSaver.run();
9+
return (async () => {return settings.whitelist[msg.host] = true;})();
10+
} else if (msg.host) {
11+
wlSaver.run();
12+
return (async () => {return delete settings.whitelist[msg.host];})();
13+
}
414
});

src/bg/webRequest.js

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ const processed = new Set();
44
const stackCleaner = new DelayableAction(60, 120, () => {
55
processed.clear();
66
});
7-
const saver = new DelayableAction(10, 60, () => {
8-
settings.save();
7+
const ignoredSaver = new DelayableAction(10, 60, () => {
8+
if (settings.ignorePeriod) browser.storage.local.set({ignored: settings.ignored});
99
});
10-
const filter = {urls: ["https://*/*"], types: ['main_frame']};
10+
const filter = {urls: ["http://*/*"], types: ['main_frame']};
11+
const sfilter = {urls: ["https://*/*"], types: ['main_frame']};
1112
const error_rx = /^SEC_ERROR|(?:_|\b)(?:SSL|TLS|CERT)(?:_|\b)|\b[Cc]ertificate/;
1213
const other_errors = new Set([
1314
'MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED',
@@ -22,7 +23,7 @@ const other_errors = new Set([
2223
function ignore(host) {
2324
if (!settings.ignored[host]) {
2425
settings.ignored[host] = Date.now();
25-
if (settings.ignorePeriod) saver.run();
26+
if (settings.ignorePeriod) ignoredSaver.run();
2627
}
2728
}
2829

@@ -51,6 +52,7 @@ browser.webRequest.onBeforeRequest.addListener(d => {
5152
}
5253
if (
5354
!settings.ignored[url.hostname] &&
55+
!settings.whitelist[url.hostname] &&
5456
url.hostname !== 'localhost' &&
5557
url.hostname !== 'loopback' &&
5658
!/^127\.\d+\.\d+\.\d+$/.test(url.hostname)
@@ -60,7 +62,7 @@ browser.webRequest.onBeforeRequest.addListener(d => {
6062
url.protocol = 'https:';
6163
return {redirectUrl: url.toString()}
6264
}
63-
}, {urls: ["http://*/*"], types: ['main_frame']}, ['blocking']);
65+
}, filter, ['blocking']);
6466

6567
browser.webRequest.onBeforeRedirect.addListener(d => {
6668
const url = new URL(d.url);
@@ -71,12 +73,18 @@ browser.webRequest.onBeforeRedirect.addListener(d => {
7173
processed.add(newTarget.hostname);
7274
stackCleaner.run();
7375
}
74-
}, filter);
76+
}, sfilter);
7577

7678
browser.webRequest.onCompleted.addListener(d => {
7779
const url = new URL(d.url);
78-
if ( d.statusCode >= 400 && processed.has(url.hostname)
79-
&& !settings.ignored[url.hostname] ) downgrade(url, d);
80+
if (!processed.has(url.hostname)) return;
81+
if ( d.statusCode >= 400 && !settings.ignored[url.hostname] ) downgrade(url, d);
82+
else browser.pageAction.show(d.tabId);
83+
}, sfilter);
84+
85+
browser.webRequest.onCompleted.addListener(d => {
86+
const url = new URL(d.url);
87+
if (settings.whitelist[url.hostname]) browser.pageAction.show(d.tabId);
8088
}, filter);
8189

8290
browser.webRequest.onErrorOccurred.addListener(d => {
@@ -85,4 +93,4 @@ browser.webRequest.onErrorOccurred.addListener(d => {
8593
( error_rx.test(d.error) || other_errors.has(d.error) )
8694
) downgrade(url, d);
8795
else console.info(`Error info: ${d.error}`);
88-
}, filter);
96+
}, sfilter);

src/manifest.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,18 @@
2323
"browser_style": true,
2424
"page": "pages/options.htm"
2525
},
26+
"page_action": {
27+
"browser_style": true,
28+
"default_icon": {"64": "assets/httpz.svg"},
29+
"default_popup": "pages/popup.htm",
30+
"default_title": "HTTPZ"
31+
},
2632
"permissions": [
2733
"storage",
34+
"tabs",
2835
"webRequest",
2936
"webRequestBlocking",
3037
"<all_urls>"
3138
],
32-
"version": "0.6.0b"
39+
"version": "0.6.0b2"
3340
}

src/pages/options.js

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,6 @@
11
'use strict';
22

3-
var settings;
4-
5-
const ui = (() => {
6-
const dom = document.getElementsByTagName('*');
7-
return new Proxy(dom, {
8-
get: function(obj, prop) {
9-
return obj[prop];
10-
},
11-
set: function(obj, prop, val) {
12-
obj[prop].value = val;
13-
return true;
14-
}
15-
});
16-
})();
3+
const ui = document.getElementsByTagName('*');
174

185
function setStatus(msg, type) {
196
ui.status.textContent = msg;
@@ -23,8 +10,7 @@ function setStatus(msg, type) {
2310
}, 2500);
2411
}
2512

26-
browser.runtime.sendMessage(true).then(msg => {
27-
settings = msg;
13+
browser.runtime.sendMessage('options').then(msg => {
2814
ui.session.checked = !msg.ignorePeriod;
2915
ui.xdays.checked = msg.ignorePeriod > 0;
3016
ui.days.disabled = !ui.xdays.checked;
@@ -33,31 +19,31 @@ browser.runtime.sendMessage(true).then(msg => {
3319
const changePeriod = e => {
3420
ui.days.disabled = !ui.xdays.checked;
3521
if (ui.xdays.checked) {
36-
ui.days.value = settings.ignorePeriod > 0 ? settings.ignorePeriod : 1;
22+
ui.days.value = msg.ignorePeriod > 0 ? msg.ignorePeriod : 1;
3723
}
3824
};
3925
ui.session.onchange = changePeriod;
4026
ui.xdays.onchange = changePeriod;
4127
ui.permanent.onchange = changePeriod;
4228
ui.clear.onclick = e => {
43-
browser.storage.local.set({ignored: {}}).then(() => {;
29+
browser.storage.local.set({ignored: {}}).then(() => {
4430
setStatus('List of sites cleared', '');
4531
});
4632
};
4733
ui.save.onclick = e => {
48-
if (ui.session.checked) {
49-
settings.ignorePeriod = 0;
50-
settings.ignored = {};
51-
} else if (ui.xdays.checked) {
34+
const changes = Object.assign({}, msg);
35+
if (ui.xdays.checked) {
5236
if (!/^\d+$/.test(ui.days.value.toString())) {
5337
setStatus('Invalid input', 'error');
5438
return;
5539
}
56-
settings.ignorePeriod = +ui.days.value;
57-
} else settings.ignorePeriod = -1;
40+
changes.ignorePeriod = +ui.days.value;
41+
} else if (ui.session.checked) {
42+
changes.ignorePeriod = 0;
43+
changes.ignored = {};
44+
} else changes.ignorePeriod = -1;
5845
setStatus('. . .', '');
59-
browser.storage.local.set(settings)
60-
.then(() => {
46+
browser.storage.local.set(changes).then(() => {
6147
setStatus('Saved!', 'saved');
6248
});
6349
};

src/pages/popup.css

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
* {
2+
box-sizing: border-box;
3+
text-align: center;
4+
}
5+
body {
6+
display: table;
7+
padding: 2em;
8+
width: 30em;
9+
}
10+
p { font-weight: 100; }
11+
button { margin-left: 0.25em; }

src/pages/popup.htm

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<link href="popup.css" rel="stylesheet">
6+
</head>
7+
<body>
8+
<p id="info"></p>
9+
<button class="browser-style" id="whitelist"></button>
10+
<script src="popup.js"></script>
11+
</body>
12+
</html>

src/pages/popup.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'use strict';
2+
3+
const ui = document.getElementsByTagName('*');
4+
5+
browser.tabs.query({active: true, currentWindow: true}).then(tabs => {
6+
const tab = tabs[0];
7+
const url = new URL(tab.url);
8+
if (url.protocol === 'https:') {
9+
ui.info.textContent = `${url.hostname} was automatically redirected to HTTPS. Click the button below to whitelist this site and reload the tab in HTTP.`;
10+
ui.whitelist.textContent = 'whitelist';
11+
ui.whitelist.onclick = e => {
12+
ui.whitelist.disabled = true;
13+
browser.runtime.sendMessage({host: url.hostname, value: true}).then(() => {
14+
url.protocol = 'http:';
15+
browser.tabs.update(
16+
tab.id,
17+
{ loadReplace: true, url: url.toString() }
18+
);
19+
});
20+
};
21+
} else {
22+
ui.info.textContent = `HTTPZ did not try to redirect ${url.hostname} to HTTPS because it is in the whitelist. Click the button below to remove this site from the whitelist and attempt to reload the tab in HTTPS.`;
23+
ui.whitelist.textContent = 'remove from whitelist';
24+
ui.whitelist.onclick = e => {
25+
ui.whitelist.disabled = true;
26+
browser.runtime.sendMessage({host: url.hostname, value: false}).then(() => {
27+
browser.tabs.reload(tab.id);
28+
});
29+
};
30+
}
31+
});

0 commit comments

Comments
 (0)