AeThex-Connect/src/backend/server.js
2026-02-28 23:50:09 -07:00

147 lines
4.9 KiB
JavaScript

const express = require('express');
const http = require('http');
const cors = require('cors');
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
require('dotenv').config();
const authRoutes = require('./routes/authRoutes');
const domainRoutes = require('./routes/domainRoutes');
const messagingRoutes = require('./routes/messagingRoutes');
const messagesRoutes = require('./routes/messagesRoutes');
const channelsRoutes = require('./routes/channelsRoutes');
const voiceRoutes = require('./routes/voiceRoutes');
const gameforgeRoutes = require('./routes/gameforgeRoutes');
const callRoutes = require('./routes/callRoutes');
const messageApiRoutes = require('./routes/messageApiRoutes');
const channelApiRoutes = require('./routes/channelApiRoutes');
const realtimeMessagesRoutes = require('./routes/realtimeMessagesRoutes');
const voiceCallRoutes = require('./routes/voiceCallRoutes');
const liveKitRoutes = require('./routes/liveKitRoutes');
const chatRoutes = require('./routes/chatRoutes');
const serverRoutes = require('./routes/serverRoutes');
const socketService = require('./services/socketService');
const path = require('path');
const app = express();
const httpServer = http.createServer(app);
const PORT = process.env.PORT || 3000;
// Trust proxy for Codespaces/containers
app.set('trust proxy', 1);
// Security middleware
app.use(helmet());
app.use(cors({
origin: function(origin, callback) {
const allowed = [
'https://atx-connect.up.railway.app',
process.env.FRONTEND_URL
];
// Allow localhost on any port in dev
if (!origin || origin.includes('localhost') || origin.includes('127.0.0.1')) {
return callback(null, true);
}
if (allowed.includes(origin)) {
return callback(null, true);
}
callback(new Error('CORS not allowed'));
},
credentials: true
}));
// Rate limiting
const limiter = rateLimit({
windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS) || 15 * 60 * 1000, // 15 minutes
max: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS) || 100,
message: 'Too many requests from this IP, please try again later.',
standardHeaders: true,
legacyHeaders: false,
});
app.use('/api/', limiter);
// Body parsing middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Health check endpoint
app.get('/health', (req, res) => {
res.json({ status: 'ok', timestamp: new Date().toISOString() });
});
// Serve React frontend build
const frontendPath = path.join(__dirname, '../frontend/dist');
app.use(express.static(frontendPath));
// API routes
app.use('/api/auth', authRoutes);
app.use('/api/passport/domain', domainRoutes);
app.use('/api/messaging', messagingRoutes);
app.use('/api/messages', messagesRoutes);
app.use('/api/channels', channelsRoutes);
app.use('/api/gameforge', gameforgeRoutes);
app.use('/api/calls', callRoutes);
app.use('/api/message', messageApiRoutes);
app.use('/api/channel', channelApiRoutes);
app.use('/api/realtime/messages', realtimeMessagesRoutes);
app.use('/api/voice', voiceCallRoutes);
app.use('/api/livekit', liveKitRoutes);
app.use('/api/chat', chatRoutes);
app.use('/api/servers', serverRoutes);
// Initialize Socket.io
const io = socketService.initialize(httpServer);
app.set('io', io); // Make io available in routes
// SPA fallback - serve index.html for all non-API routes (React Router)
app.get('*', (req, res) => {
// Don't serve index.html for API routes
if (req.path.startsWith('/api/')) {
return res.status(404).json({
success: false,
error: 'Endpoint not found'
});
}
res.sendFile(path.join(__dirname, '../frontend/dist/index.html'));
});
// Error handler
app.use((err, req, res, next) => {
console.error('Server error:', err);
res.status(500).json({
success: false,
error: process.env.NODE_ENV === 'development' ? err.message : 'Internal server error'
});
});
// Start server - bind to 0.0.0.0 for Railway/containers
httpServer.listen(PORT, '0.0.0.0', () => {
console.log(`
╔═══════════════════════════════════════════════════════╗
║ AeThex Connect - Communication Platform ║
║ Server running on port ${PORT}
║ Environment: ${process.env.NODE_ENV || 'development'}
╚═══════════════════════════════════════════════════════╝
`);
console.log(`Health check: http://localhost:${PORT}/health`);
console.log(`API Base URL: http://localhost:${PORT}/api`);
console.log(`Socket.io: Enabled`);
});
// Graceful shutdown
process.on('SIGTERM', () => {
console.log('SIGTERM received, shutting down gracefully...');
process.exit(0);
});
process.on('SIGINT', () => {
console.log('SIGINT received, shutting down gracefully...');
process.exit(0);
});
module.exports = app;