Claim shared item views atomically and log guest audit IPs

This commit is contained in:
johnnyq
2026-07-27 20:58:37 -04:00
parent b555a300bc
commit 70d165e8bc
6 changed files with 194 additions and 12 deletions

View File

@@ -56,6 +56,12 @@ if (isset($_GET['id']) && isset($_GET['key'])) {
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']);
@@ -67,10 +73,6 @@ if (isset($_GET['id']) && isset($_GET['key'])) {
header('Content-Disposition: attachment; filename=' . $file_name);
readfile($file_path);
// Update file view count
$new_item_views = $item_views + 1;
mysqli_query($mysqli, "UPDATE shared_items SET item_views = $new_item_views WHERE item_id = $item_id");
//Logging
logAudit("Share", "View", "Downloaded shared file $file_name via link", $client_id);

View File

@@ -13,6 +13,10 @@ session_start();
require_once "../includes/inc_set_timezone.php"; // Must be included after session_start to work
// logAudit() reads these globals - without them guest audit rows have no IP
$session_ip = escapeSql(getIP());
$session_user_agent = escapeSql($_SERVER['HTTP_USER_AGENT']);
if (isset($_GET['accept_quote'], $_GET['url_key'])) {
$quote_id = intval($_GET['accept_quote']);

View File

@@ -128,6 +128,14 @@ if ($item_type == "Document") {
exit();
}
// Claim the view before any content is disclosed
if (!claimSharedItemView($item_id)) {
echo "<div class='alert alert-danger'>Item cannot be viewed at this time. Check with the person that sent you this link to ensure it is correct and has not expired.</div>";
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';
exit();
}
$doc_title = escapeHtml($doc_row['document_name']);
$doc_title_escaped = escapeSql($doc_row['document_name']);
$doc_content = $purifier->purify($doc_row['document_content']);
@@ -135,10 +143,6 @@ if ($item_type == "Document") {
echo "<h3>$doc_title</h3>";
echo "<div class='prettyContent'>$doc_content</div>";
// Update document view count
$new_item_views = $item_views + 1;
mysqli_query($mysqli, "UPDATE shared_items SET item_views = $new_item_views WHERE item_id = $item_id");
// Logging
$name = mysqli_real_escape_string($mysqli, $doc_title);
logAudit("Share", "View", "Viewed shared $item_type $doc_title_escaped via link", $client_id);
@@ -176,6 +180,14 @@ if ($item_type == "Document") {
exit();
}
// Claim the view before the credential is decrypted or rendered
if (!claimSharedItemView($item_id)) {
echo "<div class='alert alert-danger'>Item cannot be viewed at this time. Check with the person that sent you this link to ensure it is correct and has not expired.</div>";
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php';
exit();
}
$credential_id = intval($credential_row['credential_id']);
$credential_name = escapeHtml($credential_row['credential_name']);
$credential_uri = escapeHtml($credential_row['credential_uri']);
@@ -254,10 +266,6 @@ if ($item_type == "Document") {
<?php
// Update credential view count
$new_item_views = $item_views + 1;
mysqli_query($mysqli, "UPDATE shared_items SET item_views = $new_item_views WHERE item_id = $item_id");
// Logging
$name = escapeSql($credential_row['credential_name']);
logAudit("Share", "View", "Viewed shared $item_type $name via link", $client_id);

View File

@@ -14,6 +14,10 @@ $user_agent = escapeSql($_SERVER['HTTP_USER_AGENT']);
$os = escapeSql(getOS($user_agent));
$browser = escapeSql(getWebBrowser($user_agent));
// logAudit() reads these globals - without them guest audit rows have no IP
$session_ip = $ip;
$session_user_agent = $user_agent;
// Get Company Name
$sql = mysqli_query($mysqli, "SELECT company_name FROM companies WHERE company_id = 1");
$row = mysqli_fetch_assoc($sql);