From cc9c45f1e4739e3757d3b82a7690575c890ba1f5 Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Wed, 6 Jan 2021 11:39:24 -0500 Subject: [PATCH] Adding to and further reviewing admin-managed settings --- platform/chromium/managed_storage.json | 45 ++++++++++------- src/css/dashboard.css | 6 +++ src/dashboard.html | 3 +- src/js/background.js | 2 + src/js/dashboard.js | 59 +++++++++++++++------- src/js/messaging.js | 7 ++- src/js/storage.js | 68 ++++++++++++++++++-------- 7 files changed, 131 insertions(+), 59 deletions(-) diff --git a/platform/chromium/managed_storage.json b/platform/chromium/managed_storage.json index 71cefe284..cca1122c8 100644 --- a/platform/chromium/managed_storage.json +++ b/platform/chromium/managed_storage.json @@ -7,26 +7,24 @@ "description": "All entries present will overwrite local settings.", "type": "string" }, - "toSet": { - "title": "Settings to overwrite at launch time", - "type": "object", - "properties": { - "hiddenSettings": { - "title": "A list of [name,value] pairs to populate hidden settings", - "type": "array", - "items": { - "title": "A [name,value] pair", - "type": "array", - "items": { "type": "string" } - } - }, - "trustedSiteDirectives": { - "title": "A list of trusted-site directives", - "type": "array", - "items": { "type": "string" } - } + "advancedSettings": { + "title": "A list of [name,value] pairs to populate advanced settings", + "type": "array", + "items": { + "title": "A [name,value] pair", + "type": "array", + "items": { "type": "string" } } }, + "disableDashboard": { + "title": "Set to true to prevent access to configuration options", + "type": "boolean" + }, + "disabledPopupPanelParts": { + "title": "An array of strings used to remove parts of the popup panel", + "type": "array", + "items": { "type": "string" } + }, "toAdd": { "title": "Settings to add at launch time", "type": "object", @@ -38,6 +36,17 @@ "items": { "type": "string" } } } + }, + "toOverwrite": { + "title": "Settings to overwrite at launch time", + "type": "object", + "properties": { + "trustedSiteDirectives": { + "title": "A list of trusted-site directives", + "type": "array", + "items": { "type": "string" } + } + } } } } diff --git a/src/css/dashboard.css b/src/css/dashboard.css index a6933af6c..fa17451a7 100644 --- a/src/css/dashboard.css +++ b/src/css/dashboard.css @@ -72,6 +72,12 @@ iframe { body:not(.canUpdateShortcuts) .tabButton[data-pane="shortcuts.html"] { display: none; } +body .tabButton[data-pane="no-dashboard.html"] { + display: none; + } +body.noDashboard #dashboard-nav { + display: none; + } /* high dpi devices */ :root.hidpi .tabButton { diff --git a/src/dashboard.html b/src/dashboard.html index 0668cdf12..53ee2dae9 100644 --- a/src/dashboard.html +++ b/src/dashboard.html @@ -19,7 +19,8 @@ --> + -->
diff --git a/src/js/background.js b/src/js/background.js index f23ec0c4c..735e8af1e 100644 --- a/src/js/background.js +++ b/src/js/background.js @@ -111,6 +111,8 @@ const µBlock = (( ) => { // jshint ignore:line hiddenSettingsAdmin: {}, hiddenSettings: Object.assign({}, hiddenSettingsDefault), + noDashboard: false, + // Features detection. privacySettingsSupported: vAPI.browserSettings instanceof Object, cloudStorageSupported: vAPI.cloud instanceof Object, diff --git a/src/js/dashboard.js b/src/js/dashboard.js index 19f7a94a3..46dcadbef 100644 --- a/src/js/dashboard.js +++ b/src/js/dashboard.js @@ -84,7 +84,9 @@ const loadDashboardPanel = function(pane, first) { tabButton.classList.add('selected'); tabButton.scrollIntoView(); uDom.nodeFromId('iframe').setAttribute('src', pane); - vAPI.localStorage.setItem('dashboardLastVisitedPane', pane); + if ( pane !== 'no-dashboard.html' ) { + vAPI.localStorage.setItem('dashboardLastVisitedPane', pane); + } }; if ( first ) { return loadPane(); @@ -104,25 +106,48 @@ const onTabClickHandler = function(ev) { loadDashboardPanel(ev.target.getAttribute('data-pane')); }; -// https://github.com/uBlockOrigin/uBlock-issues/issues/106 -vAPI.messaging.send('dashboard', { - what: 'canUpdateShortcuts', -}).then(response => { - document.body.classList.toggle('canUpdateShortcuts', response === true); -}); +if ( self.location.hash.slice(1) === 'no-dashboard.html' ) { + document.body.classList.add('noDashboard'); +} -vAPI.localStorage.getItemAsync('dashboardLastVisitedPane').then(value => { - loadDashboardPanel(value !== null ? value : 'settings.html', true); +(async ( ) => { + const results = await Promise.all([ + // https://github.com/uBlockOrigin/uBlock-issues/issues/106 + vAPI.messaging.send('dashboard', { what: 'dashboardConfig' }), + vAPI.localStorage.getItemAsync('dashboardLastVisitedPane'), + ]); - uDom('.tabButton').on('click', onTabClickHandler); + { + const details = results[0]; + document.body.classList.toggle( + 'canUpdateShortcuts', + details.canUpdateShortcuts === true + ); + if ( details.noDashboard ) { + self.location.hash = '#no-dashboard.html'; + document.body.classList.add('noDashboard'); + } else if ( self.location.hash === '#no-dashboard.html' ) { + self.location.hash = ''; + } + } - // https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event - window.addEventListener('beforeunload', ( ) => { - if ( discardUnsavedData(true) ) { return; } - event.preventDefault(); - event.returnValue = ''; - }); -}); + { + let pane = results[1]; + if ( self.location.hash !== '' ) { + pane = self.location.hash.slice(1) || null; + } + loadDashboardPanel(pane !== null ? pane : 'settings.html', true); + + uDom('.tabButton').on('click', onTabClickHandler); + + // https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event + window.addEventListener('beforeunload', ( ) => { + if ( discardUnsavedData(true) ) { return; } + event.preventDefault(); + event.returnValue = ''; + }); + } +})(); /******************************************************************************/ diff --git a/src/js/messaging.js b/src/js/messaging.js index 693fa56fa..e107ace75 100644 --- a/src/js/messaging.js +++ b/src/js/messaging.js @@ -1214,8 +1214,11 @@ const onMessage = function(request, sender, callback) { let response; switch ( request.what ) { - case 'canUpdateShortcuts': - response = µb.canUpdateShortcuts; + case 'dashboardConfig': + response = { + canUpdateShortcuts: µb.canUpdateShortcuts, + noDashboard: µb.noDashboard, + }; break; case 'getAutoCompleteDetails': diff --git a/src/js/storage.js b/src/js/storage.js index 02a03c371..2b70d42fa 100644 --- a/src/js/storage.js +++ b/src/js/storage.js @@ -97,23 +97,49 @@ const hsUser = this.hiddenSettings; const results = await Promise.all([ - vAPI.adminStorage.get('toSet'), + vAPI.adminStorage.get([ + 'advancedSettings', + 'disableDashboard', + 'disabledPopupPanelParts', + ]), vAPI.storage.get('hiddenSettings'), ]); - if ( - results[0] instanceof Object && - Array.isArray(results[0].hiddenSettings) - ) { - for ( const entry of results[0].hiddenSettings ) { - if ( entry.length < 1 ) { continue; } - const name = entry[0]; - if ( hsDefault.hasOwnProperty(name) === false ) { continue; } - const value = entry.length < 2 - ? hsDefault[name] - : this.hiddenSettingValueFromString(name, entry[1]); - if ( value === undefined ) { continue; } - hsDefault[name] = hsAdmin[name] = hsUser[name] = value; + if ( results[0] instanceof Object ) { + const { + advancedSettings, + disableDashboard, + disabledPopupPanelParts + } = results[0]; + if ( Array.isArray(advancedSettings) ) { + for ( const entry of advancedSettings ) { + if ( entry.length < 1 ) { continue; } + const name = entry[0]; + if ( hsDefault.hasOwnProperty(name) === false ) { continue; } + const value = entry.length < 2 + ? hsDefault[name] + : this.hiddenSettingValueFromString(name, entry[1]); + if ( value === undefined ) { continue; } + hsDefault[name] = hsAdmin[name] = hsUser[name] = value; + } + } + µBlock.noDashboard = disableDashboard === true; + if ( Array.isArray(disabledPopupPanelParts) ) { + const partNameToBit = new Map([ + [ 'globalStats', 0b00010 ], + [ 'basicTools', 0b00100 ], + [ 'extraTools', 0b01000 ], + [ 'firewall', 0b10000 ], + ]); + let bits = hsDefault.popupPanelDisabledSections; + for ( const part of disabledPopupPanelParts ) { + const bit = partNameToBit.get(part); + if ( bit === undefined ) { continue; } + bits |= bit; + } + hsDefault.popupPanelDisabledSections = + hsAdmin.popupPanelDisabledSections = + hsUser.popupPanelDisabledSections = bits; } } @@ -1260,15 +1286,15 @@ self.addEventListener('hiddenSettingsChanged', ( ) => { // values are left to the user's choice. µBlock.restoreAdminSettings = async function() { - let toSet = {}; + let toOverwrite = {}; let data; try { const store = await vAPI.adminStorage.get([ 'adminSettings', - 'toSet', + 'toOverwrite', ]) || {}; - if ( store.toSet instanceof Object ) { - toSet = store.toSet; + if ( store.toOverwrite instanceof Object ) { + toOverwrite = store.toOverwrite; } const json = store.adminSettings; if ( typeof json === 'string' && json !== '' ) { @@ -1315,9 +1341,9 @@ self.addEventListener('hiddenSettingsChanged', ( ) => { binNotEmpty = true; } - if ( Array.isArray(toSet.trustedSiteDirectives) ) { - µBlock.netWhitelistDefault = toSet.trustedSiteDirectives.slice(); - bin.netWhitelist = toSet.trustedSiteDirectives.slice(); + if ( Array.isArray(toOverwrite.trustedSiteDirectives) ) { + µBlock.netWhitelistDefault = toOverwrite.trustedSiteDirectives.slice(); + bin.netWhitelist = toOverwrite.trustedSiteDirectives.slice(); binNotEmpty = true; } else if ( Array.isArray(data.whitelist) ) { bin.netWhitelist = data.whitelist;