![]() 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/ |
# ๐ IMPERSONATION SYSTEM AUDIT REPORT
## ๐ Executive Summary
The impersonation system was experiencing a critical issue where users would "pop in and out" of impersonated accounts, particularly when minimizing/restoring the browser. This was caused by multiple issues in the JWT callback logic, frontend session handling, and session refresh mechanisms.
## ๐จ Critical Issues Found
### 1. **JWT Callback Logic Flaw** โ ๏ธ CRITICAL
**Problem:** The JWT callback was skipping impersonation checks when `trigger === 'update'`
```typescript
// BUGGY CODE:
} else if (token.id && trigger !== 'update') {
// This skipped impersonation checks on session updates!
```
**Impact:** When the frontend called `update({ trigger: 'update' })`, the session would revert to the original user, causing the "pop in and out" behavior.
**Fix Applied:** โ
Removed the `trigger !== 'update'` condition to ensure impersonation is checked on ALL requests.
### 2. **Frontend Session Update Issues** โ ๏ธ HIGH
**Problem:**
- Insufficient wait time (500ms) for session updates
- Using `router.push()` instead of hard page reload
- No session refresh on app mount
**Impact:** Session state inconsistencies between frontend and backend.
**Fixes Applied:** โ
- Increased wait time to 1000ms
- Changed to `window.location.href` for hard page reload
- Added session refresh on app mount
### 3. **Database Unique Constraint Violations** โ ๏ธ HIGH
**Problem:** Multiple active sessions for the same user violating the unique constraint `(originalUserId, isActive)`.
**Impact:** Impersonation API calls would fail with unique constraint errors.
**Fixes Applied:** โ
- Improved session cleanup logic in impersonation API
- Created cleanup scripts for stuck sessions
- Fixed `updateMany` operations to use individual updates
## ๐ ๏ธ Fixes Implemented
### **Backend Fixes**
1. **Fixed JWT Callback Logic** (`src/lib/auth.ts`)
```typescript
// BEFORE: Skipped impersonation checks on 'update' triggers
} else if (token.id && trigger !== 'update') {
// AFTER: Always check impersonation
} else if (token.id) {
```
2. **Improved Impersonation API** (`src/pages/api/admin/impersonate.ts`)
- Better error handling for unique constraint violations
- Proper session cleanup before creating new sessions
- Retry logic for failed impersonation attempts
3. **Enhanced Session Cleanup** (`scripts/fix-impersonation-sessions.js`)
- Individual session updates to avoid unique constraint issues
- Comprehensive cleanup of expired and duplicate sessions
### **Frontend Fixes**
1. **Improved Session Update Logic** (`src/hooks/useImpersonation.ts`)
```typescript
// BEFORE: router.push() with 500ms wait
await new Promise(resolve => setTimeout(resolve, 500));
router.push(data.redirectUrl);
// AFTER: Hard reload with 1000ms wait
await new Promise(resolve => setTimeout(resolve, 1000));
window.location.href = data.redirectUrl;
```
2. **Added Session Refresh on App Mount** (`src/pages/_app.tsx`)
```typescript
function SessionRefresh() {
const { data: session, update } = useSession();
useEffect(() => {
if (session?.user) {
update({ trigger: 'update' });
}
}, []);
return null;
}
```
3. **Enhanced Stop Impersonation** (`src/hooks/useImpersonation.ts`)
- Proper session cleanup
- Hard page reload to ensure consistency
## ๐งช Testing Results
### **Database Tests** โ
PASSED
- โ
Session creation works correctly
- โ
Session cleanup works correctly
- โ
Unique constraint violations resolved
- โ
Expired session cleanup works
### **Session Flow Tests** โ
PASSED
- โ
JWT callback checks impersonation on all triggers
- โ
Session state is consistent between frontend and backend
- โ
Page reloads ensure session consistency
## ๐ Performance Impact
- **Minimal:** The fixes add negligible overhead
- **Improved Reliability:** Eliminates session inconsistencies
- **Better UX:** No more "pop in and out" behavior
## ๐ Security Considerations
- โ
Impersonation sessions are properly tracked and logged
- โ
Session expiration is enforced (1 hour)
- โ
Only SuperAdmins and Admins can impersonate
- โ
Cannot impersonate other SuperAdmins (unless you're a SuperAdmin)
## ๐ Maintenance Recommendations
1. **Regular Cleanup:** Run the cleanup script periodically:
```bash
node scripts/fix-impersonation-sessions.js
```
2. **Monitoring:** Watch for unique constraint errors in logs
3. **Session Expiration:** Consider reducing session expiration time if needed
4. **Audit Logs:** Review impersonation logs regularly for security
## ๐ฏ Success Criteria
- [x] No more "pop in and out" behavior when minimizing/restoring browser
- [x] Impersonation sessions persist correctly
- [x] No unique constraint violations
- [x] Proper session cleanup on stop impersonation
- [x] Consistent session state across all components
## ๐ Support
If issues persist:
1. Check browser console for errors
2. Run `node scripts/list-all-impersonation-sessions.js` to check session state
3. Run `node scripts/delete-all-impersonation-sessions.js` to reset if needed
4. Review server logs for JWT callback errors
---
**Audit Completed:** โ
All critical issues resolved
**System Status:** ๐ข Fully operational
**Next Review:** Recommended in 30 days