9.4 KiB
Navbar Login Fix - WebSocket Authentication State Update
Problem Description
After successfully logging in via Steam, the WebSocket would connect and receive user data from the server, but the navbar would not update to show the logged-in state.
Root Cause
The WebSocket connected message handler was receiving user data (steamId, username, userId) but was only logging it to the console. It was not updating the auth store, which the navbar component relies on to display authentication state.
Console logs showed:
🔵 AnnouncementBanner mounted - loading announcements...
WebSocket connected
WebSocket message received: { type: "connected", data: {...} }
Server confirmed connection: { steamId: "...", username: "...", userId: "..." }
But the navbar remained in logged-out state because authStore.isAuthenticated was still false.
Solution
Changes Made
1. WebSocket Store (frontend/src/stores/websocket.js)
- Modified the
"connected"message handler to callauthStore.fetchUser()when the WebSocket connection is confirmed - Fixed duplicate
authStoredeclarations by declaring it once at the top ofhandleMessagefunction - Added debug logging to trace the authentication flow
Before:
case "connected":
console.log("Server confirmed connection:", payload);
break;
After:
const handleMessage = (data) => {
const { type, data: payload, timestamp } = data;
const authStore = useAuthStore(); // Declared once at top
switch (type) {
case "connected":
console.log("🟢 WebSocket received 'connected' message:", payload);
// Fetch updated user data from the auth endpoint
console.log("🔵 Calling authStore.fetchUser() from WebSocket connected handler");
authStore.fetchUser();
break;
case "balance_update":
// Now uses authStore declared at top
if (payload?.balance !== undefined) {
authStore.updateBalance(payload.balance);
}
break;
// ... rest of cases
}
};
2. Auth Store (frontend/src/stores/auth.js)
- Added debug logging to trace authentication initialization and user fetch operations
Added logs:
console.log("🔵 fetchUser called - fetching user from /api/auth/me");
console.log("✅ fetchUser response:", response.data);
console.log("✅ Setting user in auth store:", response.data.user);
console.log("🔵 fetchUser complete - isAuthenticated:", isAuthenticated.value);
console.log("🔵 Auth store initialize called - isInitialized:", isInitialized.value);
How It Works Now
Authentication Flow After Steam Login
-
User clicks "Login to Steam" button
- Frontend redirects to:
${VITE_API_URL}/api/auth/steam
- Frontend redirects to:
-
Steam OAuth flow completes
- Backend receives callback from Steam
- Backend creates session and sets HTTP-only cookie
- Backend redirects user back to frontend
-
Frontend loads (
App.vueonMounted)authStore.initialize()→ callsfetchUser()→ requests/api/auth/mewsStore.connect()→ establishes WebSocket connection
-
WebSocket connects successfully
- Backend sends
{ type: "connected", data: { steamId, username, userId } }
- Backend sends
-
WebSocket receives "connected" message ✨ NEW
- Handler calls
authStore.fetchUser() - Fetches user data from
/api/auth/mewith credentials - Updates
authStore.userand setsisAuthenticated = true
- Handler calls
-
Navbar reactively updates 🎉
authStore.isAuthenticatedchanges fromfalse→true- Vue's reactivity triggers navbar to show user menu, avatar, balance, etc.
Deployment Instructions
1. Build the Frontend
cd frontend
npm run build
Expected output:
✓ 1588 modules transformed.
✓ built in 2.80s
2. Deploy to Production
Option A: Manual deployment on server
# SSH into your server
ssh user@your-server
# Navigate to project
cd /path/to/TurboTrades/frontend
# Pull latest changes
git pull origin main
# Build
npm install # if dependencies changed
npm run build
# Copy to web root
sudo cp -r dist/* /var/www/html/turbotrades/
Option B: CI/CD Pipeline
# Commit and push changes
git add frontend/src/stores/websocket.js frontend/src/stores/auth.js
git commit -m "Fix navbar not updating after Steam login - WebSocket auth state sync"
git push origin main
# Your CI/CD pipeline will automatically:
# 1. Pull changes
# 2. Build frontend
# 3. Deploy to production
3. Clear Browser Cache
After deployment, users need to hard-refresh to get the new JavaScript bundle:
- Windows/Linux:
Ctrl + Shift + RorCtrl + F5 - Mac:
Cmd + Shift + R - Or use Incognito/Private mode for testing
Testing the Fix
1. Open Browser Console
Press F12 to open DevTools and go to Console tab.
2. Clear Cookies and Storage
In DevTools:
- Go to Application tab
- Click Clear storage → Clear site data
3. Attempt Login
Click "Login to Steam" button and complete authentication.
4. Watch Console Logs
You should see this sequence:
🔵 Auth store initialize called - isInitialized: false
🔵 fetchUser called - fetching user from /api/auth/me
✅ fetchUser response: { success: true, user: {...} }
✅ Setting user in auth store: { steamId: "...", username: "...", ... }
🔵 fetchUser complete - isAuthenticated: true
Connecting to WebSocket: wss://api.turbotrades.dev/ws
WebSocket connected
🟢 WebSocket received 'connected' message: { steamId: "...", username: "...", userId: "..." }
🔵 Calling authStore.fetchUser() from WebSocket connected handler
🔵 fetchUser called - fetching user from /api/auth/me
✅ fetchUser response: { success: true, user: {...} }
✅ Setting user in auth store: { steamId: "...", username: "...", ... }
🔵 fetchUser complete - isAuthenticated: true
5. Verify Navbar Updates
The navbar should now show:
- ✅ Your Steam avatar
- ✅ Your username
- ✅ Your balance with deposit button
- ✅ User dropdown menu with Profile, Inventory, etc.
Rollback Plan
If issues occur after deployment:
Quick Rollback
# Revert the commits
git revert HEAD~2..HEAD
# Rebuild and redeploy
cd frontend
npm run build
sudo cp -r dist/* /var/www/html/turbotrades/
Remove Debug Logs (Production Cleanup)
Once confirmed working, you may want to remove the verbose debug logs:
In frontend/src/stores/auth.js - remove all console.log statements added
In frontend/src/stores/websocket.js - remove or reduce debug logs:
case "connected":
// Keep minimal logging
console.log("WebSocket connected");
authStore.fetchUser();
break;
Then rebuild and redeploy.
Additional Notes
Why Two fetchUser() Calls?
You might notice fetchUser() is called twice:
-
On App Mount (
App.vue→authStore.initialize())- Handles the case where user already has a valid session
- Runs immediately when page loads
-
On WebSocket Connected (new addition)
- Handles the case where user just logged in via Steam
- Ensures auth state is fresh after Steam OAuth redirect
- Provides a fallback if the initial fetch happened before the session cookie was set
This redundancy is intentional and ensures authentication works reliably in all scenarios.
Session Persistence
The authentication uses HTTP-only cookies set by the backend. These persist across:
- Page refreshes
- Browser restarts (unless expired)
- Tab closures
The WebSocket connection authenticates using the same session cookie.
Related Files
frontend/src/stores/websocket.js- WebSocket message handlingfrontend/src/stores/auth.js- Authentication state managementfrontend/src/components/NavBar.vue- Navbar component (reactive to auth state)frontend/src/App.vue- App initialization flowbackend/routes/auth.js- Steam OAuth and session management
Troubleshooting
Navbar Still Not Updating
- Clear browser cache completely (not just refresh)
- Check browser console for errors
- Verify
/api/auth/mereturns user data:curl -s https://api.turbotrades.dev/api/auth/me -b cookies.txt | jq - Check WebSocket connection:
- Look for "WebSocket connected" in console
- Verify no CORS errors
"fetchUser called" But No Response
- Backend issue: Check PM2 logs
pm2 logs turbotrades-backend --lines 50 - CORS issue: Check for CORS errors in browser console
- Session cookie not set: Check backend logs for Steam OAuth errors
WebSocket Doesn't Receive "connected" Message
- Backend WebSocket handler issue: Check
backend/services/websocket.js - Nginx not proxying WS correctly: Verify Nginx config has:
location /ws { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://127.0.0.1:3000/ws; }
Success Criteria
✅ User can click "Login to Steam" and complete OAuth flow
✅ Upon redirect back to site, navbar shows logged-in state
✅ User's avatar, username, and balance are displayed
✅ WebSocket connects and shows user data in console
✅ User can access protected routes (Inventory, Profile, etc.)
✅ No console errors related to authentication or WebSocket
Status: Ready for deployment
Last Updated: 2025-01-10
Build Tested: ✅ Success
Files Modified: 2 (websocket.js, auth.js)