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) {