Show privacy ratings on emails on decrypt and on composing

1.1.101
Chris Fuertes 2019-03-19 14:50:18 +01:00
parent e96e3e7e24
commit 3d33b3b34c
15 changed files with 847 additions and 147 deletions

View File

@ -1,7 +1,8 @@
FROM alpine:latest
RUN apk add zip
RUN apk add --update zip
RUN apk add --update make
WORKDIR /usr/src/app
COPY chrome .
COPY . .
CMD ["zip", "-r", "build/p4t.xpi", "."]
CMD ["make", "clean", "xpi"]

6
Makefile Normal file
View File

@ -0,0 +1,6 @@
xpi:
cd chrome; zip -r p4t.xpi . ; cd ..
mv chrome/p4t.xpi build
clean:
rm build/p4t.xpi
all:xpi

View File

@ -1,16 +1,85 @@
//TODO: Implement for restartless app https://developer.mozilla.org/en-US/docs/Archive/Add-ons/How_to_convert_an_overlay_extension_to_restartless#Step_9_bootstrap.js
/* globals Components, Services */
/* exported install, uninstall, startup, shutdown */
Components.utils.import('resource://gre/modules/Services.jsm');
function install() {
console.log("bootstrap.js: Install");
}
function startup() {
console.log("bootstrap.js: Startup");
windowObserver.init();
}
function shutdown() {
console.log("bootstrap.js: Shutdown");
windowObserver.destroy();
}
function uninstall() {
console.log("bootstrap.js: Uninstall");
}
}
let windowObserver = {
init: function() {
console.log("INIT");
this.enumerate('mail:3pane', this.paint);
this.enumerate('mail:messageWindow', this.paint);
this.enumerate('msgcompose', this.paint);
this.enumerate('mailnews:mailviewlist', this.paint);
this.enumerate('msghdr', this.paint);
Services.ww.registerNotification(this);
},
destroy: function() {
this.enumerate('mail:3pane', this.unpaint);
this.enumerate('msgcompose', this.unpaint);
Services.ww.unregisterNotification(this);
},
enumerate: function(windowType, callback) {
let windowEnum = Services.wm.getEnumerator(windowType);
while (windowEnum.hasMoreElements()) {
callback.call(this, windowEnum.getNext());
}
},
observe: function(subject) {
subject.addEventListener('load', function() {
windowObserver.paint(subject);
}, false);
},
paint: function(win) {
console.log("PAINT", win.location.href);
let script;
switch (win.location.href) {
case 'chrome://messenger/content/messenger.xul':
script = 'chrome://p4t/content/pepmessenger.js';
break;
case 'chrome://messenger/content/messengercompose/messengercompose.xul':
script = 'chrome://p4t/content/pepmessengercompose.js';
break;
case 'chrome://messenger/content/messengercompose/msgHdrViewOverlay.xul':
script = 'chrome://p4t/content/pepmsghdrview.js';
break;
default:
return;
}
Services.scriptloader.loadSubScript(script, win);
},
unpaint: function(win) {
console.log("UN PAINT");
switch (win.location.href) {
case 'chrome://messenger/content/messenger.xul':
win.pEpMessenger.destroy();
break;
case 'chrome://messenger/content/messengercompose/messengercompose.xul':
break;
case 'chrome://messenger/content/messengercompose/msgHdrViewOverlay.xul':
win.pEpMsgHdrView.destroy();
break;
}
}
};

View File

@ -90,12 +90,24 @@ class pEp {
return result;
}
checkPrivacy() {
async emailRatings(email) {
return await this.getIdentityRating(email);
}
async getIdentityRating(email) {
let identity = new pEp.Identity(email, "", "", "");
return await this.adapter.getIdentityRating(identity);
}
async getOngoingRating(from, to = []) {
let msgId = PEP_PREFIX + String(this.requestId++);
let message = new pEp.Message(msgId, "test", "test", from, to);
return await this.adapter.getOngoingRating(message);
}
async getPrivacyColorFromRating(rating) {
return await this.adapter.color_from_rating(rating);
return await this.adapter.colorFromRating(rating);
}
showTrustwords() {
@ -143,7 +155,6 @@ class pEp {
pEp.Identity = class {
constructor(address, id = "", name = "anonymous", fingerprint) {
if (typeof address === "string") {
this.user_id = id;
this.username = name;
@ -189,11 +200,22 @@ pEp.Message = class {
this.shortmsg = short;
this.longmsg = long;
this.from = new pEp.Identity(from);
this.to = to.reduce((addresses, addr) => {
addresses.push(new pEp.Identity(addr));
return addresses;
}, []);
if(pEp.Identity.prototype.isPrototypeOf(from)) {
this.from = from;
}
else {
this.from = new pEp.Identity(from);
}
if(pEp.Identity.prototype.isPrototypeOf(to[0])) {
this.to = to;
}
else {
this.to = to.reduce((addresses, addr) => {
addresses.push(new pEp.Identity(addr));
return addresses;
}, []);
}
this.dir = dir;
this.enc_format = enc_format;

View File

@ -4,6 +4,9 @@ const SERVER_TYPE_CALL_FUNC = "callFunction";
const API_METHOD_SERVER_VERSION = "serverVersion";
const API_METHOD_DECRYPT = "decrypt_message";
const API_METHOD_ENCRYPT = "encrypt_message";
const API_METHOD_GET_OUTGOING_RATING = "outgoing_message_rating";
const API_METHOD_IDENTITY_RATING = "identity_rating";
const DIR_INCOMING = 0;
const DIR_OUTGOING = 1;
const ENC_FORMAT_PIECES = 1;
@ -33,6 +36,7 @@ class pEpAdapter {
this.log = log;
this.server = server;
this.requestId = 0;
this.ratings = [];
}
async serverVersion() {
@ -49,6 +53,20 @@ class pEpAdapter {
});
}
async getOngoingRating(message) {
this.log("pEpAdapter.js: getOngoingRating()");
let params = [message, "0"];
return await this.server.callPepAdapter(
SERVER_TYPE_CALL_FUNC,
API_METHOD_GET_OUTGOING_RATING,
params
).then((response) => {
return response.result.outParams[0].rating;
}).catch((err) => {
this.log(err);
});
}
async decrypt_message(message) {
this.log("pEpAdapter.js: decrypt_message()", message);
let params = [
@ -96,11 +114,19 @@ class pEpAdapter {
case(PEP_RESPONSE_OK):
case(PEP_RESPONSE_DECRYPTED):
decryptedMessage = response.result.outParams[3];
if (decryptedMessage === null) {
decryptedMessage = response.result.outParams[1];
} else {
decryptedMessage.rating = response.result.outParams[1].rating;
}
this.log("callPepAdapter: 'decrypt' returned with success: ", response);
break;
case(PEP_UNENCRYPTED):
decryptedMessage = message;
decryptedMessage.rating = RATING_COLOR_NO_COLOR;
this.log("callPepAdapter: 'decrypt' returned with UNENCRYPTED status: ", response);
break;
@ -114,23 +140,6 @@ class pEpAdapter {
});
}
async decrypt(subject, body, sender = "*", to, cc, replyTo, enc_format = ENC_FORMAT_PEP) {
this.log("pEpAdapter.js: decrypt()");
let message = new pEp.Message(null, subject, body, sender, to, DIR_INCOMING, enc_format);
if (cc) {
message.cc = cc;
}
if (replyTo) {
message.reply_to = replyTo;
}
message.addAttachment(btoa(body), body.length);
this.decrypt_message(message);
}
async encrypt_message(message) {
let params = [
message,
@ -192,34 +201,57 @@ class pEpAdapter {
});
}
async encrypt(subject, body, from, to = [], stringlist = [], encodingFormat = ENC_FORMAT_PEP) {
async colorFromRating(rating) {
let msgId = PEP_PREFIX + String(this.requestId);
let message = new pEp.Message(msgId, subject, body, from, to, DIR_OUTGOING, encodingFormat);
return this.encrypt_message(message);
if (rating === -2 || rating === 2) {
return RATING_COLOR_NO_COLOR;
}
if (rating < 0) {
return RATING_COLOR_RED;
}
if (rating < 6) {
return RATING_COLOR_NO_COLOR;
}
if (rating >= 7) {
return RATING_COLOR_GREEN;
}
return RATING_COLOR_YELLOW;
}
async color_from_rating(rating) {
async getIdentityRating(identity) {
this.log("pEpAdapter.js: getIdentityRating()");
// new Proxy(this.server.callPepAdapter, {
// apply(target, thisArg, args) {
// if(this.ratings[email]) {
// return this.ratings[email];
// }
// let rating = Reflect.apply(target, thisArg, args);
// this.ratings[email] = rating;
// return rating;
// }
// }
// );
let color = RATING_COLOR_NO_COLOR;
if (rating === -2 || rating === 2) {
color = RATING_COLOR_NO_COLOR;
}
else if (rating < 0) {
color = RATING_COLOR_RED;
}
else if (rating < 6) {
color = RATING_COLOR_NO_COLOR;
}
else if (rating >= 7) {
color = RATING_COLOR_GREEN;
}
else {
color = RATING_COLOR_YELLOW;
let cachedMail = this.ratings[identity.address];
if(cachedMail) {
return cachedMail;
}
return color;
let params = [ identity, ["OP"] ];
return await this.server.callPepAdapter(
SERVER_TYPE_CALL_FUNC,
API_METHOD_IDENTITY_RATING,
params
).then((response) => {
return response.result.return;
}).catch((err) => {
this.log(err);
});
}
}

31
chrome/content/pEp.css Normal file
View File

@ -0,0 +1,31 @@
.green {
background-color: #59b753;
border-color: #468f41;
}
.yellow {
background-color: #e3d02e;
border-color: #c7b729;
color: black;
}
.red {
background-color: #fc625d;
border-color: #c35855;
}
.no-color {
background-color: #dddddd;
border-color: #959595;
color: black;
}
.privacy-bar {
height: 25px;
color: white;
position: fixed;
bottom:15px;
width: 100%;
margin: auto;
padding-left: 10px;
}

View File

@ -1,14 +1,202 @@
const Cu = Components.utils;
Cu.import("chrome://p4t/content/modules/pEp.js");
Cu.import("chrome://p4t/content/p4tb.js");
window.addEventListener("load", function(e) {
let privacyPanel = document.getElementById("pEp-statusbar-privacy-status");
let pEpMessenger = {
init: () => {
console.log("pEpMessenger: init()");
},
destroy: () => {
console.log("pEpMessenger: destroy()");
},
pEpController.getVersion().then(value => {
privacyPanel.value = `p≡p running (v${value})`;
}).
catch(e => {
privacyPanel.value = `p≡p not running`;
});
getCurrentMessageURI: () => {
if (gFolderDisplay.selectedMessages.length === 1) {
return gFolderDisplay.selectedMessageUris[0];
}
return null;
},
}, false);
readMailFromUri: (msgUri) => {
let msgWindow = Cc["@mozilla.org/messenger/msgwindow;1"].createInstance();
msgWindow = msgWindow.QueryInterface(Ci.nsIMsgWindow);
let msgStream = Cc["@mozilla.org/network/sync-stream-listener;1"].createInstance();
msgStream = msgStream.QueryInterface(Ci.nsIInputStream);
let messenger = Cc["@mozilla.org/messenger;1"].getService(Ci.nsIMessenger);
let msgService = messenger.messageServiceFromURI(msgUri);
let scriptInputStream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance();
scriptInputStream = scriptInputStream.QueryInterface(Ci.nsIScriptableInputStream);
scriptInputStream.init(msgStream);
try {
msgService.streamMessage(msgUri, // uri of message to stream
msgStream, // a stream listener listening to the message
msgWindow, // a nsIMsgWindow for progress and status feedback
null, // a nsIUrlListener that is notified when url starts and stops
false, // it will create a stream converter from message rfc2822 to
null // Header added to the URI. e.g., header=filter
);
} catch (ex) {
console.debug("Error while reading mail from server", ex);
}
// Get only the PGP message
let keyFound = false;
let content = "";
let str = "";
const PGP_MESSAGE_HEADER = "-----BEGIN PGP MESSAGE-----";
const PGP_MESSAGE_FOOTER = "-----END PGP MESSAGE-----";
const INPUTSTREAM_READING_SIZE = 512;
while (scriptInputStream.available()) {
str = scriptInputStream.read(INPUTSTREAM_READING_SIZE);
let pgpStartIndex = str.indexOf(PGP_MESSAGE_HEADER);
let pgpEndIndex = str.indexOf(PGP_MESSAGE_FOOTER);
if (pgpStartIndex >= 0) {
keyFound = true;
str = str.substring(pgpStartIndex);
} else if (pgpEndIndex >= 0) {
content += str.substring(0, pgpEndIndex + PGP_MESSAGE_FOOTER.length);
break;
}
if (keyFound) {
content += str;
}
}
return content;
},
_parseAddress: (address) => {
let hdr = Cc["@mozilla.org/messenger/headerparser;1"].createInstance(Ci.nsIMsgHeaderParser);
let mails = hdr.parseEncodedHeader(address, "utf-8");
return mails.map((mail) => {
return {
address: mail.email,
username: mail.name
};
})
},
onLoadListener: (event) => {
console.log("pepmessenger.js: onLoadListener()");
let onStartHeadersMessageListener = () => {
let messagePanelFrame = window.GetMessagePaneFrame();
console.log("pepmessenger.js: onLoadMsgPanelFrameListener(), frame: ", messagePanelFrame);
if (messagePanelFrame != null) {
console.log("pepmessenger.js: onLoadListener() added listener");
messagePanelFrame.addEventListener("load", onLoadMsgPanelFrameListener, false);
}
};
let onEndHeadersMessageListener = () => {
};
gMessageListeners.push({
onStartHeaders: onStartHeadersMessageListener,
onEndHeaders: onEndHeadersMessageListener
});
onStartHeadersMessageListener();
onEndHeadersMessageListener();
},
onLoadMsgPanelFrameListener: (event) => {
/* global currentHeaderData: false, gViewAllHeaders: false, gExpandedHeaderList: false, goDoCommand: false, HandleSelectedAttachments: false */
function updateSubject(newSubject) {
let subjectBox = document.getElementById("expandedsubjectBox");
subjectBox.headerValue = newSubject;
}
function updateBody(newBody) {
//TODO Not implemented yet
let panel = window.GetMessagePaneFrame();
let bodyElement = panel.document.getElementsByTagName("body")[0];
let node = bodyElement.firstChild;
while (node) {
if (node.nodeName === "DIV" || node.nodeName === "PRE") {
if (node.textContent.indexOf("-----BEGIN PGP")) {
node.innerHTML = newBody;
return;
}
}
node = node.nextSibling;
}
}
function updatePrivacy(privacyStatus) {
let privacyPanel = document.getElementById("pEp-msghdr-privacy-label");
switch (privacyStatus) {
case "red":
case "green":
case "yellow":
break;
default:
privacyStatus = "no-color";
break;
}
privacyPanel.value = privacyStatus;
privacyPanel.class = privacyStatus;
}
let messageString;
console.log("pepmessenger.js: onLoadMsgPanelFrameListener()", currentHeaderData);
// Clean previous privacy labels
updatePrivacy("no-color");
// read email from tb
let currentUri = this.getCurrentMessageURI();
if (currentUri !== null) {
try {
messageString = this.readMailFromUri(currentUri);
console.log("===============");
console.log(messageString);
console.log("===============");
}
catch (e) {
console.debug("Errors while reading message from uri", e);
}
if (messageString === "") {
console.debug("Nothing to decrypt");
return;
}
let sender = this._parseAddress(currentHeaderData.from.headerValue)[0];
let to = this._parseAddress(currentHeaderData.to.headerValue);
pEpController.decryptMail(messageString, sender, to, currentHeaderData["message-id"].headerValue).then((message) => {
if (message === null) {
console.log("Message not decrypted");
return;
}
// replace encrypted mail with decrypted from pEpAdapter
updateSubject(message.shortmsg);
updateBody(message.longmsg);
pEpController.getPrivacyColorFromRating(message.rating).then(
(rating) => {
updatePrivacy(rating);
}
);
}).catch((err) => {
console.log(err)
});
}
}
};
pEpMessenger.init();

View File

@ -5,19 +5,11 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
-->
<overlay id="p4tMessengerOverlay"
<?xml-stylesheet href="chrome://p4t/content/pEp.css" type="text/css"?>
<overlay id="p4tMsgComposeOverlay"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="appplication/javascript" src="chrome://p4t/content/pepmessenger.js"/>
<statusbar id="status-bar">
<statusbarpanel id="pep-statusbar">
<hbox align="center">
<label id="pep-statusbar-privacy-status" value="" />
</hbox>
</statusbarpanel>
</statusbar>
<script type="application/javascript" src="chrome://p4t/content/pepmessenger.js"/>
</overlay>

View File

@ -156,6 +156,7 @@ let initListener = (event) => {
// Monkeypatching onRecipientsChanged event to add some pEp functionality
onRecipientsChanged = (aAutomatic) => {
addressPopupListener();
pEp_onRecipientsChanged();
tb_onRecipientsChanged(aAutomatic);
};
@ -177,6 +178,62 @@ let initListener = (event) => {
gMsgCompose.RegisterStateListener(stateListener);
};
let addressPopupListener = (event) => {
console.log("pepmessengercompose.js: addressPopupListener()");
let msgCompFields = gMsgCompose.compFields;
Recipients2CompFields(msgCompFields);
let from = gCurrentIdentity.email;
let to = msgCompFields.to || [];
pEpController.getOngoingRating(from, to).then((rating) => {
pEpController.getPrivacyColorFromRating(rating).then((color) => {
createPrivacyNode(color);
});
});
};
let privacyStatusToTextClass = (privacyStatus) => {
let privacyText = "Unknown";
switch (privacyStatus) {
case "red":
privacyText = "Mistrusted";
case "green":
privacyText = "Secure & Trusted";
case "yellow":
privacyText = "Secure";
break;
default:
privacyStatus = "no-color";
break;
}
return {class: privacyStatus, text: privacyText};
};
let createPrivacyNode = (privacyStatus) => {
let privacyTextClass = privacyStatusToTextClass(privacyStatus);
let privacyNodeId = "pEp-compose-privacy-bar";
let oldNode = document.getElementById(privacyNodeId);
if (oldNode) {
oldNode.parentNode.removeChild(oldNode);
}
let newNode = document.createElement("hbox");
newNode.setAttribute("flex", "1");
newNode.classList.add("privacy-bar");
newNode.classList.add(privacyTextClass.class);
newNode.id = privacyNodeId;
let privacyLabel = document.createTextNode(privacyTextClass.text);
newNode.appendChild(privacyLabel);
let appcontentNode = document.getElementById("appcontent");
appcontentNode.parentNode.appendChild(newNode);
};
window.addEventListener("compose-window-init", initListener, true);
window.addEventListener("compose-from-changed", fromChangedListener, true);
window.addEventListener("compose-send-message", sendListener, true);

View File

@ -5,18 +5,11 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
-->
<?xml-stylesheet href="chrome://p4t/content/pEp.css" type="text/css"?>
<overlay id="p4tMsgComposeOverlay"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://p4t/content/pepmessengercompose.js"/>
<statusbar id="status-bar">
<statusbarpanel id="pep-statusbar">
<hbox align="center">
<label id="pEp-statusbar-privacy-status" value="" />
</hbox>
</statusbarpanel>
</statusbar>
</overlay>

View File

@ -36,56 +36,93 @@ let onLoadListener = (event) => {
};
let onLoadMsgPanelFrameListener = (event) => {
let privacyStatusToTextClass = (privacyStatus) => {
let privacyText = "Unknown";
switch (privacyStatus) {
case "red":
privacyText = "Mistrusted";
case "green":
privacyText = "Secure & Trusted";
case "yellow":
privacyText = "Secure";
break;
default:
privacyStatus = "no-color";
break;
}
return {class: privacyStatus, text: privacyText};
};
/* global currentHeaderData: false, gViewAllHeaders: false, gExpandedHeaderList: false, goDoCommand: false, HandleSelectedAttachments: false */
function updateSubject(newSubject) {
let subjectBox = document.getElementById("expandedsubjectBox");
subjectBox.headerValue = newSubject;
function updatePrivacy(privacyStatus) {
let privacyTextClass = privacyStatusToTextClass(privacyStatus);
let privacyNodeId = "pEp-msghdr-privacy-label";
let oldNode = document.getElementById(privacyNodeId);
if (oldNode) {
oldNode.parentNode.removeChild(oldNode);
}
function updateBody(newBody) {
//TODO Not implemented yet
let panel = window.GetMessagePaneFrame();
let bodyElement = panel.document.getElementsByTagName("body")[0];
let node = bodyElement.firstChild;
while (node) {
if (node.nodeName === "DIV" || node.nodeName === "PRE") {
if (node.textContent.indexOf("-----BEGIN PGP")) {
node.innerHTML = newBody;
return;
}
}
node = node.nextSibling;
}
}
let newNode = document.createElement("hbox");
newNode.setAttribute("flex", "1");
newNode.classList.add("privacy-bar");
newNode.classList.add(privacyTextClass.class);
newNode.id = privacyNodeId;
let privacyLabel = document.createTextNode(privacyTextClass.text);
newNode.appendChild(privacyLabel);
function updatePrivacy(privacyStatus) {
let privacyPanel = document.getElementById("pEp-msghdr-privacy-label");
let mainHeaderAreaNode = document.getElementById("msgHeaderView");
mainHeaderAreaNode.parentNode.appendChild(newNode);
}
let backgroundColor = "#dddddd";
switch (privacyStatus) {
case "red":
backgroundColor = "#fc625d";
break;
case "green":
backgroundColor = "#59b753";
break;
case "yellow":
backgroundColor = "#e3d02e";
break;
default:
privacyPanel.value = "";
privacyPanel.style = "";
function updateBodyJustBody(newBody) {
//TODO Not implemented yet
let panel = window.GetMessagePaneFrame();
let bodyElement = panel.document.getElementsByTagName("body")[0];
let node = bodyElement.firstChild;
while (node) {
if (node.nodeName === "DIV" || node.nodeName === "PRE") {
if (node.textContent.indexOf("-----BEGIN PGP")) {
node.innerHTML = newBody;
return;
}
}
privacyPanel.value = `Privacy color: ${privacyStatus}`;
privacyPanel.style = `background-color: ${backgroundColor}`;
node = node.nextSibling;
}
}
function updateBody(newBody) {
newBody = utf8_decode(quoted_printable_decode(newBody));
//TODO Not implemented yet
let panel = window.GetMessagePaneFrame();
console.log("PANEL ==========", panel);
let bodyElement = panel.document.getElementsByTagName("body")[0];
let node = bodyElement.firstChild;
while (node) {
if (node.nodeName === "DIV" || node.nodeName === "PRE") {
if (node.textContent.indexOf("-----BEGIN PGP")) {
node.innerHTML = newBody;
return;
}
}
node = node.nextSibling;
}
}
/* global currentHeaderData: false, gViewAllHeaders: false, gExpandedHeaderList: false, goDoCommand: false, HandleSelectedAttachments: false */
function updateSubject(newSubject) {
let subjectBox = document.getElementById("expandedsubjectBox");
subjectBox.headerValue = newSubject;
}
let onLoadMsgPanelFrameListener = (event) => {
console.log("pepmsghdrview.js: onLoadMsgPanelFrameListener()", currentHeaderData);
let messageString;
console.log("pepmsghdrview.js: onLoadMsgPanelFrameListener()", currentHeaderData);
// Clean previous privacy labels
updatePrivacy("no-color");
// read email from tb
let currentUri = getCurrentMessageURI();
@ -103,7 +140,6 @@ let onLoadMsgPanelFrameListener = (event) => {
if (messageString === "") {
console.debug("Nothing to decrypt");
updatePrivacy("no-color");
return;
}
@ -113,13 +149,12 @@ let onLoadMsgPanelFrameListener = (event) => {
pEpController.decryptMail(messageString, sender, to, currentHeaderData["message-id"].headerValue).then((message) => {
if (message === null) {
console.log("Message not decrypted");
updatePrivacy("no-color");
return;
}
// replace encrypted mail with decrypted from pEpAdapter
updateSubject(message.shortmsg);
updateBody(message.longmsg);
console.log("DECRYPTED MESSAGE ", message);
pEpController.getPrivacyColorFromRating(message.rating).then(
(rating) => {
updatePrivacy(rating);
@ -127,7 +162,6 @@ let onLoadMsgPanelFrameListener = (event) => {
);
}).catch((err) => {
console.log(err)
});
}
@ -213,3 +247,95 @@ let getCurrentMessageURI = () => {
window.addEventListener("load", onLoadListener, false);
let pEpHdrView = {
init: () => {
console.log("pEpMessenger: init()");
},
destroy: () => {
console.log("pEpMessenger: destroy()");
}
};
function quoted_printable_decode(str) {
// discuss at: http://phpjs.org/functions/quoted_printable_decode/
// original by: Ole Vrijenhoek
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// bugfixed by: Theriault
// reimplemented by: Theriault
// improved by: Brett Zamir (http://brett-zamir.me)
// example 1: quoted_printable_decode('a=3Db=3Dc');
// returns 1: 'a=b=c'
// example 2: quoted_printable_decode('abc =20\r\n123 =20\r\n');
// returns 2: 'abc \r\n123 \r\n'
// example 3: quoted_printable_decode('012345678901234567890123456789012345678901234567890123456789012345678901234=\r\n56789');
// returns 3: '01234567890123456789012345678901234567890123456789012345678901234567890123456789'
// example 4: quoted_printable_decode("Lorem ipsum dolor sit amet=23, consectetur adipisicing elit");
// returns 4: 'Lorem ipsum dolor sit amet#, consectetur adipisicing elit'
var RFC2045Decode1 = /=\r\n/gm,
// Decodes all equal signs followed by two hex digits
RFC2045Decode2IN = /=([0-9A-F]{2})/gim,
// the RFC states against decoding lower case encodings, but following apparent PHP behavior
// RFC2045Decode2IN = /=([0-9A-F]{2})/gm,
RFC2045Decode2OUT = function(sMatch, sHex) {
return String.fromCharCode(parseInt(sHex, 16));
};
return str.replace(RFC2045Decode1, '')
.replace(RFC2045Decode2IN, RFC2045Decode2OUT);
};
function utf8_decode(str_data) {
// discuss at: http://phpjs.org/functions/utf8_decode/
// original by: Webtoolkit.info (http://www.webtoolkit.info/)
// input by: Aman Gupta
// input by: Brett Zamir (http://brett-zamir.me)
// improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// improved by: Norman "zEh" Fuchs
// bugfixed by: hitwork
// bugfixed by: Onno Marsman
// bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// bugfixed by: kirilloid
// example 1: utf8_decode('Kevin van Zonneveld');
// returns 1: 'Kevin van Zonneveld'
var tmp_arr = [],
i = 0,
ac = 0,
c1 = 0,
c2 = 0,
c3 = 0,
c4 = 0;
str_data += '';
while (i < str_data.length) {
c1 = str_data.charCodeAt(i);
if (c1 <= 191) {
tmp_arr[ac++] = String.fromCharCode(c1);
i++;
} else if (c1 <= 223) {
c2 = str_data.charCodeAt(i + 1);
tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
i += 2;
} else if (c1 <= 239) {
// http://en.wikipedia.org/wiki/UTF-8#Codepage_layout
c2 = str_data.charCodeAt(i + 1);
c3 = str_data.charCodeAt(i + 2);
tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
} else {
c2 = str_data.charCodeAt(i + 1);
c3 = str_data.charCodeAt(i + 2);
c4 = str_data.charCodeAt(i + 3);
c1 = ((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63);
c1 -= 0x10000;
tmp_arr[ac++] = String.fromCharCode(0xD800 | ((c1 >> 10) & 0x3FF));
tmp_arr[ac++] = String.fromCharCode(0xDC00 | (c1 & 0x3FF));
i += 4;
}
}
return tmp_arr.join('');
}
pEpHdrView.init();

View File

@ -5,27 +5,11 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
-->
<?xml-stylesheet href="chrome://p4t/content/pEp.css" type="text/css"?>
<overlay id="p4tMsgComposeOverlay"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://p4t/content/pepmsghdrview.js"/>
<hbox id="expandedHeadersTopBox">
<label id="pEp-msghdr-privacy-label"
value="PRIVACY BY DEFAULT"
style="background-color: #59b753;"
/>
<br></br>
</hbox>
<statusbar id="status-bar">
<statusbarpanel id="pep-msghdr-statusbar">
<hbox align="center">
<label id="pep-msghdr-statusbar-privacy-status" value="" />
</hbox>
</statusbarpanel>
</statusbar>
</overlay>

View File

@ -5,7 +5,7 @@
<Description about="urn:mozilla:install-manifest">
<em:id>{847b3a00-7ab1-11d4-8f02-006008948af5}</em:id>
<em:version>1000.0.1-alpha</em:version>
<em:version>1.0.0-beta1</em:version>
<em:type>2</em:type> <!-- type = extension -->
<!-- MetaData -->
@ -20,7 +20,7 @@
<!-- Thunderbird -->
<Description>
<em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
<em:minVersion>52.0</em:minVersion>
<em:minVersion>60.0</em:minVersion>
<em:maxVersion>99.0</em:maxVersion>
</Description>
</em:targetApplication>

View File

@ -185,6 +185,7 @@ Sr2kl6sMaEtqKsmobd9KXjgjMZ5iV4v7EDloeBo=
user_id: "790E6B02",
username: "Hussein Kasem",
},
rating: 5,
to: [
{
address: "cfg@pep.security",
@ -287,16 +288,17 @@ nqgR
},
{
key: "X-KeyList",
value: "9D94E481AE5D1C729C0B1654DE5FC3FA9440890C"
value: "B2775D7B919C9E28EC1B9B492C0E8DE595E4A594"
}
],
from: {
"address": "cfg@pep.security",
"comm_type": 255,
"fpr": "9D94E481AE5D1C729C0B1654DE5FC3FA9440890C",
"fpr": "B2775D7B919C9E28EC1B9B492C0E8DE595E4A594",
"user_id": "pEp_own_userId",
"username": "Chris"
},
rating: 5,
to: [
{
address: "cfg@pep.security",
@ -307,4 +309,115 @@ nqgR
});
});
});
describe('Message from self 2', () => {
let result = "initial value";
before(() => {
subject = "pEp";
body = `-----BEGIN PGP MESSAGE-----
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
tqcASvhh
=3DLjpR
-----END PGP MESSAGE-----`;
let from = {
username: "Chris",
address: "cfg@pep.security",
};
let to = [{
address: "cfg@pep.security",
}];
result = pEpController.decryptMail(body, from, to, "<30ad10c0-e971-e68f-1fc6-ff3c7185c69b@pep.security>");
});
it('should return a Object', () => {
let newBody = "MIME-Version: 1.0\r\nContent-Type: multipart/mixed; boundary=\"7fdcc2331befd79f41a7c4c96b68079a\"\r\n\r\n--7fdcc2331befd79f41a7c4c96b68079a\r\nContent-Type: text/plain; charset=\"utf-8\"\r\nContent-Disposition: inline; filename=\"msg.txt\"\r\n\r\npEp-Wrapped-Message-Info: OUTER\r\n\r\n\r\n--7fdcc2331befd79f41a7c4c96b68079a\r\nContent-Type: message/rfc822\r\n\r\nMessage-ID: <pEp-60>\r\nFrom: anonymous <cfg@pep.security>\r\nTo: anonymous <cfg@pep.security>\r\nSubject: \r\nX-pEp-Version: 2.0\r\nMIME-Version: 1.0\r\nContent-Type: text/plain; charset=\"utf-8\"\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Disposition: inline; filename=\"msg.txt\"\r\n\r\npEp-Wrapped-Message-Info: INNER\r\n\r\n\r\n\r\n--7fdcc2331befd79f41a7c4c96b68079a\r\nContent-Type: application/pgp-keys\r\nContent-Disposition: attachment; filename=\"pEpkey.asc\"\r\n\r\n-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n\r\nmQENBFt6xIIBCADCOVTvp1nMpdKJ6GYy5F4ajFMMMlXWkQlxoRTAy+amxHsEpT9n\r\nQbTRTcaEefdQifkP2c+2nquft2JAN0YeOE9oW9XueAtsWPoNtfzou++OS0qJx4I8\r\njcIj6gDgBl+XOrKMeDbublkcIvRhH6IJUV/HK1UTAl0FCkG4FbBh8NSRuxbjLT0v\r\na2v5DeRyj06z2GHJiEk0JJVdYNiOxUka4oG2mXk7iiRdTzXdYUEu48Q8LVTsVY1y\r\noWXYS8r7PFauybGqZzQNtR6ENJ0bSSvqufNDQRis98glNI8v4sr4yQnTMR35sUTV\r\njLwENWAkcuENhBdQfxEOPmUcdtYQVY+hoSjPABEBAAG0GENocmlzIDxjZmdAcGVw\r\nLnNlY3VyaXR5PokBVAQTAQgAPhYhBLJ3XXuRnJ4o7BubSSwOjeWV5KWUBQJbesSE\r\nAhsDBQkB4TOABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJECwOjeWV5KWUQQMH\r\n/j8VNwIQ9sm98vtWrXGqH8ARbBsp+tIXu6QggNsCAkk+7qWMgWM7oeEZ6SRIRHGQ\r\n/gk6whLH+fvJQKVkZIa7mn1reH1XXLO5L9sLQT5EWK3X3BxwdGtO3i0M3zBLuYXT\r\nZ7TZF/ot2feaQiRAUItKSgqU6Sobq4LnAvPInrM+MWqglYco2la/PlUcBUaI/gp7\r\nPkLMpwJBLPd3l+bViqss4hfi5cvHhNkswiFs6xNsoadlXLlwdWbDcHeWri8Uh4mC\r\nAKhSu3Xrhy+js8ReRYBiqp+JPignTOx4HQM1ekjBeum15AlYxnhAgl6aZ2WtMBII\r\nU4vZqqWtP04HLoo9VBH9udy5AQ0EW3rEgwEIAOqNuUmrz/4lWhIuPRx/EC+yxnMu\r\nnqepXkER8u7k5795lM6H8sLfGuF3fVrYvW4bbavXcibJGKO2c3rd4jp9usOfK/VX\r\nMxpPM5IxZUL7VA9zEcjf+FO8EMRAoYUYSxFxFWN1PPoYDYyXEKf8TbPcqPwzw6/Q\r\nYlhppBnIPXeZWf7WHhL4OMqNcpg8EuwwxhqxYCadLkbVRt8hXK+dHdQK7hLN4ftb\r\n1EmuRsbzLRD6VNcCBKSwm+sJ8vNE11xiEOPZLxd468hum1hVfeknDijGX16IivUV\r\nVkoHkGkR00qXV2ijQChFH4/Zu6eyivCSq3ME/s2LQa4XsEdbIp9VFaFS+qkAEQEA\r\nAYkBPAQYAQgAJhYhBLJ3XXuRnJ4o7BubSSwOjeWV5KWUBQJbesSDAhsMBQkB4TOA\r\nAAoJECwOjeWV5KWUAWoIAKo1VuCKGhT8J0zI+mNpT8Xx4yy/Nl2athSGw5rktsmF\r\ncEEwnWy2sYvkqpbbBxC1VOqzKQ/+/VL7ArPODkrFDpbZZ2qt5xC7ugT8wQRDhNx5\r\nesPZrty6vrfwt95PBWuJ+cQPts94D6qCpl4gl+wcg/fVMULIaN8plKXeeuUy80Yd\r\nZJMCenurL5JTz/bRETaIAUYbmJ3JNoJgJzqxMP1z2GyOB/pXouzSavPimdLxNmtK\r\niL3FFJqX3San2mu0+kUzGiO0gN0nrAPSObbJkZlhZIxAPWS6DyDlKKOoVppswFqR\r\nblHVpYLS0gr9k2it10aw+o2kUaM52QfrAEc1hTtf6AU=\r\n=Zj4H\r\n-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n--7fdcc2331befd79f41a7c4c96b68079a--\r\n";
return result.should.become({
id: "<30ad10c0-e971-e68f-1fc6-ff3c7185c69b@pep.security>",
longmsg: newBody,
shortmsg: subject,
attachments: [{
size: body.length,
value: btoa(body)
}],
opt_fields: [
{
key: "X-EncStatus",
value: "trusted_and_anonymized"
},
{
key: "X-KeyList",
value: "B2775D7B919C9E28EC1B9B492C0E8DE595E4A594,B2775D7B919C9E28EC1B9B492C0E8DE595E4A594"
}
],
from: {
"address": "cfg@pep.security",
"comm_type": 255,
"fpr": "B2775D7B919C9E28EC1B9B492C0E8DE595E4A594",
"user_id": "pEp_own_userId",
"username": "Chris"
},
rating: 8,
to: [
{
address: "cfg@pep.security",
username: "Chris",
comm_type: 0
}
]
});
});
});
});

View File

@ -0,0 +1,86 @@
/* eslint-disable no-console */
let {describe, it, before, beforeEach} = require('mocha');
let chai = require('chai').use(require('chai-as-promised'));
chai.should();
let pEp = require('../../chrome/content/modules/pEp');
let pEpAdapter = require('../../chrome/content/modules/pEpAdapter');
let pEpServer = require('../../chrome/content/modules/pEpServer');
let XhrQueue = require('../../chrome/content/modules/xhrQueue');
let log = console.log;
let fs = require('fs');
let os = require('os');
let connectionInfoDetector = function () {
return JSON.parse(fs.readFileSync('/Users/chris/.pEp/json-token', 'utf8'));
};
let server = new pEpServer(log, connectionInfoDetector, new XhrQueue(log));
let adapter = new pEpAdapter(console.log, server);
let pEpController = new pEp([], log, adapter, fs, os);
describe('pEp Get Ongoing Message Rating Feature', () => {
//TODO Launch a pEp Desktop Adapter instance before each test
describe('Perfect scenario', () => {
let result = "initial value";
before(() => {
result = pEpController.getOngoingRating("cfg@pep.security", ["cfg@pep.security"]);
});
it('should return a Object', () => {
return result.should.become(8);
});
});
describe('Perfect scenario 2', () => {
let result = "initial value";
before(() => {
result = pEpController.getOngoingRating("cfg@pep.security", ["hk@pep.security"]);
});
it('should return a Object', () => {
return result.should.become(6);
});
});
describe('With 2 receviers', () => {
let result = "initial value";
before(() => {
result = pEpController.getOngoingRating("cfg@pep.security", ["cfg@pep.security", "hk@pep.security"]);
});
it('should return a Object', () => {
return result.should.become(6);
});
});
describe('With none receviers', () => {
let result = "initial value";
before(() => {
result = pEpController.getOngoingRating("cfg@pep.security", []);
});
it('should return a Object', () => {
return result.should.become(0);
});
});
describe('With none receviers', () => {
let result = "initial value";
before(() => {
result = pEpController.getOngoingRating("cfg@pep.security", ["randomguy@randomdomain.com"]);
});
it('should return a Object', () => {
return result.should.become(3);
});
});
});