SyedFouzan's picture
{
ffb4c35 verified
Raw History Blame Contribute Delete
3.43 kB
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
const { createServer } = require('http');
const { Server } = require('socket.io');
require('dotenv').config();
const authRoutes = require('./routes/auth');
const taskRoutes = require('./routes/tasks');
const userRoutes = require('./routes/users');
const documentRoutes = require('./routes/documents');
const analyticsRoutes = require('./routes/analytics');
const reportsRoutes = require('./routes/reports');
const { authenticateToken } = require('./middleware/auth');
const logger = require('./utils/logger');
const app = express();
const server = createServer(app);
const io = new Server(server, {
cors: {
origin: process.env.FRONTEND_URL || "http://localhost:3000",
methods: ["GET", "POST"]
}
});
// Rate limiting
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
// Middleware
app.use(helmet());
app.use(limiter);
app.use(cors({
origin: process.env.FRONTEND_URL || "http://localhost:3000",
credentials: true
}));
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));
// Logging
app.use(require('morgan')('combined', { stream: { write: message => logger.info(message.trim()) } }));
// Socket.io connection handling
io.use((socket, next) => {
const token = socket.handshake.auth.token;
if (!token) {
return next(new Error('Authentication error'));
}
jwt.verify(token, process.env.JWT_SECRET, (err, decoded) => {
if (err) return next(new Error('Authentication error'));
socket.userId = decoded.userId;
next();
});
});
io.on('connection', (socket) => {
logger.info(`User ${socket.userId} connected`);
socket.join(`user_${socket.userId}`);
socket.on('task:update', (data) => {
socket.to(`user_${data.assignee}`).emit('task:update', data);
});
socket.on('task:comment', (data) => {
socket.to(`user_${data.taskAssignee}`).emit('task:comment', data);
});
socket.on('disconnect', () => {
logger.info(`User ${socket.userId} disconnected`);
});
});
// Routes
app.use('/api/auth', authRoutes);
app.use('/api/tasks', authenticateToken, taskRoutes);
app.use('/api/users', authenticateToken, userRoutes);
app.use('/api/documents', authenticateToken, documentRoutes);
app.use('/api/analytics', authenticateToken, analyticsRoutes);
app.use('/api/reports', authenticateToken, reportsRoutes);
// Health check
app.get('/api/health', (req, res) => {
res.json({ status: 'OK', timestamp: new Date().toISOString() });
});
// Error handling middleware
app.use((err, req, res, next) => {
logger.error(err.stack);
res.status(500).json({ message: 'Something went wrong!' });
});
// 404 handler
app.use('*', (req, res) => {
res.status(404).json({ message: 'Route not found' });
});
// Database connection
mongoose.connect(process.env.MONGO_URI || 'mongodb://localhost:27017/taskflow-pro', {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
logger.info('Connected to MongoDB');
})
.catch((error) => {
logger.error('MongoDB connection error:', error);
process.exit(1);
});
const PORT = process.env.PORT || 8080;
server.listen(PORT, () => {
logger.info(`Server running on port ${PORT}`);
});
module.exports = { app, io };