[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [pluggable-transports/snowflake-webext] 05/08: improvement: revoke 'background' permission when "Enabled" is off
This is an automated email from the git hooks/post-receive script.
shelikhoo pushed a commit to branch main
in repository pluggable-transports/snowflake-webext.
commit 18a95215421d1d912cf945d97239a90083a765ae
Author: WofWca <wofwca@xxxxxxxxxxxxxx>
AuthorDate: Tue Jun 21 22:46:45 2022 +0300
improvement: revoke 'background' permission when "Enabled" is off
---
init-webext.js | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
make.js | 9 ++++---
static/popup.js | 42 ++++++++++++++++++---------------
webext/embed.js | 11 ++++++++-
4 files changed, 104 insertions(+), 31 deletions(-)
diff --git a/init-webext.js b/init-webext.js
index cde7d5f..003fb7f 100644
--- a/init-webext.js
+++ b/init-webext.js
@@ -5,6 +5,40 @@
UI
*/
+
+/**
+ * Decide whether we need to request or revoke the 'background' permission, and
+ * set the `runInBackground` storage value appropriately.
+ * @param {boolean | undefined} enabledSetting
+ * @param {boolean | undefined} runInBackgroundSetting
+ */
+function maybeChangeBackgroundPermission(enabledSetting, runInBackgroundSetting) {
+ const needBackgroundPermission =
+ runInBackgroundSetting
+ // When the extension is disabled, we need the permission to be revoked because
+ // otherwise it'll keep the browser process running for no reason.
+ && enabledSetting;
+ // Yes, this is called even if the permission is already in the state we need
+ // it to be in (granted/removed).
+ new Promise(r => {
+ chrome.permissions[needBackgroundPermission ? "request" : "remove"](
+ { permissions: ['background'] },
+ r
+ );
+ })
+ .then(success => {
+ // Currently the resolve value is `true` even when the permission was alrady granted
+ // before it was requested (already removed before it was revoked). TODO Need to make
+ // sure it's the desired behavior and if it needs to change.
+ // https://developer.chrome.com/docs/extensions/reference/permissions/#method-remove
+ // https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/permissions/remove#return_value
+ // https://github.com/mdn/content/pull/17516
+ if (success) {
+ chrome.storage.local.set({ runInBackground: runInBackgroundSetting });
+ }
+ });
+}
+
class WebExtUI extends UI {
constructor() {
@@ -94,15 +128,38 @@ class WebExtUI extends UI {
if (m.retry) {
// FIXME: Can set a retrying state here
this.tryProbe();
- return;
+ } else if (m.enabled != undefined) {
+ (new Promise((resolve) => {
+ chrome.storage.local.set({ "snowflake-enabled": m.enabled }, resolve);
+ }))
+ .then(() => {
+ log("Stored toggle state");
+ this.initToggle();
+ });
+ if (
+ typeof SUPPORTS_WEBEXT_OPTIONAL_BACKGROUND_PERMISSION !== 'undefined'
+ // eslint-disable-next-line no-undef
+ && SUPPORTS_WEBEXT_OPTIONAL_BACKGROUND_PERMISSION
+ ) {
+ new Promise(r => chrome.storage.local.get({ runInBackground: false }, r))
+ .then(storage => {
+ maybeChangeBackgroundPermission(m.enabled, storage.runInBackground);
+ });
+ }
+ } else if (m.runInBackground != undefined) {
+ if (
+ typeof SUPPORTS_WEBEXT_OPTIONAL_BACKGROUND_PERMISSION !== 'undefined'
+ // eslint-disable-next-line no-undef
+ && SUPPORTS_WEBEXT_OPTIONAL_BACKGROUND_PERMISSION
+ ) {
+ new Promise(r => chrome.storage.local.get({ "snowflake-enabled": false }, r))
+ .then(storage => {
+ maybeChangeBackgroundPermission(storage["snowflake-enabled"], m.runInBackground);
+ });
+ }
+ } else {
+ log("Unrecognized message");
}
- (new Promise((resolve) => {
- chrome.storage.local.set({ "snowflake-enabled": m.enabled }, resolve);
- }))
- .then(() => {
- log("Stored toggle state");
- this.initToggle();
- });
}
onDisconnect() {
diff --git a/make.js b/make.js
index 63e4cb6..6116257 100755
--- a/make.js
+++ b/make.js
@@ -174,9 +174,6 @@ function buildWebext(browserEngine) {
execSync(`rm -rf ${outDir} && mkdir ${outDir}`);
execSync(`cp -r webext/. ${outDir}/`);
execSync(`cp -r ${STATIC}/{${SHARED_FILES.join(',')}} ${outDir}/`, { shell: '/bin/bash' });
- for (const [key, value] of Object.entries(definitions)) {
- execSync(`sed -i "s/${key}/${value}/g" ${outDir}/popup.js`);
- }
{
const manfestBasePath = `${outDir}/manifest_base.json`;
const manifest = JSON.parse(readFileSync(manfestBasePath, 'utf-8'));
@@ -192,6 +189,12 @@ function buildWebext(browserEngine) {
}
copyTranslations(outDir);
concatJS(outDir, 'webext', 'snowflake.js', '');
+ for (const [key, value] of Object.entries(definitions)) {
+ const commandStart = `sed -i "s/${key}/${value}/g" ${outDir}`;
+ execSync(`${commandStart}/popup.js`);
+ execSync(`${commandStart}/embed.js`);
+ execSync(`${commandStart}/snowflake.js`);
+ }
console.log('Webextension prepared.');
}
task('webext', 'build the webextension', function() {
diff --git a/static/popup.js b/static/popup.js
index fc4c0e7..fa7b8ed 100644
--- a/static/popup.js
+++ b/static/popup.js
@@ -11,7 +11,10 @@ function setClass(elem, className, cond) {
}
class Popup {
- constructor(getMsgFunc, changeFunc, retryFunc) {
+ /**
+ * @param {() => void} [onRunInBackgroundChange]
+ */
+ constructor(getMsgFunc, changeFunc, retryFunc, onRunInBackgroundChange) {
this.getMsgFunc = getMsgFunc;
this.enabled = document.getElementById('enabled');
this.enabled.addEventListener('change', changeFunc);
@@ -34,26 +37,27 @@ class Popup {
/** @type {HTMLInputElement} */
const runInBackgroundInput = document.getElementById('run-in-background');
document.getElementById('run-in-background-wrapper').classList.remove('display-none');
- {
- // Two-way bind the input to the permission.
- new Promise(r => chrome.permissions.contains({ permissions: ['background'] }, r))
- .then(contains => runInBackgroundInput.checked = contains);
- chrome.permissions.onAdded.addListener(({ permissions }) => {
- if (permissions.includes('background')) {
- runInBackgroundInput.checked = true;
- }
+ { // Two-way bind the input to the permission.
+ runInBackgroundInput.addEventListener('change', ({ target }) => {
+ onRunInBackgroundChange(target.checked);
+ // The permission request may be rejected, so only update the checkbox value inside
+ // the event listeners below. TODO Don't know if it's ok in terms of accessibility.
+ // Also maybe it's better looking in general to toggle the checkbox and toggle it back
+ // if the request is rejected.
+ target.checked = !target.checked;
});
- chrome.permissions.onRemoved.addListener(({ permissions }) => {
- if (permissions.includes('background')) {
- runInBackgroundInput.checked = false;
- }
+
+ // The storage is the source of truth for `runInBackground`, not
+ // `chrome.permissions.contains({ permissions: ['background'] }`, because when the "Enabled"
+ // checkbox is off, we (may) revoke that permission.
+ new Promise(r => chrome.storage.local.get({ runInBackground: false }, r))
+ .then(({ runInBackground }) => {
+ runInBackgroundInput.checked = runInBackground;
});
- runInBackgroundInput.addEventListener('change', event => {
- if (event.target.checked) {
- new Promise(r => chrome.permissions.request({ permissions: ['background'] }, r))
- .then(granted => event.target.checked = granted);
- } else {
- chrome.permissions.remove({ permissions: ['background'] });
+ chrome.storage.local.onChanged.addListener(changes => {
+ const runInBackgroundChange = changes.runInBackground;
+ if (runInBackgroundChange) {
+ runInBackgroundInput.checked = runInBackgroundChange.newValue;
}
});
}
diff --git a/webext/embed.js b/webext/embed.js
index b41d266..90dbe46 100644
--- a/webext/embed.js
+++ b/webext/embed.js
@@ -13,7 +13,16 @@ window.onload = () => {
const popup = new Popup(
(...args) => chrome.i18n.getMessage(...args),
(event) => port.postMessage({ enabled: event.target.checked }),
- () => port.postMessage({ retry: true })
+ () => port.postMessage({ retry: true }),
+ (
+ (
+ typeof SUPPORTS_WEBEXT_OPTIONAL_BACKGROUND_PERMISSION !== 'undefined'
+ // eslint-disable-next-line no-undef
+ && SUPPORTS_WEBEXT_OPTIONAL_BACKGROUND_PERMISSION
+ )
+ ? (newValue) => port.postMessage({ runInBackground: newValue })
+ : undefined
+ )
);
port.onMessage.addListener((m) => {
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits