aboutsummaryrefslogtreecommitdiffstats
path: root/src/app
diff options
context:
space:
mode:
Diffstat (limited to 'src/app')
-rw-r--r--src/app/Controllers/EditorController.php28
-rw-r--r--src/app/Models/Post.php7
2 files changed, 35 insertions, 0 deletions
diff --git a/src/app/Controllers/EditorController.php b/src/app/Controllers/EditorController.php
index c7dd9fc..c8cae0d 100644
--- a/src/app/Controllers/EditorController.php
+++ b/src/app/Controllers/EditorController.php
@@ -12,6 +12,13 @@ use App\Models\Post;
class EditorController
{
+ // Per-user and site-wide caps prevent disk exhaustion — even if someone
+ // creates multiple accounts, the total limit still applies.
+ // Each composited image is a 640×640 JPEG at quality 85, averaging ~65 KB.
+ // 50 posts/user ≈ 3.2 MB per user, 10 000 total ≈ 650 MB on disk.
+ private const MAX_POSTS_PER_USER = 50;
+ private const MAX_POSTS_TOTAL = 10000;
+
private Post $post;
public function __construct()
@@ -60,7 +67,28 @@ class EditorController
return;
}
+ if ($this->post->countByUserId($_SESSION['user_id']) >= self::MAX_POSTS_PER_USER) {
+ http_response_code(400);
+ echo json_encode(['error' => 'You have reached the maximum number of posts.']);
+ return;
+ }
+
+ if ($this->post->countAll() >= self::MAX_POSTS_TOTAL) {
+ http_response_code(400);
+ echo json_encode(['error' => 'The site has reached its storage limit.']);
+ return;
+ }
+
$imageData = $input['image_data'] ?? '';
+
+ // Reject oversized payloads before doing any processing — base64 adds ~33%
+ // overhead, so 10 MB base64 ≈ 7.5 MB image, which is more than enough
+ if (\strlen($imageData) > 10 * 1024 * 1024) {
+ http_response_code(400);
+ echo json_encode(['error' => 'Image too large.']);
+ return;
+ }
+
$overlayName = $input['overlay'] ?? '';
$overlayScale = (float) ($input['overlay_scale'] ?? 1.0);
diff --git a/src/app/Models/Post.php b/src/app/Models/Post.php
index 66c8c18..e82b0d9 100644
--- a/src/app/Models/Post.php
+++ b/src/app/Models/Post.php
@@ -42,6 +42,13 @@ class Post
return $stmt->fetchAll();
}
+ public function countByUserId(int $userId): int
+ {
+ $stmt = $this->pdo->prepare('SELECT COUNT(*) FROM posts WHERE user_id = :user_id');
+ $stmt->execute(['user_id' => $userId]);
+ return (int) $stmt->fetchColumn();
+ }
+
public function findAllPaginated(int $limit, int $offset): array
{
$stmt = $this->pdo->prepare(