All checks were successful
Build Frontend / Build Frontend (push) Successful in 25s
8.5 KiB
8.5 KiB
Ban Notification Feature - Deployment Guide
Overview
Fixed the issue where banned users only saw a toast notification instead of being redirected to the banned page. Now when a user is banned from the admin panel, they are immediately redirected via WebSocket notification.
Problem
When an admin banned a user:
- User's account was updated in database ✅
- User saw a toast notification ❌ (not helpful)
- User could continue using the site until page refresh ❌
/api/auth/mereturned 403, preventing frontend from getting ban info ❌
Solution
1. Real-time WebSocket Notifications
- Backend sends
account_bannedevent to user's active WebSocket connection - Frontend receives event and refreshes auth state
- User is immediately redirected to
/bannedpage
2. Allow Banned Users to Access /api/auth/me
- Modified
middleware/auth.jsto allow banned users to access/api/auth/me - This lets the frontend fetch ban details and redirect properly
- All other endpoints remain blocked for banned users
Changes Made
Backend (routes/admin-management.js)
// Added WebSocket import
import wsManager from "../utils/websocket.js";
// In ban handler, after saving user:
if (wsManager.isUserConnected(user.steamId)) {
if (banned) {
wsManager.sendToUser(user.steamId, {
type: "account_banned",
data: {
banned: true,
reason: user.ban.reason,
bannedAt: new Date(),
bannedUntil: user.ban.expires,
},
timestamp: Date.now(),
});
} else {
wsManager.sendToUser(user.steamId, {
type: "account_unbanned",
data: { banned: false },
timestamp: Date.now(),
});
}
}
Backend (middleware/auth.js)
// Allow banned users to access /api/auth/me
const url = request.url || "";
const routeUrl = request.routeOptions?.url || "";
const isAuthMeEndpoint =
url.includes("/auth/me") ||
routeUrl === "/me" ||
routeUrl.endsWith("/me");
if (!isAuthMeEndpoint) {
// Block access to all other endpoints
return reply.status(403).send({ /* ban error */ });
}
// If it's /api/auth/me, continue and attach user with ban info
Frontend (frontend/src/stores/websocket.js)
case "account_banned":
console.log("🔨 User account has been banned:", payload);
// Update the auth store - router guard will handle redirect
authStore.fetchUser().then(() => {
// Disconnect WebSocket since user is banned
disconnect();
// The router guard will automatically redirect to /banned page
window.location.href = "/banned";
});
break;
case "account_unbanned":
console.log("✅ User account has been unbanned:", payload);
// Update the auth store to reflect unbanned status
authStore.fetchUser().then(() => {
window.location.href = "/";
toast.success("Your account has been unbanned. Welcome back!");
});
break;
How It Works
Ban Flow
- Admin bans user → Clicks "Ban" button in admin panel
- Backend saves ban → Updates User record in MongoDB
- WebSocket notification → Server sends
account_bannedevent - Frontend receives → WebSocket store handles the event
- Auth refresh → Calls
/api/auth/me(now allowed for banned users) - Router guard → Sees
authStore.isBanned = true - Redirect → User sent to
/bannedpage immediately
Unban Flow
- Admin unbans user → Clicks "Unban" button
- Backend clears ban → Removes ban from User record
- WebSocket notification → Server sends
account_unbannedevent - Frontend receives → Refreshes auth and redirects to home
- Success toast → "Your account has been unbanned. Welcome back!"
Testing
Test Ban Notification
- Open browser window as User A (logged in)
- Open another window as Admin
- Admin bans User A from admin panel
- User A should immediately be redirected to
/bannedpage /bannedpage shows:- Account suspended message
- Ban reason
- Ban duration (or "permanent")
- Contact support button
- Logout button
Test Unban Notification
- User A is on
/bannedpage - Admin unbans User A
- User A should immediately be redirected to home page
- Success toast appears
Test Without WebSocket
- User A is logged in but WebSocket disconnected
- Admin bans User A
- User A continues using site temporarily
- On next page navigation, router guard catches ban
- User A redirected to
/bannedpage
Deployment Steps
1. Deploy Backend
# SSH to production server
ssh user@api.turbotrades.dev
# Navigate to project
cd /path/to/TurboTrades
# Pull latest changes (if using git)
git pull
# Or manually upload files:
# - routes/admin-management.js
# - middleware/auth.js
# Restart backend
pm2 restart turbotrades-backend
# Verify backend is running
pm2 logs turbotrades-backend --lines 50
2. Deploy Frontend
# On your local machine (Windows)
cd C:\Users\dg-ho\Documents\projects\TurboTrades\frontend
npm run build
# On production server
cd /path/to/TurboTrades/frontend
npm run build
sudo cp -r dist/* /var/www/html/turbotrades/
# Verify files copied
ls -la /var/www/html/turbotrades/
3. Test in Production
# Check backend logs for WebSocket connections
pm2 logs turbotrades-backend --lines 100 | grep WebSocket
# Test ban flow
curl -X POST https://api.turbotrades.dev/api/admin/users/{userId}/ban \
-H "Content-Type: application/json" \
-H "Cookie: accessToken=YOUR_ADMIN_TOKEN" \
-d '{"banned": true, "reason": "Test ban", "duration": 1}'
Files Changed
Backend
- ✅
routes/admin-management.js- Added WebSocket ban notifications - ✅
middleware/auth.js- Allow banned users to access/api/auth/me
Frontend
- ✅
frontend/src/stores/websocket.js- Handle ban/unban events - ✅
frontend/src/views/BannedPage.vue- Already exists (no changes needed) - ✅
frontend/src/router/index.js- Router guard already exists (no changes needed)
Logs to Watch
Backend
📡 Sent ban notification to user {username}
📡 Sent unban notification to user {username}
🔨 Admin {admin} banned user {user} (Reason: {reason})
Frontend Console
🔨 User account has been banned: {banInfo}
✅ User account has been unbanned: {unbanInfo}
🔵 Calling authStore.fetchUser() from WebSocket connected handler
Troubleshooting
User not redirected after ban
- Check if WebSocket is connected:
wsManager.isUserConnected(steamId) - Check browser console for WebSocket messages
- Verify
/api/auth/mereturns 200 with ban info (not 403)
403 Error on /api/auth/me
- Check
middleware/auth.jsdeployed correctly - Verify URL matching logic:
url.includes("/auth/me") - Backend logs should show:
✓ User authenticated: {username}
Ban page not showing
- Verify
authStore.isBannedis true: Check console - Check router guard in
frontend/src/router/index.js - Clear browser cache / hard refresh (Ctrl+Shift+R)
WebSocket not connected
- Check WebSocket URL:
wss://api.turbotrades.dev/ws - Verify Nginx WebSocket proxy configuration
- Check backend WebSocket server is running
Security Notes
✅ Banned users can only access /api/auth/me
- All other endpoints return 403
- Prevents banned users from trading, depositing, etc.
✅ Admins cannot ban other admins
- Check in ban handler:
user.staffLevel >= 3
✅ WebSocket notifications only sent to connected users
- Offline users will see ban on next page load via router guard
Next Steps
- Add ban notification to email (optional)
- Log ban actions for audit trail (already logged to console)
- Add ban appeal form on
/bannedpage (optional) - Add bulk ban WebSocket notifications (if implementing bulk ban)
Related Files
frontend/src/views/BannedPage.vue- The banned page UIfrontend/src/router/index.js- Router guard for ban redirectfrontend/src/stores/auth.js- Auth store withisBannedcomputedroutes/admin-management.js- Admin ban/unban endpointsmiddleware/auth.js- Authentication middlewareutils/websocket.js- WebSocket manager
Deployment Checklist
- Backend code updated
- Frontend code updated
- Frontend built (
npm run build) - Backend restarted (
pm2 restart) - Frontend deployed to web root
- Tested ban flow (admin bans user → user redirected)
- Tested unban flow (admin unbans → user redirected)
- Verified
/api/auth/meworks for banned users - Checked browser console for errors
- Checked backend logs for WebSocket messages