T.ME/BIBIL_0DAY
CasperSecurity


Server : Apache/2
System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64
User : gositeme ( 1004)
PHP Version : 8.2.29
Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Directory :  /home/gositeme/domains/lavocat.quebec/private_html/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/lavocat.quebec/private_html/server-production.js
// Production server configuration for lavocat.quebec
require('dotenv').config({ path: '.env.production' });

const { createServer } = require('https');
const { createServer: createHttpServer } = require('http');
const { parse } = require('url');
const fs = require('fs');
const path = require('path');
const next = require('next');
const WebSocket = require('ws');
const os = require('os');

const dev = false; // Production mode
const hostname = process.env.HOSTNAME || '0.0.0.0';
const port = process.env.PORT || 3000;
const httpsPort = process.env.HTTPS_PORT || 3443;

// Production Next.js app
const app = next({ 
  dev,
  hostname,
  port,
  conf: require('./next.config.production.js')
});

const handle = app.getRequestHandler();

// Global variables for WebSocket management
global.wsClients = new Map();
global.wsRoomSubscriptions = new Map();
global.wsUserPresence = new Map();

// Memory management for production
const MEMORY_CLEANUP_INTERVAL = 5 * 60 * 1000; // 5 minutes
const MAX_WS_CLIENTS = 1000;
const MAX_WS_ROOMS = 500;

// Periodic memory cleanup
setInterval(() => {
  try {
    // Clean up disconnected WebSocket clients
    for (const [clientId, client] of global.wsClients) {
      if (client.readyState === WebSocket.CLOSED || client.readyState === WebSocket.CLOSING) {
        global.wsClients.delete(clientId);
        console.log(`๐Ÿงน Cleaned up disconnected WebSocket client: ${clientId}`);
      }
    }
    
    // Clean up empty rooms
    for (const [roomId, subscribers] of global.wsRoomSubscriptions) {
      if (subscribers.size === 0) {
        global.wsRoomSubscriptions.delete(roomId);
        console.log(`๐Ÿงน Cleaned up empty room: ${roomId}`);
      }
    }
    
    // Force garbage collection if available
    if (global.gc) {
      global.gc();
    }
    
    console.log(`๐Ÿ“Š Memory status - Clients: ${global.wsClients.size}, Rooms: ${global.wsRoomSubscriptions.size}`);
  } catch (error) {
    console.error('Memory cleanup error:', error);
  }
}, MEMORY_CLEANUP_INTERVAL);

// Helper function to get network IP
const getNetworkIP = () => {
  const interfaces = os.networkInterfaces();
  for (const name of Object.keys(interfaces)) {
    for (const iface of interfaces[name]) {
      if (iface.family === 'IPv4' && !iface.internal) {
        return iface.address;
      }
    }
  }
  return 'localhost';
};

// HTTPS configuration for production
const getHttpsOptions = () => {
  try {
    const keyPath = process.env.SSL_KEY_PATH || path.join(__dirname, 'certificates', 'lavocat.quebec.key');
    const certPath = process.env.SSL_CERT_PATH || path.join(__dirname, 'certificates', 'lavocat.quebec.crt');
    
    if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
      console.log('๐Ÿ”’ Using production SSL certificates');
      return {
        key: fs.readFileSync(keyPath),
        cert: fs.readFileSync(certPath)
      };
    }
  } catch (error) {
    console.warn('Could not load HTTPS certificates:', error.message);
  }
  return null;
};

function initializeWebSocketServer(server) {
  if (global.wsServer) {
    console.log('WebSocket server is already running.');
    return;
  }

  const wss = new WebSocket.Server({ 
    server,
    path: '/_ws',
    clientTracking: true,
    maxPayload: 1024 * 1024 // 1MB max payload
  });

  global.wsServer = wss;
  const clients = global.wsClients;
  const userPresence = global.wsUserPresence;

  console.log('๐Ÿš€ WebSocket server initialized for production');

  // WebSocket connection handling
  wss.on('connection', (ws, req) => {
    const url = new URL(req.url, `http://${req.headers.host}`);
    const token = url.searchParams.get('token');
    
    let userId, user, connId;
    
    if (token) {
      try {
        const decoded = JSON.parse(Buffer.from(token, 'base64').toString());
        userId = decoded.userId;
        connId = decoded.connId || 'unknown';
        user = {
          id: decoded.userId,
          name: decoded.name,
        };
        
        // Token age validation
        const tokenAge = Date.now() - decoded.timestamp;
        if (tokenAge > 300000) { // 5 minutes max
          console.log(`๐Ÿšจ SECURITY: Token expired (age: ${tokenAge}ms)`);
          ws.close(1008, 'Token expired');
          return;
        }
        
        console.log(`โœ… Secure token authentication for user: ${user.name} (${userId}) [${connId}]`);
        
      } catch (error) {
        console.log(`๐Ÿšจ SECURITY: Invalid token format:`, error.message);
        ws.close(1008, 'Invalid token format');
        return;
      }
    } else {
      console.log(`๐Ÿšจ SECURITY: No authentication provided`);
      ws.close(1008, 'Authentication required');
      return;
    }

    if (!userId || !user.id) {
      console.log(`๐Ÿšจ SECURITY: Connection rejected - invalid user data`);
      ws.close(1008, 'Invalid user data');
      return;
    }
    
    console.log(`โœ… WebSocket connection established for user: ${user.name} (${userId}) [${connId}]`);

    // MEMORY MANAGEMENT: Check connection limits
    if (global.wsClients.size >= MAX_WS_CLIENTS) {
      console.log(`๐Ÿšจ MEMORY: Rejecting connection - too many clients (${global.wsClients.size}/${MAX_WS_CLIENTS})`);
      ws.close(1013, 'Server overloaded');
      return;
    }

    // Rate limiting per connection
    const rateLimiter = {
      messages: 0,
      lastReset: Date.now(),
      maxMessages: 100,
      windowMs: 60000
    };

    // Set user presence
    userPresence.set(userId, {
      status: 'online',
      lastSeen: Date.now(),
      currentRoom: null
    });

    const clientInfo = { userId, user, rooms: new Set(), isAlive: true, connId, rateLimiter };
    clients.set(ws, clientInfo);
    ws.clientInfo = clientInfo;

    // Heartbeat mechanism
    ws.isAlive = true;
    ws.on('pong', () => {
      ws.isAlive = true;
    });

    // Message handling
    ws.on('message', (data) => {
      try {
        const message = JSON.parse(data.toString());
        
        // Rate limiting
        const now = Date.now();
        if (now - rateLimiter.lastReset > rateLimiter.windowMs) {
          rateLimiter.messages = 0;
          rateLimiter.lastReset = now;
        }
        
        if (rateLimiter.messages >= rateLimiter.maxMessages) {
          console.log(`๐Ÿšจ RATE LIMIT: User ${user.name} exceeded message limit`);
          ws.close(1008, 'Rate limit exceeded');
          return;
        }
        
        rateLimiter.messages++;
        
        // Handle different message types
        switch (message.type) {
          case 'ping':
            ws.send(JSON.stringify({ type: 'pong', timestamp: Date.now() }));
            break;
          case 'join_room':
            // Handle room joining
            break;
          case 'leave_room':
            // Handle room leaving
            break;
          default:
            // Broadcast to room or handle other message types
            break;
        }
      } catch (error) {
        console.error('WebSocket message error:', error);
      }
    });

    // Connection close handling
    ws.on('close', (code, reason) => {
      console.log(`๐Ÿ”Œ WebSocket connection closed for user ${user.name} [${connId}] - Code: ${code}, Reason: ${reason}`);
      
      // Update user presence
      userPresence.set(userId, {
        status: 'offline',
        lastSeen: Date.now(),
        currentRoom: null
      });
      
      // Clean up client
      clients.delete(ws);
      // performanceMonitor.trackWebSocketDisconnection(); // This line was not in the original file, so it's removed.
    });

    // Error handling
    ws.on('error', (error) => {
      console.error(`โŒ WebSocket error for user ${user.name}:`, error);
      clients.delete(ws);
    });
  });

  // Heartbeat interval
  const interval = setInterval(() => {
    wss.clients.forEach((ws) => {
      if (ws.isAlive === false) {
        return ws.terminate();
      }
      ws.isAlive = false;
      ws.ping();
    });
  }, 30000);

  wss.on('close', () => {
    clearInterval(interval);
  });
}

// Start the application
app.prepare().then(() => {
  const httpsOptions = getHttpsOptions();
  
  if (httpsOptions) {
    // HTTPS Server
    const httpsServer = createServer(httpsOptions, (req, res) => {
      const parsedUrl = parse(req.url, true);
      handle(req, res, parsedUrl);
    });

    initializeWebSocketServer(httpsServer);

    httpsServer.listen(httpsPort, hostname, (err) => {
      if (err) throw err;
      console.log(`๐Ÿš€ Production HTTPS server running on https://${hostname}:${httpsPort}`);
      console.log(`๐ŸŒ Domain: lavocat.quebec`);
      console.log(`๐Ÿ“Š Environment: Production`);
    });
  } else {
    // HTTP Server (fallback)
    const httpServer = createHttpServer((req, res) => {
      const parsedUrl = parse(req.url, true);
      handle(req, res, parsedUrl);
    });

    initializeWebSocketServer(httpServer);

    httpServer.listen(port, hostname, (err) => {
      if (err) throw err;
      console.log(`๐Ÿš€ Production HTTP server running on http://${hostname}:${port}`);
      console.log(`๐ŸŒ Domain: lavocat.quebec`);
      console.log(`๐Ÿ“Š Environment: Production`);
    });
  }
}).catch((err) => {
  console.error('โŒ Error starting production server:', err);
  process.exit(1);
});

// Graceful shutdown
process.on('SIGTERM', () => {
  console.log('๐Ÿ›‘ SIGTERM received, shutting down gracefully');
  if (global.wsServer) {
    global.wsServer.close();
  }
  process.exit(0);
});

process.on('SIGINT', () => {
  console.log('๐Ÿ›‘ SIGINT received, shutting down gracefully');
  if (global.wsServer) {
    global.wsServer.close();
  }
  process.exit(0);
}); 

CasperSecurity Mini