added ban redirect correctly
All checks were successful
Build Frontend / Build Frontend (push) Successful in 25s
All checks were successful
Build Frontend / Build Frontend (push) Successful in 25s
This commit is contained in:
277
BAN_NOTIFICATION_FIX.md
Normal file
277
BAN_NOTIFICATION_FIX.md
Normal file
@@ -0,0 +1,277 @@
|
||||
# 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`)
|
||||
```javascript
|
||||
// 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`)
|
||||
```javascript
|
||||
// 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`)
|
||||
```javascript
|
||||
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
|
||||
```bash
|
||||
# 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
|
||||
```bash
|
||||
# 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
|
||||
```bash
|
||||
# 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)
|
||||
|
||||
## Related Files
|
||||
- `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
|
||||
Reference in New Issue
Block a user