import { Elysia } from "elysia"; import { migrate } from "./db"; import { routes } from "./routes"; import { checkPayments, expireProPlans } from "./monitor"; await migrate(); const SECURITY_HEADERS = { "X-Content-Type-Options": "nosniff", "X-Frame-Options": "DENY", "Strict-Transport-Security": "max-age=63072000; includeSubDomains", "Referrer-Policy": "strict-origin-when-cross-origin", }; const CORS_ORIGIN = process.env.CORS_ORIGINS?.split(",") ?? ["https://pingql.com"]; const app = new Elysia() .onAfterHandle(({ set }) => { Object.assign(set.headers, SECURITY_HEADERS); }) // CORS for web app .onRequest(({ request, set }) => { const origin = request.headers.get("origin") ?? ""; if (CORS_ORIGIN.includes(origin)) { set.headers["access-control-allow-origin"] = origin; set.headers["access-control-allow-credentials"] = "true"; set.headers["access-control-allow-methods"] = "GET, POST, OPTIONS"; set.headers["access-control-allow-headers"] = "Content-Type, Authorization"; } }) .options("/*", ({ request }) => { const origin = request.headers.get("origin") ?? ""; const allowed = CORS_ORIGIN.includes(origin) ? origin : CORS_ORIGIN[0]; return new Response(null, { status: 204, headers: { "access-control-allow-origin": allowed, "access-control-allow-credentials": "true", "access-control-allow-methods": "GET, POST, OPTIONS", "access-control-allow-headers": "Content-Type, Authorization", }, }); }) .get("/", () => ({ name: "PingQL Pay", version: "1" })) .use(routes) .listen(3002); console.log(`PingQL Pay running at http://localhost:${app.server?.port}`); // Run immediately on startup, then every 30 seconds checkPayments().catch((err) => console.error("Payment check failed:", err)); setInterval(() => { checkPayments().catch((err) => console.error("Payment check failed:", err)); }, 30_000); // Expire pro plans every hour setInterval(() => { expireProPlans().catch((err) => console.error("Plan expiry check failed:", err)); }, 60 * 60_000);