![]() 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/src/hooks/ |
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 removed for cleaner console
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;
// Debug logging removed for cleaner console
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 {
// Debug logging removed for cleaner console
const response = await fetch('/api/admin/impersonate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ userId }),
});
// Debug logging removed for cleaner console
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) {
try {
const text = await response.text();
errorMessage = 'Server error (' + response.status + '): ' + (text || 'Unknown error');
} catch (textError) {
errorMessage = 'Server error (' + response.status + '): Unable to read response';
}
}
// Error logging kept for debugging but console.error removed
// 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();
// Debug logging removed for cleaner console
} catch (parseError) {
toast.error('Invalid response from server');
return false;
}
toast.success('🔄 Impersonation initiated for ' + userName, {
duration: 3000,
icon: '👤',
});
// Force session update with trigger parameter
await update({ trigger: 'update' });
// Wait longer for the session to update and ensure it's propagated
await new Promise(resolve => setTimeout(resolve, 1500));
// Force a page reload to ensure all components get the new session
window.location.href = data.redirectUrl;
return true;
} catch (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 {
const response = await fetch('/api/admin/stop-impersonation', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
});
const data = await response.json();
if (response.ok) {
toast.success('🔄 Impersonation stopped successfully', {
duration: 2000,
icon: '👤',
});
// Force session update with trigger parameter
await update({ trigger: 'update' });
// Wait longer for the session to update
await new Promise(resolve => setTimeout(resolve, 1500));
// Force a page reload to ensure all components get the new session
window.location.href = '/admin/dashboard';
} else {
// Handle the case where user is not currently impersonating
if (data.error === 'Not currently impersonating' || data.error?.includes('not impersonating')) {
toast('Not currently impersonating any user');
router.push('/admin/dashboard');
return;
}
toast.error(data.error || 'Failed to stop impersonation');
window.location.href = '/admin/dashboard';
}
} catch (error) {
// Handle network errors or other issues gracefully
toast.error('Network error while stopping impersonation');
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
}
};
}