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/.cursor-server/data/User/History/7199f73f/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/.cursor-server/data/User/History/7199f73f/M27u.tsx
import React, { createContext, useContext, useEffect, useRef, useState, ReactNode, useCallback } from 'react';
import { useSession } from 'next-auth/react';
import { performanceMonitor } from '@/utils/performance';

// Type declarations for browser APIs used in incognito detection
declare global {
  interface Window {
    chrome?: {
      app?: any;
      runtime?: any;
    };
    webkitRequestFileSystem?: (type: number, size: number, successCallback: () => void, errorCallback: () => void) => void;
  }
}

interface DirectMessageNotification {
  senderId: string;
  senderName: string;
  lastMessage: string;
  timestamp: number;
  unreadCount: number;
}

interface IncomingVideoCall {
  senderId: string;
  senderName: string;
  signal: any;
  timestamp: number;
}

interface WebSocketContextValue {
  ws: WebSocket | null;
  connected: boolean;
  connectionState: 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
  
  // Message handling
  sendMessage: (type: string, data: any) => void;
  
  // Enhanced features
  sendTyping: (roomId: string, isTyping: boolean) => void;
  joinRoom: (roomId: string) => Promise<void>;
  leaveRoom: (roomId: string) => Promise<void>;
  
  // Direct message notifications
  directMessageNotifications: Map<string, DirectMessageNotification>;
  markDirectMessagesAsRead: (senderId: string) => void;
  getTotalUnreadDirectMessages: () => number;
  
  // Video call notifications
  incomingVideoCall: IncomingVideoCall | null;
  acceptVideoCall: (callData: IncomingVideoCall) => void;
  declineVideoCall: () => void;
  
  // Manual controls
  reconnect: () => void;
  disconnect: () => void;
  
  // Connection stats
  connectionStats: {
    reconnectAttempts: number;
    lastConnected: number | null;
    messagesSent: number;
    messagesReceived: number;
  };
  
  // ✅ ADD SIMPLE VIDEO CALL STATE
  videoCallActive: boolean;
  startVideoCall: (recipientId: string, recipientName: string) => void;
  endVideoCall: () => void;
  currentVideoCall: {
    recipientId: string;
    recipientName: string;
    isInitiator: boolean;
  } | null;
}

const WebSocketContext = createContext<WebSocketContextValue>({
  ws: null,
  connected: false,
  connectionState: 'disconnected',
  sendMessage: () => {},
  sendTyping: () => {},
  joinRoom: async () => {},
  leaveRoom: async () => {},
  directMessageNotifications: new Map(),
  markDirectMessagesAsRead: () => {},
  getTotalUnreadDirectMessages: () => 0,
  incomingVideoCall: null,
  acceptVideoCall: () => {},
  declineVideoCall: () => {},
  reconnect: () => {},
  disconnect: () => {},
  connectionStats: {
    reconnectAttempts: 0,
    lastConnected: null,
    messagesSent: 0,
    messagesReceived: 0,
  },
  videoCallActive: false,
  startVideoCall: () => {},
  endVideoCall: () => {},
  currentVideoCall: null,
});

export const WebSocketProvider = ({ children }: { children: ReactNode }) => {
  const { data: session, status } = useSession();
  
  // WebSocket connection
  const wsRef = useRef<WebSocket | null>(null);
  const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null);
  const [connected, setConnected] = useState(false);
  const [connectionState, setConnectionState] = useState<'disconnected' | 'connecting' | 'connected' | 'reconnecting'>('disconnected');
  const [wsInstance, setWsInstance] = useState<WebSocket | null>(null);
  
  // Direct message notifications
  const [directMessageNotifications, setDirectMessageNotifications] = useState<Map<string, DirectMessageNotification>>(new Map());
  
  // Video call notifications
  const [incomingVideoCall, setIncomingVideoCall] = useState<IncomingVideoCall | null>(null);

  // ✅ SIMPLE VIDEO CALL STATE - NO MORE COMPLEX SHIT
  const [videoCallActive, setVideoCallActive] = useState(false);
  const [currentVideoCall, setCurrentVideoCall] = useState<{
    recipientId: string;
    recipientName: string;
    isInitiator: boolean;
  } | null>(null);
  
  // Connection state tracking with refs to avoid stale closures
  const connectionId = useRef<string | null>(null);
  const isIntentionalDisconnect = useRef(false);
  const lastSessionId = useRef<string | null>(null);
  const reconnectAttempts = useRef(0);
  
  // Connection stats
  const [connectionStats, setConnectionStats] = useState({
    reconnectAttempts: 0,
    lastConnected: null as number | null,
    messagesSent: 0,
    messagesReceived: 0,
  });

  // SECURITY: Rate limiting for message handling
  const messageRateLimit = useRef({
    count: 0,
    lastReset: Date.now(),
    maxMessages: 100, // Max 100 messages per minute
    windowMs: 60000 // 1 minute window
  });

  // SECURITY: Input validation and sanitization
  const validateMessage = (message: any): boolean => {
    try {
      // Check message structure
      if (!message || typeof message !== 'object') {
        return false;
      }

      // Check required fields
      if (!message.type || typeof message.type !== 'string') {
        return false;
      }

      // Validate message type (whitelist approach)
      const allowedTypes = [
        'pong', 'ping', 'DIRECT_MESSAGE', 'webrtc-offer', 'webrtc-answer', 
        'webrtc-ice-candidate', 'webrtc-end-call', 'webrtc-call-rejected', 
        'webrtc-call-accepted', 'PARTICIPANT_LIST_UPDATE', 'PRESENCE_UPDATE'
      ];
      
      if (!allowedTypes.includes(message.type)) {
        return false;
      }

      // Sanitize string fields to prevent XSS
      if (message.data && typeof message.data === 'object') {
        for (const key in message.data) {
          if (typeof message.data[key] === 'string') {
            // Basic XSS prevention - remove script tags and javascript: URLs
            message.data[key] = message.data[key]
              .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
              .replace(/javascript:/gi, '')
              .replace(/on\w+\s*=/gi, '');
          }
        }
      }

      return true;
    } catch (error) {
      return false;
    }
  };

  // SECURITY: Rate limiting check
  const checkRateLimit = (): boolean => {
    const now = Date.now();
    const rateLimit = messageRateLimit.current;

    // Reset counter if window has passed
    if (now - rateLimit.lastReset > rateLimit.windowMs) {
      rateLimit.count = 0;
      rateLimit.lastReset = now;
    }

    // Check if rate limit exceeded
    if (rateLimit.count >= rateLimit.maxMessages) {
      return false;
    }

    rateLimit.count++;
    return true;
  };

  // Generate unique connection ID
  const generateConnectionId = () => {
    return `conn_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  };

  // Mark direct messages as read
  const markDirectMessagesAsRead = useCallback((senderId: string) => {
    setDirectMessageNotifications(prev => {
      const newMap = new Map(prev);
      const notification = newMap.get(senderId);
      if (notification) {
        newMap.set(senderId, { ...notification, unreadCount: 0 });
      }
      return newMap;
    });
  }, []);

  // Get total unread direct messages
  const getTotalUnreadDirectMessages = useCallback(() => {
    let total = 0;
    directMessageNotifications.forEach(notification => {
      total += notification.unreadCount;
    });
    return total;
  }, [directMessageNotifications]);

  // Video call functions
  const acceptVideoCall = useCallback((callData: IncomingVideoCall) => {
    // Send acceptance signal to caller
    if (wsRef.current?.readyState === WebSocket.OPEN) {
      const acceptMessage = {
        type: 'webrtc-call-accepted',
        data: {
          recipientId: callData.senderId,
          signal: callData.signal // Forward the original signal
        },
        senderId: session?.user?.id,
        senderName: session?.user?.name || 'Unknown User'
      };
      
      wsRef.current.send(JSON.stringify(acceptMessage));
      }
    
    // ✅ SIMPLE: JUST START THE FUCKING VIDEO CALL
    setVideoCallActive(true);
    setCurrentVideoCall({
      recipientId: callData.senderId,
      recipientName: callData.senderName,
      isInitiator: false // We're answering the call
    });
    
    // Clear the notification
    setIncomingVideoCall(null);
  }, [session?.user?.id, session?.user?.name]);

  const declineVideoCall = useCallback(() => {
    // Send rejection signal to caller
    if (incomingVideoCall && wsRef.current?.readyState === WebSocket.OPEN) {
      const rejectMessage = {
        type: 'webrtc-call-rejected',
        data: {
          recipientId: incomingVideoCall.senderId,
          reason: 'declined'
        },
        senderId: session?.user?.id,
        senderName: session?.user?.name || 'Unknown User'
      };
      
      wsRef.current.send(JSON.stringify(rejectMessage));
      }
    
    setIncomingVideoCall(null);
  }, [incomingVideoCall, session?.user?.id, session?.user?.name]);

  // ✅ SIMPLE VIDEO CALL FUNCTIONS - NO BULLSHIT
  const startVideoCall = useCallback((recipientId: string, recipientName: string) => {
    setVideoCallActive(true);
    setCurrentVideoCall({
      recipientId,
      recipientName,
      isInitiator: true
    });
  }, []);

  const endVideoCall = useCallback(() => {
    setVideoCallActive(false);
    setCurrentVideoCall(null);
  }, []);

  // ✅ SILENCED - No more annoying buzzing sounds!
  const playIncomingCallSound = useCallback(() => {
    // Sound disabled to prevent annoying buzzing
  }, []);

  // Message handler
  const handleMessage = useCallback((event: MessageEvent) => {
    // SECURITY: Rate limiting
    if (!checkRateLimit()) {
      return;
    }

    try {
      const message = JSON.parse(event.data);
      
      // SECURITY: Input validation
      if (!validateMessage(message)) {
        return;
      }
      
      setConnectionStats(prev => ({
        ...prev,
        messagesReceived: prev.messagesReceived + 1,
      }));

      switch (message.type) {
        case 'pong':
          // Handle pong - connection is healthy
          break;
          
        case 'ping':
          // Respond to server ping immediately
          if (wsRef.current?.readyState === WebSocket.OPEN) {
            wsRef.current.send(JSON.stringify({ 
              type: 'pong', 
              timestamp: Date.now() 
            }));
          }
          break;

        case 'DIRECT_MESSAGE':
          // Handle direct message notifications
          if (message.data && message.data.senderId && message.data.senderId !== session?.user?.id) {
            setDirectMessageNotifications(prev => {
              const newMap = new Map(prev);
              const senderId = message.data.senderId;
              const existing = newMap.get(senderId);
              
              newMap.set(senderId, {
                senderId,
                senderName: message.data.sender?.name || 'Unknown User',
                lastMessage: message.data.content,
                timestamp: Date.now(),
                unreadCount: (existing?.unreadCount || 0) + 1,
              });
              
              return newMap;
            });
            
            // Show browser notification if permission granted
            if (Notification.permission === 'granted') {
              new Notification(`New message from ${message.data.sender?.name || 'Unknown User'}`, {
                body: message.data.content,
                icon: '/icons/apple-touch-icon-180x180.png'
              });
            }
          }
          break;

        case 'webrtc-offer':
          // Handle incoming video call
          if (message.senderId && message.senderId !== session?.user?.id) {
            // Try to get the sender name from the message or use a fallback
            const senderName = message.senderName || message.data?.senderName || `User ${message.senderId.slice(-4)}`;
            
            // Only show notification if there isn't already one from the same sender
            if (!incomingVideoCall || incomingVideoCall.senderId !== message.senderId) {
              const callData: IncomingVideoCall = {
                senderId: message.senderId,
                senderName,
                signal: message.data?.signal || message.signal,
                timestamp: Date.now(),
              };
              
              setIncomingVideoCall(callData);
              playIncomingCallSound();
              
              // Show browser notification if permission granted
              if (Notification.permission === 'granted') {
                new Notification('📞 Incoming Video Call', {
                  body: `${senderName} is calling you`,
                  icon: '/icons/apple-touch-icon-180x180.png'
                });
              }
            } else {
              }
          }
          break;

        case 'webrtc-answer':
        case 'webrtc-ice-candidate':
        case 'webrtc-end-call':
          // These are handled by individual DirectMessage components
          break;

        case 'webrtc-call-rejected':
          // Handle call rejection notification
          if (message.senderId && message.senderId !== session?.user?.id) {
            // Dispatch event for DirectMessage components to handle
            window.dispatchEvent(new CustomEvent('video-call-rejected', {
              detail: {
                senderId: message.senderId,
                senderName: message.senderName,
                reason: message.data?.reason || 'declined'
              }
            }));
          }
          break;

        case 'webrtc-call-accepted':
          // Handle call acceptance notification
          if (message.senderId && message.senderId !== session?.user?.id) {
            // Dispatch event for DirectMessage components to handle
            window.dispatchEvent(new CustomEvent('video-call-accepted', {
              detail: {
                senderId: message.senderId,
                senderName: message.senderName,
                signal: message.data?.signal
              }
            }));
          }
          break;

        case 'webrtc-call-cancelled':
          // ✅ Handle call cancellation - STOP INCOMING NOTIFICATIONS
          if (message.senderId && message.senderId !== session?.user?.id) {
            // Clear the incoming video call notification immediately
            setIncomingVideoCall(null);
            
            // Also dispatch event for DirectMessage components
            window.dispatchEvent(new CustomEvent('video-call-cancelled', {
              detail: {
                senderId: message.senderId,
                senderName: message.senderName,
                reason: message.data?.reason || 'cancelled'
              }
            }));
          }
          break;

        default:
          // Dispatch to other components
          window.dispatchEvent(new CustomEvent('websocket-message', { detail: message }));
          break;
      }
    } catch (error) {
      }
  }, [session?.user?.id, playIncomingCallSound]);

  // Stable message sending
  const sendMessage = useCallback((type: string, data: any) => {
    if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) {
      return;
    }

    try {
      const message = JSON.stringify({ type, data });
      wsRef.current.send(message);
      
      setConnectionStats(prev => ({
        ...prev,
        messagesSent: prev.messagesSent + 1,
      }));
      
      } catch (error) {
      }
  }, []);

  // Enhanced messaging functions
  const sendTyping = useCallback((roomId: string, isTyping: boolean) => {
    sendMessage('TYPING', { roomId, isTyping, timestamp: Date.now() });
  }, [sendMessage]);

  const joinRoom = useCallback(async (roomId: string): Promise<void> => {
    return new Promise((resolve) => {
      sendMessage('JOIN_ROOM', { chatRoomId: roomId });
      // Simple resolution - server will confirm via broadcast
      setTimeout(resolve, 100);
    });
  }, [sendMessage]);

  const leaveRoom = useCallback(async (roomId: string): Promise<void> => {
    return new Promise((resolve) => {
      sendMessage('LEAVE_ROOM', { chatRoomId: roomId });
      setTimeout(resolve, 100);
    });
  }, [sendMessage]);

  // Clean disconnect function
  const disconnect = useCallback(() => {
    isIntentionalDisconnect.current = true;
    
    if (wsRef.current) {
      wsRef.current.close(1000, 'Manual disconnect');
      wsRef.current = null;
    }
    
    if (reconnectTimeoutRef.current) {
      clearTimeout(reconnectTimeoutRef.current);
      reconnectTimeoutRef.current = null;
    }
    
    setConnected(false);
    setConnectionState('disconnected');
    performanceMonitor.trackWebSocketDisconnection();
    setWsInstance(null);
    
    // Force garbage collection after disconnect to prevent memory leaks
    if (typeof window !== 'undefined' && 'gc' in window) {
      try {
        (window as any).gc();
      } catch (e) {
        // GC not available, continue
      }
    }
  }, []);

  // Enhanced connection logic with incognito mode handling
  const connect = useCallback(() => {
    // Prevent duplicate connections
    if (wsRef.current && (wsRef.current.readyState === WebSocket.CONNECTING || wsRef.current.readyState === WebSocket.OPEN)) {
      return;
    }

    if (!session?.user?.id || status !== 'authenticated') {
      return;
    }
    
    // Simplified incognito detection (less aggressive)
    const isLikelyIncognito = () => {
      try {
        // Simple storage detection
        if (!window.localStorage || !window.sessionStorage) return true;
        return false;
      } catch (e) {
        return true;
      }
    };

    const incognitoMode = isLikelyIncognito();
    if (incognitoMode) {
      }
    
    // Check if session changed
    const currentSessionId = session.user.id;
    if (lastSessionId.current && lastSessionId.current !== currentSessionId) {
      isIntentionalDisconnect.current = true;
      disconnect();
    }
    lastSessionId.current = currentSessionId;
    
    isIntentionalDisconnect.current = false;
    setConnectionState('connecting');
    
    const newConnectionId = generateConnectionId();
    connectionId.current = newConnectionId;
    
    const userId = session.user.id;
    const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
    
    // SECURITY: Create secure token instead of exposing user data in query string
    const secureToken = btoa(JSON.stringify({
      userId,
      name: session.user.name,
      timestamp: Date.now(),
      connId: newConnectionId
    }));
    
    const wsUrl = `${protocol}//${window.location.host}/_ws?token=${secureToken}`;
    
    try {
      const ws = new WebSocket(wsUrl);
      wsRef.current = ws;

      // PERFORMANCE: Reduced timeout from 15-20s to 8-10s for faster failure detection
      const connectionTimeout = incognitoMode ? 8000 : 10000;
      const connectionTimeoutRef = setTimeout(() => {
        if (ws.readyState === WebSocket.CONNECTING) {
          ws.close(1000, 'Connection timeout');
          setConnectionState('disconnected');
        }
      }, connectionTimeout);

      // PERFORMANCE: Reduced ready state checks from 5s to 3s total
      let readyStateCheckCount = 0;
      const readyStateCheck = setInterval(() => {
        readyStateCheckCount++;
        
        if (ws.readyState !== WebSocket.CONNECTING || readyStateCheckCount >= 3) {
          clearInterval(readyStateCheck);
        }
      }, 1000);

      ws.onopen = () => {
        clearInterval(readyStateCheck);
        clearTimeout(connectionTimeoutRef);
        setConnected(true);
        setConnectionState('connected');
        performanceMonitor.trackWebSocketConnection();
        setWsInstance(ws);
        
        // Reset reconnection attempts on successful connection
        reconnectAttempts.current = 0;
        setConnectionStats(prev => ({
          ...prev,
          reconnectAttempts: 0,
          lastConnected: Date.now(),
        }));

        // Clear any reconnect timeout
        if (reconnectTimeoutRef.current) {
          clearTimeout(reconnectTimeoutRef.current);
          reconnectTimeoutRef.current = null;
        }
      };

      ws.onmessage = handleMessage;

      ws.onclose = (event) => {
        clearInterval(readyStateCheck);
        clearTimeout(connectionTimeoutRef);
        
        setConnected(false);
        setConnectionState('disconnected');
        setWsInstance(null);
        if (wsRef.current === ws) {
          wsRef.current = null;
        }

        // Don't reconnect if intentional, authentication lost, or certain error codes
        if (isIntentionalDisconnect.current || 
            event.code === 1000 || 
            event.code === 1001 || 
            status !== 'authenticated') {
          return;
        }

        // PERFORMANCE: Faster reconnection with reduced retry attempts (5 instead of 8)
        if (status === 'authenticated' && session?.user?.id) {
          const attempts = reconnectAttempts.current;
          
          if (attempts >= 5) { // Reduced from 8 to 5 attempts
            setConnectionState('disconnected');
            return;
          }
          
          setConnectionState('reconnecting');
          
          // PERFORMANCE: Faster delays - max 2s instead of 3s
          const delay = event.code === 1006 ? 0 : Math.min(300 * (attempts + 1), 2000);
          
          reconnectAttempts.current += 1;
          setConnectionStats(prev => ({
            ...prev,
            reconnectAttempts: reconnectAttempts.current,
          }));

          if (delay === 0) {
            // Immediate reconnection for HMR
            if (!isIntentionalDisconnect.current) {
              connect();
            }
          } else {
            reconnectTimeoutRef.current = setTimeout(() => {
              if (!isIntentionalDisconnect.current) {
                connect();
              }
            }, delay);
          }
        }
      };

      ws.onerror = (error) => {
        clearInterval(readyStateCheck);
        clearTimeout(connectionTimeoutRef);
      };

    } catch (error) {
      setConnectionState('disconnected');
    }
  }, [session?.user?.id, session?.user?.name, status]);

  // Manual reconnection function
  const reconnect = useCallback(() => {
    // Reset reconnection attempts
    reconnectAttempts.current = 0;
    setConnectionStats(prev => ({
      ...prev,
      reconnectAttempts: 0,
    }));
    
    // Clean disconnect and reconnect immediately
    disconnect();
    // Connect immediately without any delay
    connect();
  }, [connect, disconnect]);

  // Main connection effect - only trigger on authentication changes
  useEffect(() => {
    if (status === 'authenticated' && session?.user?.id) {
      // Only connect if we don't have an active connection and we're not already connecting
      if (!wsRef.current || wsRef.current.readyState === WebSocket.CLOSED) {
        if (connectionState !== 'connecting') {
          // Connect immediately without any delay
          connect();
        }
      }
    } else if (status === 'unauthenticated') {
      // Clean disconnect when logged out
      disconnect();
    } else {
      }

    return () => {
      if (reconnectTimeoutRef.current) {
        clearTimeout(reconnectTimeoutRef.current);
      }
    };
  }, [status, session?.user?.id, connectionState, connect, disconnect]);

  // Cleanup function to clear all timers and references
  const cleanup = useCallback(() => {
    // Clear all timeouts
    if (reconnectTimeoutRef.current) {
      clearTimeout(reconnectTimeoutRef.current);
      reconnectTimeoutRef.current = null;
    }
    
    // Reset rate limiting
    messageRateLimit.current = {
      count: 0,
      lastReset: Date.now(),
      maxMessages: 100,
      windowMs: 60000
    };
    
    // Clear connection tracking
    isIntentionalDisconnect.current = false;
    connectionId.current = null;
    lastSessionId.current = null;
    reconnectAttempts.current = 0;
    
    // Force garbage collection if available
    if (typeof window !== 'undefined' && 'gc' in window) {
      try {
        (window as any).gc();
      } catch (e) {
        // GC not available, continue
      }
    }
    
    }, []);

  // Cleanup on unmount
  useEffect(() => {
    return () => {
      cleanup();
      if (wsRef.current) {
        wsRef.current.close();
        wsRef.current = null;
      }
    };
  }, [cleanup]);

  const contextValue: WebSocketContextValue = {
    ws: wsInstance,
    connected,
    connectionState,
    sendMessage,
    sendTyping,
    joinRoom,
    leaveRoom,
    reconnect,
    disconnect,
    connectionStats,
    directMessageNotifications,
    markDirectMessagesAsRead,
    getTotalUnreadDirectMessages,
    incomingVideoCall,
    acceptVideoCall,
    declineVideoCall,
    videoCallActive,
    startVideoCall,
    endVideoCall,
    currentVideoCall,
  };

  return (
    <WebSocketContext.Provider value={contextValue}>
      {children}
    </WebSocketContext.Provider>
  );
};

export const useWebSocket = () => useContext(WebSocketContext); 

CasperSecurity Mini