devweb/index.php

159 lines
3.7 KiB
PHP

<?php
session_start();
/* ================= CONFIG ================= */
$ADMIN_USER = "root";
$ADMIN_PASS = "hahahaha";
$FLAG = "{CFM1:hahahaha}";
$POSTS_FILE = __DIR__ . "/data/posts.json";
$RATE_FILE = __DIR__ . "/data/rate.json";
$UPLOAD_DIR = __DIR__ . "/uploads/";
if (!file_exists($POSTS_FILE)) file_put_contents($POSTS_FILE, "[]");
if (!file_exists($RATE_FILE)) file_put_contents($RATE_FILE, "{}");
/* ================= ROUTING ================= */
$page = $_GET['page'] ?? 'forum';
$ip = $_SERVER['REMOTE_ADDR'];
/* ================= LOGIN ================= */
if (isset($_POST['login'])) {
if ($_POST['user'] === $ADMIN_USER && $_POST['pass'] === $ADMIN_PASS) {
$_SESSION['admin'] = true;
}
}
/* ================= LOGOUT ================= */
if ($page === 'logout') {
session_destroy();
header("Location: index.php");
exit;
}
/* ================= POST ================= */
if (isset($_POST['submit_post'])) {
// Rate limit 1 post / minute
$rates = json_decode(file_get_contents($RATE_FILE), true);
if (isset($rates[$ip]) && time() - $rates[$ip] < 60) {
die("Rate limit: wait 1 minute.");
}
$imageName = null;
if (!empty($_FILES['image']['name'])) {
if ($_FILES['image']['size'] > 2 * 1024 * 1024) {
die("Image too large");
}
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $_FILES['image']['tmp_name']);
finfo_close($finfo);
if (!in_array($mime, ['image/png', 'image/jpeg'])) {
die("Only PNG or JPEG allowed");
}
$ext = pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION);
$imageName = uniqid() . "." . $ext;
move_uploaded_file($_FILES['image']['tmp_name'], $UPLOAD_DIR . $imageName);
}
$posts = json_decode(file_get_contents($POSTS_FILE), true);
$posts[] = [
"text" => htmlspecialchars($_POST['comment']),
"image" => $imageName,
"ip" => $ip,
"time" => time()
];
file_put_contents($POSTS_FILE, json_encode($posts));
$rates[$ip] = time();
file_put_contents($RATE_FILE, json_encode($rates));
header("Location: index.php");
exit;
}
/* ================= HTML ================= */
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Mini Forum DevWeb</title>
<style>
body { font-family: Arial; width: 800px; margin: auto; }
nav a { margin-right: 15px; }
.post { border: 1px solid #ccc; padding: 10px; margin-top: 10px; }
img { max-width: 300px; }
</style>
</head>
<body>
<nav>
<a href="index.php">Forum</a>
<a href="index.php?page=login">Login</a>
<a href="index.php?page=flag">Flag</a>
<a href="index.php?page=logout">Logout</a>
</nav>
<hr>
<?php if ($page === 'login'): ?>
<h2>Login admin</h2>
<form method="post">
User: <input name="user"><br>
Pass: <input type="password" name="pass"><br>
<button name="login">Login</button>
</form>
<?php elseif ($page === 'flag'): ?>
<?php if (!isset($_SESSION['admin'])): ?>
<p>Access denied</p>
<?php else: ?>
<h2>Flag DevWeb</h2>
<p><?= $FLAG ?></p>
<?php endif; ?>
<?php else: ?>
<h2>Post a comment</h2>
<form method="post" enctype="multipart/form-data">
<textarea name="comment" required></textarea><br>
<input type="file" name="image"><br>
<button name="submit_post">Post</button>
</form>
<h2>Posts</h2>
<?php
$posts = json_decode(file_get_contents($POSTS_FILE), true);
usort($posts, fn($a, $b) => $b['time'] - $a['time']);
foreach ($posts as $p):
?>
<div class="post">
<p><?= $p['text'] ?></p>
<p><b>IP:</b> <?= $p['ip'] ?></p>
<?php if ($p['image']): ?>
<img src="uploads/<?= $p['image'] ?>">
<?php endif; ?>
</div>
<?php endforeach; ?>
<?php endif; ?>
</body>
</html>