Allow contacts to upload attachments when adding ticket replies in portal

- Adds the ability for contacts to add file attachments when posting a ticket reply
- Enhancements to checkFileUpload(): Adjust file reference name generation & bad extension handling
This commit is contained in:
Marcus Hill 2023-10-21 15:24:15 +01:00
parent 7aadad3597
commit 218cdcdc4c
3 changed files with 52 additions and 6 deletions

View File

@ -628,12 +628,14 @@ function checkFileUpload($file, $allowed_extensions) {
// Check a file is actually attached/uploaded
if ($tmp === '') {
return "No file was uploaded.";
// No file uploaded
return false;
}
// Check the extension is allowed
if (!in_array($extension, $allowed_extensions)) {
return "File extension not allowed.";
// Extension not allowed
return false;
}
// Check the size is under 500 MB
@ -649,7 +651,7 @@ function checkFileUpload($file, $allowed_extensions) {
$hashedContent = hash('sha256', $fileContent);
// Generate a secure filename using the hashed content
$secureFilename = $hashedContent . '.' . $extension;
$secureFilename = $hashedContent . randomString(2) . '.' . $extension;
return $secureFilename;
}

View File

@ -77,11 +77,51 @@ if (isset($_POST['add_ticket_comment'])) {
// Add the comment
mysqli_query($mysqli, "INSERT INTO ticket_replies SET ticket_reply = '$comment', ticket_reply_type = 'Client', ticket_reply_by = $session_contact_id, ticket_reply_ticket_id = $ticket_id");
$ticket_reply_id = mysqli_insert_id($mysqli);
// Update Ticket Last Response Field & set ticket to open as client has replied
mysqli_query($mysqli, "UPDATE tickets SET ticket_status = 'Open' WHERE ticket_id = $ticket_id AND ticket_client_id = $session_client_id LIMIT 1");
// Redirect
// Store any attached any files
if (!empty($_FILES)) {
// Define & create directories, as required
mkdirMissing('../uploads/tickets/');
$upload_file_dir = "../uploads/tickets/" . $ticket_id . "/";
mkdirMissing($upload_file_dir);
for ($i = 0; $i < count($_FILES['file']['name']); $i++) {
// Extract file details for this iteration
$single_file = [
'name' => $_FILES['file']['name'][$i],
'type' => $_FILES['file']['type'][$i],
'tmp_name' => $_FILES['file']['tmp_name'][$i],
'error' => $_FILES['file']['error'][$i],
'size' => $_FILES['file']['size'][$i]
];
if ($ticket_attachment_ref_name = checkFileUpload($single_file, array('jpg', 'jpeg', 'gif', 'png', 'webp', 'pdf', 'txt', 'md', 'doc', 'docx', 'odt', 'csv', 'xls', 'xlsx', 'ods', 'pptx', 'odp', 'zip', 'tar', 'gz', 'xml', 'msg', 'json', 'wav', 'mp3', 'ogg', 'mov', 'mp4', 'av1', 'ovpn'))) {
$file_tmp_path = $_FILES['file']['tmp_name'][$i];
$file_name = sanitizeInput($_FILES['file']['name'][$i]);
$extarr = explode('.', $_FILES['file']['name'][$i]);
$file_extension = sanitizeInput(strtolower(end($extarr)));
// Define destination file path
$dest_path = $upload_file_dir . $ticket_attachment_ref_name;
move_uploaded_file($file_tmp_path, $dest_path);
mysqli_query($mysqli, "INSERT INTO ticket_attachments SET ticket_attachment_name = '$file_name', ticket_attachment_reference_name = '$ticket_attachment_ref_name', ticket_attachment_reply_id = $ticket_reply_id, ticket_attachment_ticket_id = $ticket_id");
}
}
}
// Redirect back to original page
header("Location: " . $_SERVER["HTTP_REFERER"]);
} else {
// The client does not have access to this ticket
header("Location: portal_post.php?logout");

View File

@ -6,7 +6,6 @@
require_once "inc_portal.php";
//Initialize the HTML Purifier to prevent XSS
require "../plugins/htmlpurifier/HTMLPurifier.standalone.php";
@ -14,6 +13,8 @@ $purifier_config = HTMLPurifier_Config::createDefault();
$purifier_config->set('URI.AllowedSchemes', ['data' => true, 'src' => true, 'http' => true, 'https' => true]);
$purifier = new HTMLPurifier($purifier_config);
$allowed_extensions = array('jpg', 'jpeg', 'gif', 'png', 'webp', 'pdf', 'txt', 'md', 'doc', 'docx', 'csv', 'xls', 'xlsx', 'xlsm', 'zip', 'tar', 'gz');
if (isset($_GET['id']) && intval($_GET['id'])) {
$ticket_id = intval($_GET['id']);
@ -75,11 +76,14 @@ if (isset($_GET['id']) && intval($_GET['id'])) {
<?php if ($ticket_status !== "Closed") { ?>
<form action="portal_post.php" method="post">
<form action="portal_post.php" enctype="multipart/form-data" method="post">
<input type="hidden" name="ticket_id" value="<?php echo $ticket_id ?>">
<div class="form-group">
<textarea class="form-control tinymce" name="comment" placeholder="Add comments.."></textarea>
</div>
<div class="form-group">
<input type="file" class="form-control-file" name="file[]" multiple id="fileInput" accept=".jpg, .jpeg, .gif, .png, .webp, .pdf, .txt, .md, .doc, .docx, .odt, .csv, .xls, .xlsx, .ods, .pptx, .odp, .zip, .tar, .gz, .xml, .msg, .json, .wav, .mp3, .ogg, .mov, .mp4, .av1, .ovpn">
</div>
<button type="submit" class="btn btn-primary" name="add_ticket_comment">Reply</button>
</form>