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

13 KiB
Raw Permalink Blame History

Browser Console Diagnostic Script

While logged into the frontend, open your browser console (F12) and paste this:

// ============================================
// 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?

console.log(document.cookie);

Expected: Should include accessToken= and refreshToken=

Check 2: Does backend receive cookies?

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?

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?

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?

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! 🚀