import express from "express"; import dotenv from "dotenv"; import cors from "cors"; import connectDB from "./config/db.js"; import logger from "./utils/logger.js"; // Routes import authRoutes from "./routes/auth.routes.js"; import inviteRoutes from "./routes/invites.routes.js"; import staffAuthRoutes from "./routes/staffAuth.routes.js"; import orderRoutes from "./routes/orders.routes.js"; import productRoutes from "./routes/products.routes.js"; import categoryRoutes from "./routes/categories.routes.js"; import shippingRoutes from "./routes/shipping.routes.js"; import storeRoutes from "./routes/storefront.routes.js"; import cryptoRoutes from "./routes/crypto.routes.js"; import blockedUsersRoutes from "./routes/blockedUsers.routes.js"; import chatRoutes from "./routes/chat.routes.js"; import stockRoutes from "./routes/stock.routes.js"; import promotionRoutes from "./routes/promotion.routes.js"; import { startCryptoPriceUpdater } from "./controllers/cryptoController.js"; // Direct routes for Telegram API to bypass JWT middleware import { protectTelegramApi } from "./middleware/telegramAuthMiddleware.js"; import { processTelegramMessage, createTelegramChat } from "./controllers/chat.controller.js"; dotenv.config(); const app = express(); connectDB(); // Add security headers and handle CORS app.use((req, res, next) => { // Basic security headers res.setHeader('X-Content-Type-Options', 'nosniff'); res.setHeader('X-Frame-Options', 'DENY'); res.setHeader('X-XSS-Protection', '1; mode=block'); // Handle CORS const origin = req.headers.origin; const host = req.headers.host; // For Tor (null origin), use the .onion address if we're on the API domain if (!origin || origin === 'null') { if (host.includes('internal-api')) { res.setHeader('Access-Control-Allow-Origin', 'http://6n6f6krmcudhzalzuqckms5bhc4afxc7xgjngumkafvgzmjmd2tmzeid.onion'); } else { res.setHeader('Access-Control-Allow-Origin', `https://${host}`); } } else { res.setHeader('Access-Control-Allow-Origin', origin); } // Always enable credentials since we're using specific origins res.setHeader('Access-Control-Allow-Credentials', 'true'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With, Accept, Origin'); res.setHeader('Access-Control-Expose-Headers', 'Content-Type, Authorization'); res.setHeader('Access-Control-Max-Age', '86400'); // Log the request for debugging logger.info(`Request from ${req.ip} - Origin: ${origin || 'null'} - Host: ${host}`); // Handle preflight requests if (req.method === 'OPTIONS') { res.status(204).end(); return; } next(); }); // Parse JSON for all routes app.use(express.json({ limit: "15mb" })); // Direct routes for Telegram API to bypass JWT middleware app.post("/telegram/message", protectTelegramApi, processTelegramMessage); app.post("/telegram/create", protectTelegramApi, createTelegramChat); app.get("/telegram/test-auth", protectTelegramApi, (req, res) => { res.status(200).json({ success: true, message: "Authentication successful", headers: { authHeader: req.headers.authorization ? req.headers.authorization.substring(0, 10) + "..." : "undefined", xApiKey: req.headers['x-api-key'] ? req.headers['x-api-key'].substring(0, 10) + "..." : "undefined" } }); }); // Register API routes app.use("/api/products", productRoutes); app.use("/api/chats", chatRoutes); app.use("/api/auth", authRoutes); app.use("/api/staff/auth", staffAuthRoutes); app.use("/api/invite", inviteRoutes); app.use("/api/orders", orderRoutes); app.use("/api/categories", categoryRoutes); app.use("/api/shipping-options", shippingRoutes); app.use("/api/storefront", storeRoutes); app.use("/api/crypto", cryptoRoutes); app.use("/api/blocked-users", blockedUsersRoutes); app.use("/api/stock", stockRoutes); app.use("/api/promotions", promotionRoutes); startCryptoPriceUpdater(60); const PORT = process.env.PORT || 3001; app.listen(PORT, () => { logger.info(`Server running on port ${PORT}`); });