299 lines
13 KiB
Markdown
299 lines
13 KiB
Markdown
# 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! 🚀 |