mirror of https://github.com/itflow-org/itflow
Client portal updates
This commit is contained in:
parent
7be4685ea4
commit
34d6caa016
|
|
@ -139,6 +139,20 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Portal Login</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-user-circle"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="auth_method">
|
||||
<option value="">- None -</option>
|
||||
<option value="local">Local</option>
|
||||
<option value="azure">Azure</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-photo">
|
||||
|
|
|
|||
|
|
@ -141,6 +141,34 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Portal Login</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-user-circle"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="auth_method">
|
||||
<option value="">- None -</option>
|
||||
<option value="local" <?php if($auth_method == "local") {echo "selected";} ?>>Local</option>
|
||||
<option value="azure" <?php if($auth_method == "azure") {echo "selected";} ?>>Azure</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if($auth_method == "local") { ?>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Portal Login Password</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
|
||||
</div>
|
||||
<input class="form-control" type="password" name="contact_password" placeholder="Leave blank for no change">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-photo<?php echo $contact_id; ?>">
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli,"SELECT FOUND_ROWS()"));
|
|||
$location_name_display = $location_name;
|
||||
}
|
||||
$department_id = $row['department_id'];
|
||||
$auth_method = $row['contact_auth_method'];
|
||||
|
||||
// Related Assets Query
|
||||
$sql_related_assets = mysqli_query($mysqli,"SELECT * FROM assets WHERE asset_contact_id = $contact_id AND company_id = $session_company_id ORDER BY asset_id DESC");
|
||||
|
|
|
|||
2
db.sql
2
db.sql
|
|
@ -1125,6 +1125,8 @@ CREATE TABLE `settings` (
|
|||
`config_meshcentral_uri` varchar(200) DEFAULT NULL,
|
||||
`config_meshcentral_user` varchar(200) DEFAULT NULL,
|
||||
`config_meshcentral_secret` varchar(200) DEFAULT NULL,
|
||||
`config_azure_client_id` varchar(200) DEFAULT NULL,
|
||||
`config_azure_client_secret` varchar(200) DEFAULT NULL,
|
||||
PRIMARY KEY (`company_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@ $config_meshcentral_uri = $row['config_meshcentral_uri'];
|
|||
$config_meshcentral_user = $row['config_meshcentral_user'];
|
||||
$config_meshcentral_secret = $row['config_meshcentral_secret'];
|
||||
|
||||
// Microsoft OAuth
|
||||
$config_azure_client_id = $row['config_azure_client_id'];
|
||||
$config_azure_client_secret = $row['config_azure_client_secret'];
|
||||
|
||||
// Mail
|
||||
$config_smtp_host = $row['config_smtp_host'];
|
||||
$config_smtp_port = $row['config_smtp_port'];
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ if(isset($_POST['login'])){
|
|||
<p class="login-box-msg"><?php if(isset($response)) { echo $response; } ?></p>
|
||||
<form method="post">
|
||||
<div class="input-group mb-3">
|
||||
<input type="text" class="form-control" placeholder="Email" name="email" value="<?php if(!empty($token_field)){ echo $email; }?>" required <?php if(empty($token_field)){ echo "autofocus"; } ?> >
|
||||
<input type="text" class="form-control" placeholder="Agent Email" name="email" value="<?php if(!empty($token_field)){ echo $email; }?>" required <?php if(empty($token_field)){ echo "autofocus"; } ?> >
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<span class="fas fa-envelope"></span>
|
||||
|
|
@ -173,7 +173,7 @@ if(isset($_POST['login'])){
|
|||
</div>
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<input type="password" class="form-control" placeholder="Password" name="password" value="<?php if(!empty($token_field)){ echo $password; } ?>" required>
|
||||
<input type="password" class="form-control" placeholder="Agent Password" name="password" value="<?php if(!empty($token_field)){ echo $password; } ?>" required>
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">
|
||||
<span class="fas fa-lock"></span>
|
||||
|
|
@ -184,6 +184,11 @@ if(isset($_POST['login'])){
|
|||
|
||||
<button type="submit" class="btn btn-primary btn-block mb-3" name="login">Sign In</button>
|
||||
|
||||
<hr><br>
|
||||
|
||||
<h4>Looking for the Client Portal?</h4>
|
||||
<button type="button" onclick="location.href = 'https://<?php echo $config_base_url ?>/portal/';" class="btn btn-secondary btn-block mb-3">Continue as a client</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,22 @@ $session_os = strip_tags(mysqli_real_escape_string($mysqli,get_os()));
|
|||
// Get user agent
|
||||
$session_user_agent = strip_tags(mysqli_real_escape_string($mysqli,$_SERVER['HTTP_USER_AGENT']));
|
||||
|
||||
// Get client info
|
||||
// Get info from session
|
||||
$session_client_id = $_SESSION['client_id'];
|
||||
$session_contact_id = $_SESSION['contact_id'];
|
||||
$session_company_id = $_SESSION['company_id'];
|
||||
|
||||
// Get contact info
|
||||
$contact_sql = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_id = '$session_contact_id' AND contact_client_id = '$session_client_id'");
|
||||
$contact = mysqli_fetch_array($contact_sql);
|
||||
|
||||
$session_contact_name = $contact['contact_name'];
|
||||
$session_contact_initials = initials($session_contact_name);
|
||||
$session_contact_email = $contact['contact_email'];
|
||||
|
||||
// Get client info
|
||||
$client_sql = mysqli_query($mysqli, "SELECT * FROM clients WHERE client_id = '$session_client_id'");
|
||||
$client = mysqli_fetch_array($client_sql);
|
||||
|
||||
$session_client_name = $client['client_name'];
|
||||
$session_client_primary_contact_id = $client['primary_contact'];
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
/*
|
||||
* Client Portal
|
||||
* Includes for all pages (except login)
|
||||
*/
|
||||
|
||||
include('../config.php');
|
||||
include('../functions.php');
|
||||
include('check_login.php');
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
include("portal_header.php");
|
||||
110
portal/index.php
110
portal/index.php
|
|
@ -4,69 +4,61 @@
|
|||
* Landing / Home page for the client portal
|
||||
*/
|
||||
|
||||
include('../config.php');
|
||||
include('../functions.php');
|
||||
include('check_login.php');
|
||||
require_once("inc_portal.php");
|
||||
|
||||
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();
|
||||
// Ticket status from GET
|
||||
if (!isset($_GET['status'])) {
|
||||
// If nothing is set, assume we only want to see open tickets
|
||||
$status = 'Open';
|
||||
$ticket_status_snippet = "ticket_status != 'Closed'";
|
||||
} elseif (isset($_GET['status']) && ($_GET['status']) == 'Open') {
|
||||
$status = 'Open';
|
||||
$ticket_status_snippet = "ticket_status != 'Closed'";
|
||||
} elseif (isset($_GET['status']) && ($_GET['status']) == 'Closed') {
|
||||
$status = 'Closed';
|
||||
$ticket_status_snippet = "ticket_status = 'Closed'";
|
||||
} else {
|
||||
$status = '%';
|
||||
$ticket_status_snippet = "ticket_status LIKE '%'";
|
||||
}
|
||||
|
||||
$contact_sql = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_id = '$session_contact_id' AND contact_client_id = '$session_client_id' LIMIT 1");
|
||||
$contact_row = mysqli_fetch_array($contact_sql);
|
||||
|
||||
$contact_tickets = mysqli_query($mysqli, "SELECT * FROM tickets WHERE ticket_status != 'Closed' AND ticket_contact_id = '$session_contact_id' AND ticket_client_id = '$session_client_id'");
|
||||
$tickets = mysqli_fetch_array($contact_tickets);
|
||||
$contact_tickets = mysqli_query($mysqli, "SELECT * FROM tickets LEFT JOIN contacts ON ticket_contact_id = contact_id WHERE $ticket_status_snippet AND ticket_contact_id = '$session_contact_id' AND ticket_client_id = '$session_client_id' ORDER BY ticket_id DESC");
|
||||
?>
|
||||
|
||||
<h2>Welcome, <?php echo $session_contact_name ?>, to the <?php echo $config_app_name ?> client portal.</h2>
|
||||
<br>
|
||||
<h2>My tickets</h2>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<form method="get">
|
||||
<label>Ticket Status</label>
|
||||
<select class="form-control" name="status" onchange="this.form.submit()">
|
||||
<option value="%" <?php if($status == "%"){echo "selected";}?> >Any</option>
|
||||
<option value="Open" <?php if($status == "Open"){echo "selected";}?> >Open</option>
|
||||
<option value="Closed" <?php if($status == "Closed"){echo "selected";}?> >Closed</option>
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Subject</th>
|
||||
<th scope="col">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title><?php echo $config_app_name; ?> | Client Portal</title>
|
||||
<?php
|
||||
while($ticket = mysqli_fetch_array($contact_tickets)){
|
||||
echo "<tr>";
|
||||
echo "<td> <a href='ticket.php?id=$ticket[ticket_id]'> $ticket[ticket_subject]</a></td>";
|
||||
echo "<td>$ticket[ticket_status]</td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Tell the browser to be responsive to screen width -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="../plugins/fontawesome-free/css/all.min.css">
|
||||
|
||||
<!-- Theme style -->
|
||||
<link rel="stylesheet" href="../dist/css/adminlte.min.css">
|
||||
|
||||
<!-- Google Font: Source Sans Pro -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
|
||||
</head>
|
||||
<div class="container">
|
||||
<h2>Logged in as <?php echo $contact_row['contact_name'] ?></h2>
|
||||
|
||||
<br>
|
||||
<h3>My open tickets</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Subject</th>
|
||||
<th scope="col">State</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<?php
|
||||
while($ticket = mysqli_fetch_array($contact_tickets)){
|
||||
echo "<tr>";
|
||||
echo "<td> <a href='ticket.php?id=$ticket[ticket_id]'> $ticket[ticket_subject]</a></td>";
|
||||
echo "<td>$ticket[ticket_status]</td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php include("portal_footer.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'])){
|
|||
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
|
||||
</head>
|
||||
<div class="container">
|
||||
<div class="col-4 offset-3">
|
||||
<br>
|
||||
<h2><?php echo $config_app_name; ?> - Client Portal Login</h2>
|
||||
<br>
|
||||
<h2 align="center"><?php echo $config_app_name; ?> - Client Portal Login</h2>
|
||||
<div class="row">
|
||||
<div class="col-4 offset-2">
|
||||
<h4>Local</h4>
|
||||
<form action="login.php" method="post">
|
||||
<div class="form-group">
|
||||
<input class="form-control" type="text" name="email" placeholder="someone@example.com">
|
||||
<input class="form-control" type="password" name="password" placeholder="Password">
|
||||
</div>
|
||||
|
||||
<form action="login.php" method="post">
|
||||
<div class="form-group">
|
||||
<input class="form-control" type="text" name="email" placeholder="someone@example.com">
|
||||
<input class="form-control" type="password" name="password" placeholder="Pa$$word">
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary" type="submit" name="login">Login</button>
|
||||
</form>
|
||||
<?php
|
||||
<button class="btn btn-primary" type="submit" name="login">Login</button>
|
||||
</form>
|
||||
<?php
|
||||
if(!empty($_SESSION['login_message'])){
|
||||
echo $_SESSION['login_message'];
|
||||
unset($_SESSION['login_message']);
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
if(!empty($client_id)){ ?>
|
||||
<div class="col-4 offset-2">
|
||||
<h4>SSO</h4>
|
||||
<button type="button" class="btn btn-secondary" onclick="location.href = 'login_microsoft.php';">Login with Microsoft Azure AD</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
/*
|
||||
* Client Portal
|
||||
* OAuth Login via Microsoft IDP
|
||||
*/
|
||||
|
||||
include('../config.php');
|
||||
include('../functions.php');
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
$sql_settings = mysqli_query($mysqli,"SELECT config_azure_client_id, config_azure_client_secret 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'];
|
||||
$client_secret = $settings['config_azure_client_secret'];
|
||||
|
||||
//$redirect_uri = "https://$config_base_url/portal/login_microsoft.php";
|
||||
$redirect_uri = "http://localhost/itflow/portal/login_microsoft.php";
|
||||
|
||||
# https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
|
||||
## {tenant} is set to organistions to allow any MS Work/School account - See above for valid values. Must be used in conjunction with the correct setting on the App Registration
|
||||
$auth_code_url = "https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize";
|
||||
$token_grant_url = "https://login.microsoftonline.com/organizations/oauth2/v2.0/token";
|
||||
|
||||
// Initial Login Request, via Microsoft
|
||||
// Returns a authorization code if login was successful
|
||||
if ($_SERVER['REQUEST_METHOD'] == "GET"){
|
||||
//if ($_GET['action'] == 'login'){
|
||||
|
||||
$params = array (
|
||||
'client_id' => $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 "<script> setTimeout(function(){ window.location = \"login.php\"; },1000);</script>";
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
/*
|
||||
* Client Portal
|
||||
* HTML Footer
|
||||
*/
|
||||
?>
|
||||
|
||||
<!-- Close container -->
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<hr>
|
||||
|
||||
<p class="text-center"><?php echo $config_app_name ?></p>
|
||||
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="../plugins/jquery/jquery.min.js"></script>
|
||||
|
||||
<!-- Bootstrap 4 -->
|
||||
<script src="../plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
/*
|
||||
* Client Portal
|
||||
* HTML Header
|
||||
*/
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title><?php echo $config_app_name; ?> | Client Portal - Tickets</title>
|
||||
|
||||
<!-- Tell the browser to be responsive to screen width -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="../plugins/fontawesome-free/css/all.min.css">
|
||||
|
||||
<!-- Theme style -->
|
||||
<link rel="stylesheet" href="../dist/css/adminlte.min.css">
|
||||
|
||||
<!-- Google Font: Source Sans Pro -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<!-- Navbar -->
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="index.php"><?php echo $config_app_name ?></a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item <?php if(basename($_SERVER['PHP_SELF']) == "index.php") {echo "active";} ?>">
|
||||
<a class="nav-link" href="index.php">Home</a>
|
||||
</li>
|
||||
<?php if($session_contact_id == $session_client_primary_contact_id) { ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="ticket_view_all.php">All Tickets</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="ticket_add">New Ticket</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav pull-right">
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<?php echo $session_contact_name ?>
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||
<a class="dropdown-item" href="profile.php">Profile</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="portal_post.php?logout">Logout</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<br>
|
||||
|
||||
<!-- Page content container -->
|
||||
<div class="container">
|
||||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
/*
|
||||
* Client Portal
|
||||
* User profile
|
||||
*/
|
||||
|
||||
require('inc_portal.php');
|
||||
?>
|
||||
|
||||
<h2>Profile</h2>
|
||||
|
||||
<p>Name: <?php echo $session_contact_name ?></p>
|
||||
<p>Email: <?php echo $session_contact_email ?></p>
|
||||
<p>Client: <?php echo $session_client_name ?></p>
|
||||
<p>Client Primary Contact: <?php if($session_client_primary_contact_id == $session_contact_id) {echo "Yes"; } else {echo "No";} ?></p>
|
||||
<p>Login via: <?php echo $_SESSION['login_method'] ?> </p>
|
||||
|
||||
<?php
|
||||
include('portal_footer.php');
|
||||
|
|
@ -4,75 +4,82 @@
|
|||
* Ticket detail page
|
||||
*/
|
||||
|
||||
include('../config.php');
|
||||
include('../functions.php');
|
||||
include('check_login.php');
|
||||
|
||||
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();
|
||||
}
|
||||
require_once("inc_portal.php");
|
||||
|
||||
if(isset($_GET['id']) && intval($_GET['id'])) {
|
||||
$ticket_id = intval($_GET['id']);
|
||||
$ticket_sql = mysqli_query($mysqli, "SELECT * FROM tickets WHERE ticket_id = '$ticket_id' AND ticket_client_id = '$session_client_id'");
|
||||
|
||||
if($session_contact_id == $session_client_primary_contact_id){
|
||||
$ticket_sql = mysqli_query($mysqli, "SELECT * FROM tickets WHERE ticket_id = '$ticket_id' AND ticket_client_id = '$session_client_id'");
|
||||
}
|
||||
else{
|
||||
$ticket_sql = mysqli_query($mysqli, "SELECT * FROM tickets WHERE ticket_id = '$ticket_id' AND ticket_client_id = '$session_client_id' AND ticket_contact_id = '$session_contact_id'");
|
||||
}
|
||||
|
||||
$ticket = mysqli_fetch_array($ticket_sql);
|
||||
|
||||
if ($ticket) {
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title><?php echo $config_app_name; ?> | Client Portal - Tickets</title>
|
||||
<h2><i class="fas fa-fw fa-ticket-alt text-secondary"></i> Ticket details: <?php echo $ticket['ticket_prefix'], $ticket['ticket_number'] ?></h2>
|
||||
|
||||
<!-- Tell the browser to be responsive to screen width -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="../plugins/fontawesome-free/css/all.min.css">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title"><?php echo $ticket['ticket_subject'] ?></h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>
|
||||
<b>State:</b> <?php echo $ticket['ticket_status'] ?>
|
||||
<br>
|
||||
<b>Priority:</b> <?php echo $ticket['ticket_priority'] ?>
|
||||
</p>
|
||||
<?php echo $ticket['ticket_details'] ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Theme style -->
|
||||
<link rel="stylesheet" href="../dist/css/adminlte.min.css">
|
||||
|
||||
<!-- Google Font: Source Sans Pro -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
|
||||
</head>
|
||||
<div class="container">
|
||||
|
||||
<h2>Ticket Details - <?php echo $ticket['ticket_subject'] ?></h2>
|
||||
<p>
|
||||
Reference: <?php echo $ticket['ticket_prefix'], $ticket['ticket_number'] ?>
|
||||
<br>
|
||||
State: <?php echo $ticket['ticket_status'] ?>
|
||||
<br>
|
||||
Priority: <?php echo $ticket['ticket_priority'] ?>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<!-- Either show the reply comments box, ticket smiley feedback, or thanks for feedback -->
|
||||
|
||||
<?php if($ticket['ticket_status'] !== "Closed") { ?>
|
||||
|
||||
<div class="form-group">
|
||||
<form action="portal_post.php" method="post">
|
||||
<div class="form-group">
|
||||
<textarea class="form-control" name="comment" placeholder="Add comments.."></textarea>
|
||||
</div>
|
||||
<input type="hidden" name="ticket_id" value="<?php echo $ticket['ticket_id'] ?>">
|
||||
<button type="submit" class="btn btn-primary" name="add_ticket_comment">Add comment</button>
|
||||
<button type="submit" class="btn btn-primary" name="add_ticket_comment">Save reply</button>
|
||||
</form>
|
||||
</div>
|
||||
<hr>
|
||||
<?php }
|
||||
|
||||
elseif(empty($ticket['ticket_feedback'])) { ?>
|
||||
|
||||
<h4>Rate your ticket</h4>
|
||||
|
||||
<form action="portal_post.php" method="post">
|
||||
<input type="hidden" name="ticket_id" value="<?php echo $ticket['ticket_id'] ?>">
|
||||
|
||||
<button type="submit" class="btn btn-primary btn-lg" name="add_ticket_feedback" value="Good" onclick="this.form.submit()">
|
||||
<span class="fa fa-smile" aria-hidden="true"></span> Good
|
||||
</button>
|
||||
|
||||
<button type="submit" class="btn btn-danger btn-lg" name="add_ticket_feedback" value="Bad" onclick="this.form.submit()">
|
||||
<span class="fa fa-frown" aria-hidden="true"></span> Bad
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<?php }
|
||||
|
||||
else{ ?>
|
||||
|
||||
<h4>Rated <?php echo $ticket['ticket_feedback'] ?> -- Thanks for your feedback!</h4>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<!-- End comments/feedback -->
|
||||
|
||||
<hr><br>
|
||||
|
||||
<?php
|
||||
$sql = mysqli_query($mysqli,"SELECT * FROM ticket_replies LEFT JOIN users ON ticket_reply_by = user_id LEFT JOIN contacts ON ticket_reply_by = contact_id WHERE ticket_reply_ticket_id = $ticket_id AND ticket_reply_archived_at IS NULL AND ticket_reply_type != 'Internal' ORDER BY ticket_reply_id DESC");
|
||||
|
||||
|
|
@ -80,6 +87,7 @@ if(isset($_GET['id']) && intval($_GET['id'])) {
|
|||
$ticket_reply_id = $row['ticket_reply_id'];
|
||||
$ticket_reply = $row['ticket_reply'];
|
||||
$ticket_reply_created_at = $row['ticket_reply_created_at'];
|
||||
$ticket_reply_updated_at = $row['ticket_reply_updated_at'];
|
||||
$ticket_reply_by = $row['ticket_reply_by'];
|
||||
$ticket_reply_type = $row['ticket_reply_type'];
|
||||
|
||||
|
|
@ -103,9 +111,9 @@ if(isset($_GET['id']) && intval($_GET['id'])) {
|
|||
<img src="<?php echo "../uploads/users/$user_id/$user_avatar"; ?>" alt="User Avatar" class="img-size-50 mr-3 img-circle">
|
||||
<?php }else{ ?>
|
||||
<span class="fa-stack fa-2x">
|
||||
<i class="fa fa-circle fa-stack-2x text-secondary"></i>
|
||||
<span class="fa fa-stack-1x text-white"><?php echo $user_initials; ?></span>
|
||||
</span>
|
||||
<i class="fa fa-circle fa-stack-2x text-secondary"></i>
|
||||
<span class="fa fa-stack-1x text-white"><?php echo $user_initials; ?></span>
|
||||
</span>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
|
@ -113,7 +121,7 @@ if(isset($_GET['id']) && intval($_GET['id'])) {
|
|||
<div class="media-body">
|
||||
<?php echo $ticket_reply_by_display; ?>
|
||||
<br>
|
||||
<small class="text-muted"><?php echo $ticket_reply_created_at; ?> <?php if(!empty($ticket_reply_updated_at)){ echo "modified: $ticket_reply_updated_at"; } ?></small>
|
||||
<small class="text-muted"><?php echo $ticket_reply_created_at; ?> <?php if(!empty($ticket_reply_updated_at)){ echo "(edited: $ticket_reply_updated_at)"; } ?></small>
|
||||
</div>
|
||||
</div>
|
||||
</h3>
|
||||
|
|
@ -131,9 +139,6 @@ if(isset($_GET['id']) && intval($_GET['id'])) {
|
|||
?>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<?php
|
||||
}
|
||||
else{
|
||||
|
|
@ -142,4 +147,6 @@ if(isset($_GET['id']) && intval($_GET['id'])) {
|
|||
}
|
||||
else{
|
||||
header("Location: index.php");
|
||||
}
|
||||
}
|
||||
|
||||
require_once("portal_footer.php");
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
/*
|
||||
* Client Portal
|
||||
* New ticket form
|
||||
*/
|
||||
|
||||
require('inc_portal.php');
|
||||
?>
|
||||
|
||||
<h2>Raise a new ticket</h2>
|
||||
|
||||
<div class="col-8">
|
||||
<form action="portal_post.php" method="post">
|
||||
|
||||
<div class="form-group">
|
||||
<label>Subject <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-tag"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="subject" placeholder="Subject" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Priority <strong class="text-danger">*</strong></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-thermometer-half"></i></span>
|
||||
</div>
|
||||
<select class="form-control select2" name="priority" required>
|
||||
<option>Low</option>
|
||||
<option>Medium</option>
|
||||
<option>High</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Details <strong class="text-danger">*</strong></label>
|
||||
<textarea class="form-control" rows="4" name="details" required></textarea>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary" name="add_ticket">Raise ticket</button>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
include('portal_footer.php');
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
/*
|
||||
* Client Portal
|
||||
* Primary contact view: all tickets
|
||||
*/
|
||||
|
||||
require('inc_portal.php');
|
||||
|
||||
if($session_contact_id !== $session_client_primary_contact_id){
|
||||
header("Location: portal_post.php?logout");
|
||||
exit();
|
||||
}
|
||||
|
||||
// Ticket status from GET
|
||||
if (!isset($_GET['status'])) {
|
||||
// If nothing is set, assume we only want to see open tickets
|
||||
$status = 'Open';
|
||||
$ticket_status_snippet = "ticket_status != 'Closed'";
|
||||
} elseif (isset($_GET['status']) && ($_GET['status']) == 'Open') {
|
||||
$status = 'Open';
|
||||
$ticket_status_snippet = "ticket_status != 'Closed'";
|
||||
} elseif (isset($_GET['status']) && ($_GET['status']) == 'Closed') {
|
||||
$status = 'Closed';
|
||||
$ticket_status_snippet = "ticket_status = 'Closed'";
|
||||
} else {
|
||||
$status = '%';
|
||||
$ticket_status_snippet = "ticket_status LIKE '%'";
|
||||
}
|
||||
|
||||
$all_tickets = mysqli_query($mysqli, "SELECT * FROM tickets LEFT JOIN contacts ON ticket_contact_id = contact_id WHERE $ticket_status_snippet AND ticket_client_id = '$session_client_id' ORDER BY ticket_id DESC");
|
||||
?>
|
||||
|
||||
<h2>All tickets</h2>
|
||||
<div class="col-md-2">
|
||||
<div class="form-group">
|
||||
<form method="get">
|
||||
<label>Ticket Status</label>
|
||||
<select class="form-control" name="status" onchange="this.form.submit()">
|
||||
<option value="%" <?php if($status == "%"){echo "selected";}?> >Any</option>
|
||||
<option value="Open" <?php if($status == "Open"){echo "selected";}?> >Open</option>
|
||||
<option value="Closed" <?php if($status == "Closed"){echo "selected";}?> >Closed</option>
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Subject</th>
|
||||
<th scope="col">Contact</th>
|
||||
<th scope="col">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<?php
|
||||
while($ticket = mysqli_fetch_array($all_tickets)){
|
||||
echo "<tr>";
|
||||
echo "<td> <a href='ticket.php?id=$ticket[ticket_id]'> $ticket[ticket_subject]</a></td>";
|
||||
echo "<td>$ticket[contact_name]</td>";
|
||||
echo "<td>$ticket[ticket_status]</td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
include('portal_footer.php');
|
||||
28
post.php
28
post.php
|
|
@ -718,8 +718,10 @@ if(isset($_POST['edit_general_settings'])){
|
|||
$mesh_uri = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['meshcentral_uri'])));
|
||||
$mesh_user = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['meshcentral_user'])));
|
||||
$mesh_secret = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['meshcentral_secret'])));
|
||||
$azure_client_id = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['azure_client_id'])));
|
||||
$azure_client_secret = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['azure_client_secret'])));
|
||||
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_base_url = '$config_base_url', config_meshcentral_uri = '$mesh_uri', config_meshcentral_user = '$mesh_user', config_meshcentral_secret = '$mesh_secret' WHERE company_id = $session_company_id");
|
||||
mysqli_query($mysqli,"UPDATE settings SET config_base_url = '$config_base_url', config_meshcentral_uri = '$mesh_uri', config_meshcentral_user = '$mesh_user', config_meshcentral_secret = '$mesh_secret', config_azure_client_id = '$azure_client_id', config_azure_client_secret = '$azure_client_secret' WHERE company_id = $session_company_id");
|
||||
|
||||
//Logging
|
||||
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Settings', log_action = 'Modify', log_description = '$session_name modified general settings', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_created_at = NOW(), log_user_id = $session_user_id, company_id = $session_company_id");
|
||||
|
|
@ -3972,12 +3974,14 @@ if(isset($_POST['add_contact'])){
|
|||
$primary_contact = intval($_POST['primary_contact']);
|
||||
$notes = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['notes'])));
|
||||
$location_id = intval($_POST['location']);
|
||||
$auth_method = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['auth_method'])));
|
||||
|
||||
if(!file_exists("uploads/clients/$session_company_id/$client_id")) {
|
||||
|
||||
if(!file_exists("uploads/clients/$session_company_id/$client_id")) {
|
||||
mkdir("uploads/clients/$session_company_id/$client_id");
|
||||
}
|
||||
|
||||
mysqli_query($mysqli,"INSERT INTO contacts SET contact_name = '$name', contact_title = '$title', contact_phone = '$phone', contact_extension = '$extension', contact_mobile = '$mobile', contact_email = '$email', contact_notes = '$notes', contact_created_at = NOW(), contact_department_id = $department, contact_location_id = $location_id, contact_client_id = $client_id, company_id = $session_company_id");
|
||||
mysqli_query($mysqli,"INSERT INTO contacts SET contact_name = '$name', contact_title = '$title', contact_phone = '$phone', contact_extension = '$extension', contact_mobile = '$mobile', contact_email = '$email', contact_notes = '$notes', contact_auth_method = '$auth_method', contact_created_at = NOW(), contact_department_id = $department, contact_location_id = $location_id, contact_client_id = $client_id, company_id = $session_company_id");
|
||||
|
||||
$contact_id = mysqli_insert_id($mysqli);
|
||||
|
||||
|
|
@ -4051,6 +4055,8 @@ if(isset($_POST['edit_contact'])){
|
|||
$primary_contact = intval($_POST['primary_contact']);
|
||||
$notes = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['notes'])));
|
||||
$location_id = intval($_POST['location']);
|
||||
$auth_method = trim(strip_tags(mysqli_real_escape_string($mysqli,$_POST['auth_method'])));
|
||||
$password = $_POST['contact_password'];
|
||||
|
||||
$existing_file_name = strip_tags(mysqli_real_escape_string($mysqli,$_POST['existing_file_name']));
|
||||
|
||||
|
|
@ -4058,14 +4064,20 @@ if(isset($_POST['edit_contact'])){
|
|||
mkdir("uploads/clients/$session_company_id/$client_id");
|
||||
}
|
||||
|
||||
mysqli_query($mysqli,"UPDATE contacts SET contact_name = '$name', contact_title = '$title', contact_phone = '$phone', contact_extension = '$extension', contact_mobile = '$mobile', contact_email = '$email', contact_notes = '$notes', contact_department_id = $department, contact_location_id = $location_id, contact_updated_at = NOW() WHERE contact_id = $contact_id AND company_id = $session_company_id");
|
||||
mysqli_query($mysqli,"UPDATE contacts SET contact_name = '$name', contact_title = '$title', contact_phone = '$phone', contact_extension = '$extension', contact_mobile = '$mobile', contact_email = '$email', contact_notes = '$notes', contact_auth_method = '$auth_method', contact_department_id = $department, contact_location_id = $location_id, contact_updated_at = NOW() WHERE contact_id = $contact_id AND company_id = $session_company_id");
|
||||
|
||||
//Update Primay contact in clients if primary contact is checked
|
||||
// Update Primary contact in clients if primary contact is checked
|
||||
if($primary_contact > 0){
|
||||
mysqli_query($mysqli,"UPDATE clients SET primary_contact = $contact_id WHERE client_id = $client_id");
|
||||
}
|
||||
|
||||
//Check to see if a file is attached
|
||||
// Set password
|
||||
if(!empty($password)){
|
||||
$password_hash = password_hash($password, PASSWORD_DEFAULT);
|
||||
mysqli_query($mysqli, "UPDATE contacts SET contact_password_hash = '$password_hash' WHERE contact_client_id = '$client_id'");
|
||||
}
|
||||
|
||||
// Check to see if a file is attached
|
||||
if($_FILES['file']['tmp_name'] != ''){
|
||||
|
||||
// get details of the uploaded file
|
||||
|
|
@ -5658,7 +5670,7 @@ if(isset($_POST['add_ticket_reply'])){
|
|||
$mail->isHTML(true); // Set email format to HTML
|
||||
|
||||
$mail->Subject = "Ticket update - [$ticket_prefix$ticket_number] - $ticket_subject";
|
||||
$mail->Body = "Hello, $contact_name<br><br>Your ticket regarding \"$ticket_subject\" has been updated.<br><br>--------------------------------<br>$ticket_reply--------------------------------<br><br>Ticket: $ticket_prefix$ticket_number<br>Subject: $ticket_subject<br>Status: $ticket_status<br><br>~<br>$session_company_name<br>Support Department<br>$config_ticket_from_email<br>$company_phone";
|
||||
$mail->Body = "Hello, $contact_name<br><br>Your ticket regarding \"$ticket_subject\" has been updated.<br><br>--------------------------------<br>$ticket_reply--------------------------------<br><br>Ticket: $ticket_prefix$ticket_number<br>Subject: $ticket_subject<br>Status: $ticket_status<br>https://$config_base_url/portal/ticket.php?id=$ticket_id<br><br>~<br>$session_company_name<br>Support Department<br>$config_ticket_from_email<br>$company_phone";
|
||||
$mail->send();
|
||||
}
|
||||
catch(Exception $e){
|
||||
|
|
@ -5688,7 +5700,7 @@ if(isset($_POST['edit_ticket_reply'])){
|
|||
$ticket_reply_id = intval($_POST['ticket_reply_id']);
|
||||
$ticket_reply = trim(mysqli_real_escape_string($mysqli,$purifier->purify(html_entity_decode($_POST['ticket_reply']))));
|
||||
|
||||
mysqli_query($mysqli,"UPDATE ticket_replies SET ticket_reply = '$ticket_reply', ticket_reply_updated_at = NOW() WHERE ticket_reply_id = $ticket_reply_id AND company_id = $session_company_id") or die(mysqli_error($mysqli));
|
||||
mysqli_query($mysqli,"UPDATE ticket_replies SET ticket_reply = '$ticket_reply', ticket_reply_updated_at = NOW() WHERE ticket_reply_id = $ticket_reply_id AND ticket_reply_type != 'Client' AND company_id = $session_company_id") or die(mysqli_error($mysqli));
|
||||
|
||||
//Logging
|
||||
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Ticket Update Modify', log_action = 'Modified', log_description = '$ticket_update_id', log_created_at = NOW(), company_id = $session_company_id, log_user_id = $session_user_id");
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
<hr>
|
||||
|
||||
<h4>Mesh Central Asset Integration</h4>
|
||||
|
||||
<div class="form-group">
|
||||
<label>MeshCentral URI & Port</label>
|
||||
<div class="input-group">
|
||||
|
|
@ -56,6 +58,29 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<h4>Client Portal SSO via Microsoft Azure AD</h4>
|
||||
<div class="form-group">
|
||||
<label>MS Azure OAuth App (Client) ID</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" name="azure_client_id" placeholder="e721e3b6-01d6-50e8-7f22-c84d951a52e7" value="<?php echo $config_azure_client_id; ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>MS Azure OAuth Secret</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-key"></i></span>
|
||||
</div>
|
||||
<input type="password" class="form-control" name="azure_client_secret" placeholder="Auto-generated from App Registration" value="<?php echo $config_azure_client_secret; ?>" autocomplete="new-password">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<button type="submit" name="edit_general_settings" class="btn btn-primary">Save</button>
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ if(isset($_GET['ticket_id'])){
|
|||
$ticket_subject = $row['ticket_subject'];
|
||||
$ticket_details = $row['ticket_details'];
|
||||
$ticket_priority = $row['ticket_priority'];
|
||||
$ticket_feedback = $row['ticket_feedback'];
|
||||
$ticket_status = $row['ticket_status'];
|
||||
$ticket_created_at = $row['ticket_created_at'];
|
||||
$ticket_date = date('Y-m-d',strtotime($ticket_created_at));
|
||||
|
|
@ -316,6 +317,7 @@ if(isset($_GET['ticket_id'])){
|
|||
</div>
|
||||
</h3>
|
||||
|
||||
<?php if($ticket_reply_type !== "Client") { ?>
|
||||
<div class="card-tools">
|
||||
<div class="dropdown dropleft">
|
||||
<button class="btn btn-tool" type="button" id="dropdownMenuButton" data-toggle="dropdown">
|
||||
|
|
@ -328,6 +330,8 @@ if(isset($_GET['ticket_id'])){
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
|
|
@ -429,6 +433,7 @@ if(isset($_GET['ticket_id'])){
|
|||
$ticket_closed_by_display = $row['user_name'];
|
||||
?>
|
||||
<div class="ml-1"><i class="fa fa-fw fa-user text-secondary mr-2 mb-2"></i>Closed by: <?php echo strtoupper($ticket_closed_by_display); ?></a></div>
|
||||
<div class="ml-1"><i class="fa fa-fw fa-comment-dots text-secondary mr-2 mb-2"></i>Feedback: <?php echo $ticket_feedback; ?></a></div>
|
||||
<?php } ?>
|
||||
<?php if(!empty($ticket_total_reply_time)){ ?>
|
||||
<div class="ml-1"><i class="far fa-fw fa-clock text-secondary mr-2 mb-2"></i>Total time worked: <?php echo $ticket_total_reply_time; ?></div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue