diff --git a/WHATSNEW.md b/WHATSNEW.md index 30a74765f0beb979e1888e4ccf97ece524053a2d..8e4aa862036de3cfb56c46d19dab9a11717edb22 100644 --- a/WHATSNEW.md +++ b/WHATSNEW.md @@ -185,6 +185,14 @@ database engines other than MySQL. The ORM was originally introduced in osTicket v1.8.0, but has seen the greatest boost in capability in this release. About 47% of the SQL queries are removed between v1.9.7 and v1.10 +osTicket v1.9.8.1 +================= +### Enhancements + * Add option to disable email address verification + +### Improvements + * Fix crash upgrading from osTicket v1.6 + osTicket v1.9.8 =============== ### Enhancements diff --git a/include/class.config.php b/include/class.config.php index 406e0e8952e2efe2c1683b7c6ca2333701c0efb8..f9aec5d0f040a3bcf1e338a35dcdaece50ea586c 100644 --- a/include/class.config.php +++ b/include/class.config.php @@ -169,6 +169,7 @@ class OsticketConfig extends Config { 'default_help_topic' => 0, 'help_topic_sort_mode' => 'a', 'client_verify_email' => 1, + 'verify_email_addrs' => 1, ); function OsticketConfig($section=null) { @@ -663,6 +664,10 @@ class OsticketConfig extends Config { return $this->get('admin_email'); } + function verifyEmailAddrs() { + return (bool) $this->get('verify_email_addrs'); + } + function getReplySeparator() { return $this->get('reply_separator'); } @@ -1273,6 +1278,7 @@ class OsticketConfig extends Config { 'alert_email_id'=>$vars['alert_email_id'], 'default_smtp_id'=>$vars['default_smtp_id'], 'admin_email'=>$vars['admin_email'], + 'verify_email_addrs'=>isset($vars['verify_email_addrs']) ? 1 : 0, 'enable_auto_cron'=>isset($vars['enable_auto_cron'])?1:0, 'enable_mail_polling'=>isset($vars['enable_mail_polling'])?1:0, 'strip_quoted_reply'=>isset($vars['strip_quoted_reply'])?1:0, diff --git a/include/class.ostsession.php b/include/class.ostsession.php index d93de839a9770e422dcde63205060af27ff95fa7..f649955494a8ba85460fcf2ff463bbc46ce3a9e6 100644 --- a/include/class.ostsession.php +++ b/include/class.ostsession.php @@ -135,7 +135,7 @@ abstract class SessionBackend { var $isnew = false; var $ttl; - function __construct($ttl) { + function __construct($ttl=SESSION_TTL) { $this->ttl = $ttl; } diff --git a/include/class.search.php b/include/class.search.php index 5caecbd0d2dcb68052f68ae2321a32fda1c06b4a..137c1d375b041492ba8d285c6d2c27e792195867 100644 --- a/include/class.search.php +++ b/include/class.search.php @@ -538,6 +538,8 @@ class MysqlSearchBackend extends SearchBackend { // FILES ------------------------------------ // Flush non-full batch of records + $this->__index(null, true); + if (!$this->_reindexed) { // Stop rebuilding the index $this->getConfig()->set('reindex', 0); diff --git a/include/class.staff.php b/include/class.staff.php index d23a3704a07a9349e29e8f836f954ec56dce2b4b..be5ea3562a664d6693cdc9983a2f4e87de8e67e4 100644 --- a/include/class.staff.php +++ b/include/class.staff.php @@ -864,7 +864,7 @@ implements AuthenticatedUser, EmailContact, TemplateVariable { && (!isset($this->staff_id) || $uid!=$this->getId())) $errors['username']=__('Username already in use'); - if(!$vars['email'] || !Validator::is_email($vars['email'])) + if(!$vars['email'] || !Validator::is_valid_email($vars['email'])) $errors['email']=__('Valid email is required'); elseif(Email::getIdByEmail($vars['email'])) $errors['email']=__('Already in use system email'); diff --git a/include/class.thread.php b/include/class.thread.php index 4e75673662f726096e7af968dd4e3bd0903e1d3f..eb02999f4161070eb369d97fd6f360dccfe4ac01 100644 --- a/include/class.thread.php +++ b/include/class.thread.php @@ -1352,6 +1352,9 @@ implements TemplateVariable { $entry->body = $body; if (!$entry->save()) return false; + + // Set the $entry here for search indexing + $entry->ht['body'] = $body; } // Save mail message id, if available @@ -1929,9 +1932,14 @@ class HtmlThreadEntryBody extends ThreadEntryBody { } function getSearchable() { - // <br> -> \n - $body = preg_replace(array('`<br(\s*)?/?>`i', '`</div>`i'), "\n", $this->body); # <?php - $body = Format::htmldecode(Format::striptags($body)); + // Replace tag chars with spaces (to ensure words are separated) + $body = Format::html($this->body, array('hook_tag' => function($el, $attributes=0) { + static $non_ws = array('wbr' => 1); + return (isset($non_ws[$el])) ? '' : ' '; + })); + // Collapse multiple white-spaces + $body = html_entity_decode($body, ENT_QUOTES); + $body = preg_replace('`\s+`u', ' ', $body); return Format::searchable($body); } diff --git a/include/class.validator.php b/include/class.validator.php index fcb350126a22191da7572719617d42a0cfab7be8..88075ab45b41f52c553caa2b6dd18a4b68add2fe 100644 --- a/include/class.validator.php +++ b/include/class.validator.php @@ -156,14 +156,20 @@ class Validator { return false; } - if ($verify && !checkdnsrr($m->host, 'MX')) - return false; + // According to RFC2821, the domain (A record) can be treated as an + // MX if no MX records exist for the domain. Also, include a + // full-stop trailing char so that the default domain of the server + // is not added automatically + if ($verify and !count(dns_get_record($m->host.'.', DNS_MX))) + return 0 < count(dns_get_record($m->host.'.', DNS_A|DNS_AAAA)); return true; } function is_valid_email($email) { - return self::is_email($email, false, true); + global $cfg; + // Default to FALSE for installation + return self::is_email($email, false, $cfg && $cfg->verifyEmailAddrs()); } function is_phone($phone) { diff --git a/include/i18n/en_US/help/tips/settings.email.yaml b/include/i18n/en_US/help/tips/settings.email.yaml index 6285ef4fcaf505acc9363472daf5616c11dada03..8bd3ed3a7b636036013c911b4cf635c5c5f9e97c 100644 --- a/include/i18n/en_US/help/tips/settings.email.yaml +++ b/include/i18n/en_US/help/tips/settings.email.yaml @@ -129,3 +129,11 @@ ticket_response_files: content: > If enabled, any attachments an Agent may attach to a ticket response will be also included in the email to the User. + +verify_email_addrs: + title: Verify Email Addresses + content: > + Enable this option to check if the email address has a mail + exchanger (MX) in the domain's DNS. This is useful to detect + incorrectly typed email addresses. This is perfomed in addition to + checking the email address wellformedness. diff --git a/include/pear/Mail/mimeDecode.php b/include/pear/Mail/mimeDecode.php index bc524f0cc2cbc8abd75d4c26dcb06201cbd1b98e..fd1fdba0720575aaecad82934bb542dcd6f5dd25 100644 --- a/include/pear/Mail/mimeDecode.php +++ b/include/pear/Mail/mimeDecode.php @@ -307,6 +307,7 @@ class Mail_mimeDecode extends PEAR case 'multipart/digest': case 'multipart/alternative': case 'multipart/related': + case 'multipart/relative': case 'multipart/mixed': if(!isset($content_type['other']['boundary'])){ $this->_error = 'No boundary found for ' . $content_type['value'] . ' part'; diff --git a/include/staff/settings-emails.inc.php b/include/staff/settings-emails.inc.php index 85a89370baf0af1e97672e0f748755be3c217670..5e977a706f0d96c435562b6ebef21d68ef697671 100644 --- a/include/staff/settings-emails.inc.php +++ b/include/staff/settings-emails.inc.php @@ -82,6 +82,15 @@ if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin() || !$config) <i class="help-tip icon-question-sign" href="#admins_email_address"></i> </td> </tr> + <tr> + <td width="180" class="required"><?php echo __("Verify Email Addresses");?>:</td> + <td> + <input type="checkbox" name="verify_email_addrs" <?php + if ($config['verify_email_addrs']) echo 'checked="checked"'; ?>> + <?php echo __('Verify email address domain'); ?> + <i class="help-tip icon-question-sign" href="#verify_email_addrs"></i> + </td> + </tr> <tr><th colspan=2><em><strong><?php echo __('Incoming Emails'); ?>:</strong> </em></th> <tr> diff --git a/include/upgrader/streams/core/c00511c7-7be60a84.task.php b/include/upgrader/streams/core/c00511c7-7be60a84.task.php index eca25aee2c623a13a956d2d7df13843ba4b7bee0..91706eaff0a86e7800c33964bce225a6e826e028 100644 --- a/include/upgrader/streams/core/c00511c7-7be60a84.task.php +++ b/include/upgrader/streams/core/c00511c7-7be60a84.task.php @@ -6,7 +6,8 @@ class MigrateDbSession extends MigrationTask { function run() { # How about 'dis for a hack? - osTicketSession::write(session_id(), session_encode()); + $session = new DbSessionBackend(); + $session->write(session_id(), session_encode()); } }