Initial commit
This commit is contained in:
commit
f702886c45
6 files changed
+279
No files matched your search
@@ -0,0 +1,60 @@
|
|||||||
|
-- phpMyAdmin SQL Dump
|
||||||
|
-- version 5.2.2
|
||||||
|
-- https://www.phpmyadmin.net/
|
||||||
|
--
|
||||||
|
-- Host: 127.0.0.1:3306
|
||||||
|
-- Generation Time: Mar 08, 2025 at 06:43 AM
|
||||||
|
-- Server version: 11.4.3-MariaDB-1
|
||||||
|
-- PHP Version: 8.3.11
|
||||||
|
|
||||||
|
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
||||||
|
START TRANSACTION;
|
||||||
|
SET time_zone = "+00:00";
|
||||||
|
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||||
|
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||||
|
/*!40101 SET NAMES utf8mb4 */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Database: `nameacolor`
|
||||||
|
--
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `colors`
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE `colors` (
|
||||||
|
`id` int(11) NOT NULL,
|
||||||
|
`name` text NOT NULL,
|
||||||
|
`color` char(6) NOT NULL,
|
||||||
|
`timestamp` int(11) NOT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Indexes for dumped tables
|
||||||
|
--
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Indexes for table `colors`
|
||||||
|
--
|
||||||
|
ALTER TABLE `colors`
|
||||||
|
ADD PRIMARY KEY (`id`);
|
||||||
|
|
||||||
|
--
|
||||||
|
-- AUTO_INCREMENT for dumped tables
|
||||||
|
--
|
||||||
|
|
||||||
|
--
|
||||||
|
-- AUTO_INCREMENT for table `colors`
|
||||||
|
--
|
||||||
|
ALTER TABLE `colors`
|
||||||
|
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||||
|
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<?php
|
||||||
|
$sitekey = "";
|
||||||
|
$secretkey = "";
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
$dbusername = "";
|
||||||
|
$dbpass = "";
|
||||||
|
$dbname = "";
|
||||||
|
$dbhost = "";
|
||||||
|
$dbport = "";
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
function connectToDatabase() {
|
||||||
|
include __DIR__ . "/../config/connection.php";
|
||||||
|
try {
|
||||||
|
$dsn = "mysql:host=$dbhost;dbname=$dbname;port=$dbport";
|
||||||
|
$options = [
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
|
];
|
||||||
|
$conn = new PDO($dsn, $dbusername, $dbpass, $options);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
die("Failed to connect to database: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
return $conn;
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
include __DIR__ . "/config/captcha.php";
|
||||||
|
|
||||||
|
include __DIR__ . "/incl/db.php";
|
||||||
|
|
||||||
|
$conn = connectToDatabase();
|
||||||
|
|
||||||
|
$stmt = $conn->prepare("SELECT * FROM colors");
|
||||||
|
$stmt->execute();
|
||||||
|
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
usort($result, function($a, $b) {
|
||||||
|
return strtotime($b['timestamp']) - strtotime($a['timestamp']);
|
||||||
|
});
|
||||||
|
|
||||||
|
$lastInsertId = $_GET['highlight'] ?? null;
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Name A Color</title>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
|
||||||
|
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: "Lexend", sans-serif;
|
||||||
|
background-color: #121212;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.named-color {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 10px;
|
||||||
|
background-color: #1e1e1e;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
width: 128px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.named-color.highlight {
|
||||||
|
border: 2px solid #006eff
|
||||||
|
}
|
||||||
|
|
||||||
|
.used-text {
|
||||||
|
display: none;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const usedColors = <?= json_encode(array_column($result, 'color')) ?>;
|
||||||
|
const colorInput = document.querySelector('.color-picker');
|
||||||
|
const element = document.querySelector('.used-text');
|
||||||
|
const submit = document.querySelector('.submit-button');
|
||||||
|
let captchaComplete = false;
|
||||||
|
|
||||||
|
colorInput.value = '#<?= bin2hex(random_bytes(3)) ?>';
|
||||||
|
|
||||||
|
const checkColor = () => {
|
||||||
|
if (usedColors.includes(colorInput.value.substr(1))) {
|
||||||
|
element.style.display = 'block';
|
||||||
|
submit.disabled = true;
|
||||||
|
} else {
|
||||||
|
element.style.display = 'none';
|
||||||
|
if (captchaComplete) {
|
||||||
|
submit.disabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
turnstile.ready(function () {
|
||||||
|
turnstile.render(".cf-turnstile", {
|
||||||
|
sitekey: "<?= $sitekey ?>",
|
||||||
|
callback: function (token) {
|
||||||
|
captchaComplete = true;
|
||||||
|
submit.disabled = false;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
colorInput.addEventListener('input', checkColor);
|
||||||
|
checkColor();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Name A Color!</h1>
|
||||||
|
<hr>
|
||||||
|
<h2>Name your own color!</h2>
|
||||||
|
<form action="upload.php" method="post">
|
||||||
|
<p class="used-text">This color has already been named!</p>
|
||||||
|
<label for="color">Color:</label>
|
||||||
|
<input type="color" id="color" name="color" class="color-picker" required>
|
||||||
|
<label for="name">Name:</label>
|
||||||
|
<input type="text" id="name" name="name" maxlength="50" required>
|
||||||
|
<button type="submit" class="submit-button" disabled>Name it!</button>
|
||||||
|
<div class="cf-turnstile"></div>
|
||||||
|
</form>
|
||||||
|
<hr>
|
||||||
|
<h2>Colors that were named</h2>
|
||||||
|
<?php
|
||||||
|
foreach ($result as $row) {
|
||||||
|
echo "<div class=\"named-color" . ($lastInsertId != null && $lastInsertId == $row['id'] ? " highlight" : "") . "\">";
|
||||||
|
echo "<div style=\"width: 128px; height: 128px; background: #" . $row['color'] . ";\"></div>";
|
||||||
|
echo "<p>" . htmlspecialchars(base64_decode($row['name'])) . " • #". $row["color"] ."</p>";
|
||||||
|
echo "</div>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
include __DIR__ . "/config/captcha.php";
|
||||||
|
include __DIR__ . "/incl/db.php";
|
||||||
|
|
||||||
|
$time = time();
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
|
||||||
|
$ip = $_SERVER["HTTP_CF_CONNECTING_IP"];
|
||||||
|
$token = $_POST['cf-turnstile-response'] ?? '';
|
||||||
|
$url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'secret' => $secretkey,
|
||||||
|
'response' => $token,
|
||||||
|
'remoteip' => $ip,
|
||||||
|
];
|
||||||
|
|
||||||
|
$ch = curl_init($url);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch, CURLOPT_POST, true);
|
||||||
|
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
|
||||||
|
|
||||||
|
$result = curl_exec($ch);
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
if ($result !== false) {
|
||||||
|
$outcome = json_decode($result, true);
|
||||||
|
|
||||||
|
if (!isset($outcome['success']) || !$outcome['success']) {
|
||||||
|
echo "Invalid Captcha";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "Couldn't validate Captcha";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$conn = connectToDatabase();
|
||||||
|
|
||||||
|
$color = $_POST['color'];
|
||||||
|
$name = base64_encode($_POST['name'] ?? '');
|
||||||
|
|
||||||
|
$color = ltrim($color, '#');
|
||||||
|
if (!preg_match('/^[a-f0-9]{6}$/i', $color)) {
|
||||||
|
echo "Invalid color";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen($name) < 3) {
|
||||||
|
echo "Name too short";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen($name) > 50) {
|
||||||
|
echo "Name too long";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $conn->prepare("SELECT name FROM colors WHERE color = :color");
|
||||||
|
$stmt->bindParam(':color', $color);
|
||||||
|
$stmt->execute();
|
||||||
|
|
||||||
|
if ($stmt->rowCount() > 0) {
|
||||||
|
echo "Color already taken";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $conn->prepare("INSERT INTO colors (color, name, timestamp) VALUES (:color, :name, :time)");
|
||||||
|
$stmt->bindParam(':color', $color);
|
||||||
|
$stmt->bindParam(':name', $name);
|
||||||
|
$stmt->bindParam(':time', $time);
|
||||||
|
$stmt->execute();
|
||||||
|
$lastInsertId = $conn->lastInsertId();
|
||||||
|
header("Location: /?highlight=$lastInsertId");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
header("Location: /");
|
||||||
Reference in new issue
Block a user