diff options
author | Patrick Brunschwig <[email protected]> | 2021-06-13 08:44:02 +0200 |
---|---|---|
committer | Patrick Brunschwig <[email protected]> | 2021-06-13 08:45:35 +0200 |
commit | 12d9e583e852c791144a6cb799a9ac4eb8f242c8 (patch) | |
tree | 48eedce20b928b711ac6efc68f1ffa6de4dc6236 | |
parent | c67cdbc511f0727321c7d60b76b28e76b288680c (diff) | |
download | enigmail-12d9e583e852c791144a6cb799a9ac4eb8f242c8.tar.gz enigmail-12d9e583e852c791144a6cb799a9ac4eb8f242c8.tar.bz2 enigmail-12d9e583e852c791144a6cb799a9ac4eb8f242c8.zip |
implemented update check for Interlink to allow for quick updates
-rw-r--r-- | package/Makefile | 1 | ||||
-rw-r--r-- | package/core.jsm | 8 | ||||
-rw-r--r-- | package/enigmailUpdate.jsm | 151 | ||||
-rwxr-xr-x | package/prefs/defaultPrefs.js | 3 | ||||
-rw-r--r-- | ui/locale/en-US/enigmail.properties | 3 | ||||
-rwxr-xr-x | util/genxpi | 1 |
6 files changed, 166 insertions, 1 deletions
diff --git a/package/Makefile b/package/Makefile index 665d5215..b9678d55 100644 --- a/package/Makefile +++ b/package/Makefile @@ -34,6 +34,7 @@ MODFILES = \ persistentCrypto.jsm \ dialog.jsm \ enigmailOverlays.jsm \ + enigmailUpdate.jsm \ errorHandling.jsm \ events.jsm \ execution.jsm \ diff --git a/package/core.jsm b/package/core.jsm index 03505bc3..301af73d 100644 --- a/package/core.jsm +++ b/package/core.jsm @@ -40,6 +40,7 @@ const getEnigmailWksMimeHandler = EnigmailLazy.loader("enigmail/wksMimeHandler.j const getEnigmailOverlays = EnigmailLazy.loader("enigmail/enigmailOverlays.jsm", "EnigmailOverlays"); const getEnigmailSqlite = EnigmailLazy.loader("enigmail/sqliteDb.jsm", "EnigmailSqliteDb"); const getEnigmailGnuPGUpdate = EnigmailLazy.loader("enigmail/gnupgUpdate.jsm", "EnigmailGnuPGUpdate"); +const getEnigmailUpdate = EnigmailLazy.loader("enigmail/enigmailUpdate.jsm", "EnigmailUpdate"); const getEnigmailTimer = EnigmailLazy.loader("enigmail/timer.jsm", "EnigmailTimer"); const Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services; @@ -392,8 +393,13 @@ Enigmail.prototype = { getEnigmailTimer().setTimeout( function() { + getEnigmailUpdate().runUpdateCheck(); + }, 18 * 1000); // wait 3 minutes before starting the update checker - FIXME + + getEnigmailTimer().setTimeout( + function() { getEnigmailGnuPGUpdate().runUpdateCheck(); - }, 240); // wait 4 minutes before starting the update checker + }, 240 * 1000); // wait 4 minutes before starting the update checker getEnigmailLog().DEBUG("core.jsm: Enigmail.initialize: END\n"); }, diff --git a/package/enigmailUpdate.jsm b/package/enigmailUpdate.jsm new file mode 100644 index 00000000..3db7ca82 --- /dev/null +++ b/package/enigmailUpdate.jsm @@ -0,0 +1,151 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + + +"use strict"; + +var EXPORTED_SYMBOLS = ["EnigmailUpdate"]; + +const EnigmailPrefs = ChromeUtils.import("chrome://enigmail/content/modules/prefs.jsm").EnigmailPrefs; +const EnigmailLog = ChromeUtils.import("chrome://enigmail/content/modules/log.jsm").EnigmailLog; +const EnigmailVersioning = ChromeUtils.import("chrome://enigmail/content/modules/versioning.jsm").EnigmailVersioning; +const EnigmailTimer = ChromeUtils.import("chrome://enigmail/content/modules/timer.jsm").EnigmailTimer; +const EnigmailLocale = ChromeUtils.import("chrome://enigmail/content/modules/locale.jsm").EnigmailLocale; +const EnigmailCompat = ChromeUtils.import("chrome://enigmail/content/modules/compat.jsm").EnigmailCompat; +const EnigmailData = ChromeUtils.import("chrome://enigmail/content/modules/data.jsm").EnigmailData; +const EnigmailApp = ChromeUtils.import("chrome://enigmail/content/modules/app.jsm").EnigmailApp; + +Components.utils.importGlobalProperties(["fetch"]); + +const UPDATE_QUERY_URL = "https://www.enigmail.net/service/getEnigmailVersion.svc"; + +var EnigmailUpdate = { + isUpdateAvailable: async function() { + EnigmailLog.DEBUG(`enigmailUpdate.jsm: isUpdateAvailable()\n`); + + if (!EnigmailCompat.isInterlink()) return false; + + let now = Math.floor(Date.now() / 1000); + let lastCheck = Number(EnigmailPrefs.getPref("lastUpdateCheck")); + if (now > lastCheck) { + EnigmailPrefs.setPref("lastUpdateCheck", String(now)); + } + + const APP_ID = EnigmailApp.getName().toLowerCase().replace(/ /g, ""); + let newVersions = await this.getUpdateInfo(APP_ID); + if (!newVersions) return false; + + let newVer; + for (let item of newVersions) { + if (item.targetApp === APP_ID) { + newVer = item; + break; + } + } + + if (newVer && EnigmailVersioning.greaterThan(newVer.enigmailVersion, EnigmailApp.getVersion())) { + // new version is available + return true; + } + + return false; + }, + + isUpdateCheckNeeded: function() { + if (!EnigmailCompat.isInterlink()) return false; + + // check once every 24 hours + let now = Math.floor(Date.now() / 1000); + return (now > Number(EnigmailPrefs.getPref("lastUpdateCheck")) + 86400); + }, + + isAutoCheckEnabled: function() { + let farAway = Math.floor(Date.parse('31 Dec 2299') / 1000); + return Number(EnigmailPrefs.getPref("lastUpdateCheck")) < farAway; + }, + + runUpdateCheck: function() { + EnigmailLog.DEBUG(`enigmailUpdate.jsm: runUpdateCheck()\n`); + + if (!EnigmailCompat.isInterlink()) return; + let self = this, + timeoutSec = 0, + retry = true; + + if (this.isUpdateCheckNeeded()) { + timeoutSec = 3 + Math.floor(Math.random() * 180); + + EnigmailLog.DEBUG(`enigmailUpdate.jsm: runUpdateCheck: check needed; waiting for ${timeoutSec} seconds\n`); + + EnigmailTimer.setTimeout(async function f() { + if (await self.isUpdateAvailable()) { + EnigmailLog.DEBUG(`enigmailUpdate.jsm: runUpdateCheck: update available\n`); + retry = false; // stop checking if we display the update info dialog + self.displayUpdateDialog(); + } + }, timeoutSec * 1000); + } + + let tryAgain = 86600 - Math.floor(Math.random() * 1800); + EnigmailLog.DEBUG(`enigmailUpdate.jsm: runUpdateCheck: will try again in ${tryAgain} seconds\n`); + + EnigmailTimer.setTimeout(function f() { + if (retry) + self.runUpdateCheck(); + }, tryAgain * 1000); + + return; + + + }, + + displayUpdateDialog: function() { + let EnigmailDialog = ChromeUtils.import("chrome://enigmail/content/modules/dialog.jsm").EnigmailDialog; + EnigmailDialog.info(null, EnigmailLocale.getString("importantUpdate.label")); + }, + + getUpdateInfo: async function(appId) { + let url = UPDATE_QUERY_URL; + + // if ENIGMAIL_UPDATE_DOWNLOAD_URL env variable is set, use that instead of the + // official URL (for testing) + let env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); + if (env.get("ENIGMAIL_UPDATE_DOWNLOAD_URL")) { + url = env.get("ENIGMAIL_UPDATE_DOWNLOAD_URL"); + } + + url += `?appId=${appId}&appVersion=${EnigmailApp.getApplicationVersion()}&itemVersion=${EnigmailApp.getVersion()}`; + + let myRequest = new Request(url, { + method: 'GET', + mode: 'cors', + redirect: 'follow', + cache: 'default' + }); + + let response; + try { + EnigmailLog.DEBUG(`enigmailUpdate.jsm: getUpdateInfo(): requesting ${url}\n`); + response = await fetch(myRequest); + if (!response.ok) { + return null; + } + + if (response.headers.has("content-type") && response.headers.get("content-type").search(/^text\/html/i) === 0) { + // if we get HTML output, we return nothing (for example redirects to error catching pages) + return null; + } + let jsonData = EnigmailData.arrayBufferToString(Cu.cloneInto(await response.arrayBuffer(), this)); + EnigmailLog.DEBUG(`enigmailUpdate.jsm: getUpdateInfo: got JSON data ${jsonData}\n`); + + return JSON.parse(jsonData); + } + catch (ex) { + EnigmailLog.DEBUG(`enigmailUpdate.jsm: getUpdateInfo: error ${ex.toString()}\n`); + return null; + } + } +}; diff --git a/package/prefs/defaultPrefs.js b/package/prefs/defaultPrefs.js index 52950b90..d00d3639 100755 --- a/package/prefs/defaultPrefs.js +++ b/package/prefs/defaultPrefs.js @@ -214,6 +214,9 @@ pref("extensions.enigmail.protectedHeadersLegacyPart", false); // do reset the "references" and "in-reply-to" headers? pref("extensions.enigmail.protectReferencesHdr", false); +// holds the timestamp of the last check for GnuPG updates +pref("extensions.enigmail.lastUpdateCheck", "0"); + // tor configuration pref("extensions.enigmail.torIpAddr", "127.0.0.1"); pref("extensions.enigmail.torServicePort", "9050"); diff --git a/ui/locale/en-US/enigmail.properties b/ui/locale/en-US/enigmail.properties index 6d3a4b46..9155f75d 100644 --- a/ui/locale/en-US/enigmail.properties +++ b/ui/locale/en-US/enigmail.properties @@ -772,3 +772,6 @@ changePasswdDlg.wrongOldPasswd=The current passphrase for your key is wrong. #strings in filterWidgets.xml filterWidget.selectKey=Select Key + +#strings in enigmailUpdate.jsm +importantUpdate.label=There is an important upgrade of Enigmail available. We recommend that you open the Add-Ons manager and install that update as soon as possible. diff --git a/util/genxpi b/util/genxpi index d24e034e..e4a08b55 100755 --- a/util/genxpi +++ b/util/genxpi @@ -110,6 +110,7 @@ set chrome/content/preferences/defaultPrefs.js \ chrome/content/modules/core.jsm \ chrome/content/modules/configBackup.jsm \ chrome/content/modules/enigmailOverlays.jsm \ + chrome/content/modules/enigmailUpdate.jsm \ chrome/content/modules/errorHandling.jsm \ chrome/content/modules/funcs.jsm \ chrome/content/modules/gnupgUpdate.jsm \ |