From a480dfc022532562f782ac6053367e72e5b00b04 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Tue, 19 May 2015 18:56:12 +0000 Subject: [PATCH] Encrypt toggle-button in compose to switch PGP encrypted mail on and off --- mail/inc/class.mail_compose.inc.php | 9 +++ mail/js/app.js | 116 +++++++++++++++------------- phpgwapi/js/jsapi/app_base.js | 41 ++++++++++ phpgwapi/js/jsapi/egw_message.js | 3 +- 4 files changed, 115 insertions(+), 54 deletions(-) diff --git a/mail/inc/class.mail_compose.inc.php b/mail/inc/class.mail_compose.inc.php index e6e0efcc62..291b3c02c8 100644 --- a/mail/inc/class.mail_compose.inc.php +++ b/mail/inc/class.mail_compose.inc.php @@ -115,6 +115,15 @@ class mail_compose 'hint' => 'Send', 'toolbarDefault' => true ), + 'pgp' => array( + 'caption' => 'Encrypt', + 'icon' => 'lock', + 'group' => ++$group, + 'onExecute' => 'javaScript:app.mail.togglePgpEncrypt', + 'hint' => 'Send message PGP encrypted: requires keys from all recipients!', + 'checkbox' => true, + 'toolbarDefault' => true + ), 'button[saveAsDraft]' => array( 'caption' => 'Save', 'icon' => 'save', diff --git a/mail/js/app.js b/mail/js/app.js index 5c194e4682..a7dfab2ee0 100644 --- a/mail/js/app.js +++ b/mail/js/app.js @@ -157,14 +157,7 @@ app.classes.mail = AppJS.extend( jQuery('iframe#mail-index_messageIFRAME').on('load', function() { // decrypt preview body if mailvelope is available - if (typeof mailvelope !== 'undefined') { - self.mailvelopeDisplay.call(self); - } else { - jQuery(window).on('mailvelope', function() - { - self.mailvelopeDisplay.call(self); - }); - } + self.mailvelopeAvailable(self.mailvelopeDisplay); self.mail_prepare_print(); }); var nm = this.et2.getWidgetById(this.nm_index); @@ -194,14 +187,7 @@ app.classes.mail = AppJS.extend( jQuery('iframe#mail-display_mailDisplayBodySrc').on('load', function() { // encrypt body if mailvelope is available - if (typeof mailvelope !== 'undefined') { - self.mailvelopeDisplay.call(self); - } else { - jQuery(window).on('mailvelope', function() - { - self.mailvelopeDisplay.call(self); - }); - } + self.mailvelopeAvailable(self.mailvelopeDisplay); self.mail_prepare_print(); }); @@ -215,10 +201,9 @@ app.classes.mail = AppJS.extend( ); break; case 'mail.compose': - if (typeof mailvelope !== 'undefined') { - this.mailvelopeCompose(); - } else { - jQuery(window).on('mailvelope', jQuery.proxy(this.mailvelopeCompose, this)); + if (this.et2.getWidgetById('composeToolbar')._actionManager.getActionById('pgp').checked) + { + this.mailvelopeAvailable(this.mailvelopeCompose); } // use a wrapper on a different url to be able to use a different fpm pool et2.menuaction = 'mail_compose::ajax_send'; @@ -4349,9 +4334,10 @@ app.classes.mail = AppJS.extend( /** * Called on load of preview or display iframe, if mailvelope is available * + * @param {Keyring} _keyring Mailvelope keyring to use * @ToDo signatures */ - mailvelopeDisplay: function() + mailvelopeDisplay: function(_keyring) { var self = this; var mailvelope = window.mailvelope; @@ -4360,19 +4346,12 @@ app.classes.mail = AppJS.extend( if (armored == "" || armored.indexOf('-----BEGIN PGP MESSAGE-----') === -1) return; - mailvelope.getKeyring('mailvelope').then(function(_keyring) + var container = iframe.parent()[0]; + var container_selector = container.id ? '#'+container.id : 'div.mailDisplayContainer'; + mailvelope.createDisplayContainer(container_selector, armored, _keyring).then(function() { - var container = iframe.parent()[0]; - var container_selector = container.id ? '#'+container.id : 'div.mailDisplayContainer'; - mailvelope.createDisplayContainer(container_selector, armored, _keyring).then(function() - { - // hide our iframe to give space for mailvelope iframe with encrypted content - iframe.hide(); - }, - function(_err) - { - self.egw.message(_err.message, 'error'); - }); + // hide our iframe to give space for mailvelope iframe with encrypted content + iframe.hide(); }, function(_err) { @@ -4389,36 +4368,67 @@ app.classes.mail = AppJS.extend( /** * Called on compose, if mailvelope is available + * + * @param {Keyring} _keyring Mailvelope keyring to use */ - mailvelopeCompose: function() + mailvelopeCompose: function(_keyring) { - var self = this; - var mailvelope = window.mailvelope; - delete this.mailvelope_editor; - mailvelope.getKeyring('mailvelope').then(function(_keyring) + + // currently Mailvelope only supports plain-text, to this is unnecessary + var mimeType = this.et2.getWidgetById('mimeType'); + var is_html = mimeType.get_value(); + var container = is_html ? '.mailComposeHtmlContainer' : '.mailComposeTextContainer'; + var editor = this.et2.getWidgetById(is_html ? 'mail_htmltext' : 'mail_plaintext'); + + var self = this; + mailvelope.createEditorContainer(container, _keyring, { + predefinedText: editor.get_value() + }).then(function(_editor) { - var is_html = self.et2.getWidgetById('mimeType').get_value(); - var container = is_html ? '.mailComposeHtmlContainer' : '.mailComposeTextContainer'; - var editor = self.et2.getWidgetById(is_html ? 'mail_htmltext' : 'mail_plaintext'); - mailvelope.createEditorContainer(container, _keyring, { - predefinedText: editor.get_value() - }).then(function(_editor) - { - self.mailvelope_editor = _editor; - editor.set_disabled(true); - }, - function(_err) - { - self.egw.message(_err.message, 'error'); - }); + self.mailvelope_editor = _editor; + editor.set_disabled(true); + mimeType.set_readonly(true); }, function(_err) { - self.egw.message(keyringId+': '+_err.message, 'error'); + self.egw.message(_err.message, 'error'); }); }, + /** + * Switch sending PGP encrypted mail on and off + * + * @param {object} _action toolbar action + */ + togglePgpEncrypt: function (_action) + { + if (_action.checked) + { + if (typeof mailvelope == 'undefined') + { + this.egw.message(this.egw.lang('You need to install Mailvelope plugin available for Chrome and Firefox and enable it for your domain.')+ + "\n"+this.egw.lang('Download from %1','mailvelope.com'), 'info'); + return; + } + var mimeType = this.et2.getWidgetById('mimeType'); + // currently Mailvelope only supports plain-text, switch to it if necessary + if (mimeType.get_value()) + { + mimeType.set_value(false); + this.et2._inst.submit(); + return; // ToDo: do that without reload + } + this.mailvelopeAvailable(this.mailvelopeCompose); + // ToDo: check recipients + } + else + { + // switch Mailvelop off again + this.et2._inst.submit(); // ToDo: do that without reload + } + }, + /** * Set the relevant widget to toolbar actions and submit * @param {type} _action toolbar action diff --git a/phpgwapi/js/jsapi/app_base.js b/phpgwapi/js/jsapi/app_base.js index 8214fd4f73..9f2d662f80 100644 --- a/phpgwapi/js/jsapi/app_base.js +++ b/phpgwapi/js/jsapi/app_base.js @@ -825,5 +825,46 @@ var AppJS = Class.extend( egw.refresh(data.msg||'',ids[0],ids[1],'update'); }).sendRequest(true); } + }, + + /** + * Check if Mailvelope is available, open (or create) "egroupware" keyring and call callback with it + * + * @param {function} _callback called if and only if mailvelope is available (context is this!) + */ + mailvelopeAvailable: function(_callback) + { + var self = this; + if (typeof mailvelope !== 'undefined') + { + self._mailvelopeOpenKeyring.call(self, _callback); + } + else + { + jQuery(window).on('mailvelope', function() + { + self._mailvelopeOpenKeyring.call(self, _callback); + }); + } + }, + + /** + * Open (or create) "egroupware" keyring and call callback with it + * + * @param {function} _callback called if and only if mailvelope is available (context is this!) + */ + _mailvelopeOpenKeyring: function(_callback) + { + var callback = _callback; + var self = this; + + mailvelope.getKeyring('mailvelope').then(function(_keyring) + { + callback.call(self, _keyring); + }, + function(_err) + { + self.egw.message(_err.message, 'error'); + }); } }); diff --git a/phpgwapi/js/jsapi/egw_message.js b/phpgwapi/js/jsapi/egw_message.js index bb6a3dd576..87fef38f07 100644 --- a/phpgwapi/js/jsapi/egw_message.js +++ b/phpgwapi/js/jsapi/egw_message.js @@ -109,9 +109,10 @@ egw.extend('message', egw.MODULE_WND_LOCAL, function(_app, _wnd) if (matches) { var parts = _msg.split(matches[0]); + var href = html_entity_decode(matches[1]); msg_div.text(parts[0]); msg_div.append(jQuery(_wnd.document.createElement('a')) - .attr('href', html_entity_decode(matches[1])) + .attr({href: href, target: href.indexOf(egw.webserverUrl) != 0 ? '_blank' : '_self'}) .text(matches[2])); msg_div.append(jQuery(_wnd.document.createElement('span')).text(parts[1])); }