/* ===================================================================== index.js — Haupteinstiegspunkt für DogFather Universe. Liefert die statische Website aus (../ ist der Ordner mit allen .html-Dateien) plus die Zugangsschranke (gate.js), 1:1 wie vorher der Cloudflare Worker (gate-worker.js). ===================================================================== */ import "dotenv/config"; import express from "express"; import cookieParser from "cookie-parser"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; import { gateMiddleware } from "./gate.js"; const __dirname = dirname(fileURLToPath(import.meta.url)); const SITE_DIR = join(__dirname, ".."); const PORT = Number(process.env.PORT || 4100); const app = express(); app.set("trust proxy", 1); app.disable("x-powered-by"); // verrät sonst unnötig den eingesetzten Technik-Stack /* Sicherheits-Header, ergänzt 05.08.2026. Vorher standen diese in der Datei `_headers` — die funktioniert aber NUR bei Cloudflare Pages/Netlify und wurde auf dem eigenen Server schlicht ignoriert, d.h. die Seite lief seit dem Umzug komplett ohne diese Schutzmaßnahmen (nachgeprüft an den Live-Antwortheadern). */ app.use((req, res, next) => { res.setHeader("X-Content-Type-Options", "nosniff"); res.setHeader("X-Frame-Options", "SAMEORIGIN"); res.setHeader("Referrer-Policy", "strict-origin-when-cross-origin"); res.setHeader("Permissions-Policy", "geolocation=(), microphone=(), camera=(), payment=()"); res.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains"); next(); }); app.use(cookieParser()); app.use(express.json({ limit: "1mb" })); app.use(gateMiddleware); app.use(express.static(SITE_DIR, { index: "index.html" })); app.use((req, res) => { res.status(404).sendFile(join(SITE_DIR, "404.html"), (err) => { if (err) res.status(404).send("Nicht gefunden."); }); }); /* Fehler-Handler (muss NACH allen Routen stehen), ergänzt 05.08.2026: antwortet mit einer schlichten Meldung statt einer Express-Standardseite mit komplettem Stacktrace und Dateipfaden. */ // eslint-disable-next-line no-unused-vars app.use((err, req, res, next) => { console.error(`[fehler] ${req.method} ${req.originalUrl}:`, err?.stack || err); if (res.headersSent) return; res.status(500).send("Es ist ein Fehler aufgetreten. Bitte später erneut versuchen."); }); /* Letztes Netz: Ein unbehandelter Fehler darf die Website nicht offline nehmen. */ process.on("unhandledRejection", (grund) => console.error("[unhandledRejection]", grund)); process.on("uncaughtException", (fehler) => console.error("[uncaughtException]", fehler?.stack || fehler)); app.listen(PORT, "127.0.0.1", () => { console.log(`DogFather Universe – Server läuft auf http://127.0.0.1:${PORT}`); });