All checks were successful
Build Frontend / Build Frontend (push) Successful in 35s
337 lines
9.4 KiB
Markdown
337 lines
9.4 KiB
Markdown
# 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 call `authStore.fetchUser()` when the WebSocket connection is confirmed
|
|
- **Fixed duplicate `authStore` declarations** by declaring it once at the top of `handleMessage` function
|
|
- **Added debug logging** to trace the authentication flow
|
|
|
|
**Before:**
|
|
```javascript
|
|
case "connected":
|
|
console.log("Server confirmed connection:", payload);
|
|
break;
|
|
```
|
|
|
|
**After:**
|
|
```javascript
|
|
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:**
|
|
```javascript
|
|
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
|
|
|
|
1. **User clicks "Login to Steam"** button
|
|
- Frontend redirects to: `${VITE_API_URL}/api/auth/steam`
|
|
|
|
2. **Steam OAuth flow completes**
|
|
- Backend receives callback from Steam
|
|
- Backend creates session and sets HTTP-only cookie
|
|
- Backend redirects user back to frontend
|
|
|
|
3. **Frontend loads** (`App.vue` `onMounted`)
|
|
- `authStore.initialize()` → calls `fetchUser()` → requests `/api/auth/me`
|
|
- `wsStore.connect()` → establishes WebSocket connection
|
|
|
|
4. **WebSocket connects successfully**
|
|
- Backend sends `{ type: "connected", data: { steamId, username, userId } }`
|
|
|
|
5. **WebSocket receives "connected" message** ✨ **NEW**
|
|
- Handler calls `authStore.fetchUser()`
|
|
- Fetches user data from `/api/auth/me` with credentials
|
|
- Updates `authStore.user` and sets `isAuthenticated = true`
|
|
|
|
6. **Navbar reactively updates** 🎉
|
|
- `authStore.isAuthenticated` changes from `false` → `true`
|
|
- Vue's reactivity triggers navbar to show user menu, avatar, balance, etc.
|
|
|
|
---
|
|
|
|
## Deployment Instructions
|
|
|
|
### 1. Build the Frontend
|
|
|
|
```bash
|
|
cd frontend
|
|
npm run build
|
|
```
|
|
|
|
**Expected output:**
|
|
```
|
|
✓ 1588 modules transformed.
|
|
✓ built in 2.80s
|
|
```
|
|
|
|
### 2. Deploy to Production
|
|
|
|
**Option A: Manual deployment on server**
|
|
```bash
|
|
# 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**
|
|
```bash
|
|
# 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 + R` or `Ctrl + 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
|
|
```bash
|
|
# 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:
|
|
```javascript
|
|
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:
|
|
|
|
1. **On App Mount** (`App.vue` → `authStore.initialize()`)
|
|
- Handles the case where user already has a valid session
|
|
- Runs immediately when page loads
|
|
|
|
2. **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 handling
|
|
- `frontend/src/stores/auth.js` - Authentication state management
|
|
- `frontend/src/components/NavBar.vue` - Navbar component (reactive to auth state)
|
|
- `frontend/src/App.vue` - App initialization flow
|
|
- `backend/routes/auth.js` - Steam OAuth and session management
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Navbar Still Not Updating
|
|
|
|
1. **Clear browser cache completely** (not just refresh)
|
|
2. **Check browser console for errors**
|
|
3. **Verify `/api/auth/me` returns user data:**
|
|
```bash
|
|
curl -s https://api.turbotrades.dev/api/auth/me -b cookies.txt | jq
|
|
```
|
|
4. **Check WebSocket connection:**
|
|
- Look for "WebSocket connected" in console
|
|
- Verify no CORS errors
|
|
|
|
### "fetchUser called" But No Response
|
|
|
|
- **Backend issue:** Check PM2 logs
|
|
```bash
|
|
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:
|
|
```nginx
|
|
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) |