import express from 'express' import { createServer } from 'http' import { Server } from 'socket.io' import cors from 'cors' import helmet from 'helmet' import compression from 'compression' import morgan from 'morgan' import dotenv from 'dotenv' import path from 'path' // Load environment variables dotenv.config() // Import routes and middleware import authRoutes from './routes/auth' import userRoutes from './routes/users' import chatRoutes from './routes/chats' import messageRoutes from './routes/messages' import uploadRoutes from './routes/upload' import adminRoutes from './routes/admin' // Import middleware import { errorHandler } from './middleware/errorHandler' import { rateLimiter } from './middleware/rateLimiter' import { authMiddleware } from './middleware/auth' // Import socket handlers import { setupSocketHandlers } from './socket' // Import database import { initializeDatabase } from './config/database' const app = express() const server = createServer(app) // Initialize Socket.IO const io = new Server(server, { cors: { origin: process.env.CORS_ORIGIN || "http://localhost:5173", methods: ["GET", "POST"], credentials: true }, transports: ['websocket', 'polling'] }) // Middleware app.use(helmet({ crossOriginEmbedderPolicy: false, contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], styleSrc: ["'self'", "'unsafe-inline'"], scriptSrc: ["'self'"], imgSrc: ["'self'", "data:", "https:"], }, }, })) app.use(cors({ origin: process.env.CORS_ORIGIN || "http://localhost:5173", credentials: true })) app.use(compression()) app.use(morgan('combined')) app.use(express.json({ limit: '10mb' })) app.use(express.urlencoded({ extended: true, limit: '10mb' })) // Rate limiting app.use(rateLimiter) // Static files app.use('/uploads', express.static(path.join(__dirname, '../uploads'))) // Health check app.get('/health', (req, res) => { res.json({ status: 'OK', timestamp: new Date().toISOString(), uptime: process.uptime() }) }) // API Routes app.use('/api/auth', authRoutes) app.use('/api/users', authMiddleware, userRoutes) app.use('/api/chats', authMiddleware, chatRoutes) app.use('/api/messages', authMiddleware, messageRoutes) app.use('/api/upload', authMiddleware, uploadRoutes) app.use('/api/admin', authMiddleware, adminRoutes) // 404 handler app.use('*', (req, res) => { res.status(404).json({ success: false, error: 'Route not found' }) }) // Error handling middleware app.use(errorHandler) // Setup Socket.IO handlers setupSocketHandlers(io) // Initialize database and start server async function startServer() { try { // Initialize database connection await initializeDatabase() console.log('Database connected successfully') const PORT = process.env.PORT || 3001 const HOST = process.env.HOST || 'localhost' server.listen(PORT, () => { console.log(`🚀 Server running on http://${HOST}:${PORT}`) console.log(`📡 Socket.IO server ready`) console.log(`🌍 Environment: ${process.env.NODE_ENV || 'development'}`) }) } catch (error) { console.error('Failed to start server:', error) process.exit(1) } } // Graceful shutdown process.on('SIGTERM', () => { console.log('SIGTERM received, shutting down gracefully') server.close(() => { console.log('Server closed') process.exit(0) }) }) process.on('SIGINT', () => { console.log('SIGINT received, shutting down gracefully') server.close(() => { console.log('Server closed') process.exit(0) }) }) // Handle uncaught exceptions process.on('uncaughtException', (error) => { console.error('Uncaught Exception:', error) process.exit(1) }) process.on('unhandledRejection', (reason, promise) => { console.error('Unhandled Rejection at:', promise, 'reason:', reason) process.exit(1) }) startServer() export { app, server, io }