Skip to content
Snippets Groups Projects
Commit 18117d04 authored by Jared Hancock's avatar Jared Hancock
Browse files

mail: Implement the message id tracking for everyone

Also try harder to send a relevant In-Reply-To and References header back
to the client with the email message.
parent ecd2e6a9
No related branches found
No related tags found
No related merge requests found
......@@ -118,7 +118,7 @@ class Mailer {
* A: Predictable random code — used for loop detection
* B: Random data for unique identifier
* Version Code: A (at char position 10)
* C: TAG: Base64(Pack(userid, ticketid, type)), = chars discarded
* C: TAG: Base64(Pack(userid, entryId, type)), = chars discarded
* D: Signature:
* '@' + Signed Tag value, last 10 chars from
* HMAC(sha1, tag+rand, SECRET_SALT)
......@@ -126,7 +126,11 @@ class Mailer {
*/
function getMessageId($recipient, $options=array(), $version='A') {
$tag = '';
$rand = str_replace('-','_', Misc::randCode(9));
$rand = Misc::randCode(9,
// RFC822 specifies the LHS of the addr-spec can have any char
// except the specials — ()<>@,;:\".[], dash is reserved as the
// section separator, and + is reserved for historical reasons
'abcdefghiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_=');
$sig = $this->getEmail()?$this->getEmail()->getEmail():'@osTicketMailer';
if ($recipient instanceof EmailContact) {
// Create a tag for the outbound email
......@@ -235,10 +239,16 @@ class Mailer {
$messageId = $this->getMessageId($to, $options);
if ($to instanceof EmailContact
|| (is_object($to) && is_callable(array($to, 'getEmail')))
) {
$to = $to->getEmail();
if (is_object($to) && is_callable(array($to, 'getEmail'))) {
// Add personal name if available
if (is_callable(array($to, 'getName'))) {
$to = sprintf('"%s" <%s>',
$to->getName()->getOriginal(), $to->getEmail()
);
}
else {
$to = $to->getEmail();
}
}
//do some cleanup
......@@ -293,6 +303,26 @@ class Mailer {
}
}
// Make the best effort to add In-Reply-To and References headers
if (isset($options['thread'])
&& $options['thread'] instanceof ThreadEntry
) {
$headers += array('References' => $options['thread']->getEmailReferences());
if ($irt = $options['thread']->getEmailMessageId()) {
// This is an response from an email, like and autoresponse.
// Web posts will not have a email message-id
$headers += array('In-Reply-To' => $irt);
}
elseif ($parent = $options['thread']->getParent()) {
// Use the parent item as the email information source. This
// will apply for staff replies
$headers += array(
'In-Reply-To' => $parent->getEmailMessageId(),
'References' => $parent->getEmailReferences(),
);
}
}
// Use Mail_mime default initially
$eol = null;
......
......@@ -291,6 +291,11 @@ Class ThreadEntry {
return $this->ht['pid'];
}
function getParent() {
if ($this->getPid())
return ThreadEntry::lookup($this->getPid());
}
function getType() {
return $this->ht['thread_type'];
}
......@@ -362,32 +367,11 @@ Class ThreadEntry {
$headers = self::getEmailHeaderArray();
if (isset($headers['References']) && $headers['References'])
$references = $headers['References']." ";
if ($include_mid)
$references .= $this->getEmailMessageId();
if ($include_mid && ($mid = $this->getEmailMessageId()))
$references .= $mid;
return $references;
}
function getTaggedEmailReferences($prefix, $refId) {
$ref = "+$prefix".Base32::encode(pack('VV', $this->getId(), $refId));
$mid = substr_replace($this->getEmailMessageId(),
$ref, strpos($this->getEmailMessageId(), '@'), 0);
return sprintf('%s %s', $this->getEmailReferences(false), $mid);
}
function getEmailReferencesForUser($user) {
return $this->getTaggedEmailReferences('u',
($user instanceof Collaborator)
? $user->getUserId()
: $user->getId());
}
function getEmailReferencesForStaff($staff) {
return $this->getTaggedEmailReferences('s', $staff->getId());
}
function getUIDFromEmailReference($ref) {
$info = unpack('Vtid/Vuid',
......@@ -1123,10 +1107,7 @@ Class ThreadEntry {
return false;
}
// Email message id (required for all thread posts)
if (!isset($vars['mid']))
$vars['mid'] = sprintf('<%s@%s>', Misc::randCode(24),
substr(md5($cfg->getUrl()), -10));
// Email message id
$entry->saveEmailInfo($vars);
// Inline images (attached to the draft)
......
......@@ -986,7 +986,7 @@ class Ticket {
'signature' => ($dept && $dept->isPublic())?$dept->getSignature():'')
);
$email->sendAutoReply($this->getEmail(), $msg['subj'], $msg['body'],
$email->sendAutoReply($this->getOwner(), $msg['subj'], $msg['body'],
null, $options);
}
......@@ -1061,7 +1061,7 @@ class Ticket {
$msg = $this->replaceVars($msg->asArray(),
array('signature' => ($dept && $dept->isPublic())?$dept->getSignature():''));
$email->sendAutoReply($this->getEmail(), $msg['subj'], $msg['body']);
$email->sendAutoReply($this->getOwner(), $msg['subj'], $msg['body']);
}
$user = $this->getOwner();
......@@ -1123,9 +1123,8 @@ class Ticket {
'thread' => $entry);
foreach ($recipients as $recipient) {
if ($uid == $recipient->getUserId()) continue;
$options['references'] = $entry->getEmailReferencesForUser($recipient);
$notice = $this->replaceVars($msg, array('recipient' => $recipient));
$email->send($recipient->getEmail(), $notice['subj'], $notice['body'], $attachments,
$email->send($recipient, $notice['subj'], $notice['body'], $attachments,
$options);
}
......@@ -1188,9 +1187,8 @@ class Ticket {
$options = array(
'inreplyto'=>$message->getEmailMessageId(),
'references' => $message->getEmailReferencesForUser($user),
'thread'=>$message);
$email->sendAutoReply($user->getEmail(), $msg['subj'], $msg['body'],
$email->sendAutoReply($user, $msg['subj'], $msg['body'],
null, $options);
}
}
......@@ -1797,7 +1795,7 @@ class Ticket {
'inreplyto'=>$response->getEmailMessageId(),
'references'=>$response->getEmailReferences(),
'thread'=>$response);
$email->sendAutoReply($this->getEmail(), $msg['subj'], $msg['body'], $attachments,
$email->sendAutoReply($this, $msg['subj'], $msg['body'], $attachments,
$options);
}
......@@ -2864,7 +2862,7 @@ class Ticket {
'references' => $references,
'thread' => $ticket->getLastMessage()
);
$email->send($ticket->getEmail(), $msg['subj'], $msg['body'], $attachments,
$email->send($ticket->getOwner(), $msg['subj'], $msg['body'], $attachments,
$options);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment