mirror of
https://github.com/the1024club/the1024.club.git
synced 2026-01-24 12:20:19 +00:00
First code commit.
This commit is contained in:
237
index.php
Normal file
237
index.php
Normal file
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
|
||||
// Load dependencies
|
||||
require 'vendor/autoload.php';
|
||||
use ParagonIE\Sodium\CryptoSign;
|
||||
|
||||
// Enable or disable debugging/logging
|
||||
$debug = isset($_GET['debug']) ? (bool)$_GET['debug'] : true;
|
||||
if ($debug) {
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
} else {
|
||||
error_reporting(0);
|
||||
ini_set('display_errors', 0);
|
||||
}
|
||||
|
||||
// Database setup function
|
||||
function initializeDatabase($db) {
|
||||
$query = "
|
||||
CREATE TABLE IF NOT EXISTS storage (
|
||||
pubkey_hash CHAR(64) PRIMARY KEY,
|
||||
data TEXT NOT NULL,
|
||||
mime_type VARCHAR(50) NOT NULL,
|
||||
public_key BLOB NOT NULL
|
||||
)";
|
||||
$db->exec($query);
|
||||
|
||||
// Check if the 'public_key' column already exists; if not, add it.
|
||||
$columns = $db->query("PRAGMA table_info(storage)")->fetchAll(PDO::FETCH_ASSOC);
|
||||
$hasPublicKeyColumn = false;
|
||||
|
||||
foreach ($columns as $column) {
|
||||
if ($column['name'] === 'public_key') {
|
||||
$hasPublicKeyColumn = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$hasPublicKeyColumn) {
|
||||
$db->exec("ALTER TABLE storage ADD COLUMN public_key BLOB NOT NULL");
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize SQLite and auto-create the database and table if they don't exist
|
||||
$db = new PDO('sqlite:/home/retrodig/1024clubdb/storage.db');
|
||||
initializeDatabase($db);
|
||||
|
||||
// Helper function to respond with JSON
|
||||
function respond($status, $message, $data = []) {
|
||||
http_response_code($status);
|
||||
echo json_encode(['message' => $message, 'data' => $data]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Enhance Base64 decoding to handle both raw and URL-safe inputs
|
||||
function safeBase64Decode($input) {
|
||||
// First, attempt a direct Base64 decode
|
||||
$decoded = base64_decode($input, true);
|
||||
if ($decoded !== false && strlen($decoded) === 32) {
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
// If the direct decode fails, attempt a URL-safe decode
|
||||
$urlSafeInput = str_replace(['-', '_'], ['+', '/'], $input);
|
||||
return base64_decode($urlSafeInput, true);
|
||||
}
|
||||
|
||||
// Handle Base64 encoding safely
|
||||
function safeBase64Encode($input) {
|
||||
return str_replace(['+', '/'], ['-', '_'], base64_encode($input));
|
||||
}
|
||||
|
||||
// Check if 'action' is set in the query parameters before proceeding
|
||||
if (isset($_GET['action'])) {
|
||||
// Create or get storage space based on pubkey hash
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_GET['action'] === 'create') {
|
||||
$pubkey = $_POST['pubkey'] ?? null;
|
||||
|
||||
if (!$pubkey) {
|
||||
respond(400, "Missing public key");
|
||||
}
|
||||
|
||||
// Decode the public key, try both raw and URL-safe Base64 decodings
|
||||
$decodedPubkey = safeBase64Decode($pubkey);
|
||||
if ($decodedPubkey === false || strlen($decodedPubkey) !== 32) {
|
||||
respond(400, "Invalid public key");
|
||||
}
|
||||
|
||||
$pubkey_hash = bin2hex(sodium_crypto_generichash($decodedPubkey));
|
||||
|
||||
$stmt = $db->prepare("SELECT * FROM storage WHERE pubkey_hash = :pubkey_hash");
|
||||
$stmt->execute([':pubkey_hash' => $pubkey_hash]);
|
||||
$existing = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($existing) {
|
||||
respond(200, "Space already exists", ['pubkey_hash' => $pubkey_hash]);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare("INSERT INTO storage (pubkey_hash, data, mime_type, public_key) VALUES (:pubkey_hash, '', 'text/plain', :public_key)");
|
||||
$stmt->execute([':pubkey_hash' => $pubkey_hash, ':public_key' => $decodedPubkey]);
|
||||
|
||||
respond(201, "Space created", ['pubkey_hash' => $pubkey_hash]);
|
||||
}
|
||||
|
||||
// Retrieve stored data using the public key or public key hash
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET' && $_GET['action'] === 'retrieve') {
|
||||
$pubkey = $_GET['pubkey'] ?? null;
|
||||
$pubkey_hash = $_GET['pubkey_hash'] ?? null;
|
||||
|
||||
if ($pubkey) {
|
||||
// Replace spaces with '+' to account for unencoded URLs
|
||||
$pubkey = str_replace(' ', '+', $pubkey);
|
||||
|
||||
// Attempt to decode public key (try both standard and URL-safe Base64)
|
||||
$decodedPubkey = safeBase64Decode($pubkey);
|
||||
|
||||
if ($decodedPubkey === false || strlen($decodedPubkey) !== 32) {
|
||||
respond(400, "Failed to decode public key: " . htmlspecialchars($pubkey));
|
||||
}
|
||||
|
||||
// Hash the decoded public key
|
||||
$pubkey_hash = bin2hex(sodium_crypto_generichash($decodedPubkey));
|
||||
|
||||
} elseif ($pubkey_hash) {
|
||||
// Validate the provided public key hash (must be 64 characters long, hex format)
|
||||
if (!ctype_xdigit($pubkey_hash) || strlen($pubkey_hash) !== 64) {
|
||||
respond(400, "Invalid public key hash: " . htmlspecialchars($pubkey_hash));
|
||||
}
|
||||
|
||||
} else {
|
||||
respond(400, "Missing public key or public key hash");
|
||||
}
|
||||
|
||||
// Retrieve data by public key hash
|
||||
$stmt = $db->prepare("SELECT * FROM storage WHERE pubkey_hash = :pubkey_hash");
|
||||
$stmt->execute([':pubkey_hash' => $pubkey_hash]);
|
||||
$result = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$result) {
|
||||
respond(404, "No data found for this public key");
|
||||
}
|
||||
|
||||
// Set the correct MIME type and output the data without encoding
|
||||
header('Content-Type: ' . $result['mime_type']);
|
||||
echo $result['data'];
|
||||
exit;
|
||||
}
|
||||
|
||||
// Update stored data with a signed transaction
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'PUT' && $_GET['action'] === 'update') {
|
||||
parse_str(file_get_contents("php://input"), $_PUT);
|
||||
|
||||
$pubkey = $_PUT['pubkey'] ?? null;
|
||||
$signature = $_PUT['signature'] ?? null;
|
||||
$data = $_PUT['data'] ?? null;
|
||||
$mime_type = $_PUT['mime_type'] ?? 'text/plain';
|
||||
|
||||
if (!$pubkey || !$signature || !$data) {
|
||||
respond(400, "Invalid input: missing public key, signature, or data");
|
||||
}
|
||||
|
||||
// Decode base64-encoded public key and signature using safe base64 decoding
|
||||
$decodedPubkey = safeBase64Decode($pubkey);
|
||||
$decodedSignature = safeBase64Decode($signature);
|
||||
|
||||
if ($decodedPubkey === false || strlen($decodedPubkey) !== 32) {
|
||||
respond(400, "Invalid public key");
|
||||
}
|
||||
|
||||
if ($decodedSignature === false) {
|
||||
respond(400, "Invalid signature: not valid base64");
|
||||
}
|
||||
|
||||
$pubkey_hash = bin2hex(sodium_crypto_generichash($decodedPubkey));
|
||||
|
||||
if (!sodium_crypto_sign_verify_detached($decodedSignature, $data, $decodedPubkey)) {
|
||||
respond(400, "Invalid signature");
|
||||
}
|
||||
|
||||
$stmt = $db->prepare("SELECT * FROM storage WHERE pubkey_hash = :pubkey_hash");
|
||||
$stmt->execute([':pubkey_hash' => $pubkey_hash]);
|
||||
if (!$stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
respond(404, "Space not found");
|
||||
}
|
||||
|
||||
if (strlen($data) > 1024) {
|
||||
respond(400, "Data exceeds 1k size limit");
|
||||
}
|
||||
|
||||
$stmt = $db->prepare("UPDATE storage SET data = :data, mime_type = :mime_type WHERE pubkey_hash = :pubkey_hash");
|
||||
$stmt->execute([':data' => $data, ':mime_type' => $mime_type, ':pubkey_hash' => $pubkey_hash]);
|
||||
|
||||
respond(200, "Storage updated");
|
||||
}
|
||||
|
||||
// Handle deletion (not in spec, but helpful)
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'DELETE' && $_GET['action'] === 'delete') {
|
||||
$pubkey = $_POST['pubkey'] ?? null;
|
||||
$signature = $_POST['signature'] ?? null;
|
||||
|
||||
if (!$pubkey || !$signature) {
|
||||
respond(400, "Invalid input: missing public key or signature");
|
||||
}
|
||||
|
||||
// Decode base64-encoded public key and signature using safe base64 decoding
|
||||
$decodedPubkey = safeBase64Decode($pubkey);
|
||||
$decodedSignature = safeBase64Decode($signature);
|
||||
|
||||
if ($decodedPubkey === false || strlen($decodedPubkey) !== 32) {
|
||||
respond(400, "Invalid public key");
|
||||
}
|
||||
|
||||
if ($decodedSignature === false) {
|
||||
respond(400, "Invalid signature: not valid base64");
|
||||
}
|
||||
|
||||
$pubkey_hash = bin2hex(sodium_crypto_generichash($decodedPubkey));
|
||||
|
||||
if (!CryptoSign::verify_detached($decodedSignature, $pubkey_hash, $decodedPubkey)) {
|
||||
respond(400, "Invalid signature");
|
||||
}
|
||||
|
||||
$stmt = $db->prepare("DELETE FROM storage WHERE pubkey_hash = :pubkey_hash");
|
||||
$stmt->execute([':pubkey_hash' => $pubkey_hash]);
|
||||
|
||||
respond(200, "Storage deleted");
|
||||
}
|
||||
} else {
|
||||
// If no action is specified, show the contents of main.php
|
||||
if (file_exists('main.php')) {
|
||||
include 'main.php';
|
||||
} else {
|
||||
respond(400, "No action specified and main.php not found");
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user