diff -Nru thunderbird-78.10.1+build1/BUILDID thunderbird-78.10.2+build1/BUILDID --- thunderbird-78.10.1+build1/BUILDID 2021-05-04 14:28:40.000000000 +0000 +++ thunderbird-78.10.2+build1/BUILDID 2021-05-17 17:57:49.000000000 +0000 @@ -1 +1 @@ -20210503211912 \ No newline at end of file +20210513204504 \ No newline at end of file diff -Nru thunderbird-78.10.1+build1/comm/calendar/base/content/calendar-command-controller.js thunderbird-78.10.2+build1/comm/calendar/base/content/calendar-command-controller.js --- thunderbird-78.10.1+build1/comm/calendar/base/content/calendar-command-controller.js 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/calendar/base/content/calendar-command-controller.js 2021-05-17 17:53:02.000000000 +0000 @@ -199,7 +199,7 @@ return this.item_selected; case "calendar_reload_remote_calendars": - return this.has_enabled_network_calendars && !this.offline; + return this.has_enabled_reloadable_calendars && !this.offline; case "calendar_attendance_command": { let attendSel = false; if (this.todo_tasktree_focused) { @@ -570,15 +570,17 @@ /** * Returns a boolean indicating whether there is at least one enabled - * calendar that requires network access. + * calendar that can be reloaded. Note: ICS calendars can have a network URL + * or a file URL, but both are reloadable. */ - get has_enabled_network_calendars() { + get has_enabled_reloadable_calendars() { return cal .getCalendarManager() .getCalendars() .some( calendar => - !calendar.getProperty("disabled") && calendar.getProperty("requiresNetwork") !== false + !calendar.getProperty("disabled") && + (calendar.type == "ics" || calendar.getProperty("requiresNetwork") !== false) ); }, diff -Nru thunderbird-78.10.1+build1/comm/calendar/base/content/dialogs/calendar-alarm-dialog.js thunderbird-78.10.2+build1/comm/calendar/base/content/dialogs/calendar-alarm-dialog.js --- thunderbird-78.10.1+build1/comm/calendar/base/content/dialogs/calendar-alarm-dialog.js 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/calendar/base/content/dialogs/calendar-alarm-dialog.js 2021-05-17 17:53:02.000000000 +0000 @@ -15,6 +15,23 @@ var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); var { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); +var gShutdownDetected = false; + +/** + * Detects the "mail-unloading-messenger" notification to prevent snoozing items + * as well as closes this window when the main window is closed. Not doing so can + * cause data loss with CalStorageCalendar. + */ +var gShutdownObserver = { + observe() { + let windows = Array.from(Services.wm.getEnumerator("mail:3pane")); + if (windows.filter(win => !win.closed).length == 0) { + gShutdownDetected = true; + window.close(); + } + }, +}; + addEventListener("DOMContentLoaded", () => { document.getElementById("alarm-snooze-all-popup").addEventListener("snooze", event => { snoozeAllItems(event.detail); @@ -133,6 +150,9 @@ gRelativeDateUpdateTimer = setInterval(updateRelativeDates, 60 * 1000); }, timeout); + // Configure the shutdown observer. + Services.obs.addObserver(gShutdownObserver, "mail-unloading-messenger"); + // Give focus to the alarm richlist after onload completes. See bug 103197 setTimeout(onFocusWindow, 0); } @@ -142,6 +162,12 @@ * alarms and clean up the relative date update timer. */ function finishWindow() { + Services.obs.removeObserver(gShutdownObserver, "mail-unloading-messenger"); + + if (gShutdownDetected) { + return; + } + let alarmRichlist = document.getElementById("alarm-richlist"); if (alarmRichlist.children.length > 0) { @@ -153,6 +179,7 @@ if (snoozePref <= 0) { snoozePref = 5; } + snoozeAllItems(snoozePref); } diff -Nru thunderbird-78.10.1+build1/comm/mail/base/content/aboutAddonsExtra.css thunderbird-78.10.2+build1/comm/mail/base/content/aboutAddonsExtra.css --- thunderbird-78.10.1+build1/comm/mail/base/content/aboutAddonsExtra.css 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/base/content/aboutAddonsExtra.css 2021-05-17 17:53:02.000000000 +0000 @@ -30,3 +30,26 @@ .addon-detail-row-private-browsing + .addon-detail-row.addon-detail-help-row { display: none; } + +/* Hide the options entry in the options menu, as we have a dedicated button */ +addon-options panel-item[action="preferences"] { + display:none; +} + +.extension-options-button { + min-width: auto; + min-height: auto; + width: 24px; + height: 24px; + margin: 0; + margin-inline-start: 8px; + -moz-context-properties: fill; + fill: currentColor; + background-image: url("chrome://messenger/skin/icons/developer.svg"); + background-repeat: no-repeat; + background-position: center center; + /* Get the -badged ::after element in the right spot. */ + padding: 1px; + display: flex; + justify-content: flex-end; +} diff -Nru thunderbird-78.10.1+build1/comm/mail/base/content/aboutAddonsExtra.js thunderbird-78.10.2+build1/comm/mail/base/content/aboutAddonsExtra.js --- thunderbird-78.10.1+build1/comm/mail/base/content/aboutAddonsExtra.js 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/base/content/aboutAddonsExtra.js 2021-05-17 17:53:02.000000000 +0000 @@ -73,6 +73,44 @@ return _getScreenshotUrlForAddon(addon); }; + // Override parts of the addon-card customElement to be able + // to add a dedicated button for extension preferences. + await customElements.whenDefined("addon-card"); + AddonCard.prototype.addOptionsButton = async function() { + let { addon, optionsButton } = this; + if (addon.type != "extension") { + return; + } + + let addonOptionsButton = this.querySelector(".extension-options-button"); + if (addon.isActive) { + if (!addon.optionsType) { + // Upon fresh install the manifest has not been parsed and optionsType + // is not known, manually trigger parsing. + let data = new ExtensionData(addon.getResourceURI()); + await data.loadManifest(); + } + if (addon.optionsType) { + if (!addonOptionsButton) { + addonOptionsButton = document.createElement("button"); + addonOptionsButton.classList.add("extension-options-button"); + addonOptionsButton.setAttribute("action", "preferences"); + optionsButton.parentNode.insertBefore( + addonOptionsButton, + optionsButton + ); + } + } + } else if (addonOptionsButton) { + addonOptionsButton.remove(); + } + }; + AddonCard.prototype._update = AddonCard.prototype.update; + AddonCard.prototype.update = function() { + this._update(); + this.addOptionsButton(); + }; + // Override parts of the addon-permission-list customElement to be able // to show the usage of Experiments in the permission list. await customElements.whenDefined("addon-permissions-list"); diff -Nru thunderbird-78.10.1+build1/comm/mail/base/modules/PromptParent.jsm thunderbird-78.10.2+build1/comm/mail/base/modules/PromptParent.jsm --- thunderbird-78.10.1+build1/comm/mail/base/modules/PromptParent.jsm 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/base/modules/PromptParent.jsm 2021-05-17 17:53:02.000000000 +0000 @@ -151,7 +151,8 @@ try { if (browser) { - browser.enterModalState(); + // The compose editor does not support enter/leaveModalState. + browser.enterModalState?.(); PromptUtils.fireDialogEvent(win, "DOMWillOpenModalDialog", browser); } @@ -168,7 +169,7 @@ PromptUtils.propBagToObject(bag, args); } finally { if (browser) { - browser.leaveModalState(); + browser.leaveModalState?.(); PromptUtils.fireDialogEvent(win, "DOMModalDialogClosed", browser); } } diff -Nru thunderbird-78.10.1+build1/comm/mail/components/about-support/content/aboutSupport.js thunderbird-78.10.2+build1/comm/mail/components/about-support/content/aboutSupport.js --- thunderbird-78.10.1+build1/comm/mail/components/about-support/content/aboutSupport.js 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/components/about-support/content/aboutSupport.js 2021-05-17 17:53:02.000000000 +0000 @@ -230,13 +230,15 @@ let fsType; try { fsType = AboutSupportPlatform.getFileSystemType(currProfD); - let bundle = Services.strings.createBundle( - "chrome://messenger/locale/aboutSupportMail.properties" - ); - let fsText = bundle.GetStringFromName("fsType." + fsType); - let fsTextNode = document.createElement("span"); - fsTextNode.textContent = fsText; - profElem.appendChild(fsTextNode); + if (fsType) { + let bundle = Services.strings.createBundle( + "chrome://messenger/locale/aboutSupportMail.properties" + ); + let fsText = bundle.GetStringFromName("fsType." + fsType); + let fsTextNode = document.createElement("span"); + fsTextNode.textContent = fsText; + profElem.appendChild(fsTextNode); + } } catch (x) { Cu.reportError(x); } diff -Nru thunderbird-78.10.1+build1/comm/mail/components/extensions/child/ext-menus.js thunderbird-78.10.2+build1/comm/mail/components/extensions/child/ext-menus.js --- thunderbird-78.10.1+build1/comm/mail/components/extensions/child/ext-menus.js 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/components/extensions/child/ext-menus.js 2021-05-17 17:53:02.000000000 +0000 @@ -271,15 +271,17 @@ // eslint-disable-next-line no-undef new ComposeAttachment(context, a).api() ); - } - withHandlingUserInput(context.contentWindow, () => fire.asyncWithoutClone( Cu.cloneInto(info, context.cloneScope, { cloneFunctions: true, }), Cu.cloneInto(tab, context.cloneScope) - ) - ); + ); + } else { + withHandlingUserInput(context.contentWindow, () => + fire.sync(info, tab) + ); + } }; let event = context.childManager.getParentEvent("menus.onClicked"); diff -Nru thunderbird-78.10.1+build1/comm/mail/components/extensions/parent/ext-mail.js thunderbird-78.10.2+build1/comm/mail/components/extensions/parent/ext-mail.js --- thunderbird-78.10.1+build1/comm/mail/components/extensions/parent/ext-mail.js 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/components/extensions/parent/ext-mail.js 2021-05-17 17:53:02.000000000 +0000 @@ -1470,7 +1470,19 @@ * Convert a folder URI to a human-friendly path. * @return {String} */ -function folderURIToPath(uri) { +function folderURIToPath(accountId, uri) { + let server = MailServices.accounts.getAccount(accountId).incomingServer; + let rootURI = server.rootFolder.URI; + if (rootURI == uri) { + return "/"; + } + // The .URI property of an IMAP folder doesn't have %-encoded characters, but + // may include literal % chars. Services.io.newURI(uri) applies encodeURI to + // the returned filePath, but will not encode any literal % chars, which will + // cause decodeURIComponent to fail (bug 1707408). + if (server.type == "imap") { + return uri.substring(rootURI.length); + } let path = Services.io.newURI(uri).filePath; return path .split("/") @@ -1540,7 +1552,7 @@ let folderObject = { accountId, name: folder.prettyName, - path: folderURIToPath(folder.URI), + path: folderURIToPath(accountId, folder.URI), }; for (let [flag, typeName] of folderTypeMap.entries()) { diff -Nru thunderbird-78.10.1+build1/comm/mail/components/extensions/parent/ext-messages.js thunderbird-78.10.2+build1/comm/mail/components/extensions/parent/ext-messages.js --- thunderbird-78.10.1+build1/comm/mail/components/extensions/parent/ext-messages.js 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/components/extensions/parent/ext-messages.js 2021-05-17 17:53:02.000000000 +0000 @@ -207,12 +207,16 @@ ); }, async getFull(messageId) { - return new Promise(resolve => { + let mimeMsg = await new Promise(resolve => { let msgHdr = messageTracker.getMessage(messageId); MsgHdrToMimeMessage(msgHdr, null, (_msgHdr, mimeMsg) => { - resolve(convertMessagePart(mimeMsg)); + resolve(mimeMsg); }); }); + if (!mimeMsg) { + throw new ExtensionError(`Error reading message ${messageId}`); + } + return convertMessagePart(mimeMsg); }, async getRaw(messageId) { let messenger = Cc["@mozilla.org/messenger;1"].createInstance( diff -Nru thunderbird-78.10.1+build1/comm/mail/components/extensions/test/xpcshell/test_ext_accounts.js thunderbird-78.10.2+build1/comm/mail/components/extensions/test/xpcshell/test_ext_accounts.js --- thunderbird-78.10.1+build1/comm/mail/components/extensions/test/xpcshell/test_ext_accounts.js 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/components/extensions/test/xpcshell/test_ext_accounts.js 2021-05-17 17:53:02.000000000 +0000 @@ -85,8 +85,8 @@ subFolders: [ { accountId: account1Id, - name: "foo 'bar'(!)", - path: "/Trash/foo 'bar'(!)", + name: "%foo %test% 'bar'(!)+", + path: "/Trash/%foo %test% 'bar'(!)+", }, { accountId: account1Id, @@ -123,8 +123,8 @@ subFolders: [ { accountId: account2Id, - name: "foo 'bar'(!)", - path: "/INBOX/foo 'bar'(!)", + name: "%foo %test% 'bar'(!)+", + path: "/INBOX/%foo %test% 'bar'(!)+", }, { accountId: account2Id, @@ -182,14 +182,14 @@ await extension.awaitMessage("create folders"); let inbox1 = [...account1.incomingServer.rootFolder.subFolders][0]; // Test our code can handle characters that might be escaped. - inbox1.createSubfolder("foo 'bar'(!)", null); + inbox1.createSubfolder("%foo %test% 'bar'(!)+", null); inbox1.createSubfolder("Ϟ", null); // Test our code can handle unicode. let inbox2 = [...account2.incomingServer.rootFolder.subFolders][0]; inbox2.QueryInterface(Ci.nsIMsgImapMailFolder).hierarchyDelimiter = "/"; // Test our code can handle characters that might be escaped. - inbox2.createSubfolder("foo 'bar'(!)", null); - await PromiseTestUtils.promiseFolderAdded("foo 'bar'(!)"); + inbox2.createSubfolder("%foo %test% 'bar'(!)+", null); + await PromiseTestUtils.promiseFolderAdded("%foo %test% 'bar'(!)+"); inbox2.createSubfolder("Ϟ", null); // Test our code can handle unicode. await PromiseTestUtils.promiseFolderAdded("Ϟ"); diff -Nru thunderbird-78.10.1+build1/comm/mail/config/version_display.txt thunderbird-78.10.2+build1/comm/mail/config/version_display.txt --- thunderbird-78.10.1+build1/comm/mail/config/version_display.txt 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/config/version_display.txt 2021-05-17 17:53:03.000000000 +0000 @@ -1 +1 @@ -78.10.1 +78.10.2 diff -Nru thunderbird-78.10.1+build1/comm/mail/config/version.txt thunderbird-78.10.2+build1/comm/mail/config/version.txt --- thunderbird-78.10.1+build1/comm/mail/config/version.txt 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/config/version.txt 2021-05-17 17:53:02.000000000 +0000 @@ -1 +1 @@ -78.10.1 +78.10.2 diff -Nru thunderbird-78.10.1+build1/comm/mail/extensions/am-e2e/am-e2e.js thunderbird-78.10.2+build1/comm/mail/extensions/am-e2e/am-e2e.js --- thunderbird-78.10.1+build1/comm/mail/extensions/am-e2e/am-e2e.js 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/extensions/am-e2e/am-e2e.js 2021-05-17 17:53:02.000000000 +0000 @@ -789,7 +789,8 @@ let dateButton = document.createXULElement("button"); document.l10n.setAttributes(dateButton, "openpgp-key-man-change-expiry"); - dateButton.addEventListener("command", () => { + dateButton.addEventListener("command", event => { + event.stopPropagation(); enigmailEditKeyDate(key); }); dateButton.setAttribute("hidden", "true"); @@ -908,7 +909,8 @@ let info = document.createXULElement("button"); info.classList.add("openpgp-image-btn", "openpgp-props-btn"); document.l10n.setAttributes(info, "openpgp-key-man-key-props"); - info.addEventListener("command", () => { + info.addEventListener("command", event => { + event.stopPropagation(); enigmailKeyDetails(key.keyId); }); @@ -921,37 +923,43 @@ let copyItem = document.createXULElement("menuitem"); document.l10n.setAttributes(copyItem, "openpgp-key-copy-key"); - copyItem.addEventListener("command", () => { + copyItem.addEventListener("command", event => { + event.stopPropagation(); openPgpCopyToClipboard(`0x${key.keyId}`); }); let sendItem = document.createXULElement("menuitem"); document.l10n.setAttributes(sendItem, "openpgp-key-send-key"); - sendItem.addEventListener("command", () => { + sendItem.addEventListener("command", event => { + event.stopPropagation(); openPgpSendKeyEmail(`0x${key.keyId}`); }); let exportItem = document.createXULElement("menuitem"); document.l10n.setAttributes(exportItem, "openpgp-key-export-key"); - exportItem.addEventListener("command", () => { + exportItem.addEventListener("command", event => { + event.stopPropagation(); openPgpExportPublicKey(`0x${key.keyId}`); }); let backupItem = document.createXULElement("menuitem"); document.l10n.setAttributes(backupItem, "openpgp-key-backup-key"); - backupItem.addEventListener("command", () => { + backupItem.addEventListener("command", event => { + event.stopPropagation(); openPgpExportSecretKey(`0x${key.keyId}`, `0x${key.fpr}`); }); let revokeItem = document.createXULElement("menuitem"); document.l10n.setAttributes(revokeItem, "openpgp-key-man-revoke-key"); - revokeItem.addEventListener("command", () => { + revokeItem.addEventListener("command", event => { + event.stopPropagation(); openPgpRevokeKey(key); }); let deleteItem = document.createXULElement("menuitem"); document.l10n.setAttributes(deleteItem, "openpgp-delete-key"); - deleteItem.addEventListener("command", () => { + deleteItem.addEventListener("command", event => { + event.stopPropagation(); enigmailDeleteKey(key); }); diff -Nru thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/encryption.jsm thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/encryption.jsm --- thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/encryption.jsm 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/encryption.jsm 2021-05-17 17:53:02.000000000 +0000 @@ -273,7 +273,7 @@ } if (encrypt) { - if (foundKey && foundKey.getEncryptionValidity().keyValid) { + if (foundKey && foundKey.getEncryptionValidity(true).keyValid) { canEncrypt = true; } } diff -Nru thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/errorHandling.jsm thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/errorHandling.jsm --- thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/errorHandling.jsm 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/errorHandling.jsm 2021-05-17 17:53:03.000000000 +0000 @@ -78,7 +78,7 @@ keySpec: keyId, }); } - let r = key.getEncryptionValidity(); + let r = key.getEncryptionValidity(false); if (!r.keyValid) { reasonMsg = r.reason; } diff -Nru thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/funcs.jsm thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/funcs.jsm --- thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/funcs.jsm 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/funcs.jsm 2021-05-17 17:53:03.000000000 +0000 @@ -504,4 +504,36 @@ return recipients.length; }, + + /** + * Test if the given string looks roughly like an email address, + * returns true or false. + */ + stringLooksLikeEmailAddress(str) { + return /^[^ @]+@[^ @]+$/.test(str); + }, + + /** + * Extract an email address from the given string, using MailServices. + * However, be more strict, and avoid strings that appear to be + * invalid addresses. + * + * If more than one email address is found, only return the first. + * + * If we fail to extract an email address from the given string, + * because the given string doesn't conform to expectations, + * an empty string is returned. + */ + getEmailFromUserID(uid) { + let addresses = MailServices.headerParser.makeFromDisplayAddress(uid); + if ( + !addresses[0] || + !EnigmailFuncs.stringLooksLikeEmailAddress(addresses[0].email) + ) { + console.debug("failed to extract email address from: " + uid); + return ""; + } + + return addresses[0].email.trim(); + }, }; diff -Nru thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/keyObj.jsm thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/keyObj.jsm --- thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/keyObj.jsm 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/keyObj.jsm 2021-05-17 17:53:03.000000000 +0000 @@ -102,6 +102,7 @@ this.minimalKeyBlock = []; this.photoAvailable = false; this.secretAvailable = false; + this.secretMaterial = false; this._sigList = null; this.type = keyData.type; @@ -133,6 +134,7 @@ "subKeys", "fpr", "secretAvailable", + "secretMaterial", "photoAvailable", "userId", ]; @@ -240,21 +242,6 @@ userId: this.userId, keyId: "0x" + this.keyId, }); - } else if ( - this.keyTrust.search(/d/i) >= 0 || - this.keyUseFor.search(/D/i) >= 0 - ) { - // public key disabled - retVal.reason = l10n.formatValueSync("key-ring-key-disabled", { - userId: this.userId, - keyId: "0x" + this.keyId, - }); - } else if (this.keyTrust.search(/i/i) >= 0) { - // public key invalid - retVal.reason = l10n.formatValueSync("key-ring-key-invalid", { - userId: this.userId, - keyId: "0x" + this.keyId, - }); } else { retVal.keyValid = true; } @@ -282,170 +269,142 @@ userId: this.userId, keyId: "0x" + this.keyId, }); - } else if (this.keyUseFor.search(/S/) < 0) { - retVal.keyValid = false; - if (this.keyTrust.search(/u/i) < 0) { - // public key invalid - retVal.reason = l10n.formatValueSync("key-ring-key-not-trusted", { + return retVal; + } + + if (/s/.test(this.keyUseFor) && this.secretMaterial) { + return retVal; + } + + retVal.keyValid = false; + let expired = 0; + let revoked = 0; + let found = 0; + let noSecret = 0; + + for (let sk in this.subKeys) { + if (this.subKeys[sk].keyUseFor.search(/s/) >= 0) { + if (this.subKeys[sk].keyTrust.search(/e/i) >= 0) { + ++expired; + } else if (this.subKeys[sk].keyTrust.search(/r/i) >= 0) { + ++revoked; + } else if (!this.subKeys[sk].secretMaterial) { + ++noSecret; + } else { + // found subkey usable + ++found; + } + } + } + + if (!found) { + if (exceptionReason != "ignoreExpired" && expired) { + retVal.reason = l10n.formatValueSync("key-ring-sign-sub-keys-expired", { + userId: this.userId, + keyId: "0x" + this.keyId, + }); + } else if (revoked) { + retVal.reason = l10n.formatValueSync("key-ring-sign-sub-keys-revoked", { + userId: this.userId, + keyId: "0x" + this.keyId, + }); + } else if (noSecret) { + retVal.reason = l10n.formatValueSync("key-ring-no-secret-key", { userId: this.userId, keyId: "0x" + this.keyId, }); } else { - let expired = 0, - revoked = 0, - unusable = 0, - found = 0; - // public key is valid; check for signing subkeys - for (let sk in this.subKeys) { - if (this.subKeys[sk].keyUseFor.search(/S/) >= 0) { - if (this.subKeys[sk].keyTrust.search(/e/i) >= 0) { - ++expired; - } else if (this.subKeys[sk].keyTrust.search(/r/i) >= 0) { - ++revoked; - } else if ( - this.subKeys[sk].keyTrust.search(/[di-]/i) >= 0 || - this.subKeys[sk].keyUseFor.search(/D/) >= 0 - ) { - ++unusable; - } else { - // found subkey usable - ++found; - } - } - } - - if (!found) { - if (exceptionReason != "ignoreExpired" && expired) { - retVal.reason = l10n.formatValueSync( - "key-ring-sign-sub-keys-expired", - { - userId: this.userId, - keyId: "0x" + this.keyId, - } - ); - } else if (revoked) { - retVal.reason = l10n.formatValueSync( - "key-ring-sign-sub-keys-revoked", - { - userId: this.userId, - keyId: "0x" + this.keyId, - } - ); - } else if (unusable) { - retVal.reason = l10n.formatValueSync( - "key-ring-sign-sub-keys-unusable", - { - userId: this.userId, - keyId: "0x" + this.keyId, - } - ); - } else { - retVal.reason = l10n.formatValueSync( - "key-ring-pub-key-not-for-signing", - { - userId: this.userId, - keyId: "0x" + this.keyId, - } - ); + retVal.reason = l10n.formatValueSync( + "key-ring-pub-key-not-for-signing", + { + userId: this.userId, + keyId: "0x" + this.keyId, } - } else { - retVal.keyValid = true; - } + ); } + } else { + retVal.keyValid = true; } - //console.debug("getSigningValidity retVal: %o", retVal); return retVal; } /** * Check whether a key can be used for encryption and return a description of why not * + * @param {boolean} requireDecryptionKey: + * If true, require secret key material to be available + * for at least one encryption key. + * * @return Object: * - keyValid: Boolean (true if key is valid) * - reason: String (explanation of invalidity) */ - getEncryptionValidity(exceptionReason = null) { + getEncryptionValidity(requireDecryptionKey, exceptionReason = null) { let retVal = this.getPubKeyValidity(exceptionReason); if (!retVal.keyValid) { return retVal; } - if (this.keyUseFor.search(/E/) < 0) { - retVal.keyValid = false; + if ( + requireDecryptionKey && + this.keyUseFor.search(/e/) >= 0 && + this.secretMaterial + ) { + return retVal; + } + + retVal.keyValid = false; + + let expired = 0; + let revoked = 0; + let found = 0; + let noSecret = 0; + + for (let sk in this.subKeys) { + if (this.subKeys[sk].keyUseFor.search(/e/) >= 0) { + if (this.subKeys[sk].keyTrust.search(/e/i) >= 0) { + ++expired; + } else if (this.subKeys[sk].keyTrust.search(/r/i) >= 0) { + ++revoked; + } else if (requireDecryptionKey && !this.subKeys[sk].secretMaterial) { + ++noSecret; + } else { + // found subkey usable + ++found; + } + } + } - if (this.keyTrust.search(/u/i) < 0) { - // public key invalid - retVal.reason = l10n.formatValueSync("key-ring-key-invalid", { + if (!found) { + if (exceptionReason != "ignoreExpired" && expired) { + retVal.reason = l10n.formatValueSync("key-ring-enc-sub-keys-expired", { + userId: this.userId, + keyId: "0x" + this.keyId, + }); + } else if (revoked) { + retVal.reason = l10n.formatValueSync("key-ring-enc-sub-keys-revoked", { + userId: this.userId, + keyId: "0x" + this.keyId, + }); + } else if (noSecret) { + retVal.reason = l10n.formatValueSync("key-ring-no-secret-key", { userId: this.userId, keyId: "0x" + this.keyId, }); } else { - let expired = 0, - revoked = 0, - unusable = 0, - found = 0; - // public key is valid; check for encryption subkeys - - for (let sk in this.subKeys) { - if (this.subKeys[sk].keyUseFor.search(/E/) >= 0) { - if (this.subKeys[sk].keyTrust.search(/e/i) >= 0) { - ++expired; - } else if (this.subKeys[sk].keyTrust.search(/r/i) >= 0) { - ++revoked; - } else if ( - this.subKeys[sk].keyTrust.search(/[di-]/i) >= 0 || - this.subKeys[sk].keyUseFor.search(/D/) >= 0 - ) { - ++unusable; - } else { - // found subkey usable - ++found; - } - } - } - - if (!found) { - if (exceptionReason != "ignoreExpired" && expired) { - retVal.reason = l10n.formatValueSync( - "key-ring-enc-sub-keys-expired", - { - userId: this.userId, - keyId: "0x" + this.keyId, - } - ); - } else if (revoked) { - retVal.reason = l10n.formatValueSync( - "key-ring-enc-sub-keys-revoked", - { - userId: this.userId, - keyId: "0x" + this.keyId, - } - ); - } else if (unusable) { - retVal.reason = l10n.formatValueSync( - "key-ring-enc-sub-keys-unusable", - { - userId: this.userId, - keyId: "0x" + this.keyId, - } - ); - } else { - retVal.reason = l10n.formatValueSync( - "key-ring-pub-key-not-for-encryption", - { - userId: this.userId, - keyId: "0x" + this.keyId, - } - ); + retVal.reason = l10n.formatValueSync( + "key-ring-pub-key-not-for-encryption", + { + userId: this.userId, + keyId: "0x" + this.keyId, } - } else { - retVal.keyValid = true; - } + ); } + } else { + retVal.keyValid = true; } - //console.debug("getEncryptionValidity retVal: %o", retVal); return retVal; } diff -Nru thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/keyRing.jsm thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/keyRing.jsm --- thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/keyRing.jsm 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/keyRing.jsm 2021-05-17 17:53:03.000000000 +0000 @@ -36,8 +36,8 @@ const { PgpSqliteDb2 } = ChromeUtils.import( "chrome://openpgp/content/modules/sqliteDb.jsm" ); -const { uidHelper } = ChromeUtils.import( - "chrome://openpgp/content/modules/uidHelper.jsm" +const { EnigmailFuncs } = ChromeUtils.import( + "chrome://openpgp/content/modules/funcs.jsm" ); var { RNP } = ChromeUtils.import("chrome://openpgp/content/modules/RNP.jsm"); @@ -181,13 +181,12 @@ continue; } - let split = {}; - if (uidHelper.getPartsFromUidStr(userId.userId, split)) { - let uidEmail = split.email.toLowerCase(); - if (uidEmail === email) { - res.push(key); - break; - } + if ( + EnigmailFuncs.getEmailFromUserID(userId.userId).toLowerCase() === + email + ) { + res.push(key); + break; } } } @@ -231,7 +230,7 @@ continue; } if ( - key.getEncryptionValidity("ignoreExpired").keyValid && + key.getEncryptionValidity(true, "ignoreExpired").keyValid && key.getSigningValidity("ignoreExpired").keyValid ) { let thisIsExpired = @@ -1031,13 +1030,13 @@ if (uid.type !== "uid") { continue; } - let split = {}; - if (uidHelper.getPartsFromUidStr(uid.userId, split)) { - let uidEmail = split.email.toLowerCase(); - if (uidEmail === emailAddr) { - uidMatch = true; - break; - } + + if ( + EnigmailFuncs.getEmailFromUserID(uid.userId).toLowerCase() === + emailAddr + ) { + uidMatch = true; + break; } } if (!uidMatch) { @@ -1543,12 +1542,11 @@ case "r": return null; } - let split = {}; - if (uidHelper.getPartsFromUidStr(keyObj.userId, split)) { - let uidEmail = split.email.toLowerCase(); - if (uidEmail !== email) { - return null; - } + + if ( + EnigmailFuncs.getEmailFromUserID(keyObj.userId).toLowerCase() !== email + ) { + return null; } return RNP.getAutocryptKeyB64(keyId, "0x" + subKey.keyId, keyObj.userId); }, diff -Nru thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/masterpass.jsm thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/masterpass.jsm --- thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/masterpass.jsm 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/masterpass.jsm 2021-05-17 17:53:03.000000000 +0000 @@ -63,9 +63,6 @@ let [prot, unprot] = getRNP().getProtectedKeysCount(); let haveAtLeastOneSecretKey = prot || unprot; - // For user support, troubleshooting bug 1656287 - console.debug(prot + " protected and " + unprot + " unprotected keys"); - if (!this.getPassPath().exists() && haveAtLeastOneSecretKey) { // We couldn't read the OpenPGP password from file. // This could either mean the file doesn't exist, which indicates diff -Nru thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/RNP.jsm thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/RNP.jsm --- thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/RNP.jsm 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/RNP.jsm 2021-05-17 17:53:03.000000000 +0000 @@ -24,8 +24,8 @@ var { PgpSqliteDb2 } = ChromeUtils.import( "chrome://openpgp/content/modules/sqliteDb.jsm" ); -var { uidHelper } = ChromeUtils.import( - "chrome://openpgp/content/modules/uidHelper.jsm" +const { EnigmailFuncs } = ChromeUtils.import( + "chrome://openpgp/content/modules/funcs.jsm" ); var { GPGME } = ChromeUtils.import( "chrome://openpgp/content/modules/GPGME.jsm" @@ -88,6 +88,12 @@ keyObj.secretAvailable = this.getSecretAvailableFromHandle(handle); + if (keyObj.secretAvailable) { + keyObj.secretMaterial = RNPLib.isSecretKeyMaterialAvailable(handle); + } else { + keyObj.secretMaterial = false; + } + if (is_subkey) { keyObj.type = "sub"; } else { @@ -192,83 +198,11 @@ }, getProtectedKeysCount() { - let prot = 0; - let unprot = 0; - - let iter = new RNPLib.rnp_identifier_iterator_t(); - let grip = new ctypes.char.ptr(); - - if ( - RNPLib.rnp_identifier_iterator_create(RNPLib.ffi, iter.address(), "grip") - ) { - throw new Error("rnp_identifier_iterator_create failed"); - } - - while (!RNPLib.rnp_identifier_iterator_next(iter, grip.address())) { - if (grip.isNull()) { - break; - } - - let handle = new RNPLib.rnp_key_handle_t(); - if (RNPLib.rnp_locate_key(RNPLib.ffi, "grip", grip, handle.address())) { - throw new Error("rnp_locate_key failed"); - } - - if (this.getSecretAvailableFromHandle(handle)) { - let is_protected = new ctypes.bool(); - if (RNPLib.rnp_key_is_protected(handle, is_protected.address())) { - throw new Error("rnp_key_is_protected failed"); - } - if (is_protected.value) { - prot++; - } else { - unprot++; - } - } - - RNPLib.rnp_key_handle_destroy(handle); - } - - RNPLib.rnp_identifier_iterator_destroy(iter); - return [prot, unprot]; + return RNPLib.getProtectedKeysCount(); }, async protectUnprotectedKeys() { - let iter = new RNPLib.rnp_identifier_iterator_t(); - let grip = new ctypes.char.ptr(); - - let newPass = await OpenPGPMasterpass.retrieveOpenPGPPassword(); - - if ( - RNPLib.rnp_identifier_iterator_create(RNPLib.ffi, iter.address(), "grip") - ) { - throw new Error("rnp_identifier_iterator_create failed"); - } - - while (!RNPLib.rnp_identifier_iterator_next(iter, grip.address())) { - if (grip.isNull()) { - break; - } - - let handle = new RNPLib.rnp_key_handle_t(); - if (RNPLib.rnp_locate_key(RNPLib.ffi, "grip", grip, handle.address())) { - throw new Error("rnp_locate_key failed"); - } - - if (this.getSecretAvailableFromHandle(handle)) { - let is_protected = new ctypes.bool(); - if (RNPLib.rnp_key_is_protected(handle, is_protected.address())) { - throw new Error("rnp_key_is_protected failed"); - } - if (!is_protected.value) { - this.protectKeyWithSubKeys(handle, newPass); - } - } - - RNPLib.rnp_key_handle_destroy(handle); - } - - RNPLib.rnp_identifier_iterator_destroy(iter); + return RNPLib.protectUnprotectedKeys(); }, /* Some consumers want a different listing of keys, and expect @@ -392,11 +326,7 @@ }, getSecretAvailableFromHandle(handle) { - let have_secret = new ctypes.bool(); - if (RNPLib.rnp_key_have_secret(handle, have_secret.address())) { - throw new Error("rnp_key_have_secret failed"); - } - return have_secret.value; + return RNPLib.getSecretAvailableFromHandle(handle); }, // We already know sub_handle is a subkey @@ -997,7 +927,9 @@ false ); - let max_out = encrypted.length * 10; + // Allow compressed encrypted messages, max factor 1200, up to 100 MiB. + const max_decrypted_message_size = 100 * 1024 * 1024; + let max_out = Math.min(encrypted.length * 1200, max_decrypted_message_size); let output_to_memory = new RNPLib.rnp_output_t(); RNPLib.rnp_output_to_memory(output_to_memory.address(), max_out); @@ -1349,13 +1281,13 @@ if (uid.type !== "uid") { continue; } - let split = {}; - if (uidHelper.getPartsFromUidStr(uid.userId, split)) { - let uidEmail = split.email.toLowerCase(); - if (uidEmail === fromLower) { - fromMatchesAnyUid = true; - break; - } + + if ( + EnigmailFuncs.getEmailFromUserID(uid.userId).toLowerCase() === + fromLower + ) { + fromMatchesAnyUid = true; + break; } } @@ -1786,28 +1718,6 @@ return rv; }, - protectKeyWithSubKeys(handle, newPass) { - if (RNPLib.rnp_key_protect(handle, newPass, null, null, null, 0)) { - throw new Error("rnp_key_protect failed"); - } - - let sub_count = new ctypes.size_t(); - if (RNPLib.rnp_key_get_subkey_count(handle, sub_count.address())) { - throw new Error("rnp_key_get_subkey_count failed"); - } - - for (let i = 0; i < sub_count.value; i++) { - let sub_handle = new RNPLib.rnp_key_handle_t(); - if (RNPLib.rnp_key_get_subkey_at(handle, i, sub_handle.address())) { - throw new Error("rnp_key_get_subkey_at failed"); - } - if (RNPLib.rnp_key_protect(sub_handle, newPass, null, null, null, 0)) { - throw new Error("rnp_key_protect failed"); - } - RNPLib.rnp_key_handle_destroy(sub_handle); - } - }, - async importKeyBlockImpl( win, passCB, @@ -1921,33 +1831,66 @@ // the new passphrase. If a failure occurrs at some point, // all keys remain protected in memory. - let rv = RNPLib.rnp_key_unprotect(impKey, recentPass); - if (rv == 0) { - if (RNPLib.rnp_key_protect(impKey, newPass, null, null, null, 0)) { - throw new Error("rnp_key_protect failed"); + let rv = 0; + + // Don't attempt to unprotect secret keys that are unavailable. + if (RNPLib.isSecretKeyMaterialAvailable(impKey)) { + rv = RNPLib.rnp_key_unprotect(impKey, recentPass); + if (rv == 0) { + if ( + RNPLib.rnp_key_protect(impKey, newPass, null, null, null, 0) + ) { + throw new Error("rnp_key_protect failed"); + } } + } + if (rv == 0) { let sub_count = new ctypes.size_t(); if (RNPLib.rnp_key_get_subkey_count(impKey, sub_count.address())) { throw new Error("rnp_key_get_subkey_count failed"); } - for (let i = 0; i < sub_count.value && !unableToUnprotectId; i++) { + for ( + let i = 0; + i < sub_count.value && !unableToUnprotectId && !rv; + i++ + ) { let sub_handle = new RNPLib.rnp_key_handle_t(); if ( RNPLib.rnp_key_get_subkey_at(impKey, i, sub_handle.address()) ) { throw new Error("rnp_key_get_subkey_at failed"); } - if (RNPLib.rnp_key_unprotect(sub_handle, recentPass)) { - unableToUnprotectId = RNP.getKeyIDFromHandle(sub_handle); - } else if ( - RNPLib.rnp_key_protect(sub_handle, newPass, null, null, null, 0) - ) { - throw new Error("rnp_key_protect failed"); + + if (RNPLib.isSecretKeyMaterialAvailable(sub_handle)) { + rv = RNPLib.rnp_key_unprotect(sub_handle, recentPass); + if (rv) { + // if (!recentPass), we haven't yet asked the user + // for a password, or the user hasn't yet entered the + // password. That's not yet a failure. + if (recentPass) { + unableToUnprotectId = RNP.getKeyIDFromHandle(sub_handle); + } + } else if ( + RNPLib.rnp_key_protect( + sub_handle, + newPass, + null, + null, + null, + 0 + ) + ) { + throw new Error("rnp_key_protect failed"); + } } + RNPLib.rnp_key_handle_destroy(sub_handle); } - break; + + if (rv == 0) { + break; + } } if (unableToUnprotectId) { @@ -2074,6 +2017,15 @@ throw new Error("rnp_import_keys failed"); } + let impKey2 = await this.getKeyHandleByIdentifier( + RNPLib.ffi, + "0x" + k.fpr + ); + if (k.secretAvailable) { + RNPLib.protectKeyWithSubKeys(impKey2, newPass); + } + RNPLib.rnp_key_handle_destroy(impKey2); + result.importedKeys.push("0x" + k.id); RNPLib.rnp_input_destroy(input_from_memory); @@ -2113,10 +2065,10 @@ if (uid.type != "uid") { continue; } - let splitUid = {}; - uidHelper.getPartsFromUidStr(uid.userId, splitUid); - if (splitUid.email) { - allEmails.push(splitUid.email); + + let uidEmail = EnigmailFuncs.getEmailFromUserID(uid.userId); + if (uidEmail) { + allEmails.push(uidEmail); } } await PgpSqliteDb2.updateAcceptance(k.fpr, allEmails, acceptance); @@ -2725,10 +2677,9 @@ let userId = uid_str.readStringReplaceMalformed(); RNPLib.rnp_buffer_destroy(uid_str); - let split = {}; if ( - uidHelper.getPartsFromUidStr(userId, split) && - split.email.toLowerCase() == emailWithoutBrackets + EnigmailFuncs.getEmailFromUserID(userId).toLowerCase() == + emailWithoutBrackets ) { foundUid = true; diff -Nru thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/RNPLib.jsm thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/RNPLib.jsm --- thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/RNPLib.jsm 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/RNPLib.jsm 2021-05-17 17:53:02.000000000 +0000 @@ -15,6 +15,9 @@ var { EnigmailCryptoAPI } = ChromeUtils.import( "chrome://openpgp/content/modules/cryptoAPI.jsm" ); +var EnigmailTimer = ChromeUtils.import( + "chrome://openpgp/content/modules/timer.jsm" +).EnigmailTimer; var { OpenPGPMasterpass } = ChromeUtils.import( "chrome://openpgp/content/modules/masterpass.jsm" ); @@ -215,6 +218,39 @@ } }, + async _fixUnprotectedKeys() { + // Bug 1710290, protect all unprotected keys. + // To do so, we require that the user has already unlocked + // by entering the global master password, if it is set. + // Ensure that other repairing is done first, if necessary, + // as handled by masterpass.jsm (OpenPGP automatic password). + + // Note we have two failure scenarios, either a failure, or + // retrieveOpenPGPPassword() returning null (that function + // might fail because of inconsistencies or corruption). + let canRepair = false; + try { + console.log("Trying to automatically protect the unprotected keys."); + let mp = await OpenPGPMasterpass.retrieveOpenPGPPassword(); + if (mp) { + await RNPLib.protectUnprotectedKeys(); + await RNPLib.saveKeys(); + canRepair = true; + console.log("Successfully protected the unprotected keys."); + let [prot, unprot] = RNPLib.getProtectedKeysCount(); + console.debug( + `Found (${prot} protected and ${unprot} unprotected secret keys.` + ); + } + } catch (ex) { + console.log(ex); + } + + if (!canRepair) { + console.log("Cannot protect the unprotected keys at this time."); + } + }, + async init() { this.ffi = new rnp_ffi_t(); if (this.rnp_ffi_create(this.ffi.address(), "GPG", "GPG")) { @@ -251,18 +287,185 @@ let secnum = new ctypes.size_t(); this.rnp_get_secret_key_count(this.ffi, secnum.address()); + let [prot, unprot] = this.getProtectedKeysCount(); console.debug( - "public keys: " + pubnum.value + ", secret keys: " + secnum.value + `Found ${pubnum.value} public keys and ${secnum.value} secret keys (${prot} protected, ${unprot} unprotected)` ); - /* - if (this.rnp_ffi_destroy(this.ffi)) { - throw new Error("Couldn't destroy librnp."); + if (unprot) { + // We need automatic repair, which can involve a master password + // prompt. Let's use a short timer, so we keep it out of the + // early startup code. + console.log( + "Will attempt to automatically protect the unprotected keys in 30 seconds" + ); + EnigmailTimer.setTimeout(RNPLib._fixUnprotectedKeys, 30000); } - */ return true; }, + /** + * Returns two numbers, the number of protected and unprotected keys. + * Because we use an automatic password for all secret keys + * (regardless of a primary password being used), + * the number of unprotected keys should be zero. + */ + getProtectedKeysCount() { + let prot = 0; + let unprot = 0; + + let iter = new RNPLib.rnp_identifier_iterator_t(); + let grip = new ctypes.char.ptr(); + + if ( + RNPLib.rnp_identifier_iterator_create( + RNPLib.ffi, + iter.address(), + "grip" + ) + ) { + throw new Error("rnp_identifier_iterator_create failed"); + } + + while ( + !RNPLib.rnp_identifier_iterator_next(iter, grip.address()) && + !grip.isNull() + ) { + let handle = new RNPLib.rnp_key_handle_t(); + if (RNPLib.rnp_locate_key(RNPLib.ffi, "grip", grip, handle.address())) { + throw new Error("rnp_locate_key failed"); + } + + if (this.getSecretAvailableFromHandle(handle)) { + let is_protected = new ctypes.bool(); + if (RNPLib.rnp_key_is_protected(handle, is_protected.address())) { + throw new Error("rnp_key_is_protected failed"); + } + if (is_protected.value) { + prot++; + } else { + unprot++; + } + } + + RNPLib.rnp_key_handle_destroy(handle); + } + + RNPLib.rnp_identifier_iterator_destroy(iter); + return [prot, unprot]; + }, + + getSecretAvailableFromHandle(handle) { + let have_secret = new ctypes.bool(); + if (RNPLib.rnp_key_have_secret(handle, have_secret.address())) { + throw new Error("rnp_key_have_secret failed"); + } + return have_secret.value; + }, + + /** + * If the given secret key is a pseudo secret key, which doesn't + * contain the underlying key material, then return false. + * + * Only call this function if getSecretAvailableFromHandle returns + * true for the given handle (which means it claims to contain a + * secret key). + * + * @param {rnp_key_handle_t} handle - handle of the key to query + * @return {boolean} - true if secret key material is available + * + */ + isSecretKeyMaterialAvailable(handle) { + let protection_type = new ctypes.char.ptr(); + if ( + RNPLib.rnp_key_get_protection_type(handle, protection_type.address()) + ) { + throw new Error("rnp_key_get_protection_type failed"); + } + let result; + switch (protection_type.readString()) { + case "GPG-None": + case "GPG-Smartcard": + case "Unknown": + result = false; + break; + default: + result = true; + break; + } + RNPLib.rnp_buffer_destroy(protection_type); + return result; + }, + + async protectUnprotectedKeys() { + let iter = new RNPLib.rnp_identifier_iterator_t(); + let grip = new ctypes.char.ptr(); + + let newPass = await OpenPGPMasterpass.retrieveOpenPGPPassword(); + + if ( + RNPLib.rnp_identifier_iterator_create( + RNPLib.ffi, + iter.address(), + "grip" + ) + ) { + throw new Error("rnp_identifier_iterator_create failed"); + } + + while ( + !RNPLib.rnp_identifier_iterator_next(iter, grip.address()) && + !grip.isNull() + ) { + let handle = new RNPLib.rnp_key_handle_t(); + if (RNPLib.rnp_locate_key(RNPLib.ffi, "grip", grip, handle.address())) { + throw new Error("rnp_locate_key failed"); + } + + if (RNPLib.getSecretAvailableFromHandle(handle)) { + let is_protected = new ctypes.bool(); + if (RNPLib.rnp_key_is_protected(handle, is_protected.address())) { + throw new Error("rnp_key_is_protected failed"); + } + if (!is_protected.value) { + RNPLib.protectKeyWithSubKeys(handle, newPass); + } + } + + RNPLib.rnp_key_handle_destroy(handle); + } + + RNPLib.rnp_identifier_iterator_destroy(iter); + }, + + protectKeyWithSubKeys(handle, newPass) { + if (RNPLib.isSecretKeyMaterialAvailable(handle)) { + if (RNPLib.rnp_key_protect(handle, newPass, null, null, null, 0)) { + throw new Error("rnp_key_protect failed"); + } + } + + let sub_count = new ctypes.size_t(); + if (RNPLib.rnp_key_get_subkey_count(handle, sub_count.address())) { + throw new Error("rnp_key_get_subkey_count failed"); + } + + for (let i = 0; i < sub_count.value; i++) { + let sub_handle = new RNPLib.rnp_key_handle_t(); + if (RNPLib.rnp_key_get_subkey_at(handle, i, sub_handle.address())) { + throw new Error("rnp_key_get_subkey_at failed"); + } + if (RNPLib.isSecretKeyMaterialAvailable(sub_handle)) { + if ( + RNPLib.rnp_key_protect(sub_handle, newPass, null, null, null, 0) + ) { + throw new Error("rnp_key_protect failed"); + } + } + RNPLib.rnp_key_handle_destroy(sub_handle); + } + }, + async saveKeyRing(fileObj, keyRingFlag) { let oldSuffix = ".old"; let oldFile = fileObj.clone(); @@ -1395,6 +1598,14 @@ ctypes.uint32_t ), + rnp_key_get_protection_type: librnp.declare( + "rnp_key_get_protection_type", + abi, + rnp_result_t, + rnp_key_handle_t, + ctypes.char.ptr.ptr + ), + rnp_result_t, rnp_ffi_t, rnp_password_cb_t, diff -Nru thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/trust.jsm thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/trust.jsm --- thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/trust.jsm 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/trust.jsm 2021-05-17 17:53:03.000000000 +0000 @@ -53,18 +53,7 @@ return TRUSTLEVELS_SORTED.indexOf(flag) < TRUSTLEVELS_SORTED_IDX_UNKNOWN; }, - /** - * return a merged value of trust level "key disabled" - * - * @keyObj - |object| containing the key data - * - * @return - |string| containing the trust value or "D" for disabled keys - */ getTrustCode(keyObj) { - if (keyObj.keyUseFor.includes("D")) { - return "D"; - } - return keyObj.keyTrust; }, diff -Nru thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/uidHelper.jsm thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/uidHelper.jsm --- thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/modules/uidHelper.jsm 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/modules/uidHelper.jsm 2021-05-17 17:53:02.000000000 +0000 @@ -8,6 +8,10 @@ var EXPORTED_SYMBOLS = ["uidHelper"]; +var EnigmailFuncs = ChromeUtils.import( + "chrome://openpgp/content/modules/funcs.jsm" +).EnigmailFuncs; + /* Parse a OpenPGP user ID string and split it into its parts. * The expected syntax is: * Name (comment) @@ -22,7 +26,7 @@ // If that condition is true, then conclude it's probably an // email address that wasn't enclosed in <>. looksLikeEmail(str) { - return str.match(/^(".+"|[^ ]+)@[^ @]+$/); + return EnigmailFuncs.stringLooksLikeEmailAddress(str); }, getPartsFromUidStr(uid, resultObj) { @@ -34,34 +38,13 @@ return false; } - // RegExp strategy: - // Search until the first ( or < character, use that as Name. - // Then search for the () characters, allow any characters until ). - // Do the same for <>. - // No characters are allowed between a closing ) and opening <. - // All characters after a trailing > are ignored. - let result = uid.match(/^ *([^(<]*)? *(\([^)]*\))? *(<[^>]*>)?/); - if (result.length != 4) { + resultObj.email = EnigmailFuncs.getEmailFromUserID(uid); + if (!resultObj.email) { return false; } - if (result[1]) { - resultObj.name = result[1].trim(); - } - - if (result[1] && !result[2] && !result[3]) { - if (this.looksLikeEmail(resultObj.name)) { - resultObj.email = resultObj.name; - resultObj.name = ""; - } - } else { - if (result[2]) { - resultObj.comment = result[2].substring(1, result[2].length - 1).trim(); - } - if (result[3]) { - resultObj.email = result[3].substring(1, result[3].length - 1).trim(); - } - } + resultObj.name = uid.replace(resultObj.email, ""); + resultObj.name = resultObj.name.replace("<>", "").trim(); return true; }, diff -Nru thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/ui/enigmailKeyManager.js thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/ui/enigmailKeyManager.js --- thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/ui/enigmailKeyManager.js 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/ui/enigmailKeyManager.js 2021-05-17 17:53:03.000000000 +0000 @@ -61,9 +61,6 @@ var { KeyLookupHelper } = ChromeUtils.import( "chrome://openpgp/content/modules/keyLookupHelper.jsm" ); -var { uidHelper } = ChromeUtils.import( - "chrome://openpgp/content/modules/uidHelper.jsm" -); var l10n = new Localization(["messenger/openpgp/openpgp.ftl"], true); @@ -783,10 +780,9 @@ } result.value = result.value.trim(); - let isEmail = uidHelper.looksLikeEmail(result.value); let imported = false; - if (isEmail) { + if (EnigmailFuncs.stringLooksLikeEmailAddress(result.value)) { imported = KeyLookupHelper.lookupAndImportByEmail( window, result.value, @@ -1387,12 +1383,6 @@ case "q": keyTrustStyle = "enigmail_keyValid_unknown"; break; - case "i": - keyTrustStyle = "enigmail_keyValid_invalid"; - break; - case "d": - keyTrustStyle = "enigmail_keyValid_disabled"; - break; case "r": keyTrustStyle = "enigmail_keyValid_revoked"; break; @@ -1419,14 +1409,9 @@ break; } - if (keyObj.keyUseFor.includes("D")) { - keyTrustStyle = "enigmail_keyValid_disabled"; - } - if ( - (keyObj.keyTrust.length > 0 && - ENIG_KEY_NOT_VALID.includes(keyObj.keyTrust.charAt(0))) || - keyObj.keyUseFor.includes("D") + keyObj.keyTrust.length > 0 && + ENIG_KEY_NOT_VALID.includes(keyObj.keyTrust.charAt(0)) ) { keyTrustStyle += " enigKeyInactive"; } diff -Nru thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/ui/enigmailMessengerOverlay.js thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/ui/enigmailMessengerOverlay.js --- thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/ui/enigmailMessengerOverlay.js 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/ui/enigmailMessengerOverlay.js 2021-05-17 17:53:03.000000000 +0000 @@ -137,9 +137,6 @@ var KeyLookupHelper = ChromeUtils.import( "chrome://openpgp/content/modules/keyLookupHelper.jsm" ).KeyLookupHelper; -var { uidHelper } = ChromeUtils.import( - "chrome://openpgp/content/modules/uidHelper.jsm" -); var { PgpSqliteDb2 } = ChromeUtils.import( "chrome://openpgp/content/modules/sqliteDb.jsm" ); @@ -400,6 +397,7 @@ ]) { this.removeNotification(value); } + Enigmail.msg.showPartialDecryptionReminder = false; let element = document.getElementById("openpgpKeyBox"); if (element) { @@ -687,14 +685,6 @@ cryptoBox.setAttribute("decryptDone", "true"); } - // Interrupt if the message wasn't properly decrypted. - if ( - !Enigmail.msg.decryptedMessage || - typeof Enigmail.msg.decryptedMessage == "undefined" - ) { - return; - } - // Show the partial inline encryption reminder only if the decryption action // came from a partially inline encrypted message. if (Enigmail.msg.showPartialDecryptionReminder) { @@ -1099,12 +1089,7 @@ ); }, - trimIfEncrypted(msgText) { - // If it's an encrypted message, we want to trim (at least) the - // separator line between the header and the content. - // However, trimming all lines should be safe. - let trimEncrypted = false; - + getFirstPGPMessageType(msgText) { let indexEncrypted = msgText.indexOf("-----BEGIN PGP MESSAGE-----"); let indexSigned = msgText.indexOf("-----BEGIN PGP SIGNED MESSAGE-----"); if (indexEncrypted >= 0) { @@ -1112,11 +1097,23 @@ indexSigned == -1 || (indexSigned >= 0 && indexEncrypted < indexSigned) ) { - trimEncrypted = true; + return "encrypted"; } } - if (trimEncrypted) { + if (indexSigned >= 0) { + return "signed"; + } + + return ""; + }, + + trimIfEncrypted(msgText) { + // If it's an encrypted message, we want to trim (at least) the + // separator line between the header and the content. + // However, trimming all lines should be safe. + + if (Enigmail.msg.getFirstPGPMessageType(msgText) == "encrypted") { // \xA0 is non-breaking-space msgText = msgText.replace(/^[ \t\xA0]+/gm, ""); } @@ -1149,20 +1146,14 @@ var msgText = null; var foundIndex = -1; + let bodyElementFound = false; + let hasHeadOrTailNode = false; + if (bodyElement.firstChild) { let node = bodyElement.firstChild; while (node) { if ( node.firstChild && - node.firstChild.nodeName == "LEGEND" && - node.firstChild.className == "mimeAttachmentHeaderName" - ) { - // we reached the area where inline attachments are displayed - // --> don't try to decrypt displayed inline attachments - break; - } - if ( - node.firstChild && node.firstChild.nodeName.toUpperCase() == "LEGEND" && node.firstChild.className == "mimeAttachmentHeaderName" ) { @@ -1171,27 +1162,39 @@ break; } if (node.nodeName === "DIV") { + if (bodyElementFound) { + hasHeadOrTailNode = true; + break; + } + foundIndex = node.textContent.indexOf(findStr); + if (foundIndex < 0) { + hasHeadOrTailNode = true; + node = node.nextSibling; + continue; + } + if (foundIndex >= 0) { if ( node.textContent.indexOf(findStr + " LICENSE AUTHORIZATION") == foundIndex ) { foundIndex = -1; + node = node.nextSibling; + continue; } } if (foundIndex === 0) { bodyElement = node; - break; - } - if ( + bodyElementFound = true; + } else if ( foundIndex > 0 && node.textContent.substr(foundIndex - 1, 1).search(/[\r\n]/) === 0 ) { bodyElement = node; - break; + bodyElementFound = true; } } node = node.nextSibling; @@ -1199,6 +1202,10 @@ } if (foundIndex >= 0 && !this.hasInlineQuote(topElement)) { + let beginIndex = {}; + let endIndex = {}; + let indentStr = {}; + if ( Enigmail.msg.savedHeaders["content-type"].search(/^text\/html/i) === 0 ) { @@ -1214,6 +1221,23 @@ } else { msgText = bodyElement.textContent; } + + if (!isAuto) { + let blockType = EnigmailArmor.locateArmoredBlock( + msgText, + 0, + "", + beginIndex, + endIndex, + indentStr + ); + if (!blockType) { + msgText = ""; + } else { + msgText = msgText.substring(beginIndex.value, endIndex.value + 1); + } + } + msgText = this.trimIfEncrypted(msgText); } @@ -1290,7 +1314,7 @@ } if (isAuto) { - let ht = this.hasHeadOrTailBesidesInlinePGP(msgText); + let ht = hasHeadOrTailNode || this.hasHeadOrTailBesidesInlinePGP(msgText); if (ht) { let infoId; let buttonId; @@ -1311,8 +1335,8 @@ { label: buttonLabel, popup: null, - async callback(aNotification, aButton) { - await Enigmail.msg.processOpenPGPSubset(); + callback(aNotification, aButton) { + Enigmail.msg.processOpenPGPSubset(); return false; // Close notification. }, }, @@ -1554,6 +1578,19 @@ var displayedUriSpec = Enigmail.msg.getCurrentMsgUriSpec(); if (!msgUriSpec || displayedUriSpec == msgUriSpec) { + if (exitCode && !statusFlags) { + // Failure, but we don't know why it failed. + // Peek inside msgText, and check what kind of content it is, + // so we can show a minimal error. + + let msgType = Enigmail.msg.getFirstPGPMessageType(msgText); + if (msgType == "encrypted") { + statusFlags = EnigmailConstants.DECRYPTION_FAILED; + } else if (msgType == "signed") { + statusFlags = EnigmailConstants.BAD_SIGNATURE; + } + } + Enigmail.hdrView.updateHdrIcons( exitCode, statusFlags, @@ -1643,14 +1680,8 @@ } if (!plainText) { - if ( - interactive && - Enigmail.msg.securityInfo && - Enigmail.msg.securityInfo.statusInfo - ) { - EnigmailDialog.info(window, Enigmail.msg.securityInfo.statusInfo); - } - return; + // Show the subset that we cannot process, together with status. + plainText = msgText; } if (retry >= 2) { @@ -1758,32 +1789,52 @@ if (bodyElement.firstChild) { node = bodyElement.firstChild; + let divFound = false; + while (node) { if (node.nodeName == "DIV") { - // for safety reasons, we replace the complete visible message with - // the decrypted or signed part (bug 983) - node.innerHTML = EnigmailFuncs.formatPlaintextMsg( - EnigmailData.convertToUnicode(messageContent, charset) - ); - Enigmail.msg.movePEPsubject(); - return; + if (divFound) { + node.innerHTML = ""; + } else { + // for safety reasons, we replace the complete visible message with + // the decrypted or signed part (bug 983) + divFound = true; + node.innerHTML = EnigmailFuncs.formatPlaintextMsg( + EnigmailData.convertToUnicode(messageContent, charset) + ); + Enigmail.msg.movePEPsubject(); + } } node = node.nextSibling; } + if (divFound) { + return; + } + + let preFound = false; + // if no
node is found, try with
 (bug 24762)
       node = bodyElement.firstChild;
       while (node) {
         if (node.nodeName == "PRE") {
-          node.innerHTML = EnigmailFuncs.formatPlaintextMsg(
-            EnigmailData.convertToUnicode(messageContent, charset)
-          );
-          Enigmail.msg.movePEPsubject();
-          return;
+          if (preFound) {
+            node.innerHTML = "";
+          } else {
+            preFound = true;
+            node.innerHTML = EnigmailFuncs.formatPlaintextMsg(
+              EnigmailData.convertToUnicode(messageContent, charset)
+            );
+            Enigmail.msg.movePEPsubject();
+          }
         }
         node = node.nextSibling;
       }
 
+      if (preFound) {
+        return;
+      }
+
       // HACK for MS-EXCHANGE-Server Problem:
       // - remove empty text/plain part
       //   and set message content as inner text
@@ -3492,11 +3543,9 @@
         continue;
       }
 
-      let splitUid = {};
-      uidHelper.getPartsFromUidStr(id.userId, splitUid);
-      splitUid.email = splitUid.email.toLowerCase();
-
-      if (splitUid.email == authorEmail) {
+      if (
+        EnigmailFuncs.getEmailFromUserID(id.userId).toLowerCase() == authorEmail
+      ) {
         return true;
       }
     }
diff -Nru thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/ui/keyDetailsDlg.js thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/ui/keyDetailsDlg.js
--- thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/content/ui/keyDetailsDlg.js	2021-05-04 14:24:02.000000000 +0000
+++ thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/content/ui/keyDetailsDlg.js	2021-05-17 17:53:03.000000000 +0000
@@ -11,7 +11,7 @@
 /* global EnigCleanGuiList: false, EnigGetTrustLabel: false, EnigShowPhoto: false, EnigSignKey: false */
 /* global EnigEditKeyExpiry: false, EnigEditKeyTrust: false, EnigChangeKeyPwd: false */
 /* global EnigCreateRevokeCert: false, EnigmailTimer: false, EnigmailCryptoAPI: false */
-/* global PgpSqliteDb2: false, l10n: false, EnigmailDialog: false */
+/* global PgpSqliteDb2: false, l10n: false, EnigmailDialog: false, EnigmailFuncs: false */
 
 // from enigmailKeyManager.js:
 /* global keyMgrAddPhoto: false, EnigmailCompat: false */
@@ -20,10 +20,6 @@
 
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-var { uidHelper } = ChromeUtils.import(
-  "chrome://openpgp/content/modules/uidHelper.jsm"
-);
-
 var gModePersonal = false;
 
 var gKeyId = null;
@@ -162,10 +158,9 @@
 
   gUserId = keyObj.userId;
 
-  let splitUid = {};
-  uidHelper.getPartsFromUidStr(keyObj.userId, splitUid);
-  if (splitUid.email) {
-    gAllEmails.push(splitUid.email);
+  let userEmail = EnigmailFuncs.getEmailFromUserID(keyObj.userId);
+  if (userEmail) {
+    gAllEmails.push(userEmail);
   }
 
   setLabel("userId", gUserId);
@@ -288,10 +283,11 @@
         item.setAttribute("class", "enigmailDisabled");
       }
 
-      let splitUid = {};
-      uidHelper.getPartsFromUidStr(keyDetails.userIds[i].userId, splitUid);
-      if (splitUid.email) {
-        gAllEmails.push(splitUid.email);
+      let uidEmail = EnigmailFuncs.getEmailFromUserID(
+        keyDetails.userIds[i].userId
+      );
+      if (uidEmail) {
+        gAllEmails.push(uidEmail);
       }
     }
   }
@@ -545,10 +541,15 @@
     expire = subkey.expiry;
   }
 
-  let subkeyType =
-    subkey.type === "pub"
-      ? l10n.formatValueSync("key-type-primary")
-      : l10n.formatValueSync("key-type-subkey");
+  let subkeyType = "";
+  if (subkey.secretAvailable && !subkey.secretMaterial) {
+    subkeyType = "(!) ";
+  }
+  if (subkey.type === "pub") {
+    subkeyType += l10n.formatValueSync("key-type-primary");
+  } else {
+    subkeyType += l10n.formatValueSync("key-type-subkey");
+  }
 
   let usagetext = "";
   let i;
diff -Nru thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/test/unit/rnp/test_secretKeys.js thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/test/unit/rnp/test_secretKeys.js
--- thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/test/unit/rnp/test_secretKeys.js	2021-05-04 14:24:02.000000000 +0000
+++ thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/test/unit/rnp/test_secretKeys.js	2021-05-17 17:53:03.000000000 +0000
@@ -16,10 +16,15 @@
 const { EnigmailConstants } = ChromeUtils.import(
   "chrome://openpgp/content/modules/constants.jsm"
 );
+const { EnigmailFiles } = ChromeUtils.import(
+  "chrome://openpgp/content/modules/files.jsm"
+);
 const { EnigmailKeyRing } = ChromeUtils.import(
   "chrome://openpgp/content/modules/keyRing.jsm"
 );
-
+const { FileUtils } = ChromeUtils.import(
+  "resource://gre/modules/FileUtils.jsm"
+);
 const { OpenPGPTestUtils } = ChromeUtils.import(
   "resource://testing-common/mozmill/OpenPGPTestUtils.jsm"
 );
@@ -139,3 +144,84 @@
     "after import, EnigmailKeyRing.getKeyById should return an object with a secret key"
   );
 });
+
+add_task(async function testImportSecretKeyIsProtected() {
+  let carolFile = do_get_file(
+    `${keyDir}/carol@example.com-0x3099ff1238852b9f-secret.asc`
+  );
+  let carolSec = EnigmailFiles.readFile(carolFile);
+
+  // Carol's secret key is protected with password "x".
+  let getCarolPassword = function(win, keyId, resultFlags) {
+    return "x";
+  };
+
+  let importResult = await RNP.importKeyBlockImpl(
+    null,
+    getCarolPassword,
+    carolSec,
+    false,
+    true
+  );
+
+  Assert.equal(
+    importResult.exitCode,
+    0,
+    "Should be able to import Carol's secret key"
+  );
+
+  let aliceFile = do_get_file(
+    `${keyDir}/alice@openpgp.example-0xf231550c4f47e38e-secret.asc`
+  );
+  let aliceSec = EnigmailFiles.readFile(aliceFile);
+
+  // Alice's secret key is unprotected.
+  importResult = await RNP.importKeyBlockImpl(
+    null,
+    null,
+    aliceSec,
+    false,
+    true
+  );
+
+  Assert.equal(
+    importResult.exitCode,
+    0,
+    "Should be able to import Alice's secret key"
+  );
+
+  let [prot, unprot] = OpenPGPTestUtils.getProtectedKeysCount();
+  Assert.notEqual(prot, 0, "Should have protected secret keys");
+  Assert.equal(unprot, 0, "Should not have any unprotected secret keys");
+});
+
+add_task(async function testImportOfflinePrimaryKey() {
+  let keyBlock = EnigmailFiles.readFile(
+    do_get_file(`${keyDir}/ofelia-secret-subkeys.asc`)
+  );
+
+  let cancelPassword = function(win, keyId, resultFlags) {
+    resultFlags.canceled = true;
+    return "";
+  };
+
+  let importResult = await RNP.importKeyBlockImpl(
+    null,
+    cancelPassword,
+    keyBlock,
+    false,
+    true
+  );
+
+  Assert.ok(importResult.exitCode == 0);
+
+  let primaryKey = await RNP.findKeyByEmail("", false);
+
+  let encSubKey = RNP.getSuitableSubkey(primaryKey, "encrypt");
+  let keyId = RNP.getKeyIDFromHandle(encSubKey);
+  Assert.equal(
+    keyId,
+    "31C31DF1DFB67601",
+    "should obtain key ID of encryption subkey"
+  );
+});
diff -Nru thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/test/unit/rnp/test_uid.js thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/test/unit/rnp/test_uid.js
--- thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/test/unit/rnp/test_uid.js	1970-01-01 00:00:00.000000000 +0000
+++ thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/test/unit/rnp/test_uid.js	2021-05-17 17:53:03.000000000 +0000
@@ -0,0 +1,154 @@
+/* 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 http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Tests for OpenPGP encryption alias rules.
+ */
+
+"use strict";
+
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { OpenPGPTestUtils } = ChromeUtils.import(
+  "resource://testing-common/mozmill/OpenPGPTestUtils.jsm"
+);
+const { EnigmailFuncs } = ChromeUtils.import(
+  "chrome://openpgp/content/modules/funcs.jsm"
+);
+const uidHelper = ChromeUtils.import(
+  "chrome://openpgp/content/modules/uidHelper.jsm"
+).uidHelper;
+
+const tests = [
+  {
+    input: "Cherry Blossom (桜の花) (description) ",
+    email: "email@example.com",
+  },
+  {
+    input:
+      "Cherry Blossom (桜の花) (description) (more information) ",
+    email: "email@example.com",
+  },
+  {
+    input: "First Last ",
+    email: "email@example.com",
+  },
+  {
+    input: "Last, First ",
+    email: "email@example.com",
+  },
+  {
+    input: "email@example.com",
+    email: "email@example.com",
+  },
+  {
+    input: "",
+    email: "email@example.com",
+  },
+  {
+    input: "First Last email@example.com>",
+    email: "",
+  },
+  {
+    input: "First Last (comment) ",
+    email: "email@example.com",
+  },
+  {
+    input: "First Last (a) (b) (c) (comment) ",
+    email: "email@example.com",
+  },
+  {
+    input: "First Last (comment ",
+    email: "email@example.com",
+  },
+  {
+    input: "First Last )comment) ",
+    email: "email@example.com",
+  },
+  {
+    input: "",
+    email: "",
+  },
+  {
+    input: "First Last () <>",
+    email: "",
+  },
+  {
+    input: "First Last () <> <> <>",
+    email: "",
+  },
+  {
+    input: "First Last () <> ",
+    email: "",
+  },
+  {
+    input: "First  (comment) ",
+    email: "",
+  },
+  {
+    input: "First Last  (bad comment)",
+    email: "email@example.com",
+  },
+  {
+    input: "First Last  extra text",
+    email: "email@example.com",
+  },
+  {
+    input: "First Last  extra text",
+    email: "",
+  },
+  {
+    input: "First Last (comment (nested)) ",
+    email: "email@example.com",
+  },
+  {
+    input:
+      "First Last (comment (no second closing bracket) ",
+    email: "email@example.com",
+  },
+  {
+    input: "",
+    email: "",
+  },
+  {
+    input: "",
+    email: "",
+  },
+];
+
+/**
+ * Initialize OpenPGP add testing keys.
+ */
+add_task(async function setUp() {
+  do_get_profile();
+
+  await OpenPGPTestUtils.initOpenPGP();
+});
+
+add_task(async function testAlias() {
+  for (let test of tests) {
+    console.debug("testing input: " + test.input);
+
+    let email = EnigmailFuncs.getEmailFromUserID(test.input);
+
+    Assert.equal(test.email, email);
+  }
+});
+
+add_task(async function testUidHelper() {
+  let splitUid = {};
+  uidHelper.getPartsFromUidStr(
+    "First Last (comment1) (comment2) ",
+    splitUid
+  );
+  Assert.equal(
+    splitUid.email,
+    "email@example.com",
+    "uidHelper should be able to extract email"
+  );
+  Assert.equal(
+    splitUid.name,
+    "First Last (comment1) (comment2)",
+    "uidHelper should be able to extract name"
+  );
+});
diff -Nru thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/test/unit/rnp/xpcshell.ini thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/test/unit/rnp/xpcshell.ini
--- thunderbird-78.10.1+build1/comm/mail/extensions/openpgp/test/unit/rnp/xpcshell.ini	2021-05-04 14:24:02.000000000 +0000
+++ thunderbird-78.10.2+build1/comm/mail/extensions/openpgp/test/unit/rnp/xpcshell.ini	2021-05-17 17:53:03.000000000 +0000
@@ -10,3 +10,4 @@
 [test_secretKeys.js]
 [test_alias.js]
 [test_badKeys.js]
+[test_uid.js]
diff -Nru thunderbird-78.10.1+build1/comm/mail/installer/windows/nsis/defines.nsi.in thunderbird-78.10.2+build1/comm/mail/installer/windows/nsis/defines.nsi.in
--- thunderbird-78.10.1+build1/comm/mail/installer/windows/nsis/defines.nsi.in	2021-05-04 14:24:02.000000000 +0000
+++ thunderbird-78.10.2+build1/comm/mail/installer/windows/nsis/defines.nsi.in	2021-05-17 17:53:03.000000000 +0000
@@ -65,8 +65,13 @@
 # the x86 registry keys (e.g. the uninstall registry key).
 #ifdef HAVE_64BIT_BUILD
 !define HAVE_64BIT_BUILD
+#ifdef _ARM64_
+!define ARCH "AArch64"
+!define MinSupportedVer "Microsoft Windows 10 for ARM"
+#else
 !define ARCH "x64"
 !define MinSupportedVer "Microsoft Windows 7 x64"
+#endif
 #else
 !define MinSupportedVer "Microsoft Windows 7"
 !define ARCH "x86"
diff -Nru thunderbird-78.10.1+build1/comm/mail/installer/windows/nsis/installer.nsi thunderbird-78.10.2+build1/comm/mail/installer/windows/nsis/installer.nsi
--- thunderbird-78.10.1+build1/comm/mail/installer/windows/nsis/installer.nsi	2021-05-04 14:24:02.000000000 +0000
+++ thunderbird-78.10.2+build1/comm/mail/installer/windows/nsis/installer.nsi	2021-05-17 17:53:03.000000000 +0000
@@ -1150,11 +1150,18 @@
   ${EndIf}
 
 !ifdef HAVE_64BIT_BUILD
-  ${Unless} ${RunningX64}
+  ${If} "${ARCH}" == "AArch64"
+    ${IfNot} ${IsNativeARM64}
+    ${OrIfNot} ${AtLeastWin10}
+      MessageBox MB_OKCANCEL|MB_ICONSTOP "$(WARN_MIN_SUPPORTED_OSVER_MSG)" IDCANCEL +2
+      ExecShell "open" "${URLSystemRequirements}"
+      Quit
+    ${EndIf}
+  ${ElseIfNot} ${RunningX64}
     MessageBox MB_OKCANCEL|MB_ICONSTOP "$(WARN_MIN_SUPPORTED_OSVER_MSG)" IDCANCEL +2
     ExecShell "open" "${URLSystemRequirements}"
     Quit
-  ${EndUnless}
+  ${EndIf}
   SetRegView 64
 !endif
 
diff -Nru thunderbird-78.10.1+build1/comm/mail/installer/windows/nsis/maintenanceservice_installer.nsi thunderbird-78.10.2+build1/comm/mail/installer/windows/nsis/maintenanceservice_installer.nsi
--- thunderbird-78.10.1+build1/comm/mail/installer/windows/nsis/maintenanceservice_installer.nsi	2021-05-04 14:24:02.000000000 +0000
+++ thunderbird-78.10.2+build1/comm/mail/installer/windows/nsis/maintenanceservice_installer.nsi	2021-05-17 17:53:03.000000000 +0000
@@ -37,7 +37,7 @@
 !insertmacro GetParameters
 !insertmacro GetSize
 
-; The test slaves use this fallback key to run tests.
+; The test machines use this fallback key to run tests.
 ; And anyone that wants to run tests themselves should already have
 ; this installed.
 !define FallbackKey \
@@ -151,14 +151,14 @@
 
   ; We always write out a copy and then decide whether to install it or
   ; not via calling its 'install' cmdline which works by version comparison.
-  CopyFiles "$EXEDIR\maintenanceservice.exe" "$INSTDIR\$TempMaintServiceName"
+  CopyFiles /SILENT "$EXEDIR\maintenanceservice.exe" "$INSTDIR\$TempMaintServiceName"
 
   ; The updater.ini file is only used when performing an install or upgrade,
   ; and only if that install or upgrade is successful.  If an old updater.ini
   ; happened to be copied into the maintenance service installation directory
   ; but the service was not newer, the updater.ini file would be unused.
   ; It is used to fill the description of the service on success.
-  CopyFiles "$EXEDIR\updater.ini" "$INSTDIR\updater.ini"
+  CopyFiles /SILENT "$EXEDIR\updater.ini" "$INSTDIR\updater.ini"
 
   ; Install the application maintenance service.
   ; If a service already exists, the command line parameter will stop the
@@ -181,6 +181,7 @@
   ; Since the Maintenance service can be installed either x86 or x64,
   ; always use the 64-bit registry.
   ${If} ${RunningX64}
+  ${OrIf} ${IsNativeARM64}
     ; Previous versions always created the uninstall key in the 32-bit registry.
     ; Clean those old entries out if they still exist.
     SetRegView 32
@@ -218,6 +219,7 @@
   ; WriteRegStr HKLM "${FallbackKey}\0" "name" "Mozilla Corporation"
   ; WriteRegStr HKLM "${FallbackKey}\0" "issuer" "DigiCert SHA2 Assured ID Code Signing CA"
   ${If} ${RunningX64}
+  ${OrIf} ${IsNativeARM64}
     SetRegView lastused
   ${EndIf}
 SectionEnd
@@ -240,6 +242,14 @@
   ClearErrors
 FunctionEnd
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; NOTE: The maintenance service uninstaller does not currently get updated when
+; the service itself does during application updates. Under normal use, only
+; running the Thunderbird installer will generate a new maintenance service
+; uninstaller. That means anything added here will not be seen by users until
+; they run a new Thunderbird installer. Fixing this is tracked in
+; https://bugzilla.mozilla.org/show_bug.cgi?id=1665193
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 Section "Uninstall"
   ; Delete the service so that no updates will be attempted
   ExecWait '"$INSTDIR\maintenanceservice.exe" uninstall'
@@ -315,9 +325,11 @@
   RMDir /REBOOTOK "$APPDATA\Mozilla"
   RMDir /REBOOTOK "$INSTDIR\logs"
   RMDir /REBOOTOK "$INSTDIR\update"
+  RMDir /REBOOTOK "$INSTDIR\UpdateLogs"
   RMDir /REBOOTOK "$INSTDIR"
 
   ${If} ${RunningX64}
+  ${OrIf} ${IsNativeARM64}
     SetRegView 64
   ${EndIf}
   DeleteRegKey HKLM "${MaintUninstallKey}"
@@ -325,6 +337,7 @@
   DeleteRegValue HKLM "Software\Mozilla\MaintenanceService" "FFPrefetchDisabled"
   DeleteRegKey HKLM "${FallbackKey}\"
   ${If} ${RunningX64}
+  ${OrIf} ${IsNativeARM64}
     SetRegView lastused
   ${EndIf}
 SectionEnd
diff -Nru thunderbird-78.10.1+build1/comm/mail/installer/windows/nsis/shared.nsh thunderbird-78.10.2+build1/comm/mail/installer/windows/nsis/shared.nsh
--- thunderbird-78.10.1+build1/comm/mail/installer/windows/nsis/shared.nsh	2021-05-04 14:24:02.000000000 +0000
+++ thunderbird-78.10.2+build1/comm/mail/installer/windows/nsis/shared.nsh	2021-05-17 17:53:03.000000000 +0000
@@ -110,11 +110,13 @@
     ; Since the Maintenance service can be installed either x86 or x64,
     ; always use the 64-bit registry for checking if an attempt was made.
     ${If} ${RunningX64}
+    ${OrIf} ${IsNativeARM64}
       SetRegView 64
     ${EndIf}
     ReadRegDWORD $5 HKLM "Software\Mozilla\MaintenanceService" "Attempted"
     ClearErrors
     ${If} ${RunningX64}
+    ${OrIf} ${IsNativeARM64}
       SetRegView lastused
     ${EndIf}
 
@@ -482,6 +484,7 @@
 
   ; Running Thunderbird 32 bit
   ${If} ${RunningX64}
+  ${OrIf} ${IsNativeARM64}
     ; Running Thunderbird 32 bit on a Windows 64 bit system
     ClearErrors
     ReadRegDWORD $2 HKLM "Software\Mozilla\${AppName}\32to64DidMigrate" "$1"
@@ -723,6 +726,7 @@
     ; if the binary is replaced with a different certificate.
     ; We always use the 64bit registry for certs.
     ${If} ${RunningX64}
+    ${OrIf} ${IsNativeARM64}
       SetRegView 64
     ${EndIf}
     DeleteRegKey HKLM "$R0"
@@ -742,6 +746,7 @@
     WriteRegStr HKLM "$R0\1" "name" "${CERTIFICATE_NAME_PREVIOUS}"
     WriteRegStr HKLM "$R0\1" "issuer" "${CERTIFICATE_ISSUER_PREVIOUS}"
     ${If} ${RunningX64}
+    ${OrIf} ${IsNativeARM64}
       SetRegView lastused
     ${EndIf}
     ClearErrors
diff -Nru thunderbird-78.10.1+build1/comm/mail/installer/windows/nsis/uninstaller.nsi thunderbird-78.10.2+build1/comm/mail/installer/windows/nsis/uninstaller.nsi
--- thunderbird-78.10.1+build1/comm/mail/installer/windows/nsis/uninstaller.nsi	2021-05-04 14:24:02.000000000 +0000
+++ thunderbird-78.10.2+build1/comm/mail/installer/windows/nsis/uninstaller.nsi	2021-05-17 17:53:03.000000000 +0000
@@ -190,6 +190,7 @@
 
   ; The maintenance service always uses the 64-bit registry on x64 systems
   ${If} ${RunningX64}
+  ${OrIf} ${IsNativeARM64}
     SetRegView 64
   ${EndIf}
 
@@ -205,6 +206,7 @@
 
   ; Restore back the registry view
   ${If} ${RunningX64}
+  ${OrIf} ${IsNativeARM64}
     SetRegView lastUsed
   ${EndIf}
 
@@ -215,11 +217,13 @@
     ReadRegStr $1 HKLM ${MaintUninstallKey} "UninstallString"
     SetRegView lastused
 
-    ${If} $1 == ""
-    ${AndIf} ${RunningX64}
-      SetRegView 64
-      ReadRegStr $1 HKLM ${MaintUninstallKey} "UninstallString"
-      SetRegView lastused
+    ${If} ${RunningX64}
+    ${OrIf} ${IsNativeARM64}
+      ${If} $1 == ""
+        SetRegView 64
+        ReadRegStr $1 HKLM ${MaintUninstallKey} "UninstallString"
+        SetRegView lastused
+      ${EndIf}
     ${EndIf}
 
     ; If the uninstall string does not exist, skip executing it
@@ -440,10 +444,12 @@
   ${If} $MaintCertKey != ""
     ; Always use the 64bit registry for certs on 64bit systems.
     ${If} ${RunningX64}
+    ${OrIf} ${IsNativeARM64}
       SetRegView 64
     ${EndIf}
     DeleteRegKey HKLM "$MaintCertKey"
     ${If} ${RunningX64}
+    ${OrIf} ${IsNativeARM64}
       SetRegView lastused
     ${EndIf}
   ${EndIf}
diff -Nru thunderbird-78.10.1+build1/comm/mail/locales/en-US/messenger/openpgp/openpgp.ftl thunderbird-78.10.2+build1/comm/mail/locales/en-US/messenger/openpgp/openpgp.ftl
--- thunderbird-78.10.1+build1/comm/mail/locales/en-US/messenger/openpgp/openpgp.ftl	2021-05-04 14:24:02.000000000 +0000
+++ thunderbird-78.10.2+build1/comm/mail/locales/en-US/messenger/openpgp/openpgp.ftl	2021-05-17 17:53:03.000000000 +0000
@@ -455,18 +455,13 @@
 # Strings in keyObj.jsm
 key-ring-pub-key-revoked = The key { $userId } (key ID { $keyId }) is revoked.
 key-ring-pub-key-expired = The key { $userId } (key ID { $keyId }) has expired.
-key-ring-key-disabled = The key { $userId } (key ID { $keyId }) is disabled; it cannot be used.
-key-ring-key-invalid = The key { $userId } (key ID { $keyId }) is not valid. Please consider verifying it correctly.
-key-ring-key-not-trusted=The key { $userId } (key ID { $keyId }) is not trusted enough. Please set the trust level of your key to "ultimate" to use it for signing.
 key-ring-no-secret-key = You do not seem to have the secret key for { $userId } (key ID { $keyId }) on your keyring; you cannot use the key for signing.
 key-ring-pub-key-not-for-signing = The key { $userId } (key ID { $keyId }) cannot be used for signing.
 key-ring-pub-key-not-for-encryption = The key { $userId } (key ID { $keyId }) cannot be used for encryption.
 key-ring-sign-sub-keys-revoked = All signing-subkeys of key { $userId } (key ID { $keyId }) are revoked.
 key-ring-sign-sub-keys-expired = All signing-subkeys of key { $userId } (key ID { $keyId }) have expired.
-key-ring-sign-sub-keys-unusable = All signing-subkeys of key { $userId } (key ID { $keyId }) are revoked, expired or otherwise unusable.
 key-ring-enc-sub-keys-revoked = All encryption subkeys of key { $userId } (key ID { $keyId }) are revoked.
 key-ring-enc-sub-keys-expired = All encryption subkeys of key { $userId } (key ID { $keyId }) have expired.
-key-ring-enc-sub-keys-unusable = All encryption subkeys of key { $userId } (key ID { $keyId }) are revoked, expired or otherwise unusable.
 
 # Strings in gnupg-keylist.jsm
 keyring-photo = Photo
diff -Nru thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/browser_viewMessage.js thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/browser_viewMessage.js
--- thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/browser_viewMessage.js	2021-05-04 14:24:02.000000000 +0000
+++ thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/browser_viewMessage.js	2021-05-17 17:53:03.000000000 +0000
@@ -269,6 +269,153 @@
   close_window(mc);
 });
 
+let partialInlineTests = [
+  {
+    filename: "partial-encrypt-for-carol-plaintext.eml",
+    expectDecryption: true,
+    expectVerification: false,
+    expectSuccess: false,
+  },
+  {
+    filename: "partial-encrypt-for-carol-html.eml",
+    expectDecryption: true,
+    expectVerification: false,
+    expectSuccess: false,
+  },
+  {
+    filename: "partial-encrypt-for-alice-plaintext.eml",
+    expectDecryption: true,
+    expectVerification: false,
+    expectSuccess: true,
+  },
+  {
+    filename: "partial-encrypt-for-alice-html.eml",
+    expectDecryption: true,
+    expectVerification: false,
+    expectSuccess: true,
+  },
+  {
+    filename: "partial-signed-from-carol-plaintext.eml",
+    expectDecryption: false,
+    expectVerification: true,
+    expectSuccess: false,
+  },
+  {
+    filename: "partial-signed-from-carol-html.eml",
+    expectDecryption: false,
+    expectVerification: true,
+    expectSuccess: false,
+  },
+  {
+    filename: "partial-signed-from-bob-plaintext.eml",
+    expectDecryption: false,
+    expectVerification: true,
+    expectSuccess: true,
+  },
+  {
+    filename: "partial-signed-from-bob-html.eml",
+    expectDecryption: false,
+    expectVerification: true,
+    expectSuccess: true,
+  },
+];
+
+/**
+ * Test the notification/decryption/verification behavior for partially
+ * encrypted/signed inline PGP messages.
+ */
+add_task(async function testPartialInlinePGPDecrypt() {
+  for (let test of partialInlineTests) {
+    if (!test.filename) {
+      continue;
+    }
+
+    info(`Testing partial inline; filename=${test.filename}`);
+
+    // Setup the message.
+    let mc = await open_message_from_file(
+      new FileUtils.File(getTestFilePath("data/eml/" + test.filename))
+    );
+
+    let notificationBox = "mail-notification-top";
+    let notificationValue = "decryptInlinePG";
+
+    // Ensure the "partially encrypted notification" is visible.
+    wait_for_notification_to_show(mc, notificationBox, notificationValue);
+
+    let body = getMsgBodyTxt(mc);
+
+    Assert.ok(
+      body.includes("BEGIN PGP"),
+      "unprocessed PGP message should still be shown"
+    );
+
+    Assert.ok(body.includes("prefix"), "prefix should still be shown");
+    Assert.ok(body.includes("suffix"), "suffix should still be shown");
+
+    // Click on the button to process the message subset.
+    let processButton = get_notification_button(
+      mc,
+      notificationBox,
+      notificationValue,
+      {
+        popup: null,
+      }
+    );
+    EventUtils.synthesizeMouseAtCenter(processButton, {}, mc.window);
+
+    // Assert that the message was processed and the partial content reminder
+    // notification is visible.
+    wait_for_notification_to_show(
+      mc,
+      notificationBox,
+      "decryptInlinePGReminder"
+    );
+
+    // Get updated body text after processing the PGP subset.
+    body = getMsgBodyTxt(mc);
+
+    Assert.ok(!body.includes("prefix"), "prefix should not be shown");
+    Assert.ok(!body.includes("suffix"), "suffix should not be shown");
+
+    if (test.expectDecryption) {
+      let containsSecret = body.includes(
+        "Insert a coin to play your personal lucky melody."
+      );
+      if (test.expectSuccess) {
+        Assert.ok(containsSecret, "secret decrypted content should be shown");
+        Assert.ok(
+          OpenPGPTestUtils.hasEncryptedIconState(mc.window.document, "ok"),
+          "decryption success icon is shown"
+        );
+      } else {
+        Assert.ok(
+          !containsSecret,
+          "secret decrypted content should not be shown"
+        );
+        Assert.ok(
+          OpenPGPTestUtils.hasEncryptedIconState(mc.window.document, "notok"),
+          "decryption failure icon is shown"
+        );
+      }
+    } else if (test.expectVerification) {
+      if (test.expectSuccess) {
+        Assert.ok(
+          OpenPGPTestUtils.hasSignedIconState(mc.window.document, "verified"),
+          "ok verification icon is shown"
+        );
+      } else {
+        Assert.ok(
+          OpenPGPTestUtils.hasSignedIconState(mc.window.document, "unknown"),
+          "unknown verification icon is shown"
+        );
+      }
+    }
+
+    close_window(mc);
+  }
+});
+
 /**
  * Test that the message is properly reloaded and the message security icon is
  * updated if the user changes the signature acceptance level.
@@ -353,46 +500,8 @@
   close_window(mc);
 });
 
-/**
- * Test the notification and decryption behavior for partially encrypted inline
- * PGP messages.
- */
-add_task(async function testPartialInlinePGPDecrypt() {
-  // Setup the message.
-  let mc = await open_message_from_file(
-    new FileUtils.File(
-      getTestFilePath("data/eml/alice-partially-encrypted.eml")
-    )
-  );
-
-  let notificationBox = "mail-notification-top";
-  let notificationValue = "decryptInlinePG";
-
-  // Ensure the "partially encrypted notification" is visible.
-  wait_for_notification_to_show(mc, notificationBox, notificationValue);
-
-  // Click on the "decrypt" button.
-  let decryptButton = get_notification_button(
-    mc,
-    notificationBox,
-    notificationValue,
-    {
-      popup: null,
-    }
-  );
-  EventUtils.synthesizeMouseAtCenter(decryptButton, {}, mc.window);
-
-  // Assert that the message was decrypted and the partial decryption reminder
-  // notification is visible.
-  wait_for_notification_to_show(mc, notificationBox, "decryptInlinePGReminder");
-
-  Assert.ok(
-    OpenPGPTestUtils.hasEncryptedIconState(mc.window.document, "ok"),
-    "encrypted icon is displayed"
-  );
-
-  close_window(mc);
-});
+// After test testUpdateMessageSignature acceptance of Bob's key
+// has changed from verified to unverified.
 
 /**
  * Test that a signed (only) inline PGP message with UTF-8 characters
diff -Nru thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/alice-partially-encrypted.eml thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/alice-partially-encrypted.eml
--- thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/alice-partially-encrypted.eml	2021-05-04 14:24:02.000000000 +0000
+++ thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/alice-partially-encrypted.eml	1970-01-01 00:00:00.000000000 +0000
@@ -1,17 +0,0 @@
-From: "Alice Lovelace" 
-To: "Alice Lovelace" 
-Subject: partially encrypted test message
-Date: Wed, 29 Oct 2020 02:34:56 +0000
-Content-Type: text/plain
-MIME-Version: 1.0
-
------BEGIN PGP MESSAGE-----
-
-hF4DR2b2udXyHrYSAQdACSB+uDWodBJ2WRuPm53gxq/RUAc9TSEa1pbow+HTWU8w
-5SomxZAC/JN0vnLqgLWL7JKgmQyYD9d7HI76iTThvJf2cLZXp1+HRyHN2c9gCHjE
-0lIB7FhFzhbBPoT+4Nhla6ISM/KNTkbkebJ4VtZL05/hFn98qKJq61hn9iBvLQ5/
-URrmx+0iVgA1jUTUDuZSt5PRFHYFJqGoOvdHD2mccmIhawet
-=lIZv
------END PGP MESSAGE-----
-
-Additional unexpected text
diff -Nru thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/bob-enc-html-nbsp.eml thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/bob-enc-html-nbsp.eml
--- thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/bob-enc-html-nbsp.eml	2021-05-04 14:24:02.000000000 +0000
+++ thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/bob-enc-html-nbsp.eml	2021-05-17 17:53:03.000000000 +0000
@@ -17,18 +17,18 @@
 
 
 
-
-----BEGIN PGP MESSAGE-----
-
 
+
-----BEGIN PGP MESSAGE-----

+
 

hE4DR2b2udXyHrYSAQdAINgYcnZM2bAYVKuB30JR5bPNGYtFFj5EEZuHzU7B1TAg +div>
Q0qb+biPpakzFZH5xXDLJVrZFo4H76bR0ds7UROgqjDSVAFVyLyVzbXQGBf8krPa +div>
WuIrCJRc+/GBk0CHwc3cV47F8kdbeH/7uHsTbanaz3yn5gtVXBhoR5iOanSaHfCE +div>
vmaIc6oiurKdS9PuTnqbD91uW8PKdw=3D=3D -
=3DVp7p
-
-----END PGP MESSAGE-----
+div>
+
=3DVp7p

+
-----END PGP MESSAGE-----

 
 
diff -Nru thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/partial-encrypt-for-alice-html.eml thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/partial-encrypt-for-alice-html.eml --- thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/partial-encrypt-for-alice-html.eml 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/partial-encrypt-for-alice-html.eml 2021-05-17 17:53:03.000000000 +0000 @@ -0,0 +1,31 @@ +From: "Bob" +To: "Alice Lovelace" +Subject: Inline Encrypted for Alice, with extra text in multipart HTML +Date: Wed, 14 Apr 2021 01:01:01 +0000 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494" + +--32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494 +Content-Type: text/html; charset=utf-8 + +prefix + +--32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494 +Content-Type: text/html; charset=utf-8 + +-----BEGIN PGP MESSAGE----- + +hE4DR2b2udXyHrYSAQdAq+9AhQzI4XpD9WtuB7f3OZHNFvdHza5WND3yLgxX8kwg +eXs+jZGr3TNUpR+XRxCf9+7Er2JyJk7fvL4suUHpHEzSbQG57r4TxneCcV9pukK3 +wzSqNt2o/q/eVO6WwOs3Lo5+31gs9+z6lrVhVjO2cynPdjlNLCQlwRudsQfpNgrF +4pO7n0tCrX0qWaKYgdQuJwIt1HS2nLYd+ryb9eLWO/Xhy3quo8YpD0yueSHjexI= +=rSoz +-----END PGP MESSAGE----- + +--32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494 +Content-Type: text/html; charset=utf-8 + +suffix + +--32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494-- diff -Nru thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/partial-encrypt-for-alice-plaintext.eml thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/partial-encrypt-for-alice-plaintext.eml --- thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/partial-encrypt-for-alice-plaintext.eml 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/partial-encrypt-for-alice-plaintext.eml 2021-05-17 17:53:03.000000000 +0000 @@ -0,0 +1,19 @@ +From: "Bob" +To: "Alice Lovelace" +Subject: Inline Encrypted for Alice, with extra plaintext +Date: Wed, 14 Apr 2021 01:01:02 +0000 +MIME-Version: 1.0 +Content-Type: text/plain + +prefix + +-----BEGIN PGP MESSAGE----- + +hE4DR2b2udXyHrYSAQdAq+9AhQzI4XpD9WtuB7f3OZHNFvdHza5WND3yLgxX8kwg +eXs+jZGr3TNUpR+XRxCf9+7Er2JyJk7fvL4suUHpHEzSbQG57r4TxneCcV9pukK3 +wzSqNt2o/q/eVO6WwOs3Lo5+31gs9+z6lrVhVjO2cynPdjlNLCQlwRudsQfpNgrF +4pO7n0tCrX0qWaKYgdQuJwIt1HS2nLYd+ryb9eLWO/Xhy3quo8YpD0yueSHjexI= +=rSoz +-----END PGP MESSAGE----- + +suffix diff -Nru thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/partial-encrypt-for-carol-html.eml thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/partial-encrypt-for-carol-html.eml --- thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/partial-encrypt-for-carol-html.eml 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/partial-encrypt-for-carol-html.eml 2021-05-17 17:53:03.000000000 +0000 @@ -0,0 +1,41 @@ +From: "Bob" +To: "Carol" +Subject: Inline Encrypted for Caron, with extra text in multipart HTML +Date: Wed, 14 Apr 2021 01:01:03 +0000 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494" + +--32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494 +Content-Type: text/html; charset=utf-8 + +prefix + +--32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494 +Content-Type: text/html; charset=utf-8 + +-----BEGIN PGP MESSAGE----- + +hQIMA7L9So5P9bk9ARAA01Dr6NF4RrED8YADJx3WOOhIgUd55axpniQBPr66Xp6l +mOCmPJnpSTA6DJzu28AyilrOedVx4rBfY9Bs4WS6d9joFo+zj+aoo9p8nBt2tu/8 +Ox8DbwWgVoQ4Po72LfZdH9FsPzfi4I2ytp/tjfHqjgl9Aakkm3vj09OM15aEfYxd +oOO0DFk4vyuWojE6u1Y1bdg20hqPvmciyRFfgZC/51swcwFIDm34R20ASRzrwu1h +kRUHEiGuz3JXPQnzADmK9OcLso9OxGX80WDe136BJG/wgFKqxCwmv0ykplOTJcm3 +VFWAJzguT27JGvJ+2/93IA2uyz1b7Rr4Ly6s6k9zhAPsDudyI2pOiIVpWWSGwiPW +kX78JB5jvgjNs3Wh1dHp/TyKqivQz1qbgH2M78sKUdmbCHiD3Ak5b3F8h3JhrU7X +3zwamZMmove1bkScL4TGXBMMZhwUe6BPg3fq42UHLtXccHlfm+XRWgHbT0su4ezZ +2n3+5YDYozyfmytxZ7jeL9OSbQTNbNZmA+GTf10RX8ww9wwiffLNe8LGdwNaL96i +F2lsC1Hfczw16fThBIEx7UF9LmJzzPNN7aOf+fbOLvkQFSPiGZg9tmXGzzRjDboT +VKhpbV3GNFsCoOcry3Q7xzDgKiWXkdqCTqP9AGJfksQ0mdLQB94tfBYouX+g7PLS +bQEyf6is0CReegpCSbSUZXURLPo381LrYdpV/PA0L+MDZse3xEKpc69zmE+H4oAT +t/zF/Bh0ezxbN0AAHyldj82I7CP+Vtat0qSnUGsbd7G5nswwswxHXTA+FfDo+qBl +U70ypxk/ZqPWcAAEkBo= +=zsMo +-----END PGP MESSAGE----- + +--32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494 +Content-Type: text/html; charset=utf-8 + +suffix + +--32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494-- diff -Nru thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/partial-encrypt-for-carol-plaintext.eml thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/partial-encrypt-for-carol-plaintext.eml --- thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/partial-encrypt-for-carol-plaintext.eml 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/partial-encrypt-for-carol-plaintext.eml 2021-05-17 17:53:03.000000000 +0000 @@ -0,0 +1,29 @@ +From: "Bob" +To: "Carol" +Subject: Inline Encrypted for Carol, with extra plaintext +Date: Wed, 14 Apr 2021 01:01:04 +0000 +MIME-Version: 1.0 +Content-Type: text/plain + +prefix + +-----BEGIN PGP MESSAGE----- + +hQIMA7L9So5P9bk9ARAA01Dr6NF4RrED8YADJx3WOOhIgUd55axpniQBPr66Xp6l +mOCmPJnpSTA6DJzu28AyilrOedVx4rBfY9Bs4WS6d9joFo+zj+aoo9p8nBt2tu/8 +Ox8DbwWgVoQ4Po72LfZdH9FsPzfi4I2ytp/tjfHqjgl9Aakkm3vj09OM15aEfYxd +oOO0DFk4vyuWojE6u1Y1bdg20hqPvmciyRFfgZC/51swcwFIDm34R20ASRzrwu1h +kRUHEiGuz3JXPQnzADmK9OcLso9OxGX80WDe136BJG/wgFKqxCwmv0ykplOTJcm3 +VFWAJzguT27JGvJ+2/93IA2uyz1b7Rr4Ly6s6k9zhAPsDudyI2pOiIVpWWSGwiPW +kX78JB5jvgjNs3Wh1dHp/TyKqivQz1qbgH2M78sKUdmbCHiD3Ak5b3F8h3JhrU7X +3zwamZMmove1bkScL4TGXBMMZhwUe6BPg3fq42UHLtXccHlfm+XRWgHbT0su4ezZ +2n3+5YDYozyfmytxZ7jeL9OSbQTNbNZmA+GTf10RX8ww9wwiffLNe8LGdwNaL96i +F2lsC1Hfczw16fThBIEx7UF9LmJzzPNN7aOf+fbOLvkQFSPiGZg9tmXGzzRjDboT +VKhpbV3GNFsCoOcry3Q7xzDgKiWXkdqCTqP9AGJfksQ0mdLQB94tfBYouX+g7PLS +bQEyf6is0CReegpCSbSUZXURLPo381LrYdpV/PA0L+MDZse3xEKpc69zmE+H4oAT +t/zF/Bh0ezxbN0AAHyldj82I7CP+Vtat0qSnUGsbd7G5nswwswxHXTA+FfDo+qBl +U70ypxk/ZqPWcAAEkBo= +=zsMo +-----END PGP MESSAGE----- + +suffix diff -Nru thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/partial-signed-from-bob-html.eml thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/partial-signed-from-bob-html.eml --- thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/partial-signed-from-bob-html.eml 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/partial-signed-from-bob-html.eml 2021-05-17 17:53:03.000000000 +0000 @@ -0,0 +1,41 @@ +From: "Bob" +To: "Alice Lovelace" +Subject: Inline Signed by Bob, with extra text in multipart HTML +Date: Wed, 14 Apr 2021 01:01:05 +0000 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494" + +--32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494 +Content-Type: text/html; charset=utf-8 + +prefix + +--32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494 +Content-Type: text/html; charset=utf-8 + +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +Insert a coin to play your personal lucky melody. +-----BEGIN PGP SIGNATURE----- + +iQHIBAEBCgAyFiEE0aZuGiOxgsmYD3iM+/zIKgFeczAFAmB4Yg8UHGJvYkBvcGVu +cGdwLmV4YW1wbGUACgkQ+/zIKgFeczC6twv/fYtlE8oNqhP5OzR48/rCEmJQ/U8Z +NIp2Mvg3fpIMY1m2z4nwufCj4xNHM4okyqXnVouWBSLkRL3oPlkXj+syY1lV3Bv2 +Gbl5JMmpMbdSjKAEg7VaYg9C6ELbb25EhBLok1JYMXn5o+wfmm+UN+EU8IbXck5Q +roFNueM6wFv6nvM64jQIkqoyJ2OvNYg1lTJXp7EXEnwRRIW9IDd1XInVrx4jou3Q +Ax4/VbyJQiE37JC6NAJ9hBh/noO36IGAXvBeyN/TVOBySBFC1XoZdhjVoA7eWbZY +m1Pxtar5P1Pb6Nac2c4b8Z1FHZFd81zYbJZkJYG6oApbOBFsn+Lf1+LkVKAiewos +A91QVSP9pqiJmWFZ17tCxRM5YPIPRT35nV3TN3snHGsNvvAJ9mc3YOO7aM0aitx7 +1p3IqdFUz3G8qUlMDthV4WDBj7N1LnRyKCRU6W58hoDXLEjYXMBYSP8+UHqS953M +ILOfsOglDqxjdwrNf2TK9y+zpyXX16yI1eHB +=1Be6 +-----END PGP SIGNATURE----- + +--32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494 +Content-Type: text/html; charset=utf-8 + +suffix + +--32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494-- diff -Nru thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/partial-signed-from-bob-plaintext.eml thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/partial-signed-from-bob-plaintext.eml --- thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/partial-signed-from-bob-plaintext.eml 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/partial-signed-from-bob-plaintext.eml 2021-05-17 17:53:03.000000000 +0000 @@ -0,0 +1,29 @@ +From: "Bob" +To: "Alice Lovelace" +Subject: Inline Signed by Bob, with extra plaintext +Date: Wed, 14 Apr 2021 01:01:06 +0000 +MIME-Version: 1.0 +Content-Type: text/plain + +prefix + +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +Insert a coin to play your personal lucky melody. +-----BEGIN PGP SIGNATURE----- + +iQHIBAEBCgAyFiEE0aZuGiOxgsmYD3iM+/zIKgFeczAFAmB4Yg8UHGJvYkBvcGVu +cGdwLmV4YW1wbGUACgkQ+/zIKgFeczC6twv/fYtlE8oNqhP5OzR48/rCEmJQ/U8Z +NIp2Mvg3fpIMY1m2z4nwufCj4xNHM4okyqXnVouWBSLkRL3oPlkXj+syY1lV3Bv2 +Gbl5JMmpMbdSjKAEg7VaYg9C6ELbb25EhBLok1JYMXn5o+wfmm+UN+EU8IbXck5Q +roFNueM6wFv6nvM64jQIkqoyJ2OvNYg1lTJXp7EXEnwRRIW9IDd1XInVrx4jou3Q +Ax4/VbyJQiE37JC6NAJ9hBh/noO36IGAXvBeyN/TVOBySBFC1XoZdhjVoA7eWbZY +m1Pxtar5P1Pb6Nac2c4b8Z1FHZFd81zYbJZkJYG6oApbOBFsn+Lf1+LkVKAiewos +A91QVSP9pqiJmWFZ17tCxRM5YPIPRT35nV3TN3snHGsNvvAJ9mc3YOO7aM0aitx7 +1p3IqdFUz3G8qUlMDthV4WDBj7N1LnRyKCRU6W58hoDXLEjYXMBYSP8+UHqS953M +ILOfsOglDqxjdwrNf2TK9y+zpyXX16yI1eHB +=1Be6 +-----END PGP SIGNATURE----- + +suffix diff -Nru thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/partial-signed-from-carol-html.eml thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/partial-signed-from-carol-html.eml --- thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/partial-signed-from-carol-html.eml 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/partial-signed-from-carol-html.eml 2021-05-17 17:53:03.000000000 +0000 @@ -0,0 +1,44 @@ +From: "Carol" +To: "Alice Lovelace" +Subject: Inline Signed by Carol, with extra text in multipart HTML +Date: Wed, 14 Apr 2021 01:01:07 +0000 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494" + +--32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494 +Content-Type: text/html; charset=utf-8 + +prefix + +--32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494 +Content-Type: text/html; charset=utf-8 + +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +Insert a coin to play your personal lucky melody. +-----BEGIN PGP SIGNATURE----- + +iQJGBAEBCgAwFiEEuPL29L060/gtxEaDMJn/EjiFK58FAmB4YicSHGNhcm9sQGV4 +YW1wbGUuY29tAAoJEDCZ/xI4hSuflLwP/1wmmla7bXjzbyIGFnSiC+xMT0vcos+s +uv4jdcC1cPxpCj51EZEQGLzmKUMJaD1ruK7AnimhA55tb22NetDW0OHA917VeuoI ++cY1Hm8YqJI9LF9KbnzfbTtqeAcFKPjQe7OBFIvru3Z38Ng2JTnRXkM0xolZjpOz +m14f241+LT62xQwKW3rlG3FLW1yWdVQ5vi8jptbZrhC4J7B2Mzhgt1BX0aV/IK69 +3heQKQIttjslwy2ka8IusfSgPiioSBSULcmlN+FV9kKPNCVAoFvjpGRR9hJfZ92E +6ESuYdphCH+M8FTSKBrKrX6hvl21SpHS0qExr1Xh3MYJvE+8jX0egjuf32Rf/io8 +LYJ/aiBpkDbikCY8rQUD7+HmHGvCiN8tGakeIbjkS3V0vMA3WsZJPtUt/dmVaVHw +TPuXUMnhbQpuqXI6K175WnzHFaOXoV67AVhLqM6CZTdhJLUz1NNVvaSJ1P8nxAz+ +wEEh33138gtuWfsT4xfaitbQ2KqmkVLvu1CJ7k1+GiEOxWNiPgSHo5Z/Iimi4VB3 +Bwxk77iZOOinqmlhd680s9UK/AnZxJ1I+5NYKx8yuATWYmYoorDKZLvJxZH5DPz5 +XTu+v79iGvIXcSLyOsvcMDLLnA6tj4pBRB+MgxweiVjHfrdvG7ohDwXgklI39I62 +eO84IXMU+peK +=Kjsi +-----END PGP SIGNATURE----- + +--32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494 +Content-Type: text/html; charset=utf-8 + +suffix + +--32989E6E4C7AEB7775BAD49432989E6E4C7AEB7775BAD494-- diff -Nru thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/partial-signed-from-carol-plaintext.eml thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/partial-signed-from-carol-plaintext.eml --- thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/eml/partial-signed-from-carol-plaintext.eml 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/eml/partial-signed-from-carol-plaintext.eml 2021-05-17 17:53:03.000000000 +0000 @@ -0,0 +1,32 @@ +From: "Carol" +To: "Alice Lovelace" +Subject: Inline Signed by Carol, with extra plaintext +Date: Wed, 14 Apr 2021 01:01:08 +0000 +MIME-Version: 1.0 +Content-Type: text/plain + +prefix + +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +Insert a coin to play your personal lucky melody. +-----BEGIN PGP SIGNATURE----- + +iQJGBAEBCgAwFiEEuPL29L060/gtxEaDMJn/EjiFK58FAmB4YicSHGNhcm9sQGV4 +YW1wbGUuY29tAAoJEDCZ/xI4hSuflLwP/1wmmla7bXjzbyIGFnSiC+xMT0vcos+s +uv4jdcC1cPxpCj51EZEQGLzmKUMJaD1ruK7AnimhA55tb22NetDW0OHA917VeuoI ++cY1Hm8YqJI9LF9KbnzfbTtqeAcFKPjQe7OBFIvru3Z38Ng2JTnRXkM0xolZjpOz +m14f241+LT62xQwKW3rlG3FLW1yWdVQ5vi8jptbZrhC4J7B2Mzhgt1BX0aV/IK69 +3heQKQIttjslwy2ka8IusfSgPiioSBSULcmlN+FV9kKPNCVAoFvjpGRR9hJfZ92E +6ESuYdphCH+M8FTSKBrKrX6hvl21SpHS0qExr1Xh3MYJvE+8jX0egjuf32Rf/io8 +LYJ/aiBpkDbikCY8rQUD7+HmHGvCiN8tGakeIbjkS3V0vMA3WsZJPtUt/dmVaVHw +TPuXUMnhbQpuqXI6K175WnzHFaOXoV67AVhLqM6CZTdhJLUz1NNVvaSJ1P8nxAz+ +wEEh33138gtuWfsT4xfaitbQ2KqmkVLvu1CJ7k1+GiEOxWNiPgSHo5Z/Iimi4VB3 +Bwxk77iZOOinqmlhd680s9UK/AnZxJ1I+5NYKx8yuATWYmYoorDKZLvJxZH5DPz5 +XTu+v79iGvIXcSLyOsvcMDLLnA6tj4pBRB+MgxweiVjHfrdvG7ohDwXgklI39I62 +eO84IXMU+peK +=Kjsi +-----END PGP SIGNATURE----- + +suffix diff -Nru thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/keys/carol@example.com-0x3099ff1238852b9f-secret.asc thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/keys/carol@example.com-0x3099ff1238852b9f-secret.asc --- thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/keys/carol@example.com-0x3099ff1238852b9f-secret.asc 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/keys/carol@example.com-0x3099ff1238852b9f-secret.asc 2021-05-17 17:53:03.000000000 +0000 @@ -1,6 +1,6 @@ -----BEGIN PGP PRIVATE KEY BLOCK----- -lQcYBF9GZTQBEACjK8Db1095rU74k/RwLhmp9rmFBZR6qyEHANlHSVwqARxa4aJP +lQdGBF9GZTQBEACjK8Db1095rU74k/RwLhmp9rmFBZR6qyEHANlHSVwqARxa4aJP aNoLbqNPefuFg9ib3J0rKcZfqgnqC4usPVSTdmC4w0MdmHvh+1tUoXcxnrjYNRRb P+lC7zaLRRnEEioimC0Mkh+ow1u4F2QFBjwcV9bD7i0T1DRfR5k5kh3kcaYFnGnw MjwjJzLtvu3OZbXYsofCw7890TP4LkqLEQVOw1OrxBnRd5QNBVojcQi6rnKOQ7AU @@ -11,95 +11,97 @@ 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 -HPY+hgEl/EY8TO73FMtXqT3BJVMKAQ== -=16lA +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 +ASX8RjxM7vcUy1epPcElUwoB +=BUDZ -----END PGP PRIVATE KEY BLOCK----- diff -Nru thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/keys/ofelia-public.asc thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/keys/ofelia-public.asc --- thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/keys/ofelia-public.asc 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/keys/ofelia-public.asc 2021-05-17 17:53:03.000000000 +0000 @@ -0,0 +1,68 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +pU+YaR+fAGsRti5YsTIyMQ== +=NsF4 +-----END PGP PUBLIC KEY BLOCK----- diff -Nru thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/keys/ofelia-secret.asc thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/keys/ofelia-secret.asc --- thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/keys/ofelia-secret.asc 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/keys/ofelia-secret.asc 2021-05-17 17:53:03.000000000 +0000 @@ -0,0 +1,129 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +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 +MQ== +=lHHo +-----END PGP PRIVATE KEY BLOCK----- diff -Nru thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/keys/ofelia-secret-subkeys.asc thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/keys/ofelia-secret-subkeys.asc --- thunderbird-78.10.1+build1/comm/mail/test/browser/openpgp/data/keys/ofelia-secret-subkeys.asc 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/test/browser/openpgp/data/keys/ofelia-secret-subkeys.asc 2021-05-17 17:53:03.000000000 +0000 @@ -0,0 +1,108 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lQGVBGCIokUBDADHq7bIIV5CJrKuMrQVOAWcFRE21Y8tupL24fPZBTtU+Lq/zkQO +SOKjjoHCBxj00bQXa4e0Dz1+cWVzsFahM2y52tpbR5J7HuRnoAbSuNDis0NtCnrT +mWdyktm0zHwNeWdGVpp43RwdZEfb55jeqrymtCjD8RruQvUHbfwubKBed3/PjxHK +vJTYJ2HzLS+iB2PE6q0sSup5D7RkICU+wpTooRwJXDtkreLWDCO/60b/4EsG7fPJ +og2EFGqMI3R5PUpdosunT3d6y2/TmPtU8yLxShIHxHD+E4lOhNKfA346W7nE4QHI +RMhhe3WvBoc8DUaxtlQKj0l363ugCniefXgVlXYWq8aHb3V+9WYXdVAMimZklGaZ +BnMGUN266LKOdZTq4fPOVgp2mt/xsEdf+LAsdSiSaseOeps2LmVts7VK23yi0PfB +aNB1IvnPWs/sLaYsGjZU/upcTbliEiRdffTPvPo3b+6Xbih6LCLSJnS5tkRf1EI3 +ZDFMijtAQuSYI90AEQEAAf8AZQBHTlUBtDVPZmVsaWEgKG9mZmxpbmUgcHJpbWFy +eSBrZXkpIDxvZmVsaWFAb3BlbnBncC5leGFtcGxlPokBzgQTAQoAOBYhBFd114Aa +9q4p+yj3UJfc2l5W67giBQJgiKJFAhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheA +AAoJEJfc2l5W67giMJAMAKZl983eqg++H3yDjIKV8vM+ae2scZO1TCkNQ7D/8fA4 +ZJZMA7omLH9H08nUAe/ZcV5hEguQQw4/VJIMssw5fZK/Dzau2osMQ2cap26ZCr/6 +Gu81zyNguJWDtdOZTm7UmwTmwHettglSa8yhbhNyJnU3vepXejGtzv7pDwc+LqnE +LfYfMwxpjKkeA8/ufO3aehbiGk39KAk1PpzXDok/I60X6hnb1moLGfZIPUtDCnw+ +2+1HK4E5ONeb6/ypNZiGOVRWOaCq4/STDBwxdj7g924nT3OTuy7BlAQdy/bYGv9g +3XAlT7/X4jZ4NThc65ukwm+Ahwura1ancla86gLoK+cBjWHrKHyVlRuzdo5qoPVz +Jfc3p8regpJ10gA2OxmrBtA1nfiAk5oocS4dMMxk/cmHZnJ6R2oj4bjymFXggptR +g6v8lXc90Zxb3umecDqqX6PL+n0+p6N1QI4+fAdbX7L+GnyghFC6gtaSGvTLb2H5 +DYzmZdcidBBqjltkHkUHK50FWARgiKJgAQwA0YYPxBC2l0kqr5xtN7ClgvAKOi0Y +UQV/AY5yx5SUY3CMTotrdpCJSCz/ytu8eR7RXbpj3vf/uNjDPB/p3pXFcltREzQA +pEgX4NOneVS/aiqzusTzdLTSI2Yb45koVsK5LhKD3aQx4Mvsk9vyV/Uj36a9dEju +7WR1lxHYR385iOye1nA7MY/G+bFB5/i/S7XmblTfNviSeQMNBnW1AGr0oVZjJaQm +pLpN88cAeHxYzHVs5rMwGDfwUgpAbLGYdZhu39NaYk4gnMv8lBdXcHzSDrhu+lEB +JfqPccbIFDfYcxJH9BDkHp+Fy5ifr8H5nQXRR7/U+is/6jU3m/HT4oEJCWjPiMFs +Hcz3fwNeNV8H/Ypd3M/zr6d6uGmtV7VMHT+XNSqX6SzOmacn0ogqhPJ77QxVjJgT +U/gkG5Nbj+ECVGLXlY21PbH52IDj6gg5FgJ10awMuZh9LJCVpM/OnVOv0z9laO8K +AUe+j2CeTZ97ELEJWH5YN0K1fbcVEz3VT20FABEBAAEAC/sH9aQoWkuFcxsdsWnu +FquC+OQlPPdShKHu3jQlZCiVn9NEse6ILN96Osi7h8jLf8yLrKavSWk74sgv7Ypw +kUH/S9Fy/aO/RJnbnvlwFjRwr7nvhhyK5MpNhqCCmfE6sopfDLGuZtbE58T6AlNc +3LbbKotsnSSufLAsPVpOWlqbhVmsuHYXNj4PLZkHsJ8bx4eUeMGYu1gHzteHf6CQ +/n8tQzSLBocNSk08eI/froxKYB+d+AADZi9JU+hfTgkxAR8LiIca+mMHPmTjo3UE +lrrXw2bzJsT3PQBVaulvGOjydZo7pBr0tvjy8WEFfNpsAl97Wii+2Xlv0r7z9gq1 +BVuwI7DSWpTMMaCVPzMjqkz7zfNbKr64HH15MLVtj14D3YZY98aDd9J4gP4chjnb +1+/J0uKiRkGBR9IPbHpzMcriZIMT3+Dmnh6QHZ41PwIz2Z2MmYIISpyBHxL2Ulpz +XdaZfGghdqKhHbE5WzYtKG8fuCBqAZQuDLivWo4GH3A6VxUGANpczIKzcwX2E7ns +ZXpQtUC/hKYklRThhaCSJMzzGj24IgbGP3kcOwJQHxtMJxWZ6QstS3qk/E+7siTe +WsbKZa59HHAss1Qw5VG63tJcmiEQm9NrVOFSgSx4qEkmOLT3lrk7FGTui2sM7HZ/ +Sq681OUeg+nEhkaS0wnln+wfMvykts6VYHY/UMansnblX9czhJToQP9/cLZwVGHm +rHKDO9a9ilHA0OaHlQaHUYHMxOzWMrpxFyj18kQtFBQ8jDcqQwYA9aNAbbEpbbJI +wBVIz0vOic71PWjWP/1JC7jaDIUkI3j+NiAdcz0hqjsJLfTjnLFvV7iJvLeObe7D +zqY0RxCJfrL6fHxEpxXWuQKsinL0sDL2q8cR4cdTGxbmC204tXtKKLQICHEQdK51 +m67ULRVedg3I4SZQQwl1em+shhWR5ySP22cHO3d5gZD6CoGs+gC8tLixu5u52hS6 +3Ndvy2523cvTkDrK3g0BkJ5lILGbbI+Fv76tO1AmGbUMeiRQE0sXBgDb2AxkmLlc +p/n7NM8dDpeN5qJ7CSA9lcVNKmGWfEkaXRzPYbh+bXWIawLqB4pdKSCmrYEgEdFk +1aFerxKwKlZwL2plw3erhQ5auw+zGH5yumPvrQr0jFSYzuzfqzS3WtEWMcrc95Ex +e6ij4NpgRJI+MVM5ePvpCO4MJFSK5ZRTICkPYFRRvQe/Cm22HyQzdbIToq6sRw21 +DcbFrDZnCKtaPdSx3iV72ZJsu/w9FiURRypoJR1YusNa4pOYEdlf7UXTpokDbAQY +AQoAIBYhBFd114Aa9q4p+yj3UJfc2l5W67giBQJgiKJgAhsCAcAJEJfc2l5W67gi +wPQgBBkBCgAdFiEEpYfgrh6lrG5A3YT5G8j1dk00j+EFAmCIomAACgkQG8j1dk00 +j+E8IAwAn39q961rFEt/q9P/oI8AajmV/t26VmiEZYj+DXKuXAqsaUb8d8HqP9/P +L/IfalPElbBa/6aqmAwMFyM6A/fTRi8LUqCTTjUebWILmrQ51h99hA6p+wkVJo4Y +LQTQv6eu6YYrOJY7NfkvyTHC+OFmJvVbpfyB3+O2RsBeiGZJKhl4NoHbv31TYl/z +G3VD9xMJJ32U7QF6Oj4Ueo92EwU79IXPoP37stLn2moDW25emZ7ShLrYUKm1MCy2 +mUTP4369RHQ+2jFv6ih3oCdTObqEU3kCvQdQfl0CNHYUw7yQ7IHvXDDfMQgBScT0 +/8f3DeVqhzE7dWpbgR+3J8VJ0BH7wf1tW5yTpoHNsfWqtvzpmX0uJd3z1i60Bp2x +CHx6Kd7T+cZ/tTtnw7oCwcsPonSA4Tuc5tP+XuNVr7FbXlBPHQ6Nx27djAwUVF1g ++tdSLZZcKJgGIp7F+o7iFFzDtB6jddXi/6Z0sYuetEek/PYfZuyYULfuTziT2ZUh +mFrtbloovWwL/0toYKSK2wDPvYEuuZy2GBPwEaOr1rodx7tcwli4hA4i/8idetyZ +uHt1IV+hCLsbvohBz55Yd107Ft/XX3V6Fp0yrvjfm22CZ7l1p9JQIBfkzhJadEz1 +R4dFeYBoLesOIDSmHb3+7slzSFhIjTOXQ2y+op9++YAxO7rH9t1zi+hIiAhaB+lv +K9QHKxWw1DVgeC5oq1EavfnWvpyVeJEEVr13ZGC6L3wCnwCSDH/LYeccQhwTgI4R +iZHrxzqYmylEWl0805loQGqXRJiQ3qJV49d6DwbpxqG5h348q3X9/MBrf33UlE6V +cGlnA+jJWrTDLFVfvq43tkK5ijwCEARxy2gZbSe2yCJISjUbj91dKZodZSke/Yp5 +b7796hF3BgYfc4/nHwZ3/y1T9QiP9aNqjewdgu5lV0vCWeSuxClDhsN6j26HmAcX +GskaWqSJQMkFE8XiHMpUCe4XdqRRXD5whKs6p3K/++3TY3iFDg2Rkazqv1lWoioV +w7mVvoNfjRdeEZ0FWARgiKJvAQwAns+yngkGgkrAWOqNMPQtpSbchsiKQoGieaYN +fx5PdXW221DLUHTYDQKgN0w6mPCnYqH0oFpozfL8368ZE+sIumpRM1nEyhSqx2fi +Tv0TX/cM1YkKpSkSfk/sBN8VNiChG4UessVnrxze1waNgikp91bbSSbbjpK/bBvn +3v1rifFi17K+5Hg8YVLFrm6p7CbGdjVZbMzDrkQlzell0bicrwZu3L5YPEMNozVY +FIu2EMB6jVh/Digq2EGosw0W1p08b9ZSEcAuHM5WEkArZ1ejOpgKN8JhS1bmsNta +PMdQvxa7vnaSBCI8mQmG6/8G/1gzerjV00DVsvsViQeCLZdWsvLVHl00lzetnZGI +kd+EukjnQD4jQTt96ma2teIIKba3EXvDaK5plsI/zHfyvVqoxf/y9Jn90kPBZfxB +RK3x4Oiu0Q3bHcDzoCKji5HlMBsWzD2/ayo8CLyJqkL5z/B3Hk4fwUSiU8hjJrKm +woeFQUbDbY3xuxX1bpYkGbL0/H4pABEBAAEAC/wKMkQh1OsD0QhV/SM5DihjFuJo +TfZgjEGyBUkPDRNlc3wcyyxumz3m4fEG8+A8QxFAKi1SYVOiy3PUacHWr0u1ak+R +2DTkE50eZetYDnQgwHQkvqJ+FavAC+IXsvoB6mjloy+kIzwDuHsPO7a4sWtmG7/D +C9ljZ0UejBEgVk2CAwtJVYrfkN+xkParuyOyS5AI9WZrL59tsCbsOEzHAQ8gRq22 +AwuXvOdif/GKiijTnQQRUKoBru8HSPnrmw7JEzm9AK3RrVQPMgKgzttjPDqU7k6e +S7PHmeWJScRqt9Viq4L8zpHOn1KM+NHN4LgP123MFPSYCXys3Ph6B1RjiePTR0kl +rFWf7T4y3SEPOBgC9QthJjDl4IhvP+dHJBeFOnz4qbaQNLSSzn86tBmnfljOhTu9 +bkV+aHnfN+Fz00RrZDr37s+Z5459vhL+drvrvTHDzRp3Y5Ywhn5uk5t7oK/csrRv +fwPoOz7Pns4a9xTjLo7ykPEtq6rHwtW8y8BZxOEGAMcfYszVoZd4LGHh+8zGqTQA +QRypRmBZ7bNt2MOOWUBIXo1w70hmc3VuuAWBfNI683EDJA49gA/EwRuhmGHnbuUz +VRi1AYmc8fGk542c94+3ak3KQZP3Pvx9gpzjTeB3aqFtNCtfXQIlcPKF//IwKZUR +duNXjuw35o17czPfTJiU/Uda3OXko2r4Mjg+oqJhKqFLh93yWvlLxJgHThFt3BrV +GwJdxXOFOPp6vrdEYjvWtCIYx+VwWl6UvKkHe6DE8QYAzCyYVmIxG2zGk4Pwx96y +IikF7Kw6J/RXFUn+OiGc8ydk2mmienG3sML905U5tiRYRFBW3BTra3lLSUFx07N5 +EH+EGdOfA2QuqwmUDT1hliFW2XFuC8kxY/NctKmSdkS3ZpHegP4GBjZCgux3W8hr +ZU/+2TW44m2bnvqJHwuvDYvXnSapyhhuAEqwUrfZ1Y5kJQ18zajyGpvU/ej8TCK4 +3NXOikcxnH4OLeJpjmBlCC3IInkt36JSxgwcrMPsQOy5Bf98SjLxzBN7WSvDfIF8 +D49+pPqhTuetUrgro6nQtcDDgG5FaJPo7KSHBfWFuBingFe7EvrBMjfsJX+RbW7D +xa/waujiHyfeQaLLdM9tRD5E29cvIHPpit0CJgZlNlrr2hlSNMX7Ymo4S+c0JzWr +kZUxZBVTwOGUAhZPpSKesq9aISOaTMrpSMmRqoCYYYc5Su+0RP/ah0fZaCmg8kZB +JUmXPgWT/wv/YjOV8Qq5I/LX8xqf1p+Pg9ej75P+PYfQB//jPYkBtgQYAQoAIBYh +BFd114Aa9q4p+yj3UJfc2l5W67giBQJgiKJvAhsMAAoJEJfc2l5W67gin9gMAMbF +890cE1CaNghv2nN5SscmZzAZSc8qTjqWLYMmxftuMNaoL8rjuowp++k/oRXGwW31 +MyqwKrAP3ezv88o7cNDFjriGHKN5ZZxNJRqsiF7VcyMbi/7OoHONAJXF4NcY6+2K +/F8moxsG50BfX6B1gV1sezlI0Uli275karr7DNHBbpDMBMPBOESBJbF1vwxCgHrR +CdgNHcQqe43s0goLMsB+8fM+Ge9XrkfJuVS48Bl4QUecddYzzgjZQqB8VcnBQTQf +bZ+h+TgBIhayKP8EFtDshbiWSTQe8bSjGXHwWwF7BdJQsjEz8nq87oCS5WyCR38D +1gfTOWhsnZqPFv5n4qZuyT3GSEGPVPa2AH+5ddQ3R58o60eovi0oNScrxk4zXjkG +aipJhhajGXrzutAyLoesRLnCnhoLYYWAw5wC+Ioa2M3scYa3AG1ZejrE5KZ+tDB2 +iuB6Sp9Aho91nhoGO1ktcqfaUlDX2HmhdGkMdY6ppU+YaR+fAGsRti5YsTIyMQ== +=dKRC +-----END PGP PRIVATE KEY BLOCK----- diff -Nru thunderbird-78.10.1+build1/comm/mail/test/browser/shared-modules/OpenPGPTestUtils.jsm thunderbird-78.10.2+build1/comm/mail/test/browser/shared-modules/OpenPGPTestUtils.jsm --- thunderbird-78.10.1+build1/comm/mail/test/browser/shared-modules/OpenPGPTestUtils.jsm 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/test/browser/shared-modules/OpenPGPTestUtils.jsm 2021-05-17 17:53:03.000000000 +0000 @@ -21,8 +21,8 @@ const { PgpSqliteDb2 } = ChromeUtils.import( "chrome://openpgp/content/modules/sqliteDb.jsm" ); -const { uidHelper } = ChromeUtils.import( - "chrome://openpgp/content/modules/uidHelper.jsm" +const { EnigmailFuncs } = ChromeUtils.import( + "chrome://openpgp/content/modules/funcs.jsm" ); const { RNP } = ChromeUtils.import("chrome://openpgp/content/modules/RNP.jsm"); @@ -186,10 +186,13 @@ let ids = Array.isArray(id) ? id : [id]; for (let i = 0; i < ids.length; i++) { let key = EnigmailKeyRing.getKeyById(ids[i]); - let parts = {}; - uidHelper.getPartsFromUidStr(key.userId, parts); - await PgpSqliteDb2.updateAcceptance(key.fpr, [parts.email], acceptance); + let email = EnigmailFuncs.getEmailFromUserID(key.userId); + await PgpSqliteDb2.updateAcceptance(key.fpr, [email], acceptance); } return ids.slice(); }, + + getProtectedKeysCount() { + return RNP.getProtectedKeysCount(); + }, }; diff -Nru thunderbird-78.10.1+build1/comm/mail/themes/linux/mail/messenger.css thunderbird-78.10.2+build1/comm/mail/themes/linux/mail/messenger.css --- thunderbird-78.10.1+build1/comm/mail/themes/linux/mail/messenger.css 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/themes/linux/mail/messenger.css 2021-05-17 17:53:03.000000000 +0000 @@ -86,14 +86,20 @@ .mail-toolbox > toolbar:-moz-lwtheme, #compose-toolbox > toolbar:-moz-lwtheme, #navigation-toolbox > toolbar:-moz-lwtheme { - --toolbarbutton-hover-background: var(--lwt-toolbarbutton-hover-background, rgba(0, 0, 0, .1)); - --toolbarbutton-hover-bordercolor: var(--lwt-toolbarbutton-hover-background, rgba(0, 0, 0, .1)); + --toolbarbutton-hover-background: var(--lwt-toolbarbutton-hover-background, + rgba(0, 0, 0, .1)); + --toolbarbutton-hover-bordercolor: var(--lwt-toolbarbutton-hover-background, + rgba(0, 0, 0, .1)); + + --toolbarbutton-active-background: var(--lwt-toolbarbutton-active-background, + rgba(0, 0, 0, .15)); + --toolbarbutton-active-bordercolor: var(--lwt-toolbarbutton-active-background, + rgba(0, 0, 0, .15)); + --toolbarbutton-active-boxshadow: 0 0 0 1px var(--lwt-toolbarbutton-active-background, + rgba(0, 0, 0, .15)) inset; - --toolbarbutton-active-background: var(--lwt-toolbarbutton-active-background, rgba(0, 0, 0, .15)); - --toolbarbutton-active-bordercolor: var(--lwt-toolbarbutton-active-background, rgba(0, 0, 0, .15)); - --toolbarbutton-active-boxshadow: 0 0 0 1px var(--lwt-toolbarbutton-active-background, rgba(0, 0, 0, .15)) inset; - - --toolbarbutton-checkedhover-backgroundcolor: var(--lwt-toolbarbutton-hover-background, rgba(0, 0, 0, .2)); + --toolbarbutton-checkedhover-backgroundcolor: var(--lwt-toolbarbutton-hover-background, + rgba(0, 0, 0, .15)); } .toolbar[brighttext], @@ -110,15 +116,20 @@ :root[lwt-tree-brighttext] .calendar-list-create, :root[lwt-tree-brighttext] #quick-filter-bar > hbox, :root[lwt-tree-brighttext] #searchTerms { - --toolbarbutton-hover-background: var(--lwt-toolbarbutton-hover-background, rgba(255, 255, 255, .25)); - --toolbarbutton-hover-bordercolor: var(--lwt-toolbarbutton-hover-background, rgba(255, 255, 255, .5)); - --toolbarbutton-header-bordercolor: var(--lwt-toolbarbutton-hover-background, rgba(255, 255, 255, .25)); - - --toolbarbutton-active-background: var(--lwt-toolbarbutton-active-background, rgba(255, 255, 255, .4)); - --toolbarbutton-active-bordercolor: var(--lwt-toolbarbutton-active-background, rgba(255, 255, 255, .7)); - --toolbarbutton-active-boxshadow: 0 0 0 1px var(--lwt-toolbarbutton-active-background, rgba(255, 255, 255, .4)) inset; + --toolbarbutton-hover-background: var(--lwt-toolbarbutton-hover-background, + rgba(255, 255, 255, .25)); + --toolbarbutton-hover-bordercolor: var(--lwt-toolbarbutton-hover-background, + rgba(255, 255, 255, .5)); + --toolbarbutton-header-bordercolor: var(--lwt-toolbarbutton-hover-background, + rgba(255, 255, 255, .25)); + + --toolbarbutton-active-background: var(--lwt-toolbarbutton-active-background, + rgba(255, 255, 255, .4)); + --toolbarbutton-active-bordercolor: var(--lwt-toolbarbutton-active-background, + rgba(255, 255, 255, .7)); + --toolbarbutton-active-boxshadow: none; - --toolbarbutton-checkedhover-backgroundcolor: var(--lwt-toolbarbutton-hover-background, rgba(255, 255, 255, .5)); + --toolbarbutton-checkedhover-backgroundcolor: rgba(0, 0, 0, .25); } #tabs-toolbar { @@ -333,8 +344,9 @@ } toolbox[labelalign="end"] .toolbarbutton-1, -toolbox[labelalign="end"] .toolbarbutton-1[type="menu-button"] - > .toolbarbutton-menubutton-button { +toolbox[labelalign="end"] .toolbarbutton-menubutton-button, +toolbox:not([mode="full"]) .toolbarbutton-1, +toolbox:not([mode="full"]) .toolbarbutton-menubutton-button { -moz-box-orient: horizontal; } @@ -365,7 +377,6 @@ border-radius: var(--toolbarbutton-border-radius); transition-property: background-color, border-color; transition-duration: 150ms; - background-clip: padding-box; } .toolbarbutton-1[type="menu-button"] > .toolbarbutton-menubutton-button { @@ -380,7 +391,7 @@ .toolbarbutton-1:not([disabled="true"]):hover > .toolbarbutton-menubutton-dropmarker, .toolbarbutton-1:not([type="menu-button"]):not([disabled="true"]):not([checked="true"]):not([open="true"]):not(:active):hover { - background: var(--toolbarbutton-hover-background); + background-color: var(--toolbarbutton-hover-background); border-color: var(--toolbarbutton-hover-bordercolor); box-shadow: var(--toolbarbutton-hover-boxshadow); } @@ -389,7 +400,7 @@ .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled="true"]):hover:active, .toolbarbutton-1[open="true"] > .toolbarbutton-menubutton-dropmarker:not([disabled="true"]), .toolbarbutton-1:not([type="menu-button"]):not([disabled="true"]):-moz-any([open="true"],[checked="true"],:hover:active) { - background: var(--toolbarbutton-active-background); + background-color: var(--toolbarbutton-active-background); border-color: var(--toolbarbutton-active-bordercolor); box-shadow: var(--toolbarbutton-active-boxshadow); transition-duration: 10ms; @@ -480,6 +491,32 @@ padding: 1px; } +toolbox:not([labelalign="end"]) > toolbar[mode="full"] + .toolbarbutton-1:not(.button-appmenu)[type="menu"] { + padding-inline-end: 12px !important; + background-image: url("chrome://messenger/skin/icons/toolbarbutton-arrow.svg"); + background-size: 9px 9px; + background-repeat: no-repeat; + background-position: calc(100% - 4px) center; + -moz-context-properties: fill, fill-opacity, stroke-opacity; + stroke-opacity: 1; +} + +toolbox:not([labelalign="end"]) > toolbar[mode="full"] + .toolbarbutton-1:not(.button-appmenu)[type="menu"][disabled="true"] { + stroke-opacity: 0.4; +} + +toolbox:not([labelalign="end"]) > toolbar[mode="full"] + .toolbarbutton-1:not(.button-appmenu)[type="menu"]:-moz-locale-dir(rtl) { + background-position: 4px center; +} + +toolbox:not([labelalign="end"]) > toolbar[mode="full"] + .toolbarbutton-1:not(.button-appmenu)[type="menu"] > .toolbarbutton-menu-dropmarker { + display: none; +} + toolbar[mode="full"] .toolbarbutton-1:not([hideWebExtensionLabel="true"]) { min-width: 55px; } diff -Nru thunderbird-78.10.1+build1/comm/mail/themes/osx/mail/messenger.css thunderbird-78.10.2+build1/comm/mail/themes/osx/mail/messenger.css --- thunderbird-78.10.1+build1/comm/mail/themes/osx/mail/messenger.css 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/themes/osx/mail/messenger.css 2021-05-17 17:53:03.000000000 +0000 @@ -24,24 +24,16 @@ --toolbarbutton-border-radius: 3px; --toolbarbutton-icon-fill-opacity: .85; - --toolbarbutton-hover-background: hsla(0, 0%, 100%, .1) - linear-gradient(hsla(0, 0%, 100%, .3), - hsla(0, 0%, 100%, .1)) no-repeat; - --toolbarbutton-hover-bordercolor: hsla(0, 0%, 0%, .2); - --toolbarbutton-header-bordercolor: hsla(0, 0%, 0%, .2); - --toolbarbutton-hover-boxshadow: 0 1px 0 hsla(0, 0%, 100%, .5), - 0 1px 0 hsla(0, 0%, 100%, .5) inset; - - --toolbarbutton-active-background: hsla(0, 0%, 0%, .02) - linear-gradient(hsla(0, 0%, 0%, .12), - transparent) border-box; - --toolbarbutton-active-bordercolor: hsla(0, 0%, 0%, .3); - --toolbarbutton-active-boxshadow: 0 1px 0 hsla(0, 0%, 100%, .5), - 0 1px 0 hsla(0, 0%, 0%, .05) inset, - 0 1px 1px hsla(0, 0%, 0%, .2) inset; - --toolbarbutton-inactive-bordercolor: rgba(0, 0, 0, 0.1); - --toolbarbutton-inactive-boxshadow: 0 1px 0 hsla(0, 0%, 0%, .05) inset; - --toolbarbutton-checkedhover-backgroundcolor: hsla(0, 0%, 0%, .09); + --toolbarbutton-hover-background: rgba(0, 0, 0, .05); + --toolbarbutton-hover-bordercolor: rgba(0, 0, 0, .25); + --toolbarbutton-header-bordercolor: rgba(0, 0, 0, .25); + --toolbarbutton-hover-boxshadow: none; + + --toolbarbutton-active-background: rgba(0, 0, 0, .1); + --toolbarbutton-active-bordercolor: rgba(0, 0, 0, .3); + --toolbarbutton-active-boxshadow: 0 1px 1px rgba(0, 0, 0, .1) inset, 0 0 1px rgba(0, 0, 0, .3) inset; + + --toolbarbutton-checkedhover-backgroundcolor: rgba(200, 200, 200, .5); --toolbarbutton-icon-fill-attention: var(--lwt-toolbarbutton-icon-fill-attention, #0a84ff); --lwt-header-image: none; @@ -106,14 +98,50 @@ :root[lwt-tree-brighttext] .crypto-button, :root[lwt-tree-brighttext] .calendar-list-create, :root[lwt-tree-brighttext] #folderPane-toolbar { - --toolbarbutton-hover-background: var(--lwt-toolbarbutton-hover-background, hsla(0, 0%, 100%, .1)); - --toolbarbutton-hover-bordercolor: var(--lwt-toolbarbutton-hover-background, hsla(0, 0%, 0%, .2)); - - --toolbarbutton-active-background: var(--lwt-toolbarbutton-active-background, hsla(0, 0%, 0%, .02)); - --toolbarbutton-active-bordercolor: var(--lwt-toolbarbutton-active-background, hsla(0, 0%, 0%, .3)); - --toolbarbutton-active-boxshadow: 0 0 0 1px var(--lwt-toolbarbutton-active-background, hsla(0, 0%, 0%, .2)) inset; + --toolbarbutton-hover-background: var(--lwt-toolbarbutton-hover-background, + rgba(0, 0, 0, .1)); + --toolbarbutton-hover-bordercolor: var(--lwt-toolbarbutton-hover-background, + rgba(0, 0, 0, .1)); + + --toolbarbutton-active-background: var(--lwt-toolbarbutton-active-background, + rgba(0, 0, 0, .15)); + --toolbarbutton-active-bordercolor: var(--lwt-toolbarbutton-active-background, + rgba(0, 0, 0, .15)); + --toolbarbutton-active-boxshadow: 0 0 0 1px var(--lwt-toolbarbutton-active-background, + rgba(0, 0, 0, .15)) inset; + + --toolbarbutton-checkedhover-backgroundcolor: var(--lwt-toolbarbutton-hover-background, + rgba(0, 0, 0, .15)); +} + +.toolbar[brighttext], +.contentTabToolbox[brighttext], +#header-view-toolbar[brighttext], +#ab-toolbox > toolbar[brighttext], +.mail-toolbox > toolbar[brighttext], +#event-toolbox > toolbar[brighttext], +#compose-toolbox > toolbar[brighttext], +#headers-box > toolbar[brighttext], +#FormatToolbox > toolbar[brighttext], +:root[lwt-tree-brighttext] .otr-container, +:root[lwt-tree-brighttext] .crypto-button, +:root[lwt-tree-brighttext] .calendar-list-create, +:root[lwt-tree-brighttext] #quick-filter-bar > hbox, +:root[lwt-tree-brighttext] #searchTerms { + --toolbarbutton-hover-background: var(--lwt-toolbarbutton-hover-background, + rgba(255, 255, 255, .25)); + --toolbarbutton-hover-bordercolor: var(--lwt-toolbarbutton-hover-background, + rgba(255, 255, 255, .5)); + --toolbarbutton-header-bordercolor: var(--lwt-toolbarbutton-hover-background, + rgba(255, 255, 255, .25)); + + --toolbarbutton-active-background: var(--lwt-toolbarbutton-active-background, + rgba(255, 255, 255, .4)); + --toolbarbutton-active-bordercolor: var(--lwt-toolbarbutton-active-background, + rgba(255, 255, 255, .7)); + --toolbarbutton-active-boxshadow: none; - --toolbarbutton-checkedhover-backgroundcolor: var(--lwt-toolbarbutton-hover-background, hsla(0, 0%, 0%, .09)); + --toolbarbutton-checkedhover-backgroundcolor: rgba(0, 0, 0, .25); } :-moz-any(.chromeclass-toolbar, .chromeclass-menubar, #tabbar-toolbar) @@ -230,7 +258,6 @@ border-radius: var(--toolbarbutton-border-radius); transition-property: background, border-color; transition-duration: 250ms; - background-clip: padding-box; } .findbar-button:not(:-moz-any([checked="true"],[disabled="true"])):hover, @@ -240,7 +267,7 @@ .toolbarbutton-menubutton-dropmarker, .toolbarbutton-1:not([type="menu-button"]):not([disabled="true"]):not([checked="true"]):not([open="true"]):not(:active):hover { border-color: var(--toolbarbutton-hover-bordercolor); - background: var(--toolbarbutton-hover-background); + background-color: var(--toolbarbutton-hover-background); box-shadow: var(--toolbarbutton-hover-boxshadow); } @@ -248,7 +275,7 @@ .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled="true"]):hover:active, .toolbarbutton-1[open="true"] > .toolbarbutton-menubutton-dropmarker:not([disabled="true"]), .toolbarbutton-1:not([type="menu-button"]):not([disabled="true"]):-moz-any([open="true"],[checked="true"],:hover:active) { - background: var(--toolbarbutton-active-background); + background-color: var(--toolbarbutton-active-background); border-color: var(--toolbarbutton-active-bordercolor); box-shadow: var(--toolbarbutton-active-boxshadow); transition-duration: 10ms; @@ -314,16 +341,10 @@ -moz-box-orient: vertical; } -toolbarbutton[type="menu-button"], -toolbox[mode="text"] .toolbarbutton-1, -toolbox[mode="text"] .toolbarbutton-menubutton-button, -toolbox[mode="text"] .toolbarbutton-menubutton-dropmarker, toolbox[labelalign="end"] .toolbarbutton-1, -toolbox[labelalign="end"] toolbarpaletteitem .toolbarbutton-1, -toolbox[labelalign="end"] .toolbarbutton-1[type="menu-button"] - > .toolbarbutton-menubutton-button, -toolbox[labelalign="end"] toolbarpaletteitem - .toolbarbutton-1[type="menu-button"] > .toolbarbutton-menubutton-button { +toolbox[labelalign="end"] .toolbarbutton-menubutton-button, +toolbox:not([mode="full"]) .toolbarbutton-1, +toolbox:not([mode="full"]) .toolbarbutton-menubutton-button { -moz-box-orient: horizontal; } @@ -359,7 +380,7 @@ margin-inline-start: -5px; margin-inline-end: 4px; margin-bottom: 2px; - background: hsla(0, 0%, 0%, .3) padding-box; + background-color: hsla(0, 0%, 0%, .3); box-shadow: 0 0 0 1px hsla(0, 0%, 100%, .2); } @@ -397,6 +418,32 @@ padding: 2px 4px !important; } +toolbox:not([labelalign="end"]) > toolbar[mode="full"] + .toolbarbutton-1:not(.button-appmenu)[type="menu"] { + padding-inline-end: 15px !important; + background-image: url("chrome://messenger/skin/icons/toolbarbutton-arrow.svg"); + background-size: 9px 9px; + background-repeat: no-repeat; + background-position: calc(100% - 4px) center; + -moz-context-properties: fill, fill-opacity, stroke-opacity; + stroke-opacity: 1; +} + +toolbox:not([labelalign="end"]) > toolbar[mode="full"] + .toolbarbutton-1:not(.button-appmenu)[type="menu"][disabled="true"] { + stroke-opacity: 0.4; +} + +toolbox:not([labelalign="end"]) > toolbar[mode="full"] + .toolbarbutton-1:not(.button-appmenu)[type="menu"]:-moz-locale-dir(rtl) { + background-position: 4px center; +} + +toolbox:not([labelalign="end"]) > toolbar[mode="full"] + .toolbarbutton-1:not(.button-appmenu)[type="menu"] > .toolbarbutton-menu-dropmarker { + display: none; +} + toolbar:not([mode="icons"]) .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker { width: auto; } diff -Nru thunderbird-78.10.1+build1/comm/mail/themes/shared/mail/icons/toolbarbutton-arrow.svg thunderbird-78.10.2+build1/comm/mail/themes/shared/mail/icons/toolbarbutton-arrow.svg --- thunderbird-78.10.1+build1/comm/mail/themes/shared/mail/icons/toolbarbutton-arrow.svg 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/themes/shared/mail/icons/toolbarbutton-arrow.svg 2021-05-17 17:53:03.000000000 +0000 @@ -1,6 +1,6 @@ - - + + diff -Nru thunderbird-78.10.1+build1/comm/mail/themes/shared/openpgp/enigmail-common.css thunderbird-78.10.2+build1/comm/mail/themes/shared/openpgp/enigmail-common.css --- thunderbird-78.10.1+build1/comm/mail/themes/shared/openpgp/enigmail-common.css 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/themes/shared/openpgp/enigmail-common.css 2021-05-17 17:53:03.000000000 +0000 @@ -318,8 +318,6 @@ the following styles are available for the key trust columnm in the key manager: enigmail_keyValid_unknown - enigmail_keyValid_invalid - enigmail_keyValid_disabled enigmail_keyValid_revoked enigmail_keyValid_expired enigmail_keyTrust_untrusted diff -Nru thunderbird-78.10.1+build1/comm/mail/themes/windows/mail/messenger.css thunderbird-78.10.2+build1/comm/mail/themes/windows/mail/messenger.css --- thunderbird-78.10.1+build1/comm/mail/themes/windows/mail/messenger.css 2021-05-04 14:24:02.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/mail/themes/windows/mail/messenger.css 2021-05-17 17:53:03.000000000 +0000 @@ -25,16 +25,16 @@ --toolbarbutton-border-radius: 0; --toolbarbutton-icon-fill-opacity: .85; - --toolbarbutton-hover-background: rgba(0, 0, 0, .1); + --toolbarbutton-hover-background: rgba(0, 0, 0, .05); --toolbarbutton-hover-bordercolor: rgba(0, 0, 0, .25); - --toolbarbutton-header-bordercolor: rgba(0, 0, 0, .1); + --toolbarbutton-header-bordercolor: rgba(0, 0, 0, .25); --toolbarbutton-hover-boxshadow: none; - --toolbarbutton-active-background: rgba(0, 0, 0, .15); - --toolbarbutton-active-bordercolor: rgba(0, 0, 0, .15); - --toolbarbutton-active-boxshadow: 0 0 0 1px rgba(0, 0, 0, .15) inset; + --toolbarbutton-active-background: rgba(0, 0, 0, .1); + --toolbarbutton-active-bordercolor: rgba(0, 0, 0, .3); + --toolbarbutton-active-boxshadow: 0 1px 1px rgba(0, 0, 0, .1) inset, 0 0 1px rgba(0, 0, 0, .3) inset; - --toolbarbutton-checkedhover-backgroundcolor: rgba(0, 0, 0, .2); + --toolbarbutton-checkedhover-backgroundcolor: rgba(200, 200, 200, .5); --toolbarbutton-icon-fill-attention: var(--lwt-toolbarbutton-icon-fill-attention, #0a84ff); --lwt-header-image: none; @@ -119,14 +119,20 @@ .mail-toolbox > toolbar:-moz-lwtheme, #compose-toolbox > toolbar:-moz-lwtheme, #navigation-toolbox > toolbar:-moz-lwtheme { - --toolbarbutton-hover-background: var(--lwt-toolbarbutton-hover-background, rgba(0, 0, 0, .1)); - --toolbarbutton-hover-bordercolor: var(--lwt-toolbarbutton-hover-background, rgba(0, 0, 0, .1)); + --toolbarbutton-hover-background: var(--lwt-toolbarbutton-hover-background, + rgba(0, 0, 0, .1)); + --toolbarbutton-hover-bordercolor: var(--lwt-toolbarbutton-hover-background, + rgba(0, 0, 0, .1)); + + --toolbarbutton-active-background: var(--lwt-toolbarbutton-active-background, + rgba(0, 0, 0, .15)); + --toolbarbutton-active-bordercolor: var(--lwt-toolbarbutton-active-background, + rgba(0, 0, 0, .15)); + --toolbarbutton-active-boxshadow: 0 0 0 1px var(--lwt-toolbarbutton-active-background, + rgba(0, 0, 0, .15)) inset; - --toolbarbutton-active-background: var(--lwt-toolbarbutton-active-background, rgba(0, 0, 0, .15)); - --toolbarbutton-active-bordercolor: var(--lwt-toolbarbutton-active-background, rgba(0, 0, 0, .15)); - --toolbarbutton-active-boxshadow: 0 0 0 1px var(--lwt-toolbarbutton-active-background, rgba(0, 0, 0, .15)) inset; - - --toolbarbutton-checkedhover-backgroundcolor: var(--lwt-toolbarbutton-hover-background, rgba(0, 0, 0, .2)); + --toolbarbutton-checkedhover-backgroundcolor: var(--lwt-toolbarbutton-hover-background, + rgba(0, 0, 0, .15)); } .toolbar[brighttext], @@ -142,15 +148,20 @@ :root[lwt-tree-brighttext] .calendar-list-create, :root[lwt-tree-brighttext] #CardViewBox, :root[lwt-tree-brighttext] #searchTerms { - --toolbarbutton-hover-background: var(--lwt-toolbarbutton-hover-background, rgba(255, 255, 255, .25)); - --toolbarbutton-hover-bordercolor: var(--lwt-toolbarbutton-hover-background, rgba(255, 255, 255, .5)); - --toolbarbutton-header-bordercolor: var(--lwt-toolbarbutton-hover-background, rgba(255, 255, 255, .25)); - - --toolbarbutton-active-background: var(--lwt-toolbarbutton-active-background, rgba(255, 255, 255, .4)); - --toolbarbutton-active-bordercolor: var(--lwt-toolbarbutton-active-background, rgba(255, 255, 255, .7)); - --toolbarbutton-active-boxshadow: 0 0 0 1px var(--lwt-toolbarbutton-active-background, rgba(255, 255, 255, .4)) inset; + --toolbarbutton-hover-background: var(--lwt-toolbarbutton-hover-background, + rgba(255, 255, 255, .25)); + --toolbarbutton-hover-bordercolor: var(--lwt-toolbarbutton-hover-background, + rgba(255, 255, 255, .5)); + --toolbarbutton-header-bordercolor: var(--lwt-toolbarbutton-hover-background, + rgba(255, 255, 255, .25)); + + --toolbarbutton-active-background: var(--lwt-toolbarbutton-active-background, + rgba(255, 255, 255, .4)); + --toolbarbutton-active-bordercolor: var(--lwt-toolbarbutton-active-background, + rgba(255, 255, 255, .7)); + --toolbarbutton-active-boxshadow: none; - --toolbarbutton-checkedhover-backgroundcolor: var(--lwt-toolbarbutton-hover-background, rgba(255, 255, 255, .5)); + --toolbarbutton-checkedhover-backgroundcolor: rgba(0, 0, 0, .25); } @media (-moz-os-version: windows-win10) and (-moz-windows-default-theme: 0) { @@ -260,8 +271,9 @@ } toolbox[labelalign="end"] .toolbarbutton-1, -toolbox[labelalign="end"] .toolbarbutton-1[type="menu-button"] - > .toolbarbutton-menubutton-button { +toolbox[labelalign="end"] .toolbarbutton-menubutton-button, +toolbox:not([mode="full"]) .toolbarbutton-1, +toolbox:not([mode="full"]) .toolbarbutton-menubutton-button { -moz-box-orient: horizontal; } @@ -570,6 +582,24 @@ :root:not(:-moz-lwtheme) treechildren::-moz-tree-row(hover) { border-color: transparent !important; } + + :root:not(:-moz-lwtheme) #threadTree > treechildren::-moz-tree-row(selected) { + background-color: -moz-CellHighlight; + border-color: -moz-CellHighlight; + } + + :root:not(:-moz-lwtheme) #threadTree > treechildren::-moz-tree-cell-text(untagged, selected) { + color: -moz-CellHighlightText !important; + } + + :root:not(:-moz-lwtheme) #threadTree > treechildren::-moz-tree-row(untagged, selected, focus) { + border-color: HighlightText; + background-color: Highlight; + } + + :root:not(:-moz-lwtheme) #threadTree > treechildren::-moz-tree-cell-text(untagged, selected, focus) { + color: HighlightText !important; + } } :root[lwt-tree] treechildren::-moz-tree-row(current, focus) { @@ -747,7 +777,7 @@ .toolbarbutton-1 > .toolbarbutton-menubutton-button, .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker { -moz-appearance: none; - background: hsla(210, 32%, 93%, 0) padding-box; + background-color: hsla(210, 32%, 93%, 0); border: 1px solid; border-radius: var(--toolbarbutton-border-radius); border-color: hsla(210, 54%, 20%, 0) hsla(210, 54%, 20%, 0) @@ -765,7 +795,7 @@ .toolbarbutton-1:not([disabled="true"]):hover > .toolbarbutton-menubutton-dropmarker, .toolbarbutton-1:not([type="menu-button"]):not([disabled="true"]):not([checked="true"]):not([open="true"]):not(:active):hover { - background: var(--toolbarbutton-hover-background); + background-color: var(--toolbarbutton-hover-background); border-color: var(--toolbarbutton-hover-bordercolor); box-shadow: var(--toolbarbutton-hover-boxshadow); } @@ -774,7 +804,7 @@ .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled="true"]):hover:active, .toolbarbutton-1[open="true"] > .toolbarbutton-menubutton-dropmarker:not([disabled="true"]), .toolbarbutton-1:not([type="menu-button"]):not([disabled="true"]):-moz-any([open="true"],[checked="true"],:hover:active) { - background: var(--toolbarbutton-active-background); + background-color: var(--toolbarbutton-active-background); border-color: var(--toolbarbutton-active-bordercolor); box-shadow: var(--toolbarbutton-active-boxshadow); transition-duration: 10ms; @@ -786,6 +816,32 @@ transition: background-color .4s; } +toolbox:not([labelalign="end"]) > toolbar[mode="full"] + .toolbarbutton-1:not(.button-appmenu)[type="menu"] { + padding-inline-end: 12px !important; + background-image: url("chrome://messenger/skin/icons/toolbarbutton-arrow.svg"); + background-size: 9px 9px; + background-repeat: no-repeat; + background-position: calc(100% - 4px) center; + -moz-context-properties: fill, fill-opacity, stroke-opacity; + stroke-opacity: 1; +} + +toolbox:not([labelalign="end"]) > toolbar[mode="full"] + .toolbarbutton-1:not(.button-appmenu)[type="menu"][disabled="true"] { + stroke-opacity: 0.4; +} + +toolbox:not([labelalign="end"]) > toolbar[mode="full"] + .toolbarbutton-1:not(.button-appmenu)[type="menu"]:-moz-locale-dir(rtl) { + background-position: 4px center; +} + +toolbox:not([labelalign="end"]) > toolbar[mode="full"] + .toolbarbutton-1:not(.button-appmenu)[type="menu"] > .toolbarbutton-menu-dropmarker { + display: none; +} + menulist > menupopup:not([is="folder-menupopup"]) > menuseparator { -moz-appearance: none; margin-top: 3px; diff -Nru thunderbird-78.10.1+build1/comm/SOURCE_CHANGESET thunderbird-78.10.2+build1/comm/SOURCE_CHANGESET --- thunderbird-78.10.1+build1/comm/SOURCE_CHANGESET 2021-05-04 14:24:04.000000000 +0000 +++ thunderbird-78.10.2+build1/comm/SOURCE_CHANGESET 2021-05-17 17:53:04.000000000 +0000 @@ -1 +1 @@ -14a9afcfb6cc0c466e0d0b8222e85de5b2d8078d \ No newline at end of file +6657aa43703aaa1de16003c4ab7e92a1cbc6dff8 \ No newline at end of file diff -Nru thunderbird-78.10.1+build1/debian/changelog thunderbird-78.10.2+build1/debian/changelog --- thunderbird-78.10.1+build1/debian/changelog 2021-05-04 14:29:45.000000000 +0000 +++ thunderbird-78.10.2+build1/debian/changelog 2021-05-17 17:59:19.000000000 +0000 @@ -1,3 +1,9 @@ +thunderbird (1:78.10.2+build1-0ubuntu0.21.04.1~mt1) hirsute; urgency=medium + + * New upstream stable release (78.10.2build1) + + -- Rico Tzschichholz Mon, 17 May 2021 19:59:19 +0200 + thunderbird (1:78.10.1+build1-0ubuntu0.21.04.1~mt1) hirsute; urgency=medium * New upstream stable release (78.10.1build1)