|
|
@ -7,16 +7,16 @@ var { pEpController } = ChromeUtils.import("chrome://pEp4Tb/content/pEpControlle |
|
|
|
|
|
|
|
// Add preferences info (see developer.thunderbird.net/add-ons/updates/tb68).
|
|
|
|
Preferences.addAll([ |
|
|
|
{ id: "extensions.pEp.storeAllSecurely", type: "bool" }, |
|
|
|
{ id: "extensions.pEp.warnUnencrypted", type: "bool" }, |
|
|
|
{ id: "extensions.pEp.protectSubjects", type: "bool" }, |
|
|
|
{ id: "extensions.pEp.passiveMode", type: "bool" }, |
|
|
|
{ id: "extensions.pEp.pEpSync", type: "bool" }, |
|
|
|
{ id: "extensions.pEp.keyFingerprint", type: "string" }, |
|
|
|
{ id: "extensions.pEp.keyLocation", type: "string" }, |
|
|
|
// examples with different types
|
|
|
|
// { id: "extensions.nameOfAddon.pref2", type: "string" },
|
|
|
|
// { id: "extensions.nameOfAddon.pref3", type: "int" },
|
|
|
|
{ id: "extensions.pEp.storeAllSecurely", type: "bool" }, |
|
|
|
{ id: "extensions.pEp.warnUnencrypted", type: "bool" }, |
|
|
|
{ id: "extensions.pEp.protectSubjects", type: "bool" }, |
|
|
|
{ id: "extensions.pEp.passiveMode", type: "bool" }, |
|
|
|
{ id: "extensions.pEp.pEpSync", type: "bool" }, |
|
|
|
{ id: "extensions.pEp.keyFingerprint", type: "string" }, |
|
|
|
{ id: "extensions.pEp.keyLocation", type: "string" }, |
|
|
|
// examples with different types
|
|
|
|
// { id: "extensions.nameOfAddon.pref2", type: "string" },
|
|
|
|
// { id: "extensions.nameOfAddon.pref3", type: "int" },
|
|
|
|
]); |
|
|
|
Preferences.get("extensions.pEp.protectSubjects").on( |
|
|
|
"change", |
|
|
@ -32,189 +32,189 @@ Preferences.get("extensions.pEp.storeAllSecurely").on( |
|
|
|
); |
|
|
|
|
|
|
|
function protectSubjectsChange() { |
|
|
|
if (Services.prefs.getBoolPref("extensions.pEp.protectSubjects", true)) { |
|
|
|
pEpController.enableprotectSubjects(); |
|
|
|
} else { |
|
|
|
pEpController.disableprotectSubjects(); |
|
|
|
} |
|
|
|
if (Services.prefs.getBoolPref("extensions.pEp.protectSubjects", true)) { |
|
|
|
pEpController.enableprotectSubjects(); |
|
|
|
} else { |
|
|
|
pEpController.disableprotectSubjects(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function passiveModeChange() { |
|
|
|
if (Services.prefs.getBoolPref("extensions.pEp.passiveMode", true)) { |
|
|
|
pEpController.enablePassiveMode(); |
|
|
|
} else { |
|
|
|
pEpController.disablePassiveMode(); |
|
|
|
} |
|
|
|
if (Services.prefs.getBoolPref("extensions.pEp.passiveMode", true)) { |
|
|
|
pEpController.enablePassiveMode(); |
|
|
|
} else { |
|
|
|
pEpController.disablePassiveMode(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function storeAllSecurelyChange() { |
|
|
|
const storeAllSecurely = Services.prefs.getBoolPref("extensions.pEp.storeAllSecurely", true); |
|
|
|
const root = document.getElementById("root"); |
|
|
|
let checkboxes = root.querySelectorAll(".account-storeSecurely"); |
|
|
|
for (let checkbox of checkboxes) { |
|
|
|
checkbox.setAttribute("disabled", storeAllSecurely); |
|
|
|
if (storeAllSecurely) { |
|
|
|
// Override.
|
|
|
|
let accountKey = checkbox.getAttribute("id"); |
|
|
|
let id = `mail.account.${accountKey}.storeSecurely`; |
|
|
|
Services.prefs.setBoolPref(id, true); |
|
|
|
} |
|
|
|
const storeAllSecurely = Services.prefs.getBoolPref("extensions.pEp.storeAllSecurely", true); |
|
|
|
const root = document.getElementById("root"); |
|
|
|
let checkboxes = root.querySelectorAll(".account-storeSecurely"); |
|
|
|
for (let checkbox of checkboxes) { |
|
|
|
checkbox.setAttribute("disabled", storeAllSecurely); |
|
|
|
if (storeAllSecurely) { |
|
|
|
// Override.
|
|
|
|
let accountKey = checkbox.getAttribute("id"); |
|
|
|
let id = `mail.account.${accountKey}.storeSecurely`; |
|
|
|
Services.prefs.setBoolPref(id, true); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function loadAccounts() { |
|
|
|
function makeIdentityFragment(identity) { |
|
|
|
const fragment = new pEpUtils.Fragment("#identity-options", document); |
|
|
|
const root = fragment.getRoot(); |
|
|
|
const [delim, delim2] = identity.fullName ? [" <", ">"] : ["", ""]; |
|
|
|
root.querySelector(".identity-title").textContent = `${identity.fullName}${delim}${identity.email}${delim2}`; |
|
|
|
|
|
|
|
let checkbox = root.querySelector(".identity-enableEncryption"); |
|
|
|
let id = `mail.identity.${identity.key}.enableEncryption`; |
|
|
|
// Get prior value, if any. Default to true.
|
|
|
|
let value = Services.prefs.getBoolPref(id, true); |
|
|
|
Preferences.add({ id, type: "bool" }); |
|
|
|
checkbox.setAttribute("preference", id); |
|
|
|
Services.prefs.setBoolPref(id, value); |
|
|
|
|
|
|
|
return root; |
|
|
|
function makeIdentityFragment(identity) { |
|
|
|
const fragment = new pEpUtils.Fragment("#identity-options", document); |
|
|
|
const root = fragment.getRoot(); |
|
|
|
const [delim, delim2] = identity.fullName ? [" <", ">"] : ["", ""]; |
|
|
|
root.querySelector(".identity-title").textContent = `${identity.fullName}${delim}${identity.email}${delim2}`; |
|
|
|
|
|
|
|
let checkbox = root.querySelector(".identity-enableEncryption"); |
|
|
|
let id = `mail.identity.${identity.key}.enableEncryption`; |
|
|
|
// Get prior value, if any. Default to true.
|
|
|
|
let value = Services.prefs.getBoolPref(id, true); |
|
|
|
Preferences.add({ id, type: "bool" }); |
|
|
|
checkbox.setAttribute("preference", id); |
|
|
|
Services.prefs.setBoolPref(id, value); |
|
|
|
|
|
|
|
return root; |
|
|
|
} |
|
|
|
|
|
|
|
function makeAccountFragment(account) { |
|
|
|
const fragment = new pEpUtils.Fragment("#account-options", document); |
|
|
|
const root = fragment.getRoot(); |
|
|
|
let accName = account.key; |
|
|
|
const server = Services.prefs.getStringPref(`mail.account.${account.key}.server`); |
|
|
|
if (server) { |
|
|
|
accName = Services.prefs.getStringPref(`mail.server.${server}.name`, accName); |
|
|
|
} |
|
|
|
|
|
|
|
function makeAccountFragment(account) { |
|
|
|
const fragment = new pEpUtils.Fragment("#account-options", document); |
|
|
|
const root = fragment.getRoot(); |
|
|
|
let accName = account.key; |
|
|
|
const server = Services.prefs.getStringPref(`mail.account.${account.key}.server`); |
|
|
|
if (server) { |
|
|
|
accName = Services.prefs.getStringPref(`mail.server.${server}.name`, accName); |
|
|
|
} |
|
|
|
root.querySelector(".account-title").textContent = accName; |
|
|
|
|
|
|
|
// Check global override.
|
|
|
|
let storeAllSecurely = Services.prefs.getBoolPref("extensions.pEp.storeAllSecurely", true); |
|
|
|
|
|
|
|
let checkbox = root.querySelector(".account-storeSecurely"); |
|
|
|
let id = `mail.account.${account.key}.storeSecurely`; |
|
|
|
// Get prior value, if any. Default to true.
|
|
|
|
let value = storeAllSecurely ? true : Services.prefs.getBoolPref(id, true); |
|
|
|
Preferences.add({ id, type: "bool" }); |
|
|
|
checkbox.setAttribute("preference", id); |
|
|
|
Services.prefs.setBoolPref(id, value); |
|
|
|
checkbox.setAttribute("disabled", storeAllSecurely); |
|
|
|
checkbox.setAttribute("id", account.key); |
|
|
|
|
|
|
|
let identities = []; |
|
|
|
for (let identity of fixIterator(account.identities, Ci.nsIMsgIdentity)) { |
|
|
|
identities.push({ key: identity.key, fullName: identity.fullName, email: identity.email }); |
|
|
|
} |
|
|
|
identities |
|
|
|
.map(makeIdentityFragment) |
|
|
|
.map((r) => root.querySelector(".insert-here").insertBefore(r, null)); |
|
|
|
return root; |
|
|
|
} |
|
|
|
|
|
|
|
const root = document.getElementById("root"); |
|
|
|
pEpUtils.removeChildren(root); |
|
|
|
|
|
|
|
let accounts = []; |
|
|
|
for (let account of fixIterator(MailServices.accounts.accounts, Ci.nsIMsgAccount)) { |
|
|
|
const server = Services.prefs.getStringPref(`mail.account.${account.key}.server`); |
|
|
|
if (!server) continue; |
|
|
|
const type = Services.prefs.getStringPref(`mail.server.${server}.type`, "badtype"); |
|
|
|
if (["rss", "im", "nntp", "badtype"].includes(type)) continue; // Skip Feeds, Chat and News.
|
|
|
|
accounts.push({ key: account.key, identities: account.identities }); |
|
|
|
root.querySelector(".account-title").textContent = accName; |
|
|
|
|
|
|
|
// Check global override.
|
|
|
|
let storeAllSecurely = Services.prefs.getBoolPref("extensions.pEp.storeAllSecurely", true); |
|
|
|
|
|
|
|
let checkbox = root.querySelector(".account-storeSecurely"); |
|
|
|
let id = `mail.account.${account.key}.storeSecurely`; |
|
|
|
// Get prior value, if any. Default to true.
|
|
|
|
let value = storeAllSecurely ? true : Services.prefs.getBoolPref(id, true); |
|
|
|
Preferences.add({ id, type: "bool" }); |
|
|
|
checkbox.setAttribute("preference", id); |
|
|
|
Services.prefs.setBoolPref(id, value); |
|
|
|
checkbox.setAttribute("disabled", storeAllSecurely); |
|
|
|
checkbox.setAttribute("id", account.key); |
|
|
|
|
|
|
|
let identities = []; |
|
|
|
for (let identity of fixIterator(account.identities, Ci.nsIMsgIdentity)) { |
|
|
|
identities.push({ key: identity.key, fullName: identity.fullName, email: identity.email }); |
|
|
|
} |
|
|
|
accounts |
|
|
|
.map(makeAccountFragment) |
|
|
|
.map(root.appendChild.bind(root)); |
|
|
|
identities |
|
|
|
.map(makeIdentityFragment) |
|
|
|
.map((r) => root.querySelector(".insert-here").insertBefore(r, null)); |
|
|
|
return root; |
|
|
|
} |
|
|
|
|
|
|
|
const root = document.getElementById("root"); |
|
|
|
pEpUtils.removeChildren(root); |
|
|
|
|
|
|
|
let accounts = []; |
|
|
|
for (let account of fixIterator(MailServices.accounts.accounts, Ci.nsIMsgAccount)) { |
|
|
|
const server = Services.prefs.getStringPref(`mail.account.${account.key}.server`); |
|
|
|
if (!server) continue; |
|
|
|
const type = Services.prefs.getStringPref(`mail.server.${server}.type`, "badtype"); |
|
|
|
if (["rss", "im", "nntp", "badtype"].includes(type)) continue; // Skip Feeds, Chat and News.
|
|
|
|
accounts.push({ key: account.key, identities: account.identities }); |
|
|
|
} |
|
|
|
accounts |
|
|
|
.map(makeAccountFragment) |
|
|
|
.map(root.appendChild.bind(root)); |
|
|
|
} |
|
|
|
|
|
|
|
function convertURLToLocalFile(aFileURL) { |
|
|
|
// convert the file url into a nsIFile
|
|
|
|
if (aFileURL) { |
|
|
|
return Services.io.getProtocolHandler("file") |
|
|
|
.QueryInterface(Ci.nsIFileProtocolHandler) |
|
|
|
.getFileFromURLSpec(aFileURL); |
|
|
|
} |
|
|
|
return null; |
|
|
|
// convert the file url into a nsIFile
|
|
|
|
if (aFileURL) { |
|
|
|
return Services.io.getProtocolHandler("file") |
|
|
|
.QueryInterface(Ci.nsIFileProtocolHandler) |
|
|
|
.getFileFromURLSpec(aFileURL); |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
function browseForKey() { |
|
|
|
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); |
|
|
|
|
|
|
|
// if we already have a key, then use the path.
|
|
|
|
var localFile = convertURLToLocalFile(document.getElementById("keyLocation").value); |
|
|
|
if (localFile) { |
|
|
|
fp.displayDirectory = localFile.parent; |
|
|
|
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); |
|
|
|
|
|
|
|
// if we already have a key, then use the path.
|
|
|
|
var localFile = convertURLToLocalFile(document.getElementById("keyLocation").value); |
|
|
|
if (localFile) { |
|
|
|
fp.displayDirectory = localFile.parent; |
|
|
|
} |
|
|
|
|
|
|
|
fp.init( |
|
|
|
window, |
|
|
|
"Select ASCII-armored file", // L10N
|
|
|
|
Ci.nsIFilePicker.modeOpen, |
|
|
|
); |
|
|
|
fp.appendFilter("ASC File", "*.asc"); // L10N
|
|
|
|
fp.appendFilters(Ci.nsIFilePicker.filterAll); |
|
|
|
|
|
|
|
fp.open((rv) => { |
|
|
|
if (rv != Ci.nsIFilePicker.returnOK || !fp.file) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
fp.init( |
|
|
|
window, |
|
|
|
"Select ASCII-armored file", // L10N
|
|
|
|
Ci.nsIFilePicker.modeOpen, |
|
|
|
); |
|
|
|
fp.appendFilter("ASC File", "*.asc"); // L10N
|
|
|
|
fp.appendFilters(Ci.nsIFilePicker.filterAll); |
|
|
|
|
|
|
|
fp.open((rv) => { |
|
|
|
if (rv != Ci.nsIFilePicker.returnOK || !fp.file) { |
|
|
|
return; |
|
|
|
} |
|
|
|
// convert the nsIFile into a nsIFile url
|
|
|
|
Preferences.get("extensions.pEp.keyLocation").value = fp.fileURL.spec; |
|
|
|
}); |
|
|
|
// convert the nsIFile into a nsIFile url
|
|
|
|
Preferences.get("extensions.pEp.keyLocation").value = fp.fileURL.spec; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
function importKey() { |
|
|
|
let location = Preferences.get("extensions.pEp.keyLocation").value; |
|
|
|
let channel = Services.io.newChannelFromURI(Services.io.newURI(location), null, |
|
|
|
Services.scriptSecurityManager.getSystemPrincipal(), null, |
|
|
|
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, |
|
|
|
Ci.nsIContentPolicy.TYPE_OTHER); |
|
|
|
let inputStream = channel.open(); |
|
|
|
let stream = Cc["@mozilla.org/binaryinputstream;1"] |
|
|
|
.createInstance(Ci.nsIBinaryInputStream); |
|
|
|
stream.setInputStream(inputStream); |
|
|
|
let streamData = ""; |
|
|
|
try { |
|
|
|
while (stream.available() > 0) { |
|
|
|
streamData += stream.readBytes(stream.available()); |
|
|
|
} |
|
|
|
} catch (e) { |
|
|
|
stream.close(); |
|
|
|
// eslint-disable-next-line prefer-template
|
|
|
|
throw new Error("Couldn't read all data from location " + location + " (" + e + ")"); |
|
|
|
let location = Preferences.get("extensions.pEp.keyLocation").value; |
|
|
|
let channel = Services.io.newChannelFromURI(Services.io.newURI(location), null, |
|
|
|
Services.scriptSecurityManager.getSystemPrincipal(), null, |
|
|
|
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, |
|
|
|
Ci.nsIContentPolicy.TYPE_OTHER); |
|
|
|
let inputStream = channel.open(); |
|
|
|
let stream = Cc["@mozilla.org/binaryinputstream;1"] |
|
|
|
.createInstance(Ci.nsIBinaryInputStream); |
|
|
|
stream.setInputStream(inputStream); |
|
|
|
let streamData = ""; |
|
|
|
try { |
|
|
|
while (stream.available() > 0) { |
|
|
|
streamData += stream.readBytes(stream.available()); |
|
|
|
} |
|
|
|
} catch (e) { |
|
|
|
stream.close(); |
|
|
|
|
|
|
|
// Send to the engine.
|
|
|
|
pEpController.importKey(streamData).then((result) => { |
|
|
|
let msg; |
|
|
|
// If we get identites returned, we imported a private key,
|
|
|
|
// if we get empty identities, we imported a public key.
|
|
|
|
// Anything else is an error.
|
|
|
|
if (typeof result !== "object") { |
|
|
|
console.log(`Key import error ${result}`); |
|
|
|
msg = "Key import failed"; // L10N
|
|
|
|
} else if (result.length == 0) { |
|
|
|
console.log("Public key import not supported"); |
|
|
|
msg = "Public key import not supported"; // L10N
|
|
|
|
} else { |
|
|
|
result[0].user_id = "pEp_own_userId"; |
|
|
|
pEpController.setOwnKey(result[0]); |
|
|
|
// TODO: Check error.
|
|
|
|
const username = result[0].username; |
|
|
|
const [delim, delim2] = username ? [" <", ">"] : ["", ""]; |
|
|
|
msg = `Key successfully imported for ${username}${delim}${result[0].address}${delim2}`; // L10N
|
|
|
|
} |
|
|
|
Services.prompt.alert( |
|
|
|
null, |
|
|
|
"Key import", // L10N
|
|
|
|
msg, |
|
|
|
); |
|
|
|
}); |
|
|
|
// eslint-disable-next-line prefer-template
|
|
|
|
throw new Error("Couldn't read all data from location " + location + " (" + e + ")"); |
|
|
|
} |
|
|
|
stream.close(); |
|
|
|
|
|
|
|
// Send to the engine.
|
|
|
|
pEpController.importKey(streamData).then((result) => { |
|
|
|
let msg; |
|
|
|
// If we get identites returned, we imported a private key,
|
|
|
|
// if we get empty identities, we imported a public key.
|
|
|
|
// Anything else is an error.
|
|
|
|
if (typeof result !== "object") { |
|
|
|
console.log(`Key import error ${result}`); |
|
|
|
msg = "Key import failed"; // L10N
|
|
|
|
} else if (result.length == 0) { |
|
|
|
console.log("Public key import not supported"); |
|
|
|
msg = "Public key import not supported"; // L10N
|
|
|
|
} else { |
|
|
|
result[0].user_id = "pEp_own_userId"; |
|
|
|
pEpController.setOwnKey(result[0]); |
|
|
|
// TODO: Check error.
|
|
|
|
const username = result[0].username; |
|
|
|
const [delim, delim2] = username ? [" <", ">"] : ["", ""]; |
|
|
|
msg = `Key successfully imported for ${username}${delim}${result[0].address}${delim2}`; // L10N
|
|
|
|
} |
|
|
|
Services.prompt.alert( |
|
|
|
null, |
|
|
|
"Key import", // L10N
|
|
|
|
msg, |
|
|
|
); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
window.addEventListener("load", () => { |
|
|
|
loadAccounts(); |
|
|
|
loadAccounts(); |
|
|
|
}); |