require("dotenv").config(); const express = require("express"); const http = require("http"); const cookieParser = require("cookie-parser"); const mongoose = require("mongoose"); const { Server } = require("socket.io"); const connectDB = require("./configs/db"); const { env, validateServerConfig } = require("./configs/env"); const { registerSocketServer } = require("./socket/socketServer"); const { errorHandler, notFound } = require("./middleware/errorMiddleware"); const compression = require("compression"); validateServerConfig(); connectDB(); const app = express(); app.set("trust proxy", 1); // ======================================================== // 1. DYNAMIC CORS FORCE (SOLUSI SAPU JAGAT) // ======================================================== app.use((req, res, next) => { const origin = req.headers.origin; // Izinkan SEMUA origin (karena kita tidak pakai include credentials lagi, ini aman) res.setHeader("Access-Control-Allow-Origin", origin || "*"); res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS"); res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, Cookie, Cache-Control, Pragma, Expires"); if (req.method === "OPTIONS") { return res.status(200).send("OK"); } res.on('finish', () => { if (req.originalUrl !== "/api/health") { console.log(`[${new Date().toLocaleTimeString()}] ${req.method} ${req.originalUrl} | Status: ${res.statusCode}`); } }); next(); }); // ======================================================== // 2. MIDDLEWARE STANDAR // ======================================================== app.use(compression()); app.use(express.json({ limit: "50mb" })); app.use(express.urlencoded({ extended: true, limit: "50mb" })); app.use(cookieParser()); // --- Routes API --- app.get("/", (req, res) => res.json({ message: "API Server 7860 Active" })); app.use("/api/auth", require("./routes/authRoutes")); app.use("/api/admin", require("./routes/adminUserRoutes")); app.use("/api/faculty", require("./routes/facultyRoutes")); app.use("/api/documents", require("./routes/documentRoutes")); app.use("/api/media", require("./routes/mediaRoutes")); app.use("/api/achievements", require("./routes/achievementRoutes")); app.use("/api/announcements", require("./routes/announcementRoutes")); app.use("/api/admissions", require("./routes/admissionRoutes")); app.use("/api/about", require("./routes/aboutUsRoutes")); app.use("/api/site-content", require("./routes/siteContentRoutes")); app.use("/api/audit-trails", require("./routes/auditTrailRoutes")); app.use("/api/admin/errors", require("./routes/errorLogRoutes")); app.use(notFound); app.use(errorHandler); const PORT = 7860; const server = http.createServer(app); const io = new Server(server, { cors: { origin: true, credentials: true } }); registerSocketServer(io); server.listen(PORT, "0.0.0.0", () => { console.log(`-----------------------------------------`); console.log(`SERVER RUNNING ON PORT ${PORT}`); console.log(`DEMO READY: SEMUA DOMAIN VERCEL DIIZINKAN`); console.log(`-----------------------------------------`); });