Files
TurboTrades/BROWSER_DIAGNOSTIC.md
2026-01-10 04:57:43 +00:00

299 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Browser Console Diagnostic Script
## Quick Cookie Check (Copy & Paste into Console)
While logged into the frontend, open your browser console (F12) and paste this:
```javascript
// ============================================
// TurboTrades Cookie Diagnostic Script
// ============================================
console.clear();
console.log('%c🔍 TurboTrades Authentication Diagnostic', 'font-size: 20px; font-weight: bold; color: #4CAF50;');
console.log('%c════════════════════════════════════════', 'color: #4CAF50;');
// Step 1: Check browser cookies
console.log('\n%c1⃣ BROWSER COOKIES CHECK', 'font-size: 16px; font-weight: bold; color: #2196F3;');
console.log('─────────────────────────');
const allCookies = document.cookie;
const hasCookies = allCookies.length > 0;
if (!hasCookies) {
console.log('%c❌ NO COOKIES FOUND', 'color: #f44336; font-weight: bold;');
console.log('This means you are not logged in.');
console.log('Action: Click "Login with Steam" and complete the OAuth flow.');
} else {
console.log('%c✅ Cookies present:', 'color: #4CAF50; font-weight: bold;');
console.log(allCookies);
const hasAccessToken = allCookies.includes('accessToken=');
const hasRefreshToken = allCookies.includes('refreshToken=');
console.log('\nToken Check:');
console.log(hasAccessToken ? ' ✅ accessToken found' : ' ❌ accessToken missing');
console.log(hasRefreshToken ? ' ✅ refreshToken found' : ' ❌ refreshToken missing');
if (!hasAccessToken) {
console.log('%c\n⚠ WARNING: No accessToken cookie!', 'color: #ff9800; font-weight: bold;');
console.log('You may have been logged out or the cookies expired.');
}
}
// Step 2: Test debug endpoint
console.log('\n%c2⃣ BACKEND COOKIE CHECK', 'font-size: 16px; font-weight: bold; color: #2196F3;');
console.log('─────────────────────────');
console.log('Testing if backend receives cookies...');
fetch('/api/auth/debug-cookies', { credentials: 'include' })
.then(response => response.json())
.then(data => {
console.log('%c✅ Backend response received:', 'color: #4CAF50; font-weight: bold;');
console.log('Backend sees these cookies:', data.cookies);
console.log('\nBackend Cookie Status:');
console.log(data.hasAccessToken ? ' ✅ Backend received accessToken' : ' ❌ Backend did NOT receive accessToken');
console.log(data.hasRefreshToken ? ' ✅ Backend received refreshToken' : ' ❌ Backend did NOT receive refreshToken');
if (!data.hasAccessToken && hasCookies && allCookies.includes('accessToken=')) {
console.log('%c\n🚨 PROBLEM DETECTED:', 'color: #f44336; font-weight: bold; font-size: 14px;');
console.log('Browser has cookies but backend is NOT receiving them!');
console.log('\nLikely causes:');
console.log('1. Cookie Domain mismatch');
console.log('2. Cookie Secure flag set to true on HTTP');
console.log('3. Cookie SameSite is too restrictive');
console.log('\n📋 Cookie Configuration on Backend:');
console.log(' Domain:', data.config.cookieDomain);
console.log(' Secure:', data.config.cookieSecure);
console.log(' SameSite:', data.config.cookieSameSite);
console.log(' CORS Origin:', data.config.corsOrigin);
console.log('\n🔧 FIX: Update backend config/index.js:');
console.log(' COOKIE_DOMAIN=localhost (NOT 127.0.0.1)');
console.log(' COOKIE_SECURE=false');
console.log(' COOKIE_SAME_SITE=lax');
} else if (data.hasAccessToken) {
console.log('%c\n✅ GOOD NEWS:', 'color: #4CAF50; font-weight: bold; font-size: 14px;');
console.log('Backend is receiving your cookies correctly!');
}
})
.catch(error => {
console.log('%c❌ Backend connection failed:', 'color: #f44336; font-weight: bold;');
console.error(error);
console.log('\n⚠ Make sure backend is running on http://localhost:3000');
});
// Step 3: Test /auth/me
console.log('\n%c3⃣ AUTHENTICATION TEST', 'font-size: 16px; font-weight: bold; color: #2196F3;');
console.log('─────────────────────────');
console.log('Testing /auth/me endpoint...');
fetch('/api/auth/me', { credentials: 'include' })
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
})
.then(data => {
console.log('%c✅ AUTHENTICATED!', 'color: #4CAF50; font-weight: bold; font-size: 14px;');
console.log('User:', data.user.username);
console.log('Steam ID:', data.user.steamId);
console.log('Balance:', data.user.balance);
console.log('Staff Level:', data.user.staffLevel);
})
.catch(error => {
console.log('%c❌ NOT AUTHENTICATED:', 'color: #f44336; font-weight: bold;');
console.log(error.message);
});
// Step 4: Test sessions endpoint
console.log('\n%c4⃣ SESSIONS ENDPOINT TEST', 'font-size: 16px; font-weight: bold; color: #2196F3;');
console.log('─────────────────────────');
console.log('Testing /user/sessions endpoint...');
fetch('/api/user/sessions', { credentials: 'include' })
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
})
.then(data => {
console.log('%c✅ SESSIONS RETRIEVED!', 'color: #4CAF50; font-weight: bold; font-size: 14px;');
console.log(`Found ${data.sessions.length} active session(s)`);
data.sessions.forEach((session, i) => {
console.log(`\nSession ${i + 1}:`);
console.log(` Device: ${session.device}`);
console.log(` Browser: ${session.browser}`);
console.log(` OS: ${session.os}`);
console.log(` IP: ${session.ip}`);
console.log(` Last Active: ${new Date(session.lastActivity).toLocaleString()}`);
});
})
.catch(error => {
console.log('%c❌ SESSIONS FAILED:', 'color: #f44336; font-weight: bold;');
console.log(error.message);
console.log('\nThis is the problem you reported!');
});
// Step 5: Detailed cookie inspection
setTimeout(() => {
console.log('\n%c5⃣ DETAILED COOKIE INSPECTION', 'font-size: 16px; font-weight: bold; color: #2196F3;');
console.log('─────────────────────────');
console.log('Opening DevTools Application/Storage tab to inspect cookie attributes...');
console.log('\n📋 Cookie Attributes to Check:');
console.log('┌──────────────┬───────────────────────┬──────────────────────────┐');
console.log('│ Attribute │ Expected (Dev) │ Problem if Different │');
console.log('├──────────────┼───────────────────────┼──────────────────────────┤');
console.log('│ Domain │ localhost │ 127.0.0.1, 0.0.0.0 │');
console.log('│ Path │ / │ Any other path │');
console.log('│ SameSite │ Lax or None │ Strict │');
console.log('│ Secure │ ☐ (unchecked) │ ☑ (checked on HTTP) │');
console.log('│ HttpOnly │ ☑ (checked) │ OK │');
console.log('└──────────────┴───────────────────────┴──────────────────────────┘');
console.log('\nTo check:');
console.log('1. Press F12 (if not already open)');
console.log('2. Go to "Application" tab (Chrome) or "Storage" tab (Firefox)');
console.log('3. Click "Cookies" → "http://localhost:5173"');
console.log('4. Find "accessToken" and "refreshToken"');
console.log('5. Check the attributes match the "Expected" column');
}, 2000);
// Step 6: Network request check
setTimeout(() => {
console.log('\n%c6⃣ NETWORK REQUEST CHECK', 'font-size: 16px; font-weight: bold; color: #2196F3;');
console.log('─────────────────────────');
console.log('To verify cookies are sent with requests:');
console.log('1. Open DevTools → Network tab');
console.log('2. Click "Active Sessions" on your profile page');
console.log('3. Find the request to "/api/user/sessions"');
console.log('4. Click it and go to "Headers" tab');
console.log('5. Look for "Cookie" in Request Headers');
console.log('6. It should include: accessToken=eyJhbGc...');
console.log('\nIf Cookie header is missing or empty:');
console.log(' → Browser is not sending cookies');
console.log(' → Check cookie attributes (Step 5)');
}, 2500);
// Final summary
setTimeout(() => {
console.log('\n%c═══════════════════════════════════════════════════════', 'color: #4CAF50;');
console.log('%c DIAGNOSTIC COMPLETE ', 'color: #4CAF50; font-weight: bold; font-size: 16px;');
console.log('%c═══════════════════════════════════════════════════════', 'color: #4CAF50;');
console.log('\n📖 For detailed troubleshooting steps, see:');
console.log(' TurboTrades/TROUBLESHOOTING_AUTH.md');
console.log('\n💡 Quick fixes:');
console.log(' 1. Ensure backend .env has: COOKIE_DOMAIN=localhost');
console.log(' 2. Ensure backend .env has: COOKIE_SECURE=false');
console.log(' 3. Restart backend after config changes');
console.log(' 4. Clear cookies: DevTools → Application → Cookies → Clear');
console.log(' 5. Log in again via Steam');
console.log('\n🐛 If still broken, run backend test:');
console.log(' cd TurboTrades');
console.log(' node test-auth.js');
}, 3000);
```
## Alternative: Step-by-Step Manual Check
If you prefer to run each check manually:
### Check 1: Do you have cookies?
```javascript
console.log(document.cookie);
```
**Expected:** Should include `accessToken=` and `refreshToken=`
### Check 2: Does backend receive cookies?
```javascript
fetch('/api/auth/debug-cookies', { credentials: 'include' })
.then(r => r.json())
.then(d => console.log(d));
```
**Expected:** `hasAccessToken: true` and `hasRefreshToken: true`
### Check 3: Can you authenticate?
```javascript
fetch('/api/auth/me', { credentials: 'include' })
.then(r => r.json())
.then(d => console.log(d));
```
**Expected:** Your user object with `username`, `steamId`, etc.
### Check 4: Can you get sessions?
```javascript
fetch('/api/user/sessions', { credentials: 'include' })
.then(r => r.json())
.then(d => console.log(d));
```
**Expected:** Array of your active sessions
### Check 5: Can you setup 2FA?
```javascript
fetch('/api/user/2fa/setup', {
method: 'POST',
credentials: 'include'
})
.then(r => r.json())
.then(d => console.log(d));
```
**Expected:** QR code and secret for 2FA setup
## Common Patterns
### ❌ PATTERN 1: Browser has cookies, backend doesn't receive them
```
document.cookie → "accessToken=eyJ...; refreshToken=eyJ..."
/api/auth/debug-cookies → hasAccessToken: false
```
**Cause:** Cookie domain/secure/samesite mismatch
**Fix:** Update backend cookie config
### ❌ PATTERN 2: Everything works except 2FA and sessions
```
/api/auth/me → ✅ Works
/api/user/sessions → ❌ 401 Unauthorized
/api/user/2fa/setup → ❌ 401 Unauthorized
```
**Cause:** Routes not using cookies OR cookie not sent with specific requests
**Fix:** Check axios config has `withCredentials: true`
### ❌ PATTERN 3: Works in DevTools but not in app
```
fetch('/api/user/sessions', {credentials: 'include'}) → ✅ Works
Vue app call to same endpoint → ❌ Fails
```
**Cause:** Axios instance missing `withCredentials: true`
**Fix:** Check `frontend/src/utils/axios.js`
### ✅ PATTERN: Everything works!
```
document.cookie → Has accessToken
/api/auth/debug-cookies → hasAccessToken: true
/api/auth/me → ✅ User data
/api/user/sessions → ✅ Sessions array
/api/user/2fa/setup → ✅ QR code
```
**Status:** All good! 🎉
## What Each Error Means
| Error | Meaning | Solution |
|-------|---------|----------|
| `No access token provided` | Backend didn't receive cookie | Check cookie domain/secure/samesite |
| `Access token has expired` | Token timed out (15 min default) | Login again or implement auto-refresh |
| `User not found` | Token valid but user deleted | Clear cookies and login again |
| `Invalid access token` | Token corrupted or wrong secret | Clear cookies and login again |
| `Network Error` | Can't reach backend | Check backend is running on :3000 |
| `CORS Error` | Origin mismatch | Check backend CORS_ORIGIN=http://localhost:5173 |
## Next Steps
1. Run the main diagnostic script (copy the big script above)
2. Read the output and identify which check failed
3. Follow the specific fix for that failure
4. If still stuck, see `TROUBLESHOOTING_AUTH.md` for detailed guide
5. Run backend test: `node test-auth.js`
Good luck! 🚀