import dotenv from "dotenv"; dotenv.config(); import express from "express"; import cors from "cors"; import helmet from "helmet"; import fs from "fs"; import path from "path"; import { fileURLToPath } from "url"; process.on("unhandledRejection", (err) => { console.error("[process] Unhandled rejection:", err); }); process.on("uncaughtException", (err) => { console.error("[process] Uncaught exception:", err); }); import { corsConfig } from "./middleware/cors.js"; import { errorHandler, notFoundHandler } from "./middleware/errors.js"; import { correlationMiddleware } from "./middleware/correlation.js"; import { rateLimitAuth, rateLimitApi, rateLimitEnroll } from "./middleware/rateLimit.js"; import { authRouter } from "./routes/auth.js"; import { devicesRouter } from "./routes/devices.js"; import { enrollmentTokensRouter } from "./routes/enrollment-tokens.js"; import { groupsRouter } from "./routes/groups.js"; import { jobsRouter } from "./routes/jobs.js"; import { agentRouter } from "./routes/agent.js"; import { auditRouter } from "./routes/audit.js"; import { alertsRouter } from "./routes/alerts.js"; import { policiesRouter } from "./routes/policies.js"; import { dashboardRouter } from "./routes/dashboard.js"; import { usersRouter } from "./routes/users.js"; import { complianceRouter } from "./routes/compliance.js"; import { updateRequestsRouter } from "./routes/update-requests.js"; import { deploymentsRouter } from "./routes/deployments.js"; import { softwareRouter } from "./routes/software.js"; import { appCatalogRouter } from "./routes/appcatalog.js"; import { downloadsRouter } from "./routes/downloads.js"; import { installersRouter } from "./routes/installers.js"; import { remoteRouter } from "./routes/remote.js"; import { attachRelay } from "./ws/relay.js"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const app = express(); const port = parseInt(process.env.APP_PORT || "3000", 10); app.use(helmet({ contentSecurityPolicy: false, crossOriginEmbedderPolicy: false, })); app.use(cors(corsConfig)); app.use(express.json({ limit: "1mb" })); app.use(correlationMiddleware); app.get("/api/health", (_req, res) => { res.json({ status: "ok", version: "0.1.0" }); }); const openapiPath = path.resolve(__dirname, "../../../docs/openapi.json"); if (fs.existsSync(openapiPath)) { const spec = JSON.parse(fs.readFileSync(openapiPath, "utf-8")); app.get("/api/docs", (_req, res) => { res.send(` Fleet Forge API Docs
`); }); app.get("/api/openapi.json", (_req, res) => res.json(spec)); } app.use("/api/v1/auth/login", rateLimitAuth); app.use("/api/v1/agent/enroll", rateLimitEnroll); app.use("/api/v1", rateLimitApi); app.use("/api/v1/auth", authRouter); app.use("/api/v1/users", usersRouter); app.use("/api/v1/devices", devicesRouter); app.use("/api/v1/enrollment-tokens", enrollmentTokensRouter); app.use("/api/v1/groups", groupsRouter); app.use("/api/v1/jobs", jobsRouter); app.use("/api/v1/policies", policiesRouter); app.use("/api/v1/alerts", alertsRouter); app.use("/api/v1/audit-events", auditRouter); app.use("/api/v1/dashboard", dashboardRouter); app.use("/api/v1/compliance", complianceRouter); app.use("/api/v1/update-requests", updateRequestsRouter); app.use("/api/v1/deployments", deploymentsRouter); app.use("/api/v1/software", softwareRouter); app.use("/api/v1/appcatalog", appCatalogRouter); app.use("/api/v1/downloads", downloadsRouter); app.use("/api/v1/installers", installersRouter); app.use("/api/v1/agent", agentRouter); app.use("/api/v1/remote", remoteRouter); app.use(notFoundHandler); app.use(errorHandler); if (process.env.NODE_ENV !== "test") { const server = app.listen(port, "0.0.0.0", () => { console.log(`Fleet Forge API running on port ${port}`); }); attachRelay(server); } export default app;