diff --git a/index.php b/index.php new file mode 100644 index 0000000..95c7f93 --- /dev/null +++ b/index.php @@ -0,0 +1,169 @@ +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); +} catch(PDOException $e) { + http_response_code(500); + die(json_encode(array('error' => 'Database connection failed'))); +} + +// Clean expired entries +$pdo->exec("DELETE FROM pastes WHERE expires_at < " . time()); + +$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); +$method = $_SERVER['REQUEST_METHOD']; + +// Remove subdirectory from path if exists +$scriptDir = dirname($_SERVER['SCRIPT_NAME']); +if ($scriptDir !== '/' && strpos($path, $scriptDir) === 0) { + $path = substr($path, strlen($scriptDir)); +} +if (empty($path)) $path = '/'; + +// API Routes +if ($path === '/api/create' && $method === 'POST') { + handleCreate($pdo); + exit; +} + +if (preg_match('/^\/api\/get\/(.+)$/', $path, $matches) && $method === 'GET') { + handleGet($pdo, $matches[1]); + exit; +} + +// Serve static files +if ($path === '/' || $path === '/index.html') { + header('Content-Type: text/html; charset=utf-8'); + readfile(__DIR__ . '/index.html'); + exit; +} + +if ($path === '/style.css') { + header('Content-Type: text/css'); + readfile(__DIR__ . '/style.css'); + exit; +} + +if ($path === '/script.js') { + header('Content-Type: application/javascript'); + readfile(__DIR__ . '/script.js'); + exit; +} + +if ($path === '/favicon.svg') { + header('Content-Type: image/svg+xml'); + echo ''; + exit; +} + +http_response_code(404); +echo json_encode(array('error' => 'Not found')); + +function handleCreate($pdo) { + $input = json_decode(file_get_contents('php://input'), true); + + if (!$input) { + http_response_code(400); + echo json_encode(array('error' => 'Invalid JSON')); + return; + } + + $id = isset($input['id']) ? $input['id'] : ''; + $encryptedData = isset($input['encryptedData']) ? $input['encryptedData'] : null; + $expiresIn = min(intval(isset($input['expiresIn']) ? $input['expiresIn'] : 3600), 2592000); + $burnAfterRead = !empty($input['burnAfterRead']); + $hasPassword = !empty($input['hasPassword']); + + if (!preg_match('/^[a-f0-9]{32}$/', $id)) { + http_response_code(400); + echo json_encode(array('error' => 'Invalid ID format')); + return; + } + + if (!$encryptedData || !isset($encryptedData['iv']) || !isset($encryptedData['data'])) { + http_response_code(400); + echo json_encode(array('error' => 'Invalid encrypted data format')); + return; + } + + $data = json_encode(array('iv' => $encryptedData['iv'], 'data' => $encryptedData['data'])); + $expiresAt = time() + $expiresIn; + + try { + $stmt = $pdo->prepare("INSERT INTO pastes (id, data, created_at, expires_at, burn_after_read, has_password, views) VALUES (?, ?, ?, ?, ?, ?, 0)"); + $stmt->execute(array($id, $data, time() * 1000, $expiresAt, $burnAfterRead ? 1 : 0, $hasPassword ? 1 : 0)); + + echo json_encode(array( + 'success' => true, + 'id' => $id, + 'expiresIn' => $expiresIn, + 'hasPassword' => $hasPassword, + 'url' => 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . '/../#' . $id + )); + } catch(PDOException $e) { + http_response_code(500); + echo json_encode(array('error' => 'Failed to save paste: ' . $e->getMessage())); + } +} + +function handleGet($pdo, $id) { + if (!preg_match('/^[a-f0-9]{32}$/', $id)) { + http_response_code(400); + echo json_encode(array('error' => 'Invalid ID')); + return; + } + + try { + $stmt = $pdo->prepare("SELECT * FROM pastes WHERE id = ? AND expires_at > ?"); + $stmt->execute(array($id, time())); + $paste = $stmt->fetch(PDO::FETCH_ASSOC); + + if (!$paste) { + http_response_code(404); + echo json_encode(array('error' => 'Paste not found or expired')); + return; + } + + $data = json_decode($paste['data'], true); + + if ($paste['burn_after_read']) { + $delStmt = $pdo->prepare("DELETE FROM pastes WHERE id = ?"); + $delStmt->execute(array($id)); + } else { + $updStmt = $pdo->prepare("UPDATE pastes SET views = views + 1 WHERE id = ?"); + $updStmt->execute(array($id)); + } + + echo json_encode(array( + 'data' => $data, + 'burnAfterRead' => (bool)$paste['burn_after_read'], + 'hasPassword' => (bool)$paste['has_password'], + 'created' => intval($paste['created_at']) + )); + + } catch(PDOException $e) { + http_response_code(500); + echo json_encode(array('error' => 'Server error')); + } +}