diff --git a/agent/credentials.php b/agent/credentials.php index 1282292a..701b2119 100644 --- a/agent/credentials.php +++ b/agent/credentials.php @@ -392,7 +392,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); "SELECT * FROM shared_items WHERE item_client_id = $client_id AND item_active = 1 - AND item_views != item_view_limit + AND (COALESCE(item_view_limit, 0) = 0 OR item_views < item_view_limit) AND item_expire_at > NOW() AND item_type = 'Credential' AND item_related_id = $credential_id diff --git a/agent/files.php b/agent/files.php index a8fffa2b..9aabb6a9 100644 --- a/agent/files.php +++ b/agent/files.php @@ -734,7 +734,7 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num']) "SELECT * FROM shared_items WHERE item_client_id = $client_id AND item_active = 1 - AND item_views != item_view_limit + AND (COALESCE(item_view_limit, 0) = 0 OR item_views < item_view_limit) AND item_expire_at > NOW() AND item_type = 'File' AND item_related_id = $file_id @@ -846,7 +846,7 @@ $num_root_items = intval($row_root_files['num']) + intval($row_root_docs['num']) "SELECT * FROM shared_items WHERE item_client_id = $client_id AND item_active = 1 - AND item_views != item_view_limit + AND (COALESCE(item_view_limit, 0) = 0 OR item_views < item_view_limit) AND item_expire_at > NOW() AND item_type = 'Document' AND item_related_id = $document_id diff --git a/guest/guest_download_file.php b/guest/guest_download_file.php index c6cd12b0..a0e21f7f 100644 --- a/guest/guest_download_file.php +++ b/guest/guest_download_file.php @@ -56,17 +56,22 @@ if (isset($_GET['id']) && isset($_GET['key'])) { exit("Item cannot be viewed at this time (No file, may have been deleted)."); } + $file_name = escapeSql($file_row['file_name']); + $file_reference_name = escapeSql($file_row['file_reference_name']); + $client_id = intval($file_row['file_client_id']); + $file_path = "../uploads/clients/$client_id/$file_reference_name"; + + // Don't burn a view on a file that is missing from disk + if (!is_readable($file_path)) { + exit("Item cannot be viewed at this time (No file, may have been deleted)."); + } + // Claim the view before the file is served. The checks above stay as a // fast path for messaging - this UPDATE is what enforces the limit. if (!claimSharedItemView($item_id)) { exit("Item cannot be viewed at this time (view limit exceeded)."); } - $file_name = escapeSql($file_row['file_name']); - $file_reference_name = escapeSql($file_row['file_reference_name']); - $client_id = intval($file_row['file_client_id']); - $file_path = "../uploads/clients/$client_id/$file_reference_name"; - // Display file as download $mime_type = mime_content_type($file_path); header('Content-type: '.$mime_type); @@ -74,6 +79,6 @@ if (isset($_GET['id']) && isset($_GET['key'])) { readfile($file_path); //Logging - logAudit("Share", "View", "Downloaded shared file $file_name via link", $client_id); + logAudit("Share", "View", "Downloaded shared file $file_name via link", $client_id, $item_id); } diff --git a/guest/guest_post.php b/guest/guest_post.php index 6ab945d7..52c854be 100644 --- a/guest/guest_post.php +++ b/guest/guest_post.php @@ -32,7 +32,15 @@ if (isset($_GET['accept_quote'], $_GET['url_key'])) { $client_name = escapeSql($row['client_name']); $client_id = intval($row['client_id']); - mysqli_query($mysqli, "UPDATE quotes SET quote_status = 'Accepted' WHERE quote_id = $quote_id"); + // Claim the response - only a quote still awaiting one can be accepted, + // and only the first request through wins + mysqli_query($mysqli, "UPDATE quotes SET quote_status = 'Accepted' WHERE quote_id = $quote_id AND quote_status IN ('Sent', 'Viewed')"); + + if (mysqli_affected_rows($mysqli) !== 1) { + flashAlert("This quote is no longer awaiting a response", 'error'); + redirect(); + } + mysqli_query($mysqli, "INSERT INTO history SET history_status = 'Accepted', history_description = 'Client accepted Quote!', history_quote_id = $quote_id"); // Notification @@ -97,7 +105,15 @@ if (isset($_GET['decline_quote'], $_GET['url_key'])) { $client_name = escapeSql($row['client_name']); $client_id = intval($row['client_id']); - mysqli_query($mysqli, "UPDATE quotes SET quote_status = 'Declined' WHERE quote_id = $quote_id"); + // Claim the response - only a quote still awaiting one can be declined, + // and only the first request through wins + mysqli_query($mysqli, "UPDATE quotes SET quote_status = 'Declined' WHERE quote_id = $quote_id AND quote_status IN ('Sent', 'Viewed')"); + + if (mysqli_affected_rows($mysqli) !== 1) { + flashAlert("This quote is no longer awaiting a response", 'error'); + redirect(); + } + mysqli_query($mysqli, "INSERT INTO history SET history_status = 'Declined', history_description = 'Client declined Quote!', history_quote_id = $quote_id"); // Notification diff --git a/guest/guest_view_item.php b/guest/guest_view_item.php index 68f87fc4..f79a0737 100644 --- a/guest/guest_view_item.php +++ b/guest/guest_view_item.php @@ -145,7 +145,7 @@ if ($item_type == "Document") { // Logging $name = mysqli_real_escape_string($mysqli, $doc_title); - logAudit("Share", "View", "Viewed shared $item_type $doc_title_escaped via link", $client_id); + logAudit("Share", "View", "Viewed shared $item_type $doc_title_escaped via link", $client_id, $item_id); } elseif ($item_type == "File") { @@ -268,7 +268,7 @@ if ($item_type == "Document") { // Logging $name = escapeSql($credential_row['credential_name']); - logAudit("Share", "View", "Viewed shared $item_type $name via link", $client_id); + logAudit("Share", "View", "Viewed shared $item_type $name via link", $client_id, $item_id); }