Files
TurboTrades/BAN_NOTIFICATION_FIX.md
iDefineHD 2aff879291
All checks were successful
Build Frontend / Build Frontend (push) Successful in 25s
added ban redirect correctly
2026-01-11 03:55:47 +00:00

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:

  1. User's account was updated in database
  2. User saw a toast notification (not helpful)
  3. User could continue using the site until page refresh
  4. /api/auth/me returned 403, preventing frontend from getting ban info

Solution

1. Real-time WebSocket Notifications

  • Backend sends account_banned event to user's active WebSocket connection
  • Frontend receives event and refreshes auth state
  • User is immediately redirected to /banned page

2. Allow Banned Users to Access /api/auth/me

  • Modified middleware/auth.js to 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

  1. Admin bans user → Clicks "Ban" button in admin panel
  2. Backend saves ban → Updates User record in MongoDB
  3. WebSocket notification → Server sends account_banned event
  4. Frontend receives → WebSocket store handles the event
  5. Auth refresh → Calls /api/auth/me (now allowed for banned users)
  6. Router guard → Sees authStore.isBanned = true
  7. Redirect → User sent to /banned page immediately

Unban Flow

  1. Admin unbans user → Clicks "Unban" button
  2. Backend clears ban → Removes ban from User record
  3. WebSocket notification → Server sends account_unbanned event
  4. Frontend receives → Refreshes auth and redirects to home
  5. Success toast → "Your account has been unbanned. Welcome back!"

Testing

Test Ban Notification

  1. Open browser window as User A (logged in)
  2. Open another window as Admin
  3. Admin bans User A from admin panel
  4. User A should immediately be redirected to /banned page
  5. /banned page shows:
    • Account suspended message
    • Ban reason
    • Ban duration (or "permanent")
    • Contact support button
    • Logout button

Test Unban Notification

  1. User A is on /banned page
  2. Admin unbans User A
  3. User A should immediately be redirected to home page
  4. Success toast appears

Test Without WebSocket

  1. User A is logged in but WebSocket disconnected
  2. Admin bans User A
  3. User A continues using site temporarily
  4. On next page navigation, router guard catches ban
  5. User A redirected to /banned page

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

  1. Check if WebSocket is connected: wsManager.isUserConnected(steamId)
  2. Check browser console for WebSocket messages
  3. Verify /api/auth/me returns 200 with ban info (not 403)

403 Error on /api/auth/me

  1. Check middleware/auth.js deployed correctly
  2. Verify URL matching logic: url.includes("/auth/me")
  3. Backend logs should show: ✓ User authenticated: {username}

Ban page not showing

  1. Verify authStore.isBanned is true: Check console
  2. Check router guard in frontend/src/router/index.js
  3. Clear browser cache / hard refresh (Ctrl+Shift+R)

WebSocket not connected

  1. Check WebSocket URL: wss://api.turbotrades.dev/ws
  2. Verify Nginx WebSocket proxy configuration
  3. 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 /banned page (optional)
  • Add bulk ban WebSocket notifications (if implementing bulk ban)
  • frontend/src/views/BannedPage.vue - The banned page UI
  • frontend/src/router/index.js - Router guard for ban redirect
  • frontend/src/stores/auth.js - Auth store with isBanned computed
  • routes/admin-management.js - Admin ban/unban endpoints
  • middleware/auth.js - Authentication middleware
  • utils/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/me works for banned users
  • Checked browser console for errors
  • Checked backend logs for WebSocket messages