"Missing token."]);
exit;
}
// Load share links from file
$shareFile = META_DIR . "share_links.json";
if (!file_exists($shareFile)) {
http_response_code(404);
echo json_encode(["error" => "Share link not found."]);
exit;
}
$shareLinks = json_decode(file_get_contents($shareFile), true);
if (!is_array($shareLinks) || !isset($shareLinks[$token])) {
http_response_code(404);
echo json_encode(["error" => "Share link not found."]);
exit;
}
$record = $shareLinks[$token];
// Check expiration.
if (time() > $record['expires']) {
http_response_code(403);
echo json_encode(["error" => "This link has expired."]);
exit;
}
// If a password is required and none is provided, show a password form.
if (!empty($record['password']) && empty($providedPass)) {
?>
Enter Password
This file is protected by a password.
"Invalid password."]);
exit;
}
}
// Build file path securely.
$folder = trim($record['folder'], "/\\ ");
$file = $record['file'];
$filePath = rtrim(UPLOAD_DIR, '/\\') . DIRECTORY_SEPARATOR;
if (!empty($folder) && strtolower($folder) !== 'root') {
$filePath .= $folder . DIRECTORY_SEPARATOR;
}
$filePath .= $file;
// Resolve the real path and ensure it's within the allowed directory.
$realFilePath = realpath($filePath);
$uploadDirReal = realpath(UPLOAD_DIR);
if ($realFilePath === false || strpos($realFilePath, $uploadDirReal) !== 0) {
http_response_code(404);
echo json_encode(["error" => "File not found."]);
exit;
}
if (!file_exists($realFilePath)) {
http_response_code(404);
echo json_encode(["error" => "File not found."]);
exit;
}
// Serve the file.
$mimeType = mime_content_type($realFilePath);
header("Content-Type: " . $mimeType);
// Set Content-Disposition based on file type.
$ext = strtolower(pathinfo($realFilePath, PATHINFO_EXTENSION));
if (in_array($ext, ['jpg','jpeg','png','gif','bmp','webp','svg','ico'])) {
header('Content-Disposition: inline; filename="' . basename($realFilePath) . '"');
} else {
header('Content-Disposition: attachment; filename="' . basename($realFilePath) . '"');
}
// Optionally disable caching for sensitive files.
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Pragma: no-cache");
readfile($realFilePath);
exit;
?>