159 lines
3.7 KiB
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>
|