diff --git a/admin/admin_reply_ticket.php b/admin/admin_reply_ticket.php index 2b85c6cc..d7d3c4df 100644 --- a/admin/admin_reply_ticket.php +++ b/admin/admin_reply_ticket.php @@ -288,6 +288,12 @@ elseif ($submit_as_customer) $customerReplyStatusRs = hesk_dbQuery('SELECT `ID` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'statuses` WHERE `IsCustomerReplyStatus` = 1 LIMIT 1'); $customerReplyStatus = hesk_dbFetchAssoc($customerReplyStatusRs); $new_status = $customerReplyStatus['ID']; + + if ($ticket['status'] != $new_status) + { + $revision = sprintf($hesklang['thist9'],hesk_date(),$hesklang['wait_reply'],$_SESSION['name'].' ('.$_SESSION['user'].')'); + $sql_status = " , `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') "; + } } // -> Default: submit as "Replied by staff" else diff --git a/admin/admin_ticket.php b/admin/admin_ticket.php index 3b5cfc32..0dbcdf8a 100644 --- a/admin/admin_ticket.php +++ b/admin/admin_ticket.php @@ -2110,8 +2110,12 @@ function hesk_printCanned() return true; } + myMsg = myMsg.replace(/%%HESK_ID%%/g, ''); + myMsg = myMsg.replace(/%%HESK_TRACKID%%/g, ''); + myMsg = myMsg.replace(/%%HESK_TRACK_ID%%/g, ''); myMsg = myMsg.replace(/%%HESK_NAME%%/g, ''); myMsg = myMsg.replace(/%%HESK_EMAIL%%/g, ''); + myMsg = myMsg.replace(/%%HESK_OWNER%%/g, ''); myMsg = myMsg.replace(/%%HESK_custom1%%/g, ''); myMsg = myMsg.replace(/%%HESK_custom2%%/g, ''); myMsg = myMsg.replace(/%%HESK_custom3%%/g, ''); diff --git a/admin/index.php b/admin/index.php index 2ddf4be4..14d037e8 100644 --- a/admin/index.php +++ b/admin/index.php @@ -217,6 +217,10 @@ function do_login() hesk_process_messages($hesklang['chdp'],'NOREDIRECT','NOTICE'); } + // Set a tag that will be used to expire sessions after username or password change + $_SESSION['session_verify'] = hesk_activeSessionCreateTag($user, $_SESSION['pass']); + + // We don't need the password hash anymore unset($_SESSION['pass']); diff --git a/admin/mail.php b/admin/mail.php index e4d2547c..13821625 100644 --- a/admin/mail.php +++ b/admin/mail.php @@ -328,6 +328,12 @@ function mail_send() /* Message */ $_SESSION['mail']['message'] = hesk_input( hesk_POST('message') ) or $hesk_error_buffer .= '
  • ' . $hesklang['enter_message'] . '
  • '; + // Attach signature to the message? + if ( ! empty($_POST['signature'])) + { + $_SESSION['mail']['message'] .= "\n\n" . addslashes($_SESSION['signature']) . "\n"; + } + /* Any errors? */ if (strlen($hesk_error_buffer)) { @@ -711,6 +717,12 @@ function show_new_form() echo stripslashes($_SESSION['mail']['message']); } ?> +
    + () +
    diff --git a/admin/manage_canned.php b/admin/manage_canned.php index 19c9d75f..efa0a885 100644 --- a/admin/manage_canned.php +++ b/admin/manage_canned.php @@ -278,8 +278,11 @@ myField.value += myValue; } ?> : + | + | | - + | + $v) { diff --git a/admin/profile.php b/admin/profile.php index 6c4982ab..a6c7a83b 100644 --- a/admin/profile.php +++ b/admin/profile.php @@ -239,12 +239,12 @@ function update_profile() { } else { - $v = hesk_Pass2Hash($newpass); - if ($v == '499d74967b28a841c98bb4baaabaad699ff3c079') + $newpass_hash = hesk_Pass2Hash($newpass); + if ($newpass_hash == '499d74967b28a841c98bb4baaabaad699ff3c079') { define('WARN_PASSWORD',true); } - $sql_pass = ',`pass`=\''.$v.'\''; + $sql_pass = ',`pass`=\''.$newpass_hash.'\''; } } } @@ -314,6 +314,21 @@ function update_profile() { /* Process the session variables */ $_SESSION['new'] = hesk_stripArray($_SESSION['new']); + // Do we need a new session_verify tag? + if ( strlen($sql_username) && strlen($sql_pass) ) + { + $_SESSION['session_verify'] = hesk_activeSessionCreateTag($_SESSION['new']['user'], $newpass_hash); + } + elseif ( strlen($sql_pass) ) + { + $_SESSION['session_verify'] = hesk_activeSessionCreateTag($_SESSION['user'], $newpass_hash); + } + elseif ( strlen($sql_username) ) + { + $res = hesk_dbQuery('SELECT `pass` FROM `'.hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `id` = '".intval($_SESSION['id'])."' LIMIT 1"); + $_SESSION['session_verify'] = hesk_activeSessionCreateTag($_SESSION['new']['user'], hesk_dbResult($res) ); + } + /* Update session variables */ foreach ($_SESSION['new'] as $k => $v) { diff --git a/change_status.php b/change_status.php index 62181c4f..7ffa6315 100644 --- a/change_status.php +++ b/change_status.php @@ -53,12 +53,18 @@ $trackingID = hesk_cleanID() or die("$hesklang[int_error]: $hesklang[no_trackID] // Get new status $status = intval( hesk_GET('s', 0) ); +$oldStatus = $status; $locked = 0; // Connect to database hesk_dbConnect(); +// Get the close status. It'll be used later on +$statusRes = hesk_dbQuery('SELECT `ID` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'statuses` WHERE `IsClosedByClient` = 1'); +$statusRow = hesk_dbFetchAssoc($statusRes); +$closedStatus = $statusRow['ID']; + if ($status == 3) // Closed { // Is customer closing tickets enabled? @@ -66,11 +72,7 @@ if ($status == 3) // Closed { hesk_error($hesklang['attempt']); } - - //-- They want to close the ticket, so get the status that is the default for client-side closes - $statusRow = hesk_dbFetchAssoc(hesk_dbQuery('SELECT `ID` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'statuses` WHERE `IsClosedByClient` = 1')); - - $status = $statusRow['ID']; + $status = $closedStatus; $action = $hesklang['closed']; $revision = sprintf($hesklang['thist3'],hesk_date(),$hesklang['customer']); @@ -90,6 +92,11 @@ elseif ($status == 2) // Opened hesk_error($hesklang['attempt']); } + //-- They want to close the ticket, so get the status that is the default for client-side closes + $statusRes = hesk_dbQuery('SELECT `ID` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'statuses` WHERE `IsDefaultStaffReplyStatus` = 1'); + $statusRow = hesk_dbFetchAssoc($statusRes); + $status = $statusRow['ID']; + $action = $hesklang['opened']; $revision = sprintf($hesklang['thist4'],hesk_date(),$hesklang['customer']); @@ -110,6 +117,30 @@ hesk_dbConnect(); // Verify email address match if needed hesk_verifyEmailMatch($trackingID); +// Lets make status assignment a bit smarter when reopening tickets +if ($oldStatus == 2) +{ + // Get number of replies and last replier (customer or staff) + $ticket = hesk_dbFetchAssoc( hesk_dbQuery( "SELECT `staffreplies`, `lastreplier` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `trackid`='".hesk_dbEscape($trackingID)."' LIMIT 1") ); + + // If ticket has no staff replies set the status to "New" + if ($ticket['staffreplies'] < 1) + { + $statusRes = hesk_dbQuery('SELECT `ID` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'statuses` WHERE `IsNewTicketStatus` = 1'); + $statusRow = hesk_dbFetchAssoc($statusRes); + $status = $statusRow['ID']; + } + // If last reply was by customer set status to "Waiting reply from staff" + elseif ($ticket['lastreplier'] == 0) + { + $statusRes = hesk_dbQuery('SELECT `ID` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'statuses` WHERE `IsCustomerReplyStatus` = 1'); + $statusRow = hesk_dbFetchAssoc($statusRes); + $status = $statusRow['ID']; + } + // If nothing matches: last reply was from staff, keep status "Waiting reply from customer" +} + + // Modify values in the database hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `status`='{$status}', `locked`='{$locked}' $closedby_sql , `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') WHERE `trackid`='".hesk_dbEscape($trackingID)."' AND `locked` != '1' LIMIT 1"); @@ -120,7 +151,7 @@ if (hesk_dbAffectedRows() != 1) } // Show success message -if ($status == 2) +if ($status != $closedStatus) { hesk_process_messages($hesklang['wrepo'],'ticket.php?track='.$trackingID.$hesk_settings['e_param'].'&Refresh='.rand(10000,99999),'NOTICE'); } diff --git a/inc/admin_functions.inc.php b/inc/admin_functions.inc.php index 6ba71df4..d34662f8 100644 --- a/inc/admin_functions.inc.php +++ b/inc/admin_functions.inc.php @@ -368,6 +368,34 @@ function hesk_getHTML($in) } // END hesk_getHTML() +function hesk_activeSessionValidate($username, $password_hash, $tag) +{ + // Salt and hash need to be separated by a | + if ( ! strpos($tag, '|') ) + { + return false; + } + + // Get two parts of the tag + list($salt, $hash) = explode('|', $tag, 2); + + // Make sure the hash matches existing username and password + if ($hash == sha1($salt . $username . $password_hash) ) + { + return true; + } + + return false; +} // hesk_activeSessionValidate + + +function hesk_activeSessionCreateTag($username, $password_hash) +{ + $salt = uniqid(mt_rand(), true); + return $salt . '|' . sha1($salt . $username . $password_hash); +} // END hesk_activeSessionCreateTag() + + function hesk_autoLogin($noredirect=0) { global $hesk_settings, $hesklang, $hesk_db_link; @@ -422,6 +450,10 @@ function hesk_autoLogin($noredirect=0) hesk_process_messages($hesklang['chdp'],'NOREDIRECT','NOTICE'); } + // Set a tag that will be used to expire sessions after username or password change + $_SESSION['session_verify'] = hesk_activeSessionCreateTag($user, $_SESSION['pass']); + + // We don't need the password hash anymore unset($_SESSION['pass']); /* Login successful, clean brute force attempts */ @@ -494,7 +526,7 @@ function hesk_isLoggedIn() $referer = hesk_input($_SERVER['REQUEST_URI']); $referer = str_replace('&','&',$referer); - if (empty($_SESSION['id'])) + if ( empty($_SESSION['id']) || empty($_SESSION['session_verify']) ) { if ($hesk_settings['autologin'] && hesk_autoLogin(1) ) { @@ -508,6 +540,7 @@ function hesk_isLoggedIn() return true; } + hesk_session_stop(); $url = 'index.php?a=login¬ice=1&goto='.urlencode($referer); header('Location: '.$url); exit(); @@ -516,32 +549,41 @@ function hesk_isLoggedIn() { hesk_session_regenerate_id(); - // Need to update permissions? - if ( empty($_SESSION['isadmin']) ) + // Let's make sure access data is up-to-date + $res = hesk_dbQuery( "SELECT `user`, `pass`, `isadmin`, `categories`, `heskprivileges` FROM `".$hesk_settings['db_pfix']."users` WHERE `id` = '".intval($_SESSION['id'])."' LIMIT 1" ); + + // Exit if user not found + if (hesk_dbNumRows($res) != 1) { - $res = hesk_dbQuery("SELECT `isadmin`, `categories`, `heskprivileges` FROM `".$hesk_settings['db_pfix']."users` WHERE `id` = '".intval($_SESSION['id'])."' LIMIT 1"); - if (hesk_dbNumRows($res) == 1) - { - $me = hesk_dbFetchAssoc($res); - foreach ($me as $k => $v) - { - $_SESSION[$k]=$v; - } + hesk_session_stop(); + $url = 'index.php?a=login¬ice=1&goto='.urlencode($referer); + header('Location: '.$url); + exit(); + } - // Get allowed categories - if (empty($_SESSION['isadmin']) ) - { - $_SESSION['categories']=explode(',',$_SESSION['categories']); - } - } - else - { - hesk_session_stop(); - $url = 'index.php?a=login¬ice=1&goto='.urlencode($referer); - header('Location: '.$url); - exit(); - } - } + // Fetch results from database + $me = hesk_dbFetchAssoc($res); + + // Verify this session is still valid + if ( ! hesk_activeSessionValidate($me['user'], $me['pass'], $_SESSION['session_verify']) ) + { + hesk_session_stop(); + $url = 'index.php?a=login¬ice=1&goto='.urlencode($referer); + header('Location: '.$url); + exit(); + } + + // Update session variables as needed + if ($me['isadmin'] == 1) + { + $_SESSION['isadmin'] = 1; + } + else + { + $_SESSION['isadmin'] = 0; + $_SESSION['categories'] = explode(',', $me['categories']); + $_SESSION['heskprivileges'] = $me['heskprivileges']; + } // Users online if ($hesk_settings['online']) diff --git a/inc/common.inc.php b/inc/common.inc.php index 0ecbccd5..ad846a09 100644 --- a/inc/common.inc.php +++ b/inc/common.inc.php @@ -1259,7 +1259,7 @@ function hesk_makeURL($text, $class = '', $shortenLinks = true) // matches a xxxx://aaaaa.bbb.cccc. ... $text = preg_replace_callback( - '#(^|[\n\t (>.])([a-z][a-z\d+]*:/{2}(?:(?:[a-z0-9\-._~!$&\'(*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[a-z0-9\-._~!$&\'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&\'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&\'(*+,;=:@/?|]+|%[\dA-F]{2})*)?)#i', + '#(^|[\n\t (>.])(' . "[a-z][a-z\d+]*:/{2}(?:(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?" . ')#iu', create_function( "\$matches", "return make_clickable_callback(MAGIC_URL_FULL, \$matches[1], \$matches[2], '', '$class', '$shortenLinks');" @@ -1269,7 +1269,7 @@ function hesk_makeURL($text, $class = '', $shortenLinks = true) // matches a "www.xxxx.yyyy[/zzzz]" kinda lazy URL thing $text = preg_replace_callback( - '#(^|[\n\t (>.])(www\.(?:[a-z0-9\-._~!$&\'(*+,;=:@|]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[a-z0-9\-._~!$&\'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&\'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&\'(*+,;=:@/?|]+|%[\dA-F]{2})*)?)#i', + '#(^|[\n\t (>])(' . "www\.(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?" . ')#iu', create_function( "\$matches", "return make_clickable_callback(MAGIC_URL_WWW, \$matches[1], \$matches[2], '', '$class', '$shortenLinks');" @@ -1279,7 +1279,7 @@ function hesk_makeURL($text, $class = '', $shortenLinks = true) // matches an email address $text = preg_replace_callback( - '/(^|[\n\t (>])(' . '(?:(?:(?:[^@,"\[\]\x5c\x00-\x20\x7f-\xff\.]|\x5c(?=[@,"\[\]\x5c\x00-\x20\x7f-\xff]))(?:[^@,"\[\]\x5c\x00-\x20\x7f-\xff\.]|(?<=\x5c)[@,"\[\]\x5c\x00-\x20\x7f-\xff]|\x5c(?=[@,"\[\]\x5c\x00-\x20\x7f-\xff])|\.(?=[^\.])){1,62}(?:[^@,"\[\]\x5c\x00-\x20\x7f-\xff\.]|(?<=\x5c)[@,"\[\]\x5c\x00-\x20\x7f-\xff])|[^@,"\[\]\x5c\x00-\x20\x7f-\xff\.]{1,2})|"(?:[^"]|(?<=\x5c)"){1,62}")@(?:(?!.{64})(?:[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.?|[a-zA-Z0-9]\.?)+\.(?:xn--[a-zA-Z0-9]+|[a-zA-Z]{2,6})|\[(?:[0-1]?\d?\d|2[0-4]\d|25[0-5])(?:\.(?:[0-1]?\d?\d|2[0-4]\d|25[0-5])){3}\])' . ')/iu', + '/(^|[\n\t (>])(' . '((?:[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*(?:[\w\!\#$\%\'\*\+\-\/\=\?\^\`{\|\}\~]|&)+)@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,63})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)' . ')/iu', create_function( "\$matches", "return make_clickable_callback(MAGIC_URL_EMAIL, \$matches[1], \$matches[2], '', '$class', '$shortenLinks');" diff --git a/inc/knowledgebase_functions.inc.php b/inc/knowledgebase_functions.inc.php index 53814835..54218dae 100644 --- a/inc/knowledgebase_functions.inc.php +++ b/inc/knowledgebase_functions.inc.php @@ -270,13 +270,20 @@ function hesk_kbSearchLarge($admin = '') { global $hesk_settings, $hesklang; - if ($hesk_settings['kb_search'] != 2) - { + $action = 'knowledgebase.php'; + if ($admin) + { + if ( ! $hesk_settings['kb_search']) + { + return ''; + } + $action = 'knowledgebase_private.php'; + } + elseif ($hesk_settings['kb_search'] != 2) + { return ''; } - $action = $admin ? 'knowledgebase_private.php' : 'knowledgebase.php'; - ?>
    diff --git a/inc/posting_functions.inc.php b/inc/posting_functions.inc.php index 6a518064..7d30fd60 100644 --- a/inc/posting_functions.inc.php +++ b/inc/posting_functions.inc.php @@ -176,18 +176,34 @@ function hesk_newTicket($ticket, $isVerified = true) function hesk_cleanFileName($filename) { - $filename = str_replace( array( '%20', '+' ), '-', $filename ); + $parts = pathinfo($filename); + + if ( isset($parts['filename']) ) + { + $filename = $parts['filename']; + } + // PHP < 5.2 needs special care + elseif ( version_compare(PHP_VERSION, '5.2','<') ) + { + $filename = rtrim( str_ireplace($parts['extension'], '', $filename), '.'); + } + else + { + $filename = ''; + } + + $filename = str_replace( array( '%20', '+' ), '-', $filename ); $filename = preg_replace('/[\s-]+/', '-', $filename); $filename = remove_accents($filename); $filename = preg_replace('/[^A-Za-z0-9\.\-_]/','', $filename); - $filename = trim($filename, '.-_'); + $filename = trim($filename, '-_'); - if ( strlen($filename) < 1 ) + if ( strlen($filename) < 1 || strpos($filename, '.') === 0 ) { - $filename = mt_rand(10000,99999); + $filename = mt_rand(10000,99999) . $filename; } - return $filename; + return $filename . '.' . $parts['extension']; } // END hesk_cleanFileName() diff --git a/language/en/text.php b/language/en/text.php index 4546cb59..bda6e9ba 100644 --- a/language/en/text.php +++ b/language/en/text.php @@ -2,7 +2,7 @@ /* * Language file for Help Desk Software HESK (www.hesk.com) * Language: ENGLISH -* Version: 2.6.1 +* Version: 2.6.3 * Author: Klemen Stirn (http://www.hesk.com) * * !!! This file must be saved in UTF-8 encoding without byte order mark (BOM) !!! @@ -865,7 +865,7 @@ $hesklang['nhid']='Notes are hidden from customers!'; $hesklang['delt']='Delete this post'; $hesklang['edtt']='Edit post'; $hesklang['edt1']='Post modified'; -$hesklang['edt2']='Changes to the selecting post have been saved'; +$hesklang['edt2']='Changes to the selected post have been saved'; $hesklang['dele']='Delete this ticket'; $hesklang['repd']='Post deleted'; $hesklang['repl']='Selected post has been deleted'; @@ -1098,7 +1098,7 @@ $hesklang['nwts']='A new ticket is submitted with owner:'; $hesklang['ncrt']='Client responds to a ticket with owner:'; $hesklang['ntam']='A ticket is assigned to me'; $hesklang['npms']='A private message is sent to me'; -$hesklang['support_remove']='A lot of time and effort went into developing HESK. Support HESK, buy a license that will also remove the credits links Powered by Help Desk Software HESK from your helpdesk'; +$hesklang['support_remove']='A lot of time and effort went into developing HESK. Support HESK by purchasing a license that will remove the credits links Powered by Help Desk Software HESK from your helpdesk'; $hesklang['ycvtao']='You are not allowed to view tickets assigned to others'; $hesklang['password_not_valid']='Password must be at least 5 chars long'; $hesklang['lkbs']='Loading knowledgebase suggestions...'; diff --git a/submit_ticket.php b/submit_ticket.php index 89b7ffcc..b59d2387 100644 --- a/submit_ticket.php +++ b/submit_ticket.php @@ -188,15 +188,30 @@ $tmpvar['email'] = hesk_validateEmail( hesk_POST('email'), 'ERR', 0) or $hesk_er if ($hesk_settings['confirm_email']) { - $tmpvar['email2'] = hesk_input( hesk_POST('email2') ) or $hesk_error_buffer['email2']=$hesklang['confemail2']; + $tmpvar['email2'] = hesk_validateEmail( hesk_POST('email2'), 'ERR', 0) or $hesk_error_buffer['email2']=$hesklang['confemail2']; - if (strlen($tmpvar['email2']) && ( strtolower($tmpvar['email']) != strtolower($tmpvar['email2']) )) + // Anything entered as email confirmation? + if ( strlen($tmpvar['email2']) ) { - $tmpvar['email2'] = ''; - $_POST['email2'] = ''; - $_SESSION['c_email2'] = ''; - $_SESSION['isnotice'][] = 'email'; - $hesk_error_buffer['email2']=$hesklang['confemaile']; + // Do we have multiple emails? + if ($hesk_settings['multi_eml'] && count( array_diff( explode(',', strtolower($tmpvar['email']) ), explode(',', strtolower($tmpvar['email2']) ) ) ) == 0) + { + $_SESSION['c_email2'] = $_POST['email2']; + } + // Single email address match + elseif ( ! $hesk_settings['multi_eml'] && strtolower($tmpvar['email']) == strtolower($tmpvar['email2']) ) + { + $_SESSION['c_email2'] = $_POST['email2']; + } + else + { + // Invalid match + $tmpvar['email2'] = ''; + $_POST['email2'] = ''; + $_SESSION['c_email2'] = ''; + $_SESSION['isnotice'][] = 'email'; + $hesk_error_buffer['email2']=$hesklang['confemaile']; + } } else { diff --git a/ticket.php b/ticket.php index 24c94315..1ff87894 100644 --- a/ticket.php +++ b/ticket.php @@ -178,6 +178,12 @@ else $ticket['repliername'] = $ticket['name']; } +// If IP is unknown (tickets via email pipe/pop3 fetching) assume current visitor IP as customer IP +if ($ticket['ip'] == 'Unknown' || $ticket['ip'] == $hesklang['unknown']) +{ + hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `ip` = '".hesk_dbEscape($_SERVER['REMOTE_ADDR'])."' WHERE `id`=".intval($ticket['id'])." LIMIT 1"); +} + /* Get category name and ID */ $result = hesk_dbQuery("SELECT `name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` WHERE `id`='".intval($ticket['category'])."' LIMIT 1");