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.ca/public_html/src/hooks/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/lavocat.ca/public_html/src/hooks/useImpersonation.ts
import { useState, useEffect } from 'react';
import { useSession } from 'next-auth/react';
import { toast } from 'react-hot-toast';
import { useRouter } from 'next/router';

export function useImpersonation() {
  const { data: session, update } = useSession();
  const [isImpersonating, setIsImpersonating] = useState(false);
  const router = useRouter();

  // Debug logging for session state changes
  useEffect(() => {
    console.log('🔍 useImpersonation - Session state changed:', {
      hasSession: !!session,
      userId: session?.user?.id,
      email: session?.user?.email,
      role: session?.user?.role,
      isImpersonating: session?.user?.isImpersonating,
      originalUser: session?.user?.originalUser,
      isImpersonatingState: isImpersonating
    });
  }, [session, isImpersonating]);

  const impersonateUser = async (userId: string, userName: string) => {
    if (!session?.user) {
      toast.error('Not authenticated');
      return false;
    }

    // Check if we're already impersonating - if so, use original user's role
    const effectiveRole = session.user.isImpersonating && session.user.originalUser 
      ? session.user.originalUser.role 
      : session.user.role;

    console.log('🔍 Impersonation check:', {
      effectiveRole,
      currentRole: session.user.role,
      isImpersonating: session.user.isImpersonating,
      originalUser: session.user.originalUser
    });

    if (effectiveRole !== 'SUPERADMIN' && effectiveRole !== 'ADMIN') {
      toast.error('Only Super Admins and Admins can impersonate users');
      return false;
    }

    // Check if already impersonating
    if (session.user.isImpersonating) {
      toast.error('Already impersonating a user. Please stop current impersonation first.');
      return false;
    }

    setIsImpersonating(true);

    try {
      console.log('🔄 Starting impersonation request for userId:', userId);
      console.log('🔄 Effective role for impersonation:', effectiveRole);
      console.log('🔄 Current session:', {
        userId: session.user.id,
        email: session.user.email,
        role: session.user.role,
        isImpersonating: session.user.isImpersonating
      });
      
      const response = await fetch('/api/admin/impersonate', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ userId }),
      });
      
      console.log('📊 Response received:', {
        status: response.status,
        statusText: response.statusText,
        ok: response.ok
      });

      if (!response.ok) {
        let errorMessage = 'Failed to impersonate user';
        let errorDetails = '';
        
        try {
          const errorData = await response.json();
          errorMessage = errorData.error || errorData.message || errorMessage;
          errorDetails = errorData.details || '';
        } catch (parseError) {
          console.error('Failed to parse error response:', parseError);
          try {
            const text = await response.text();
            console.error('Raw error response:', text);
            errorMessage = `Server error (${response.status}): ${text || 'Unknown error'}`;
          } catch (textError) {
            console.error('Failed to read response as text:', textError);
            errorMessage = `Server error (${response.status}): Unable to read response`;
          }
        }
        
        console.error('❌ Impersonation failed:', {
          status: response.status,
          errorMessage,
          errorDetails
        });
        
        // Show more specific error messages
        if (response.status === 429) {
          toast.error('Rate limit exceeded. Please wait a moment and try again.');
        } else if (response.status === 403) {
          toast.error('Access denied. You may not have permission to impersonate this user.');
        } else if (response.status === 404) {
          toast.error('User not found.');
        } else {
          toast.error(errorMessage);
        }
        
        return false;
      }

      let data;
      try {
        data = await response.json();
        console.log('✅ Impersonation success data:', data);
      } catch (parseError) {
        console.error('Failed to parse success response:', parseError);
        toast.error('Invalid response from server');
        return false;
      }
      
      toast.success(`🔄 Impersonation initiated for ${userName}`, {
        duration: 3000,
        icon: '👤',
      });

      // Force session update with trigger parameter
      console.log('🔄 Forcing session update...');
      await update({ trigger: 'update' });
      
      // Wait longer for the session to update and ensure it's propagated
      console.log('🔄 Waiting for session to update...');
      await new Promise(resolve => setTimeout(resolve, 1500));
      
      // Force a page reload to ensure all components get the new session
      console.log('🔄 Reloading page to ensure session consistency...');
      window.location.href = data.redirectUrl;
      
      return true;
    } catch (error) {
      console.error('❌ Impersonation error:', error);
      
      // Handle network errors specifically
      if (error instanceof TypeError && error.message.includes('fetch')) {
        toast.error('Network error. Please check your connection and try again.');
      } else {
        toast.error(error instanceof Error ? error.message : 'Failed to impersonate user');
      }
      
      return false;
    } finally {
      setIsImpersonating(false);
    }
  };

  const stopImpersonation = async () => {
    try {
      console.log('🔄 stopImpersonation - Starting...');
      console.log('🔄 Current session state:', {
        isImpersonating: session?.user?.isImpersonating,
        originalUser: session?.user?.originalUser
      });
      
      const response = await fetch('/api/admin/stop-impersonation', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
      });
      
      console.log('📊 Stop impersonation response:', {
        status: response.status,
        statusText: response.statusText,
        ok: response.ok
      });
      
      const data = await response.json();
      
      if (response.ok) {
        console.log('✅ stopImpersonation - API success:', data);
        
        toast.success('🔄 Impersonation stopped successfully', {
          duration: 2000,
          icon: '👤',
        });
        
        // Force session update with trigger parameter
        console.log('🔄 stopImpersonation - Updating session...');
        await update({ trigger: 'update' });
        
        // Wait longer for the session to update
        console.log('🔄 stopImpersonation - Waiting for session to update...');
        await new Promise(resolve => setTimeout(resolve, 1500));
        
        // Force a page reload to ensure all components get the new session
        console.log('🔄 stopImpersonation - Reloading page to ensure session consistency...');
        window.location.href = '/admin/dashboard';
      } else {
        console.error('❌ stopImpersonation - API error:', data);
        
        // Handle the case where user is not currently impersonating
        if (data.error === 'Not currently impersonating' || data.error?.includes('not impersonating')) {
          console.log('â„šī¸ stopImpersonation - User is not currently impersonating, redirecting to admin dashboard');
          toast('Not currently impersonating any user');
          router.push('/admin/dashboard');
          return;
        }
        
        toast.error(data.error || 'Failed to stop impersonation');
        console.warn('âš ī¸ stopImpersonation - Non-critical error, forcing hard reload');
        window.location.href = '/admin/dashboard';
      }
    } catch (error) {
      console.error('❌ stopImpersonation - Error:', error);
      
      // Handle network errors or other issues gracefully
      toast.error('Network error while stopping impersonation');
      console.warn('âš ī¸ stopImpersonation - Network error, forcing hard reload');
      window.location.href = '/admin/dashboard';
    }
  };

  // Enhanced return object with more debugging info
  return {
    impersonateUser,
    stopImpersonation,
    isImpersonating,
    isCurrentlyImpersonating: session?.user?.isImpersonating || false,
    originalUser: session?.user?.originalUser || null,
    canImpersonate: !session?.user?.isImpersonating && !isImpersonating,
    debugInfo: {
      sessionExists: !!session,
      userRole: session?.user?.role,
      isImpersonating: session?.user?.isImpersonating,
      originalUserRole: session?.user?.originalUser?.role
    }
  };
} 

CasperSecurity Mini