From 1cd3762b0d7707f4dd665c00ff4d83db6172b4a7 Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Mon, 25 May 2015 12:51:33 -0400
Subject: [PATCH] Start integrating the Mailvelope browser extension via its API.
---
program/localization/en_US/messages.inc | 1
program/steps/mail/func.inc | 23 +++++
program/js/app.js | 141 +++++++++++++++++++++++++++++++++++
skins/larry/mail.css | 9 ++
skins/larry/ui.js | 8 ++
5 files changed, 181 insertions(+), 1 deletions(-)
diff --git a/program/js/app.js b/program/js/app.js
index dc5c8c1..4cb6153 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -376,6 +376,8 @@
this.http_post(postact, postdata);
}
+ this.check_mailvelope(this.env.action);
+
// detect browser capabilities
if (!this.is_framed() && !this.env.extwin)
this.browser_capabilities_check();
@@ -3341,6 +3343,141 @@
$('input.rcpagejumper').val(this.env.current_page).prop('disabled', this.env.pagecount < 2);
};
+ // check for mailvelope API
+ this.check_mailvelope = function(action)
+ {
+ if (typeof window.mailvelope !== 'undefined') {
+ this.mailvelope_init(action);
+ }
+ else {
+ $(window).on('mailvelope', function() {
+ ref.mailvelope_init(action);
+ });
+ }
+ };
+
+ //
+ this.mailvelope_init = function(action)
+ {
+ if (this.env.browser_capabilities)
+ this.env.browser_capabilities['pgpmime'] = 1;
+
+ var keyring = this.get_local_storage_prefix();
+
+ mailvelope.getKeyring(keyring).then(function(kr) {
+ ref.mailvelope_keyring = kr;
+ }, function(err) {
+ // attempt to create a new keyring for this app/user
+ mailvelope.createKeyring(keyring).then(function(kr) {
+ ref.mailvelope_keyring = kr;
+ keyring = keyring.identifier;
+ }, function(err) {
+ console.error(err)
+ });
+ });
+
+ if (action == 'show' || action == 'preview') {
+ // decrypt text body
+ if (this.env.is_pgp_content && window.mailvelope) {
+ var data = $(this.env.is_pgp_content).text();
+ ref.mailvelope_display_container(this.env.is_pgp_content, data, keyring);
+ }
+ // load pgp/mime message and pass it to the mailvelope display container
+ else if (this.env.pgp_mime_part && window.mailvelope) {
+ var msgid = this.display_message(this.get_label('loadingdata'), 'loading'),
+ selector = this.env.pgp_mime_container;
+
+ $.ajax({
+ type: 'GET',
+ url: this.url('get', { '_mbox': this.env.mailbox, '_uid': this.env.uid, '_part': this.env.pgp_mime_part }),
+ error: function(o, status, err) {
+ ref.hide_message(msgkey);
+ ref.http_error(o, status, err, lock);
+ },
+ success: function(data) {
+ ref.mailvelope_display_container(selector, data, keyring, msgid);
+ }
+ });
+ }
+ }
+ else if (action == 'compose' && window.mailvelope) {
+ this.enable_command('compose-encrypted', true);
+ }
+ };
+
+ // handler for the 'compose-encrypt' command
+ this.compose_encrypted = function(props)
+ {
+ var container = $('#' + this.env.composebody).parent();
+ mailvelope.createEditorContainer('#' + container.attr('id'), keyring).then(function(editor) {
+ ref.mailvelope_editor = editor;
+ container.addClass('mailvelope');
+ $('#' + ref.env.composebody).hide();
+ });
+ };
+
+ // callback to replace the message body with the full armored
+ this.mailvelope_submit_messageform = function(draft, saveonly)
+ {
+ // get recipients
+ var recipients = [];
+ $.each(['to', 'cc', 'bcc'], function(i,field) {
+ var pos, rcpt, val = $.trim($('[name="_' + field + '"]').val());
+ while (val.length && rcube_check_email(val, true)) {
+ rcpt = RegExp.$2
+ recipients.push(rcpt);
+ val = val.substr(val.indexOf(rcpt) + rcpt.length + 1).replace(/^\s*,\s*/, '');
+ console.log('*', val)
+ }
+ });
+
+ // check if we have keys for all recipients
+ var isvalid = recipients.length > 0;
+ ref.mailvelope_keyring.validKeyForAddress(recipients).then(function(status) {
+ $.each(status, function(k,v) {
+ console.log('validate', k, v)
+ if (!v) {
+ isvalid = false;
+ alert("No key found for "+k)
+ }
+ });
+
+ if (!isvalid) {
+ if (!recipients.length)
+ alert(ref.get_label('norecipientwarning'));
+ return false;
+ }
+
+ ref.mailvelope_editor.encrypt(recipients).then(function(armored) {
+ console.log('encrypted message', armored);
+ var form = this.gui_objects.messageform;
+
+ // all checks passed, send message
+ // var msgid = ref.set_busy(true, draft || saveonly ? 'savingmessage' : 'sendingmessage')
+
+ }, function(err) {
+ console.log(err)
+ });
+ });
+
+ return false;
+ };
+
+ // wrapper for the mailvelope.createDisplayContainer API call
+ this.mailvelope_display_container = function(selector, data, keyring, msgid)
+ {
+ mailvelope.createDisplayContainer(selector, data, keyring, {}).then(function() {
+ $(selector).addClass('mailvelope').find('.message-part, .part-notice').hide();
+ ref.hide_message(msgid);
+ setTimeout(function() { $(window).resize(); }, 10);
+ }, function(err) {
+ console.error(err)
+ ref.hide_message(msgid);
+ ref.display_message('Message decryption failed: ' + err.message, 'error')
+ });
+ };
+
+
/*********************************************************/
/********* mailbox folders methods *********/
/*********************************************************/
@@ -3612,6 +3749,10 @@
);
}
+ if (this.mailvelope_editor) {
+ return this.mailvelope_submit_messageform(draft, saveonly);
+ }
+
// all checks passed, send message
var msgid = this.set_busy(true, draft || saveonly ? 'savingmessage' : 'sendingmessage'),
lang = this.spellcheck_lang(),
diff --git a/program/localization/en_US/messages.inc b/program/localization/en_US/messages.inc
index a23bfd6..15e39c3 100644
--- a/program/localization/en_US/messages.inc
+++ b/program/localization/en_US/messages.inc
@@ -56,6 +56,7 @@
$messages['contactnameexists'] = 'A contact with the same name already exists.';
$messages['blockedimages'] = 'To protect your privacy, remote images are blocked in this message.';
$messages['encryptedmessage'] = 'This is an encrypted message and can not be displayed. Sorry!';
+$messages['externalmessagedecryption'] = 'This is an encrypted message and can be decrypted with your browser extension.';
$messages['nocontactsfound'] = 'No contacts found.';
$messages['contactnotfound'] = 'The requested contact was not found.';
$messages['contactsearchonly'] = 'Enter some search terms to find contacts';
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 684cdf9..a90541d 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -1185,7 +1185,23 @@
// unsupported (e.g. encrypted)
if ($part->realtype) {
if ($part->realtype == 'multipart/encrypted' || $part->realtype == 'application/pkcs7-mime') {
- $out .= html::span('part-notice', $RCMAIL->gettext('encryptedmessage'));
+ if (!empty($_SESSION['browser_caps']['pgpmime']) && $part->realtype == 'multipart/encrypted') {
+ // find the encrypted message payload part
+ foreach ($MESSAGE->mime_parts as $mime_id => $mpart) {
+ if ($mpart->mimetype == 'application/octet-stream' || !empty($mpart->filename)) {
+ $out .= html::span('part-notice', $RCMAIL->gettext('externalmessagedecryption'));
+ $OUTPUT->set_env('pgp_mime_part', $mime_id);
+ $OUTPUT->set_env('pgp_mime_container', '#' . $attrib['id']);
+ $OUTPUT->add_label('loadingdata');
+ $MESSAGE->encrypted_part = $mime_id;
+ break;
+ }
+ }
+ }
+
+ if (!$MESSAGE->encrypted_part) {
+ $out .= html::span('part-notice', $RCMAIL->gettext('encryptedmessage'));
+ }
}
continue;
}
@@ -1219,6 +1235,11 @@
rcmail_message_error($MESSAGE->uid);
}
+ // check if the message body is PGP encrypted
+ if (strpos($body, 'BEGIN PGP MESSAGE') !== false) {
+ $OUTPUT->set_env('is_pgp_content', '#' . $attrib['id']);
+ }
+
$plugin = $RCMAIL->plugins->exec_hook('message_body_prefix',
array('part' => $part, 'prefix' => ''));
diff --git a/skins/larry/mail.css b/skins/larry/mail.css
index effc35f1..9d8ddce 100644
--- a/skins/larry/mail.css
+++ b/skins/larry/mail.css
@@ -881,6 +881,10 @@
margin: 8px;
}
+#messagebody.mailvelope > iframe {
+ width: 99% !important;
+}
+
#message-objects div,
#messagebody span.part-notice {
margin: 8px;
@@ -1298,6 +1302,11 @@
bottom: 42px;
}
+#composebodycontainer.mailvelope > iframe[scrolling='no'] {
+ position: relative;
+ top: -12px;
+}
+
#composebody {
position: absolute;
top: 0;
diff --git a/skins/larry/ui.js b/skins/larry/ui.js
index 95efccf..9841851 100644
--- a/skins/larry/ui.js
+++ b/skins/larry/ui.js
@@ -468,6 +468,14 @@
$('div.rightcol').hide().attr('aria-hidden', 'true');
$('div.leftcol').css('margin-right', '0');
}
+
+ var mvlpe = $('#messagebody.mailvelope');
+ if (mvlpe.length) {
+ var h = $('#messagecontent').length ?
+ $('#messagecontent').height() - 16 :
+ $(window).height() - mvlpe.offset().top - 10;
+ mvlpe.height(h);
+ }
}
--
Gitblit v1.9.1