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

Merge remote branch 'upstream/develop' into develop-next

Conflicts:
	include/class.mailfetch.php
	include/class.mailparse.php
	include/class.thread.php
	scp/js/ticket.js
parents 3868ded2 4f5f852b
No related branches found
No related tags found
No related merge requests found
......@@ -202,7 +202,7 @@ class Format {
function safe_html($html) {
// Remove HEAD and STYLE sections
$html = preg_replace(
array(':<(head|style|script).+</\1>:is', # <head> and <style> sections
array(':<(head|style|script).+?</\1>:is', # <head> and <style> sections
':<!\[[^]<]+\]>:', # <![if !mso]> and friends
':<!DOCTYPE[^>]+>:', # <!DOCTYPE ... >
':<\?[^>]+>:', # <?xml version="1.0" ... >
......
......@@ -617,9 +617,11 @@ class MailFetcher {
// Fetch deliver status report
$vars['message'] = $this->getDeliveryStatusMessage($mid);
$vars['thread-type'] = 'N';
$vars['flags']['bounce'] = true;
}
else {
$vars['message'] = $this->getBody($mid);
$vars['flags']['bounce'] = TicketFilter::isBounce($info);
}
......
......@@ -584,12 +584,14 @@ class EmailDataParser {
// Fetch deliver status report
$data['message'] = $parser->getDeliveryStatusMessage();
$data['thread-type'] = 'N';
$data['flags']['bounce'] = true;
}
else {
// Typical email
$data['message'] = $parser->getBody();
$data['in-reply-to'] = @$parser->struct->headers['in-reply-to'];
$data['references'] = @$parser->struct->headers['references'];
$data['flags']['bounce'] = TicketFilter::isBounce($data['header']);
}
$data['subject'] = $parser->getSubject();
......
......@@ -246,7 +246,7 @@ Class ThreadEntry {
if(!$id && !($id=$this->getId()))
return false;
$sql='SELECT thread.*, info.email_mid '
$sql='SELECT thread.*, info.email_mid, info.headers '
.' ,count(DISTINCT attach.attach_id) as attachments '
.' FROM '.TICKET_THREAD_TABLE.' thread '
.' LEFT JOIN '.TICKET_EMAIL_INFO_TABLE.' info
......@@ -338,18 +338,18 @@ Class ThreadEntry {
return $this->ht['email_mid'];
}
function getEmailHeaders() {
function getEmailHeaderArray() {
require_once(INCLUDE_DIR.'class.mailparse.php');
$sql = 'SELECT headers FROM '.TICKET_EMAIL_INFO_TABLE
.' WHERE thread_id='.$this->getId();
$headers = db_result(db_query($sql));
return Mail_Parse::splitHeaders($headers);
if (!isset($this->ht['@headers']))
$this->ht['@headers'] = Mail_Parse::splitHeaders($this->ht['headers']);
return $this->ht['@headers'];
}
function getEmailReferences() {
if (!isset($this->_references)) {
$headers = self::getEmailHeaders();
$headers = self::getEmailHeaderArray();
if (isset($headers['References']) && $headers['References'])
$this->_references = $headers['References']." ";
$this->_references .= $this->getEmailMessageId();
......@@ -427,8 +427,8 @@ Class ThreadEntry {
function isAutoReply() {
if (!isset($this->is_autoreply))
$this->is_autoreply = $this->getEmailHeader()
? TicketFilter::isAutoReply($this->getEmailHeader()) : false;
$this->is_autoreply = $this->getEmailHeaderArray()
? TicketFilter::isAutoReply($this->getEmailHeaderArray()) : false;
return $this->is_autoreply;
}
......@@ -436,8 +436,8 @@ Class ThreadEntry {
function isBounce() {
if (!isset($this->is_bounce))
$this->is_bounce = $this->getEmailHeader()
? TicketFilter::isBounce($this->getEmailHeader()) : false;
$this->is_bounce = $this->getEmailHeaderArray()
? TicketFilter::isBounce($this->getEmailHeaderArray()) : false;
return $this->is_bounce;
}
......@@ -523,10 +523,10 @@ Class ThreadEntry {
return 0;
// TODO: Add a unique index to TICKET_ATTACHMENT_TABLE (file_id,
// ticket_id), and remove this block
// ref_id), and remove this block
if ($id = db_result(db_query('SELECT attach_id FROM '.TICKET_ATTACHMENT_TABLE
.' WHERE file_id='.db_input($fileId).' AND ticket_id='
.db_input($this->getTicketId()))))
.' WHERE file_id='.db_input($fileId).' AND ref_id='
.db_input($this->getId()))))
return $id;
$sql ='INSERT IGNORE INTO '.TICKET_ATTACHMENT_TABLE.' SET created=NOW() '
......
......@@ -1577,9 +1577,10 @@ class Ticket {
if(!$alerts) return $message; //Our work is done...
$autorespond = true;
if ($autorespond && $message->isBounceOrAutoReply())
$autorespond=false;
// Do not auto-respond to bounces and other auto-replies
$autorespond = isset($vars['flags']) ? !$vars['flags']['bounce'] : true;
if ($autorespond && $message->isAutoReply())
$autorespond = false;
$this->onMessage($message, $autorespond); //must be called b4 sending alerts to staff.
......@@ -1813,6 +1814,10 @@ class Ticket {
if(!($note=$this->getThread()->addNote($vars, $errors)))
return null;
if (isset($vars['flags']) && $vars['flags']['bounce'])
// No alerts for bounce emails
$alert = false;
//Set state: Error on state change not critical!
if(isset($vars['state']) && $vars['state']) {
if($this->setState($vars['state']))
......@@ -2391,6 +2396,8 @@ class Ticket {
# Messages that are clearly auto-responses from email systems should
# not have a return 'ping' message
if (isset($vars['flags']) && $vars['flags']['bounce'])
$autorespond = false;
if ($autorespond && $message->isAutoReply())
$autorespond = false;
......@@ -2455,6 +2462,11 @@ class Ticket {
// post response - if any
$response = null;
if($vars['response'] && $thisstaff->canPostReply()) {
// unpack any uploaded files into vars.
if ($_FILES['attachments'])
$vars['files'] = AttachmentFile::format($_FILES['attachments']);
$vars['response'] = $ticket->replaceVars($vars['response']);
if(($response=$ticket->postReply($vars, $errors, false))) {
//Only state supported is closed on response
......
......@@ -141,7 +141,8 @@ class Validator {
/*** Functions below can be called directly without class instance.
Validator::func(var..); (nolint) ***/
function is_email($email) {
return preg_match('/^([*+!.&#$|\'\\%\/0-9a-z^_`{}=?~:-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})$/i',$email);
require_once PEAR_DIR.'Mail/RFC822.php';
return !PEAR::isError(Mail_RFC822::parseAddressList($email));
}
function is_phone($phone) {
/* We're not really validating the phone number but just making sure it doesn't contain illegal chars and of acceptable len */
......
......@@ -93,6 +93,11 @@ INSERT INTO `%TABLE_PREFIX%ticket_email_info`
FROM `%TABLE_PREFIX%ticket_message`
WHERE `messageId` IS NOT NULL AND `messageId` <>'';
-- Change collation to utf8_general_ci - to avoid Illegal mix of collations error
ALTER TABLE `%TABLE_PREFIX%ticket_attachment`
CHANGE `ref_type` `ref_type` ENUM('M','R','N') CHARACTER
SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'M';
-- Update attachment table
UPDATE `%TABLE_PREFIX%ticket_attachment`
SET `ref_id` = ( SELECT T2.`id` FROM `%TABLE_PREFIX%ticket_thread` T2
......
......@@ -484,9 +484,6 @@ if($_POST && !$errors):
$vars = $_POST;
$vars['uid'] = $user? $user->getId() : 0;
if($_FILES['attachments'])
$vars['files'] = AttachmentFile::format($_FILES['attachments']);
if(($ticket=Ticket::open($vars, $errors))) {
$msg='Ticket created successfully';
$_REQUEST['a']=null;
......
......@@ -15,6 +15,39 @@ class TestValidation extends Test {
$this->assert(Validator::is_username('中国期刊全文数据'));
// Non-letters
$this->assert(!Validator::is_username('j®red'));
// Special chars
$this->assert(Validator::is_username('jar.ed'));
$this->assert(Validator::is_username('jar_ed'));
$this->assert(Validator::is_username('jar-ed'));
// Illegals
$this->assert(!Validator::is_username('j red'));
$this->assert(!Validator::is_username('jared '));
$this->assert(!Validator::is_username(' jared'));
}
function testValidEmail() {
// Common emails
$this->assert(Validator::is_email('jared@domain.tld'));
$this->assert(Validator::is_email('jared12@domain.tld'));
$this->assert(Validator::is_email('jared.12@domain.tld'));
$this->assert(Validator::is_email('jared_12@domain.tld'));
$this->assert(Validator::is_email('jared-12@domain.tld'));
// Very likely illegal
$this->assert(!Validator::is_email('jared r@domain.tld'));
$this->assert(Validator::is_email('jared@host'));
// Odd cases, but legal
$this->assert(Validator::is_email('jared@[127.0.0.1]'));
$this->assert(Validator::is_email('jared@[ipv6:::1]'));
$this->assert(Validator::is_email('*@domain.tld'));
$this->assert(Validator::is_email("'@domain.tld"));
$this->assert(Validator::is_email('"jared r"@domain.tld'));
// RFC 6530
#$this->assert(Validator::is_email('Pelé@example.com'));
#$this->assert(Validator::is_email('δοκιμή@παράδειγμα.δοκιμή'));
#$this->assert(Validator::is_email('甲斐@黒川.日本'));
}
}
return 'TestValidation';
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment