From: Michael M Slusarz Date: Thu, 6 May 2010 16:21:04 +0000 (-0600) Subject: Initial PGP & S/MIME compose support for DIMP X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=d37002c145a360394d2f23367d56208be975b9f7;p=horde.git Initial PGP & S/MIME compose support for DIMP --- diff --git a/imp/compose-dimp.php b/imp/compose-dimp.php index 3fd3acd2a..a195fc85f 100644 --- a/imp/compose-dimp.php +++ b/imp/compose-dimp.php @@ -212,6 +212,12 @@ $scripts = array( array('TextareaResize.js', 'horde') ); +if (!($prefs->isLocked('default_encrypt')) && + ($prefs->getValue('use_pgp') || $prefs->getValue('use_smime'))) { + $scripts[] = array('dialog.js', 'imp'); + $scripts[] = array('redbox.js', 'horde'); +} + IMP::status(); IMP_Dimp::header($title, $scripts); echo $t->fetch(IMP_TEMPLATES . '/dimp/compose/compose.html'); diff --git a/imp/docs/CHANGES b/imp/docs/CHANGES index dd8d0770e..904f9e0d8 100644 --- a/imp/docs/CHANGES +++ b/imp/docs/CHANGES @@ -2,6 +2,7 @@ v5.0-git -------- +[mms] Add PGP & S/MIME compose support to DIMP. [mms] Check for incorrect identity on compose if a single recipient address is tied to a different identity than the sending identity. [mms] Use CATENATE (RFC 4469), if available, to strip MIME parts (Request diff --git a/imp/js/compose-dimp.js b/imp/js/compose-dimp.js index e1576056e..77344b3ee 100644 --- a/imp/js/compose-dimp.js +++ b/imp/js/compose-dimp.js @@ -10,8 +10,10 @@ var DimpCompose = { // Variables defaulting to empty/false: // auto_save_interval, compose_cursor, disabled, drafts_mbox, - // editor_wait, is_popup, knl_p, knl_sm, last_msg, loaded, old_identity, - // rte, skip_spellcheck, spellcheck, sc_submit, uploading + // editor_wait, is_popup, knl, last_msg, loaded, old_action, + // old_identity, rte, skip_spellcheck, spellcheck, sc_submit, uploading + + knl: {}, confirmCancel: function() { @@ -74,7 +76,7 @@ var DimpCompose = { { var identity = IMP_Compose_Base.getIdentity($F('identity')); - this.setSentMailLabel(identity.id.smf_name, identity.id.smf_display, true); + this.setPopdownLabel('sm', identity.id.smf_name, identity.id.smf_display); $('bcc').setValue(identity.id.bcc); this.setSaveSentMail(identity.id.smf_save); @@ -95,45 +97,53 @@ var DimpCompose = { } }, - setSentMailLabel: function(s, l, sel) + createPopdown: function(id, opts) { - var label = $('sent_mail_folder_label'); + this.knl[id] = { + knl: new KeyNavList(opts.base, { + esc: true, + list: opts.data, + onChoose: this.setPopdownLabel.bind(this, id) + }), + opts: opts + }; + + $(opts.label).insert({ after: new Element('SPAN', { className: 'popdownImg' }).observe('click', function(e) { if (!this.disabled) { this.knl[id].knl.show(); this.knl[id].knl.ignoreClick(e); e.stop(); } }.bindAsEventListener(this)) }); + }, + + setPopdownLabel: function(id, s, l) + { + var k = this.knl[id], + label = $(k.opts.label), + input = $(k.opts.input); if (!label) { return; } if (!l) { - l = DIMP.conf_compose.flist.find(function(f) { + l = k.opts.data.find(function(f) { return f.v == s; }); - l = l.f || l.v; + l = (id == 'sm') + ? (l.f || l.v) + : l.l; } - $('save_sent_mail_folder').setValue(s); - $('sent_mail_folder_label').writeAttribute('title', l.escapeHTML()).setText(l.truncate(15)).up(1).show(); + $(input).setValue(s); + $(label).writeAttribute('title', l.escapeHTML()).setText(l.truncate(15)).up(1).show(); - if (DIMP.conf_compose.flist && sel) { - this.knl_sm.setSelected(s); + if (id == 'sm') { + k.knl.setSelected(s); } }, - setPriorityLabel: function(s, l) + retrySubmit: function(action) { - var label = $('priority_label'); - - if (!label) { - return; - } - - if (!l) { - l = DIMP.conf_compose.priority.find(function(f) { - return f.v == s; - }); + if (this.old_action) { + this.uniqueSubmit(this.old_action); + this.old_action = null; } - - $('priority').setValue(s); - $('priority_label').setText(l.l); }, uniqueSubmit: function(action) @@ -289,11 +299,18 @@ var DimpCompose = { this.resizeMsgArea(); break; } - } else if (!Object.isUndefined(d.identity)) { - this.old_identity = $F('identity'); - $('identity').setValue(d.identity); - this.changeIdentity(); - $('noticerow', 'identitychecknotice').invoke('show'); + } else { + if (!Object.isUndefined(d.identity)) { + this.old_identity = $F('identity'); + $('identity').setValue(d.identity); + this.changeIdentity(); + $('noticerow', 'identitychecknotice').invoke('show'); + } + + if (!Object.isUndefined(d.encryptjs)) { + this.old_action = d.action; + eval(d.encryptjs.join(';')); + } } this.setDisabled(false); @@ -467,7 +484,7 @@ var DimpCompose = { if (DIMP.conf_compose.cc) { this.toggleCC('cc', true); } - this.setSentMailLabel(identity.id.smf_name, identity.id.smf_display, true); + this.setPopdownLabel('sm', identity.id.smf_name, identity.id.smf_display); this.setSaveSentMail(identity.id.smf_save); if (header.bcc) { $('bcc').setValue(header.bcc); @@ -866,26 +883,37 @@ var DimpCompose = { document.observe('SpellChecker:before', this._onSpellCheckBefore.bind(this)); } - /* Create folderlist. */ + /* Create sent-mail list. */ if (DIMP.conf_compose.flist) { - this.knl_sm = new KeyNavList('save_sent_mail', { - esc: true, - list: DIMP.conf_compose.flist, - onChoose: this.setSentMailLabel.bind(this) + this.createPopdown('sm', { + base: 'save_sent_mail', + data: DIMP.conf_compose.flist, + input: 'save_sent_mail_folder', + label: 'sent_mail_folder_label' }); - this.knl_sm.setSelected(IMP_Compose_Base.getIdentity($F('identity')).id.smf_name); - $('sent_mail_folder_label').insert({ after: new Element('SPAN', { className: 'popdownImg' }).observe('click', function(e) { if (!this.disabled) { this.knl_sm.show(); this.knl_sm.ignoreClick(e); e.stop(); } }.bindAsEventListener(this)) }); + this.setPopdownLabel('sm', IMP_Compose_Base.getIdentity($F('identity')).id.smf_name); } /* Create priority list. */ if (DIMP.conf_compose.priority) { - this.knl_p = new KeyNavList('priority_label', { - esc: true, - list: DIMP.conf_compose.priority, - onChoose: this.setPriorityLabel.bind(this) + this.createPopdown('p', { + base: 'priority_label', + data: DIMP.conf_compose.priority, + input: 'priority', + label: 'priority_label' + }); + this.setPopdownLabel('p', $F('priority')); + } + + /* Create encryption list. */ + if (DIMP.conf_compose.encrypt) { + this.createPopdown('e', { + base: $('encrypt_label').up(), + data: DIMP.conf_compose.encrypt, + input: 'encrypt', + label: 'encrypt_label' }); - this.setPriorityLabel('normal'); - $('priority_label').insert({ after: new Element('SPAN', { className: 'popdownImg' }).observe('click', function(e) { if (!this.disabled) { this.knl_p.show(); this.knl_p.ignoreClick(e); e.stop(); } }.bindAsEventListener(this)) }); + this.setPopdownLabel('e', $F('encrypt')); } // Automatically resize compose address fields. @@ -921,3 +949,15 @@ document.observe('TextareaResize:resize', DimpCompose.resizeMsgArea.bind(DimpCom /* Click handler. */ DimpCore.clickHandler = DimpCore.clickHandler.wrap(DimpCompose.clickHandler.bind(DimpCompose)); + +/* Catch dialog actions. */ +document.observe('IMPDialog:success', function(e) { + switch (e.memo) { + case 'pgpPersonal': + case 'pgpSymmetric': + case 'smimePersonal': + IMPDialog.noreload = true; + DimpCompose.retrySubmit(); + break; + } +}); diff --git a/imp/lib/Ajax/Application.php b/imp/lib/Ajax/Application.php index c91c2c11a..a3356a82e 100644 --- a/imp/lib/Ajax/Application.php +++ b/imp/lib/Ajax/Application.php @@ -1324,6 +1324,8 @@ class IMP_Ajax_Application extends Horde_Ajax_Application_Base * See the list of variables needed for _dimpComposeSetup(). Additional * variables used: *
+     * 'encrypt' - (integer) The encryption method to use
+     *             (IMP ENCRYPT constants).
      * 'html' - (integer) In HTML compose mode?
      * 'message' - (string) The message text.
      * 'priority' - TODO
@@ -1337,6 +1339,7 @@ class IMP_Ajax_Application extends Horde_Ajax_Application_Base
      * 
      * 'action' - (string) The AJAX action string
      * 'draft_delete' - (integer) TODO
+     * 'encryptjs' - (array) Javascript to run after encryption failure.
      * 'identity' - (integer) If set, this is the identity that is tied to
      *              the current recipient address.
      * 'log' - (array) TODO
@@ -1372,6 +1375,7 @@ class IMP_Ajax_Application extends Horde_Ajax_Application_Base
         $imptree->eltDiffStart();
 
         $options = array(
+            'encrypt' => ($GLOBALS['prefs']->isLocked('default_encrypt') ? $prefs->getValue('default_encrypt') : $this->_vars->encrypt),
             'identity' => $identity,
             'priority' => $this->_vars->priority,
             'readreceipt' => $this->_vars->request_read_receipt,
@@ -1389,12 +1393,38 @@ class IMP_Ajax_Application extends Horde_Ajax_Application_Base
             $sent = $imp_compose->buildAndSendMessage($this->_vars->message, $headers, Horde_Nls::getEmailCharset(), $this->_vars->html, $options);
         } catch (IMP_Compose_Exception $e) {
             $result->success = 0;
-            $GLOBALS['notification']->push($e);
 
             if (!is_null($e->tied_identity)) {
                 $result->identity = $e->tied_identity;
             }
 
+            if ($e->encrypt) {
+                $imp_ui = $GLOBALS['injector']->getInstance('IMP_Ui_Compose');
+                switch ($e->encrypt) {
+                case 'pgp_symmetric_passphrase_dialog':
+                    $imp_ui->passphraseDialog('pgp_symm', $imp_compose->getCacheId());
+                    break;
+
+                case 'pgp_passphrase_dialog':
+                    $imp_ui->passphraseDialog('pgp');
+                    break;
+
+                case 'smime_passphrase_dialog':
+                    $imp_ui->passphraseDialog('smime');
+                    break;
+                }
+
+                Horde::startBuffer();
+                Horde::outputInlineScript(true);
+                if ($js_inline = Horde::endBuffer()) {
+                    $result->encryptjs = array($js_inline);
+                }
+            } else {
+                /* Don't push notification if showing passphrase dialog -
+                 * passphrase dialog contains the necessary information. */
+                $GLOBALS['notification']->push($e);
+            }
+
             return $result;
         }
 
@@ -1516,7 +1546,7 @@ class IMP_Ajax_Application extends Horde_Ajax_Application_Base
             return array($result);
         }
 
-        $imp_ui = new IMP_Ui_Compose();
+        $imp_ui = $GLOBALS['injector']->getInstance('IMP_Ui_Compose');
         $headers['to'] = $imp_ui->getAddressList($this->_vars->to);
         if ($GLOBALS['prefs']->getValue('compose_cc')) {
             $headers['cc'] = $imp_ui->getAddressList($this->_vars->cc);
diff --git a/imp/lib/Ajax/Imple/PassphraseDialog.php b/imp/lib/Ajax/Imple/PassphraseDialog.php
index e85021d67..cbe53e8fe 100644
--- a/imp/lib/Ajax/Imple/PassphraseDialog.php
+++ b/imp/lib/Ajax/Imple/PassphraseDialog.php
@@ -136,7 +136,7 @@ class IMP_Ajax_Imple_PassphraseDialog extends Horde_Ajax_Imple_Base
                     $imp_pgp = $GLOBALS['injector']->getInstance('IMP_Crypt_Pgp');
                     if ((($vars->type == 'pgpPersonal') &&
                          $imp_pgp->storePassphrase('personal', $vars->dialog_input)) ||
-                        (($vars->type == 'pgpSymmeetric') &&
+                        (($vars->type == 'pgpSymmetric') &&
                          $imp_pgp->storePassphrase('symmetric', $vars->dialog_input, $vars->symmetricid))) {
                         $result->success = 1;
                     } else {
diff --git a/imp/lib/IMP.php b/imp/lib/IMP.php
index 8032a67dd..8d5ba8b9e 100644
--- a/imp/lib/IMP.php
+++ b/imp/lib/IMP.php
@@ -827,7 +827,7 @@ class IMP
             $default = $GLOBALS['prefs']->getValue('default_encrypt');
         }
 
-        $enc_opts = array(self::ENCRYPT_NONE => _("No Encryption"));
+        $enc_opts = array(self::ENCRYPT_NONE => _("None"));
         $output = '';
 
         if (!empty($GLOBALS['conf']['gnupg']['path']) &&
diff --git a/imp/lib/Ui/Compose.php b/imp/lib/Ui/Compose.php
index 732680425..6b5150ddc 100644
--- a/imp/lib/Ui/Compose.php
+++ b/imp/lib/Ui/Compose.php
@@ -260,7 +260,7 @@ class IMP_Ui_Compose
             break;
         }
 
-        Horde_Ajax_Imple::factory(array('imp', 'PassphraseDialog'), array('params' => $params, 'type' => $type))->attach();
+        Horde_Ajax_Imple::factory(array('imp', 'PassphraseDialog'), array('onload' => true, 'params' => $params, 'type' => $type))->attach();
     }
 
     /**
diff --git a/imp/message-dimp.php b/imp/message-dimp.php
index 7bf5e5485..a6815d31f 100644
--- a/imp/message-dimp.php
+++ b/imp/message-dimp.php
@@ -76,6 +76,12 @@ if (!$disable_compose) {
     $scripts[] = array('compose-base.js', 'imp');
     $scripts[] = array('compose-dimp.js', 'imp');
 
+    if (!($prefs->isLocked('default_encrypt')) &&
+        ($prefs->getValue('use_pgp') || $prefs->getValue('use_smime'))) {
+        $scripts[] = array('dialog.js', 'imp');
+        $scripts[] = array('redbox.js', 'horde');
+        }
+
     $js_onload = $compose_result['jsonload'];
 }
 
diff --git a/imp/templates/dimp/chunks/compose.php b/imp/templates/dimp/chunks/compose.php
index 0e6378783..9c50b7cc1 100644
--- a/imp/templates/dimp/chunks/compose.php
+++ b/imp/templates/dimp/chunks/compose.php
@@ -13,6 +13,7 @@
  */
 
 $d_read = $GLOBALS['prefs']->getValue('disposition_request_read');
+$encrypt_list = (($GLOBALS['prefs']->isLocked('default_encrypt')) && ($GLOBALS['prefs']->getValue('use_pgp') || $GLOBALS['prefs']->getValue('use_smime')));
 $save_attach = $GLOBALS['prefs']->getValue('save_attachments');
 
 /* Determine if compose mode is disabled. */
@@ -76,6 +77,12 @@ $compose_disable = !IMP::canCompose();
     
    
 
+
+   
+ + +
+ diff --git a/imp/templates/dimp/javascript_defs_dimp.php b/imp/templates/dimp/javascript_defs_dimp.php index e13f3920e..9d94edd77 100644 --- a/imp/templates/dimp/javascript_defs_dimp.php +++ b/imp/templates/dimp/javascript_defs_dimp.php @@ -195,6 +195,19 @@ if (in_array(basename($_SERVER['PHP_SELF']), array('compose-dimp.php', 'message- ) ); } + + if (!($GLOBALS['prefs']->isLocked('default_encrypt')) && + ($GLOBALS['prefs']->getValue('use_pgp') || + $GLOBALS['prefs']->getValue('use_smime'))) { + $encrypt = array(); + foreach (IMP::encryptList(null, true) as $key => $val) { + $encrypt[] = array( + 'l' => htmlspecialchars($val), + 'v' => intval($key) + ); + } + $code['conf_compose']['encrypt'] = $encrypt; + } } Horde::addInlineScript(array( diff --git a/imp/themes/dimp/screen.css b/imp/themes/dimp/screen.css index e2907b839..b8d1a6e9d 100644 --- a/imp/themes/dimp/screen.css +++ b/imp/themes/dimp/screen.css @@ -409,7 +409,7 @@ div.vpRowVert.flagUnseen { text-decoration: underline; } -#priority_label { +#encrypt_label, #priority_label { cursor: default; font-weight: bold; }