diff options
Diffstat (limited to 'js/vapi-cloud.js')
-rw-r--r-- | js/vapi-cloud.js | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/js/vapi-cloud.js b/js/vapi-cloud.js new file mode 100644 index 0000000..b3d1b80 --- /dev/null +++ b/js/vapi-cloud.js @@ -0,0 +1,161 @@ +/******************************************************************************* + + ηMatrix - a browser extension to black/white list requests. + Copyright (C) 2014-2019 The uMatrix/uBlock Origin authors + Copyright (C) 2019 Alessio Vanni + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see {http://www.gnu.org/licenses/}. + + Home: https://gitlab.com/vannilla/ematrix + uMatrix Home: https://github.com/gorhill/uMatrix +*/ + +'use strict'; + +/******************************************************************************/ + +(function () { + const {classes: Cc, interfaces: Ci, utils: Cu} = Components; + Cu.import('resource://gre/modules/Services.jsm'); + + let vAPI = self.vAPI; // Guaranteed to be initialized by vapi-background.js + + vAPI.cloud = (function () { + let extensionBranchPath = 'extensions.' + location.host; + let cloudBranchPath = extensionBranchPath + '.cloudStorage'; + + // https://github.com/gorhill/uBlock/issues/80#issuecomment-132081658 + // We must use get/setComplexValue in order to properly handle strings + // with unicode characters. + let iss = Ci.nsISupportsString; + let argstr = Components.classes['@mozilla.org/supports-string;1'] + .createInstance(iss); + + let options = { + defaultDeviceName: '', + deviceName: '' + }; + + // User-supplied device name. + try { + options.deviceName = Services.prefs + .getBranch(extensionBranchPath + '.') + .getComplexValue('deviceName', iss) + .data; + } catch(ex) { + // Ignore + } + + var getDefaultDeviceName = function() { + var name = ''; + try { + name = Services.prefs + .getBranch('services.sync.client.') + .getComplexValue('name', iss) + .data; + } catch(ex) { + // Ignore + } + + return name || window.navigator.platform || window.navigator.oscpu; + }; + + let start = function (dataKeys) { + let extensionBranch = + Services.prefs.getBranch(extensionBranchPath + '.'); + let syncBranch = + Services.prefs.getBranch('services.sync.prefs.sync.'); + + // Mark config entries as syncable + argstr.data = ''; + let dataKey; + for (let i=0; i<dataKeys.length; ++i) { + dataKey = dataKeys[i]; + if (extensionBranch.prefHasUserValue('cloudStorage.' + dataKey) + === false) { + extensionBranch.setComplexValue('cloudStorage.' + dataKey, + iss, argstr); + } + + syncBranch.setBoolPref(cloudBranchPath + '.' + dataKey, true); + } + }; + + let push = function (datakey, data, callback) { + let branch = Services.prefs.getBranch(cloudBranchPath + '.'); + let bin = { + 'source': options.deviceName || getDefaultDeviceName(), + 'tstamp': Date.now(), + 'data': data, + 'size': 0 + }; + bin.size = JSON.stringify(bin).length; + argstr.data = JSON.stringify(bin); + branch.setComplexValue(datakey, iss, argstr); + + if (typeof callback === 'function') { + callback(); + } + }; + + let pull = function (datakey, callback) { + let result = null; + let branch = Services.prefs.getBranch(cloudBranchPath + '.'); + + try { + let json = branch.getComplexValue(datakey, iss).data; + if (typeof json === 'string') { + result = JSON.parse(json); + } + } catch(ex) { + // Ignore + } + + callback(result); + }; + + let getOptions = function (callback) { + if (typeof callback !== 'function') { + return; + } + + options.defaultDeviceName = getDefaultDeviceName(); + callback(options); + }; + + let setOptions = function (details, callback) { + if (typeof details !== 'object' || details === null) { + return; + } + + let branch = Services.prefs.getBranch(extensionBranchPath + '.'); + + if (typeof details.deviceName === 'string') { + argstr.data = details.deviceName; + branch.setComplexValue('deviceName', iss, argstr); + options.deviceName = details.deviceName; + } + + getOptions(callback); + }; + + return { + start: start, + push: push, + pull: pull, + getOptions: getOptions, + setOptions: setOptions + }; + })(); +})(); |