-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Logged in as
-
-
-
My open tickets
-
-
-
- | Subject |
- State |
-
-
-
-
- ";
- echo " $ticket[ticket_subject] | ";
- echo "$ticket[ticket_status] | ";
- echo "";
- }
- ?>
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/portal/login.php b/portal/login.php
index 388112a5..139a8214 100644
--- a/portal/login.php
+++ b/portal/login.php
@@ -17,6 +17,17 @@ if(!isset($_SESSION)){
session_start();
}
+$ip = strip_tags(mysqli_real_escape_string($mysqli,get_ip()));
+$user_agent = strip_tags(mysqli_real_escape_string($mysqli,$_SERVER['HTTP_USER_AGENT']));
+
+$sql_settings = mysqli_query($mysqli,"SELECT config_azure_client_id FROM settings WHERE company_id = '1'");
+$settings = mysqli_fetch_array($sql_settings);
+
+//$client_id = "e821e3a6-02c8-40e8-9f22-b84d951a62e7";
+//$client_secret = "axL7Q~hKbmIwqa3DoxJLy4p88AdBz96XAcNZW";
+
+$client_id = $settings['config_azure_client_id'];
+
if($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['login'])){
$email = strip_tags(mysqli_real_escape_string($mysqli, $_POST['email']));
@@ -30,22 +41,27 @@ if($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['login'])){
$row = mysqli_fetch_array($sql);
if($row['contact_auth_method'] == 'local'){
if(password_verify($password, $row['contact_password_hash'])){
+
$_SESSION['client_logged_in'] = TRUE;
$_SESSION['client_id'] = $row['contact_client_id'];
- $_SESSION['contact_id'] = $row['contact_client_id'];
+ $_SESSION['contact_id'] = $row['contact_id'];
$_SESSION['company_id'] = $row['company_id'];
+ $_SESSION['login_method'] = "local";
header("Location: index.php");
- //TODO: Logging
+ mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Client Login', log_action = 'Success', log_description = 'Client contact $row[contact_email] successfully logged in locally', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), log_client_id = $row[contact_client_id]");
+
}
else{
- $_SESSION['login_message'] = 'Incorrect username or password';
+ mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Client Login', log_action = 'Failed', log_description = 'Failed client portal login attempt using $email', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW()");
+ $_SESSION['login_message'] = 'Incorrect username or password.';
}
}
else{
- $_SESSION['login_message'] = 'Incorrect username or password';
+ mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Client Login', log_action = 'Failed', log_description = 'Failed client portal login attempt using $email', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW()");
+ $_SESSION['login_message'] = 'Incorrect username or password.';
}
}
@@ -74,24 +90,34 @@ if($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['login'])){
-
-
-
- Client Portal Login
+
+
- Client Portal Login
+
+
+
+
+
SSO
+
+
+
+
diff --git a/portal/login_microsoft.php b/portal/login_microsoft.php
new file mode 100644
index 00000000..3d7c0d31
--- /dev/null
+++ b/portal/login_microsoft.php
@@ -0,0 +1,136 @@
+ $client_id,
+ 'redirect_uri' => $redirect_uri,
+
+ #'response_type' =>'token',
+ 'response_type' => 'code',
+
+ 'response_mode' =>'form_post',
+ 'scope' => 'https://graph.microsoft.com/User.Read',
+ 'state' => session_id());
+
+ header ('Location: '.$auth_code_url.'?'.http_build_query ($params));
+
+}
+
+// Login was successful, Microsoft has returned us a authorization code via POST
+// Request an access token using authorization code (& client secret) (server side)
+if (isset($_POST['code']) && $_POST['state'] == session_id()){
+
+ $params = array (
+ 'client_id' =>$client_id,
+ 'code' => $_POST['code'],
+ 'redirect_uri' => $redirect_uri,
+ 'grant_type' => 'authorization_code',
+ 'client_secret' => $client_secret
+ );
+
+ // Send request via CURL (server side) so user cannot see the client secret
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL,$token_grant_url);
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS,
+ http_build_query($params));
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // DEBUG ONLY - WAMP
+
+ $access_token_response = json_decode(curl_exec($ch),1);
+ //curl_close ($ch);
+ //var_dump($ch);
+ //var_dump($access_token_response);
+
+ // Check if we have an access token
+ // If we do, send a request to Microsoft Graph API to get user info
+ if (isset($access_token_response['access_token'])){
+
+ $ch = curl_init();
+ curl_setopt ($ch, CURLOPT_HTTPHEADER, array ('Authorization: Bearer '.$access_token_response['access_token'],
+ 'Content-type: application/json'));
+ curl_setopt ($ch, CURLOPT_URL, "https://graph.microsoft.com/v1.0/me/");
+ curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // DEBUG ONLY - WAMP
+
+ $msgraph_response = json_decode (curl_exec ($ch), 1);
+
+ if (isset($msgraph_response['error'])){
+ // Something went wrong verifying the token/using the Graph API - quit
+ echo "Error with MS Graph API. Details:";
+ var_dump ($msgraph_response['error']);
+ exit();
+ }
+
+ elseif(isset($msgraph_response['id'])){
+
+ $upn = mysqli_real_escape_string($mysqli, $msgraph_response["userPrincipalName"]);
+
+ $sql = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_email = '$upn' LIMIT 1");
+ $row = mysqli_fetch_array($sql);
+ if($row['contact_auth_method'] == 'azure'){
+
+ $_SESSION['client_logged_in'] = TRUE;
+ $_SESSION['client_id'] = $row['contact_client_id'];
+ $_SESSION['contact_id'] = $row['contact_id'];
+ $_SESSION['company_id'] = $row['company_id'];
+ $_SESSION['login_method'] = "azure";
+
+ header("Location: index.php");
+
+ }
+ else{
+ $_SESSION['login_message'] = 'Something went wrong with login. Ensure you are setup for SSO.';
+ header("Location: index.php");
+ }
+ }
+ header ('Location: index.php');
+ }
+ else{
+ echo "Error getting access_token";
+ }
+
+}
+
+// If the user is just sat on the page, redirect them to login to try again
+if(empty($_GET)){
+ echo "";
+}
\ No newline at end of file
diff --git a/portal/portal_footer.php b/portal/portal_footer.php
new file mode 100644
index 00000000..4b8423a7
--- /dev/null
+++ b/portal/portal_footer.php
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/portal/portal_header.php b/portal/portal_header.php
new file mode 100644
index 00000000..57dcfda8
--- /dev/null
+++ b/portal/portal_header.php
@@ -0,0 +1,70 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/portal/portal_post.php b/portal/portal_post.php
index 95a390ad..511138a0 100644
--- a/portal/portal_post.php
+++ b/portal/portal_post.php
@@ -4,39 +4,132 @@
* Process GET/POST requests
*/
-include('../config.php');
-include('../functions.php');
-include('check_login.php');
+require_once("inc_portal.php");
-$session_company_id = $_SESSION['company_id'];
-$session_client_id = $_SESSION['client_id'];
-$session_contact_id = $_SESSION['contact_id'];
+if(isset($_GET['logout'])){
+ setcookie("PHPSESSID", '', time() - 3600, "/");
+ unset($_COOKIE['PHPSESSID']);
-if(!isset($_SESSION)){
- // HTTP Only cookies
- ini_set("session.cookie_httponly", True);
- if($config_https_only){
- // Tell client to only send cookie(s) over HTTPS
- ini_set("session.cookie_secure", True);
- }
- session_start();
+ session_unset();
+ session_destroy();
+
+ header('Location: login.php');
}
if(isset($_POST['add_ticket_comment'])){
- $requested_ticket_id = intval($_POST['ticket_id']);
- $comment = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['comment'])));
+ // HTML Purifier
+ require("../plugins/htmlpurifier/HTMLPurifier.standalone.php");
+ $purifier_config = HTMLPurifier_Config::createDefault();
+ $purifier_config->set('URI.AllowedSchemes', ['data' => true, 'src' => true, 'http' => true, 'https' => true]);
+ $purifier = new HTMLPurifier($purifier_config);
- // Verify the client has access to the provided ticket ID
- $sql = mysqli_query($mysqli, "SELECT * FROM tickets WHERE ticket_id = '$requested_ticket_id' AND ticket_status != 'Closed' AND ticket_client_id = '$session_client_id'");
+ $requested_ticket_id = intval($_POST['ticket_id']);
+
+ // Not currently providing the client portal with a full summer note editor, but need to maintain line breaks.
+ // In order to maintain line breaks consistently with the agent side, we need to allow HTML tags.
+ // So, we need to convert line breaks to HTML and clean HTML with HTML Purifier
+ $comment = trim(mysqli_real_escape_string($mysqli,$purifier->purify(html_entity_decode(nl2br($_POST['comment'])))));
+
+ if(empty($comment)){
+ header("Location: " . $_SERVER["HTTP_REFERER"]);
+ exit;
+ }
+
+ // Verify the contact has access to the provided ticket ID
+ $sql = mysqli_query($mysqli, "SELECT * FROM tickets WHERE ticket_id = '$requested_ticket_id' AND ticket_status != 'Closed' AND ticket_client_id = '$session_client_id' LIMIT 1");
$row = mysqli_fetch_array($sql);
$ticket_id = $row['ticket_id'];
- // Add client comment
- mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = '$comment', ticket_reply_type = 'Client', ticket_reply_created_at = NOW(), ticket_reply_by = '$session_contact_id', ticket_reply_ticket_id = '$ticket_id', company_id = '$session_company_id'");
+ if(intval($ticket_id)){
+ if($row['ticket_contact_id'] !== $session_contact_id AND $session_client_primary_contact_id !== $session_contact_id){
+ // This would only happen if the user intentionally modifies the hidden ticket_id value
+ header("Location: portal_post.php?logout");
+ exit();
+ }
- // Update Ticket Last Response Field & set ticket to open as client has replied
- mysqli_query($mysqli,"UPDATE tickets SET ticket_status = 'Open', ticket_updated_at = NOW() WHERE ticket_id = $ticket_id AND company_id = $session_company_id");
+ // Add comment
+ mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = '$comment', ticket_reply_type = 'Client', ticket_reply_created_at = NOW(), ticket_reply_by = '$session_contact_id', ticket_reply_ticket_id = '$ticket_id', company_id = '$session_company_id'");
- header("Location: " . $_SERVER["HTTP_REFERER"]);
+ // Update Ticket Last Response Field & set ticket to open as client has replied
+ mysqli_query($mysqli,"UPDATE tickets SET ticket_status = 'Open', ticket_updated_at = NOW() WHERE ticket_id = $ticket_id AND ticket_client_id = '$session_client_id' LIMIT 1");
+
+ header("Location: " . $_SERVER["HTTP_REFERER"]);
+ }
+ else{
+ header("Location: portal_post.php?logout");
+ exit();
+ }
+}
+
+if(isset($_POST['add_ticket_feedback'])){
+ $requested_ticket_id = intval($_POST['ticket_id']);
+ $feedback = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['add_ticket_feedback'])));
+
+ // Verify the contact has access to the provided ticket ID
+ $sql = mysqli_query($mysqli, "SELECT * FROM tickets WHERE ticket_id = '$requested_ticket_id' AND ticket_status = 'Closed' AND ticket_client_id = '$session_client_id' LIMIT 1");
+ $row = mysqli_fetch_array($sql);
+ $ticket_id = $row['ticket_id'];
+ $ticket_subject = $row['ticket_subject'];
+
+ if(intval($ticket_id)){
+ if($row['ticket_contact_id'] !== $session_contact_id AND $session_client_primary_contact_id !== $session_contact_id){
+ header("Location: " . $_SERVER["HTTP_REFERER"]);
+ exit("No access to this ticket ($requested_ticket_id)");
+ }
+
+ // Add feedback
+ mysqli_query($mysqli, "UPDATE tickets SET ticket_feedback = '$feedback' WHERE ticket_id = '$ticket_id' AND ticket_client_id = '$session_client_id' LIMIT 1");
+
+ if($feedback == "Bad"){
+ mysqli_query($mysqli,"INSERT INTO notifications SET notification_type = 'Feedback', notification = '$session_contact_name rated ticket - $ticket_subject ($ticket_id) - as bad', notification_timestamp = NOW(), notification_client_id = '$session_client_id', company_id = '$session_company_id'");
+ }
+
+ header("Location: " . $_SERVER["HTTP_REFERER"]);
+ }
+ else{
+ header("Location: portal_post.php?logout");
+ exit();
+ }
+
+
+}
+
+if(isset($_POST['add_ticket'])){
+
+ // Get ticket prefix/number
+ $sql_settings = mysqli_query($mysqli,"SELECT * FROM settings WHERE company_id = $session_company_id");
+ $row = mysqli_fetch_array($sql_settings);
+ $config_ticket_prefix = $row['config_ticket_prefix'];
+ $config_ticket_next_number = $row['config_ticket_next_number'];
+
+ // HTML Purifier
+ require("../plugins/htmlpurifier/HTMLPurifier.standalone.php");
+ $purifier_config = HTMLPurifier_Config::createDefault();
+ $purifier_config->set('URI.AllowedSchemes', ['data' => true, 'src' => true, 'http' => true, 'https' => true]);
+ $purifier = new HTMLPurifier($purifier_config);
+
+ $client_id = $session_client_id;
+ $contact = $session_contact_id;
+ $subject = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['subject'])));
+ $priority = $_POST['priority'];
+ $details = trim(mysqli_real_escape_string($mysqli,$purifier->purify(html_entity_decode(nl2br($_POST['details'])))));
+
+ // Ensure priority is low/med/high (as can be user defined)
+ if($priority !== "Low" OR $priority !== "Medium" OR $priority !== "High"){
+ $priority = "Low";
+ }
+
+ // Get the next Ticket Number and add 1 for the new ticket number
+ $ticket_number = $config_ticket_next_number;
+ $new_config_ticket_next_number = $config_ticket_next_number + 1;
+ mysqli_query($mysqli,"UPDATE settings SET config_ticket_next_number = $new_config_ticket_next_number WHERE company_id = $session_company_id");
+
+ mysqli_query($mysqli,"INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_subject = '$subject', ticket_details = '$details', ticket_priority = '$priority', ticket_status = 'Open', ticket_created_at = NOW(), ticket_created_by = '0', ticket_contact_id = $contact, ticket_client_id = $client_id, company_id = $session_company_id");
+ $id = mysqli_insert_id($mysqli);
+
+ //Logging
+ mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Ticket', log_action = 'Create', log_description = 'Client contact $session_contact_name created ticket $subject', log_created_at = NOW(), log_client_id = $client_id, company_id = $session_company_id, log_user_id = $session_user_id");
+
+ header("Location: ticket.php?id=" . $id);
}
\ No newline at end of file
diff --git a/portal/profile.php b/portal/profile.php
new file mode 100644
index 00000000..52b981e1
--- /dev/null
+++ b/portal/profile.php
@@ -0,0 +1,19 @@
+
+
+
Profile
+
+
Name:
+
Email:
+
Client:
+
Client Primary Contact:
+
Login via:
+
+
-
-
-
-
-
-
| Client Portal - Tickets
+
Ticket details:
-
-
-
-
+
+
+
+
+ State:
+
+ Priority:
+
+
+
+
-
-
-
-
-
-
-
-
-
Ticket Details -
-
- Reference:
-
- State:
-
- Priority:
-
-
-
+
-
-
+
+
+
Rate your ticket
+
+
+
+
+
+
Rated -- Thanks for your feedback!
+
+
+
+
" alt="User Avatar" class="img-size-50 mr-3 img-circle">
-
-
-
+
+
+
@@ -113,7 +121,7 @@ if(isset($_GET['id']) && intval($_GET['id'])) {
-
+
@@ -131,9 +139,6 @@ if(isset($_GET['id']) && intval($_GET['id'])) {
?>
-