diff --git a/attachment.php b/attachment.php new file mode 100644 index 0000000000000000000000000000000000000000..2446f2dc517c52ec3f08f5219a7a7c28114eacbb --- /dev/null +++ b/attachment.php @@ -0,0 +1,71 @@ +<?php +/********************************************************************* + attachment.php + + Attachments interface for clients. + Clients should never see the dir paths. + + Peter Rotich <peter@osticket.com> + Copyright (c) 2006-2012 osTicket + http://www.osticket.com + + Released under the GNU General Public License WITHOUT ANY WARRANTY. + See LICENSE.TXT for details. + + vim: expandtab sw=4 ts=4 sts=4: +**********************************************************************/ +require('secure.inc.php'); +//TODO: alert admin on any error on this file. +if(!$thisclient || !$thisclient->isClient() || !$_GET['id'] || !$_GET['ref']) die('Access Denied'); + +$sql='SELECT attach_id,ref_id,ticket.ticket_id,ticketID,ticket.created,dept_id,file_name,file_key,email FROM '.TICKET_ATTACHMENT_TABLE. + ' LEFT JOIN '.TICKET_TABLE.' ticket USING(ticket_id) '. + ' WHERE attach_id='.db_input($_GET['id']); +//valid ID?? +if(!($res=db_query($sql)) || !db_num_rows($res)) die('Invalid/unknown file'); +list($id,$refid,$tid,$extid,$date,$deptID,$filename,$key,$email)=db_fetch_row($res); + +//Still paranoid...:)...check the secret session based hash and email +$hash=MD5($tid*$refid.session_id()); +if(!$_GET['ref'] || strcmp($hash,$_GET['ref']) || strcasecmp($thisclient->getEmail(),$email)) die('Access denied: Kwaheri'); + + +//see if the file actually exits. +$month=date('my',strtotime("$date")); +$file=rtrim($cfg->getUploadDir(),'/')."/$month/$key".'_'.$filename; +if(!file_exists($file)) + $file=rtrim($cfg->getUploadDir(),'/')."/$key".'_'.$filename; + +if(!file_exists($file)) die('Invalid Attachment'); + +$extension =substr($filename,-3); +switch(strtolower($extension)) +{ + case "pdf": $ctype="application/pdf"; break; + case "exe": $ctype="application/octet-stream"; break; + case "zip": $ctype="application/zip"; break; + case "doc": $ctype="application/msword"; break; + case "xls": $ctype="application/vnd.ms-excel"; break; + case "ppt": $ctype="application/vnd.ms-powerpoint"; break; + case "gif": $ctype="image/gif"; break; + case "png": $ctype="image/png"; break; + case "jpg": $ctype="image/jpg"; break; + default: $ctype="application/force-download"; +} +header("Pragma: public"); +header("Expires: 0"); +header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); +header("Cache-Control: public"); +header("Content-Type: $ctype"); +$user_agent = strtolower ($_SERVER["HTTP_USER_AGENT"]); +if ((is_integer(strpos($user_agent,"msie"))) && (is_integer(strpos($user_agent,"win")))) +{ + header( "Content-Disposition: filename=".basename($filename).";" ); +} else { + header( "Content-Disposition: attachment; filename=".basename($filename).";" ); +} +header("Content-Transfer-Encoding: binary"); +header("Content-Length: ".filesize($file)); +readfile($file); +exit(); +?> diff --git a/captcha.php b/captcha.php new file mode 100644 index 0000000000000000000000000000000000000000..3ab68f746ddb378da077cac80b616caf6f69b129 --- /dev/null +++ b/captcha.php @@ -0,0 +1,20 @@ +<?php +/********************************************************************* + captcha.php + + Simply returns captcha image. + + Peter Rotich <peter@osticket.com> + Copyright (c) 2006-2012 osTicket + http://www.osticket.com + + Released under the GNU General Public License WITHOUT ANY WARRANTY. + See LICENSE.TXT for details. + + vim: expandtab sw=4 ts=4 sts=4: +**********************************************************************/ +require_once('main.inc.php'); +require(INCLUDE_DIR.'class.captcha.php'); +$captcha = new Captcha(5,12,ROOT_DIR.'images/captcha/'); +echo $captcha->getImage(); +?> diff --git a/index.php b/index.php index 37e5c7f1b2dd3e899d3d7a154d5e074629ed1bfe..95bdfa55dcfc5c13e4ba79f9ad97c1e7b188630b 100644 --- a/index.php +++ b/index.php @@ -13,4 +13,41 @@ vim: expandtab sw=4 ts=4 sts=4: **********************************************************************/ -require('offline.php'); +require('client.inc.php'); +$section = 'home'; +require(CLIENTINC_DIR.'header.inc.php'); +?> + +<div id="landing_page"> + <h1>Welcome to the Support Center</h1> + <p> + In order to streamline support requests and better serve you, we utilize a support ticket system. Every support request is assigned a unique ticket number which you can use to track the progress and responses online. For your reference we provide complete archives and history of all your support requests. A valid email address is required to submit a ticket. + </p> + + <div id="new_ticket"> + <h3>Open A New Ticket</h3> + <form method="link" action="open.php"> + <div>Please provide as much detail as possible so we can best assist you. To update a previously submitted ticket, please login.</div> + <input type="submit" value="Open a New Ticket"> + </form> + </div> + + <div id="check_status"> + <h3>Check Ticket Status</h3> + <form class="status_form" action="login.php" method="get"> + <div>We provide archives and history of all your current and past support requests complete with responses.</div> + <input type="submit" value="Check Ticket Status"> + </form> + </div> +</div> +<div class="clear"></div> +<?php +if($cfg && $cfg->isKnowledgebaseEnabled()){ + //FIXME: provide ability to feature or select random FAQs ?? + ?> +<br> +Be pure to browse our <a href="kb/index.php">Frequently Asked Questions (FAQs)</a>, before opening a ticket. +</div> +<?php +} ?> +<?php require(CLIENTINC_DIR.'footer.inc.php'); ?> diff --git a/login.php b/login.php new file mode 100644 index 0000000000000000000000000000000000000000..69a73c679951b0c7ec4ab30616eb08519aaaf828 --- /dev/null +++ b/login.php @@ -0,0 +1,92 @@ +<?php +/********************************************************************* + index.php + + Client Login + + Peter Rotich <peter@osticket.com> + Copyright (c) 2006-2012 osTicket + http://www.osticket.com + + Released under the GNU General Public License WITHOUT ANY WARRANTY. + See LICENSE.TXT for details. + + vim: expandtab sw=4 ts=4 sts=4: +**********************************************************************/ +require_once('client.inc.php'); +if(!defined('INCLUDE_DIR')) die('Fatal Error'); +define('CLIENTINC_DIR',INCLUDE_DIR.'client/'); +define('OSTCLIENTINC',TRUE); //make includes happy + +require_once(INCLUDE_DIR.'class.client.php'); +require_once(INCLUDE_DIR.'class.ticket.php'); +//We are ready baby +$loginmsg='Authentication Required'; +if($_POST && (!empty($_POST['lemail']) && !empty($_POST['lticket']))): + $loginmsg='Authentication Required'; + $email=trim($_POST['lemail']); + $ticketID=trim($_POST['lticket']); + //$_SESSION['_client']=array(); #Uncomment to disable login strikes. + + //Check time for last max failed login attempt strike. + $loginmsg='Invalid login'; + if($_SESSION['_client']['laststrike']) { + if((time()-$_SESSION['_client']['laststrike'])<$cfg->getClientLoginTimeout()) { + $loginmsg='Excessive failed login attempts'; + $errors['err']='You\'ve reached maximum failed login attempts allowed. Try again later or <a href="open.php">open a new ticket</a>'; + }else{ //Timeout is over. + //Reset the counter for next round of attempts after the timeout. + $_SESSION['_client']['laststrike']=null; + $_SESSION['_client']['strikes']=0; + } + } + //See if we can fetch local ticket id associated with the ID given + if(!$errors && is_numeric($ticketID) && Validator::is_email($email) && ($tid=Ticket::getIdByExtId($ticketID))) { + //At this point we know the ticket is valid. + $ticket= new Ticket($tid); + //TODO: 1) Check how old the ticket is...3 months max?? 2) Must be the latest 5 tickets?? + //Check the email given. + if($ticket->getId() && strcasecmp($ticket->getEMail(),$email)==0){ + //valid match...create session goodies for the client. + $user = new ClientSession($email,$ticket->getId()); + $_SESSION['_client']=array(); //clear. + $_SESSION['_client']['userID'] =$ticket->getEmail(); //Email + $_SESSION['_client']['key'] =$ticket->getExtId(); //Ticket ID --acts as password when used with email. See above. + $_SESSION['_client']['token'] =$user->getSessionToken(); + $_SESSION['TZ_OFFSET']=$cfg->getTZoffset(); + $_SESSION['daylight']=$cfg->observeDaylightSaving(); + //Log login info... + $msg=sprintf("%s/%s logged in [%s]",$ticket->getEmail(),$ticket->getExtId(),$_SERVER['REMOTE_ADDR']); + Sys::log(LOG_DEBUG,'User login',$msg); + //Redirect tickets.php + session_write_close(); + session_regenerate_id(); + @header("Location: tickets.php"); + require_once('tickets.php'); //Just incase. of header already sent error. + exit; + } + } + //If we get to this point we know the login failed. + $_SESSION['_client']['strikes']+=1; + if(!$errors && $_SESSION['_client']['strikes']>$cfg->getClientMaxLogins()) { + $loginmsg='Access Denied'; + $errors['err']='Forgot your login info? Please <a href="open.php">open a new ticket</a>.'; + $_SESSION['_client']['laststrike']=time(); + $alert='Excessive login attempts by a client?'."\n". + 'Email: '.$_POST['lemail']."\n".'Ticket#: '.$_POST['lticket']."\n". + 'IP: '.$_SERVER['REMOTE_ADDR']."\n".'Time:'.date('M j, Y, g:i a T')."\n\n". + 'Attempts #'.$_SESSION['_client']['strikes']; + Sys::log(LOG_ALERT,'Excessive login attempts (client)',$alert,($cfg->alertONLoginError())); + }elseif($_SESSION['_client']['strikes']%2==0){ //Log every other failed login attempt as a warning. + $alert='Email: '.$_POST['lemail']."\n".'Ticket #: '.$_POST['lticket']."\n".'IP: '.$_SERVER['REMOTE_ADDR']. + "\n".'TIME: '.date('M j, Y, g:i a T')."\n\n".'Attempts #'.$_SESSION['_client']['strikes']; + Sys::log(LOG_WARNING,'Failed login attempt (client)',$alert); + } +endif; + +$nav = new UserNav(); +$nav->setActiveNav('status'); +require(CLIENTINC_DIR.'header.inc.php'); +require(CLIENTINC_DIR.'login.inc.php'); +require(CLIENTINC_DIR.'footer.inc.php'); +?> diff --git a/logout.php b/logout.php new file mode 100644 index 0000000000000000000000000000000000000000..72c3560ecc7f540febb1ea0032c9b6cd39e2d3d6 --- /dev/null +++ b/logout.php @@ -0,0 +1,24 @@ +<?php +/********************************************************************* + logout.php + + Destroy clients session. + + Peter Rotich <peter@osticket.com> + Copyright (c) 2006-2012 osTicket + http://www.osticket.com + + Released under the GNU General Public License WITHOUT ANY WARRANTY. + See LICENSE.TXT for details. + + vim: expandtab sw=4 ts=4 sts=4: +**********************************************************************/ + +require('client.inc.php'); +//We are checking to make sure the user is logged in before a logout to avoid session reset tricks on excess logins +$_SESSION['_client']=array(); +session_unset(); +session_destroy(); +header('Location: index.php'); +require('index.php'); +?> diff --git a/offline.php b/offline.php index 3c3b24a425c78badc335c45cc62a9022fa61d1f6..24f8401a14c9710de2f9bf7af3a13985a47a099d 100644 --- a/offline.php +++ b/offline.php @@ -14,6 +14,11 @@ vim: expandtab sw=4 ts=4 sts=4: **********************************************************************/ require_once('client.inc.php'); +if($cfg && !$cfg->isHelpDeskOffline()) { + @header('Location: index.php'); //Redirect if the system is online. + include('index.php'); + exit; +} $nav=null; require(CLIENTINC_DIR.'header.inc.php'); ?> diff --git a/open.php b/open.php new file mode 100644 index 0000000000000000000000000000000000000000..a5d86d0776924c30768ac6bfea2889ee2c83052e --- /dev/null +++ b/open.php @@ -0,0 +1,50 @@ +<?php +/********************************************************************* + open.php + + New tickets handle. + + Peter Rotich <peter@osticket.com> + Copyright (c) 2006-2012 osTicket + http://www.osticket.com + + Released under the GNU General Public License WITHOUT ANY WARRANTY. + See LICENSE.TXT for details. + + vim: expandtab sw=4 ts=4 sts=4: +**********************************************************************/ +require('client.inc.php'); +define('SOURCE','Web'); //Ticket source. +$inc='open.inc.php'; //default include. +$errors=array(); +if($_POST): + $_POST['deptId']=$_POST['emailId']=0; //Just Making sure we don't accept crap...only topicId is expected. + if(!$thisuser && $cfg->enableCaptcha()){ + if(!$_POST['captcha']) + $errors['captcha']='Enter text shown on the image'; + elseif(strcmp($_SESSION['captcha'],md5($_POST['captcha']))) + $errors['captcha']='Invalid - try again!'; + } + + //FIXME: Allow logged in users to use diff email? + if($thisuser && strcasecmp($thisuser->getEmail(),$_POST['email'])) + $errors['email']='Email mismatch.'; + + //Ticket::create...checks for errors.. + if(($ticket=Ticket::create($_POST,$errors,SOURCE))){ + $msg='Support ticket request created'; + if($thisclient && $thisclient->isValid()) //Logged in...simply view the newly created ticket. + @header('Location: tickets.php?id='.$ticket->getExtId()); + //Thank the user and promise speedy resolution! + $inc='thankyou.inc.php'; + }else{ + $errors['err']=$errors['err']?$errors['err']:'Unable to create a ticket. Please correct errors below and try again!'; + } +endif; + +//page +$nav->setActiveNav('new'); +require(CLIENTINC_DIR.'header.inc.php'); +require(CLIENTINC_DIR.$inc); +require(CLIENTINC_DIR.'footer.inc.php'); +?> diff --git a/secure.inc.php b/secure.inc.php new file mode 100644 index 0000000000000000000000000000000000000000..f6664ab8174548983c9ddc9b8cb7d2436e2f2554 --- /dev/null +++ b/secure.inc.php @@ -0,0 +1,25 @@ +<?php +/********************************************************************* + secure.inc.php + + File included on every client's "secure" pages + + Peter Rotich <peter@osticket.com> + Copyright (c) 2006-2012 osTicket + http://www.osticket.com + + Released under the GNU General Public License WITHOUT ANY WARRANTY. + See LICENSE.TXT for details. + + vim: expandtab sw=4 ts=4 sts=4: +**********************************************************************/ +if(!strcasecmp(basename($_SERVER['SCRIPT_NAME']),basename(__FILE__))) die('Kwaheri rafiki!'); +if(!file_exists('client.inc.php')) die('Fatal Error.'); +require_once('client.inc.php'); +//User must be logged in! +if(!$thisclient || !$thisclient->getId() || !$thisclient->isValid()){ + require('./login.php'); + exit; +} +$thisclient->refreshSession(); +?> diff --git a/tickets.php b/tickets.php new file mode 100644 index 0000000000000000000000000000000000000000..072abef7de07d35112cbe2ff637bc254fd0d4455 --- /dev/null +++ b/tickets.php @@ -0,0 +1,82 @@ +<?php +/********************************************************************* + tickets.php + + Main client/user interface. + Note that we are using external ID. The real (local) ids are hidden from user. + + Peter Rotich <peter@osticket.com> + Copyright (c) 2006-2012 osTicket + http://www.osticket.com + + Released under the GNU General Public License WITHOUT ANY WARRANTY. + See LICENSE.TXT for details. + + vim: expandtab sw=4 ts=4 sts=4: +**********************************************************************/ +require('secure.inc.php'); +if(!is_object($thisclient) || !$thisclient->isValid()) die('Access denied'); //Double check again. + +require_once(INCLUDE_DIR.'class.ticket.php'); +$ticket=null; +$inc='tickets.inc.php'; //Default page...show all tickets. +//Check if any id is given... +if(($id=$_REQUEST['id']?$_REQUEST['id']:$_POST['ticket_id']) && is_numeric($id)) { + //id given fetch the ticket info and check perm. + $ticket= new Ticket(Ticket::getIdByExtId((int)$id)); + if(!$ticket or !$ticket->getEmail()) { + $ticket=null; //clear. + $errors['err']='Access Denied. Possibly invalid ticket ID'; + }elseif(strcasecmp($thisclient->getEmail(),$ticket->getEmail())){ + $errors['err']='Security violation. Repeated violations will result in your account being locked.'; + $ticket=null; //clear. + }else{ + //Everything checked out. + $inc='viewticket.inc.php'; + } +} +//Process post...depends on $ticket object above. +if($_POST && is_object($ticket) && $ticket->getId()): + $errors=array(); + switch(strtolower($_POST['a'])){ + case 'postmessage': + if(strcasecmp($thisclient->getEmail(),$ticket->getEmail())) { //double check perm again! + $errors['err']='Access Denied. Possibly invalid ticket ID'; + $inc='tickets.inc.php'; //Show the tickets. + } + + if(!$_POST['message']) + $errors['message']='Message required'; + //check attachment..if any is set + if($_FILES['attachment']['name']) { + if(!$cfg->allowOnlineAttachments()) //Something wrong with the form...user shouldn't have an option to attach + $errors['attachment']='File [ '.$_FILES['attachment']['name'].' ] rejected'; + elseif(!$cfg->canUploadFileType($_FILES['attachment']['name'])) + $errors['attachment']='Invalid file type [ '.$_FILES['attachment']['name'].' ]'; + elseif($_FILES['attachment']['size']>$cfg->getMaxFileSize()) + $errors['attachment']='File is too big. Max '.$cfg->getMaxFileSize().' bytes allowed'; + } + + if(!$errors){ + //Everything checked out...do the magic. + if(($msgid=$ticket->postMessage($_POST['message'],'Web'))) { + if($_FILES['attachment']['name'] && $cfg->canUploadFiles() && $cfg->allowOnlineAttachments()) + $ticket->uploadAttachment($_FILES['attachment'],$msgid,'M'); + + $msg='Message Posted Successfully'; + }else{ + $errors['err']='Unable to post the message. Try again'; + } + }else{ + $errors['err']=$errors['err']?$errors['err']:'Error(s) occured. Please try again'; + } + break; + default: + $errors['err']='Uknown action'; + } + $ticket->reload(); +endif; +include(CLIENTINC_DIR.'header.inc.php'); +include(CLIENTINC_DIR.$inc); +include(CLIENTINC_DIR.'footer.inc.php'); +?> diff --git a/view.php b/view.php new file mode 100644 index 0000000000000000000000000000000000000000..b8be15b040948bfddd9ee2b31b3fe1bd60726ed2 --- /dev/null +++ b/view.php @@ -0,0 +1,4 @@ +<?php +//We are now using tickets.php but we need to keep view.php for backward compatibility +require('tickets.php'); +?>