From 0cfc264c4b935bc4dd44ff2d80fabd84fe12bc27 Mon Sep 17 00:00:00 2001 From: ToolCTRL Date: Tue, 26 May 2026 14:36:59 +0200 Subject: [PATCH] =?UTF-8?q?GameJam:=20Hart-Deadline=20f=C3=BCr=20Einreichu?= =?UTF-8?q?ngen=20am=2027.05.2026=2022:00=20Berlin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit server.js: handleGamejamUpload lehnt nach UPLOAD_DEADLINE mit HTTP 410 und Klartext-Hinweis ab. gamejam.html: Formular wird nach Ablauf clientseitig gesperrt und ein roter Status zeigt den abgelaufenen Termin. Doppelschicht (Server + UI), Server ist verbindlich. Co-Authored-By: Claude Opus 4.7 (1M context) --- public/gamejam.html | 18 +++++++++++++++++- server.js | 10 ++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/public/gamejam.html b/public/gamejam.html index 265edaf..5335e8c 100644 --- a/public/gamejam.html +++ b/public/gamejam.html @@ -632,6 +632,10 @@ setInterval(renderHud, 1000); POST {API_BASE}/upload -> FormData { teilnehmer, game, file } */ const API_BASE = "/api/gamejam"; +/* Hart-Deadline für Einreichungen — danach ist die UI gesperrt und der Server lehnt ab. */ +const UPLOAD_DEADLINE = new Date("2026-05-27T22:00:00+02:00"); +function uploadsOpen() { return Date.now() < UPLOAD_DEADLINE.getTime(); } + const teamEl = document.getElementById("teamName"); const gameEl = document.getElementById("gameName"); const dz = document.getElementById("dropzone"); @@ -667,11 +671,23 @@ function pickFile(f) { refreshUploadBtn(); } function refreshUploadBtn() { - uploadBtn.disabled = !(API_BASE && chosenFile && teamEl.value.trim() && gameEl.value.trim()); + uploadBtn.disabled = !(uploadsOpen() && API_BASE && chosenFile && teamEl.value.trim() && gameEl.value.trim()); } teamEl.addEventListener("input", refreshUploadBtn); gameEl.addEventListener("input", refreshUploadBtn); +/* Wenn die Deadline überschritten ist: Formular sperren und Hinweis anzeigen. */ +if (!uploadsOpen()) { + teamEl.disabled = true; + gameEl.disabled = true; + fileInput.disabled = true; + dz.style.pointerEvents = "none"; + dz.style.opacity = "0.5"; + uploadBtn.textContent = "Einreichungen geschlossen"; + uploadBtn.disabled = true; + setStatus("Die Einreichungsfrist ist am 27.05.2026 um 22:00 Uhr abgelaufen.", "err"); +} + uploadBtn.addEventListener("click", async () => { if (!API_BASE || !chosenFile) return; uploadBtn.disabled = true; diff --git a/server.js b/server.js index 4241918..f855cdb 100644 --- a/server.js +++ b/server.js @@ -33,6 +33,9 @@ const GAMES_DIR = process.env.DATA_DIR ? path.join(DATA_DIR, "gamejam-games") : path.join(PUBLIC_DIR, "gamejam-games"); const MAX_UPLOAD = 5 * 1024 * 1024; /* 5 MB pro eingereichtem Spiel */ + +/* Hart-Deadline für GameJam-Uploads: 27.05.2026, 22:00 Europe/Berlin (CEST = UTC+2). */ +const UPLOAD_DEADLINE = new Date("2026-05-27T22:00:00+02:00"); const APP_REVISION = process.env.APP_REVISION || "local"; function envFlag(name, defaultValue) { @@ -345,6 +348,13 @@ function clamavPing() { /* ---------- GameJam: Spiel einreichen ---------- */ function handleGamejamUpload(req, res) { + /* Hart-Deadline durchsetzen — danach werden keine Einreichungen mehr angenommen. */ + if (Date.now() > UPLOAD_DEADLINE.getTime()) { + return sendJSON(res, 410, { + error: "Einreichungen sind seit dem 27.05.2026, 22:00 Uhr geschlossen." + }); + } + const ctype = req.headers["content-type"] || ""; const bM = ctype.match(/boundary=(?:"([^"]+)"|([^;]+))/i); if (!/multipart\/form-data/i.test(ctype) || !bM) {