фикс
This commit is contained in:
parent
b8369c53c3
commit
4ef4c5f428
@ -113,6 +113,7 @@ const getUserDetails = async (req, res) => {
|
||||
const toggleUserActive = async (req, res) => {
|
||||
try {
|
||||
const userId = req.params.id;
|
||||
const { reason } = req.body; // Добавляем возможность указать причину блокировки
|
||||
const user = await User.findById(userId);
|
||||
|
||||
if (!user) {
|
||||
@ -124,10 +125,77 @@ const toggleUserActive = async (req, res) => {
|
||||
return res.status(403).json({ message: 'Невозможно заблокировать администратора' });
|
||||
}
|
||||
|
||||
// Получаем доступ к io для отправки уведомлений
|
||||
const io = req.app.get('io');
|
||||
|
||||
// Изменяем статус активности на противоположный
|
||||
const wasActive = user.isActive;
|
||||
user.isActive = !user.isActive;
|
||||
await user.save();
|
||||
|
||||
// Если пользователь был активным и теперь блокируется
|
||||
if (wasActive && !user.isActive) {
|
||||
// Находим активное соединение пользователя
|
||||
const activeUsers = Array.from(io.sockets.sockets).map(socket => socket[1]);
|
||||
const userSockets = activeUsers.filter(socket => {
|
||||
const userData = socket.handshake.query;
|
||||
return userData && userData.userId === userId;
|
||||
});
|
||||
|
||||
// Получаем информацию о пользователе из массива activeUsers
|
||||
// (этот массив хранится в server.js)
|
||||
const activeUsersArray = Array.from(io.sockets.adapter.rooms).filter(room => {
|
||||
return room[1].has(room[0]); // Фильтруем комнаты, где id комнаты совпадает с id сокета
|
||||
}).map(room => {
|
||||
const socket = io.sockets.sockets.get(room[0]);
|
||||
return socket && socket.handshake.query.userId
|
||||
? { userId: socket.handshake.query.userId, socketId: room[0] }
|
||||
: null;
|
||||
}).filter(Boolean);
|
||||
|
||||
// Находим сокет пользователя
|
||||
const userSocketInfo = activeUsersArray.find(u => u.userId === userId);
|
||||
|
||||
// Если пользователь онлайн, отправляем уведомление о блокировке
|
||||
if (userSocketInfo && userSocketInfo.socketId) {
|
||||
io.to(userSocketInfo.socketId).emit("account_blocked", {
|
||||
message: 'Ваш аккаунт был заблокирован администратором.',
|
||||
reason: reason || 'Нарушение правил сервиса',
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
console.log(`[AdminController] Отправлено уведомление о блокировке пользователю ${userId}`);
|
||||
} else {
|
||||
// Если пользователь не в сети, просто оставляем лог
|
||||
console.log(`[AdminController] Пользователь ${userId} заблокирован, но не находится в сети для отправки уведомления`);
|
||||
}
|
||||
}
|
||||
// Если пользователь был неактивным и теперь разблокируется
|
||||
else if (!wasActive && user.isActive) {
|
||||
// Используем тот же подход для поиска сокетов пользователя
|
||||
const activeUsersArray = Array.from(io.sockets.adapter.rooms).filter(room => {
|
||||
return room[1].has(room[0]);
|
||||
}).map(room => {
|
||||
const socket = io.sockets.sockets.get(room[0]);
|
||||
return socket && socket.handshake.query.userId
|
||||
? { userId: socket.handshake.query.userId, socketId: room[0] }
|
||||
: null;
|
||||
}).filter(Boolean);
|
||||
|
||||
// Находим сокет пользователя (если он вдруг залогинился с другим статусом)
|
||||
const userSocketInfo = activeUsersArray.find(u => u.userId === userId);
|
||||
|
||||
// Если пользователь онлайн, отправляем уведомление о разблокировке
|
||||
if (userSocketInfo && userSocketInfo.socketId) {
|
||||
io.to(userSocketInfo.socketId).emit("account_unblocked", {
|
||||
message: 'Ваш аккаунт был разблокирован администратором.',
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
console.log(`[AdminController] Отправлено уведомление о разблокировке пользователю ${userId}`);
|
||||
} else {
|
||||
console.log(`[AdminController] Пользователь ${userId} разблокирован, но не находится в сети для отправки уведомления`);
|
||||
}
|
||||
}
|
||||
|
||||
res.json({
|
||||
message: user.isActive ? 'Пользователь разблокирован' : 'Пользователь заблокирован',
|
||||
isActive: user.isActive
|
||||
|
51
src/auth.js
51
src/auth.js
@ -127,6 +127,55 @@ async function logout() {
|
||||
console.log('Пользователь вышел из системы.');
|
||||
}
|
||||
|
||||
// Функция обработки события блокировки аккаунта
|
||||
function handleAccountBlocked(data) {
|
||||
// Создаем объект с информацией о блокировке
|
||||
const blockInfo = {
|
||||
blocked: true,
|
||||
message: data?.message || 'Ваш аккаунт был заблокирован администратором.',
|
||||
reason: data?.reason || 'Нарушение правил сервиса',
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
|
||||
// Сохраняем информацию о блокировке в localStorage для отображения на странице логина
|
||||
localStorage.setItem('accountBlockedInfo', JSON.stringify(blockInfo));
|
||||
|
||||
// Выполняем выход пользователя
|
||||
user.value = null;
|
||||
token.value = null;
|
||||
localStorage.removeItem('userToken');
|
||||
|
||||
// Перенаправляем на страницу входа с уведомлением о блокировке
|
||||
router.push({
|
||||
name: 'Login',
|
||||
query: { blocked: 'true' }
|
||||
});
|
||||
|
||||
console.log('Пользователь был разлогинен из-за блокировки аккаунта.');
|
||||
}
|
||||
|
||||
// Функция обработки события разблокировки аккаунта
|
||||
function handleAccountUnblocked(data) {
|
||||
console.log('Получено уведомление о разблокировке аккаунта:', data);
|
||||
|
||||
// Удаляем информацию о блокировке, если она была сохранена
|
||||
localStorage.removeItem('accountBlockedInfo');
|
||||
|
||||
// Показываем уведомление пользователю, если он сейчас в приложении
|
||||
// Можно использовать какую-то систему уведомлений в приложении
|
||||
// или просто логировать это событие
|
||||
|
||||
// Если пользователь не залогинен, но его аккаунт был разблокирован,
|
||||
// можно показать соответствующее сообщение при следующем входе
|
||||
localStorage.setItem('accountUnblockedInfo', JSON.stringify({
|
||||
unblocked: true,
|
||||
message: data?.message || 'Ваш аккаунт был разблокирован.',
|
||||
timestamp: new Date().toISOString()
|
||||
}));
|
||||
|
||||
console.log('Аккаунт пользователя разблокирован.');
|
||||
}
|
||||
|
||||
// Экспортируем то, что понадобится в компонентах
|
||||
export function useAuth() {
|
||||
return {
|
||||
@ -137,5 +186,7 @@ export function useAuth() {
|
||||
register,
|
||||
logout,
|
||||
fetchUser, // Эту функцию нужно будет вызвать при инициализации приложения
|
||||
handleAccountBlocked, // Добавляем функцию обработки блокировки аккаунта
|
||||
handleAccountUnblocked // Добавляем функцию обработки разблокировки аккаунта
|
||||
};
|
||||
}
|
@ -8,7 +8,7 @@ let socket;
|
||||
const SOCKET_URL = '/'; // Vite будет перехватывать /socket.io/ путь
|
||||
|
||||
export const connectSocket = () => {
|
||||
const { user, isAuthenticated } = useAuth();
|
||||
const { user, isAuthenticated, handleAccountBlocked, handleAccountUnblocked } = useAuth();
|
||||
|
||||
if (isAuthenticated.value && user.value && user.value._id) {
|
||||
// Подключаемся только если пользователь аутентифицирован и есть ID
|
||||
@ -46,6 +46,30 @@ export const connectSocket = () => {
|
||||
console.error('[SocketService] Ошибка подключения к Socket.IO:', error.message, error.data);
|
||||
});
|
||||
|
||||
// Добавляем обработчик для события блокировки аккаунта
|
||||
socket.on('account_blocked', (data) => {
|
||||
console.log('[SocketService] Получено уведомление о блокировке аккаунта:', data);
|
||||
// Вызываем функцию обработки блокировки из auth.js тихо, без показа браузерного уведомления
|
||||
// Отложенный вызов, чтобы избежать показа стандартного уведомления браузера
|
||||
setTimeout(() => {
|
||||
handleAccountBlocked(data);
|
||||
}, 10);
|
||||
});
|
||||
|
||||
// Добавляем обработчик для события разблокировки аккаунта
|
||||
socket.on('account_unblocked', (data) => {
|
||||
console.log('[SocketService] Получено уведомление о разблокировке аккаунта:', data);
|
||||
// Аналогично блокировке, используем setTimeout для предотвращения браузерного уведомления
|
||||
setTimeout(() => {
|
||||
// Если есть функция handleAccountUnblocked, вызываем её
|
||||
if (typeof handleAccountUnblocked === 'function') {
|
||||
handleAccountUnblocked(data);
|
||||
} else {
|
||||
console.log('[SocketService] Аккаунт разблокирован, но обработчик не определен');
|
||||
}
|
||||
}, 10);
|
||||
});
|
||||
|
||||
// Можно здесь же слушать глобальные события, если нужно
|
||||
// socket.on('getUsers', (users) => {
|
||||
// console.log('[SocketService] Получен список активных пользователей:', users);
|
||||
|
@ -16,6 +16,18 @@
|
||||
<p>Рады видеть вас снова!</p>
|
||||
</div>
|
||||
|
||||
<!-- Добавляем показ информации о блокировке аккаунта -->
|
||||
<div v-if="accountBlocked" class="blocked-account-message">
|
||||
<i class="bi-shield-exclamation"></i>
|
||||
<div class="blocked-message-content">
|
||||
<h3>Аккаунт заблокирован</h3>
|
||||
<p>{{ blockedInfo.message }}</p>
|
||||
<p v-if="blockedInfo.reason" class="block-reason">
|
||||
<strong>Причина:</strong> {{ blockedInfo.reason }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form @submit.prevent="handleLogin" class="login-form">
|
||||
<div class="form-group">
|
||||
<label for="email">
|
||||
@ -80,16 +92,30 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted } from 'vue';
|
||||
import { ref, onMounted, onUnmounted, computed } from 'vue';
|
||||
import { useAuth } from '@/auth';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
const route = useRoute();
|
||||
const email = ref('');
|
||||
const password = ref('');
|
||||
const errorMessage = ref('');
|
||||
const loading = ref(false);
|
||||
const blockedInfo = ref({
|
||||
blocked: false,
|
||||
message: 'Ваш аккаунт был заблокирован администратором.',
|
||||
reason: 'Нарушение правил сервиса',
|
||||
timestamp: ''
|
||||
});
|
||||
|
||||
const { login } = useAuth();
|
||||
|
||||
// Проверяем, был ли аккаунт заблокирован
|
||||
const accountBlocked = computed(() => {
|
||||
// Проверяем query параметр и информацию из localStorage
|
||||
return route.query.blocked === 'true' || blockedInfo.value.blocked;
|
||||
});
|
||||
|
||||
// Функция для блокировки прокрутки страницы
|
||||
const preventScroll = () => {
|
||||
document.body.style.overflow = 'hidden';
|
||||
@ -108,6 +134,23 @@ const enableScroll = () => {
|
||||
|
||||
onMounted(() => {
|
||||
preventScroll(); // Блокируем прокрутку при монтировании компонента
|
||||
|
||||
// Проверяем, есть ли информация о блокировке в localStorage
|
||||
const storedBlockInfo = localStorage.getItem('accountBlockedInfo');
|
||||
if (storedBlockInfo) {
|
||||
try {
|
||||
const parsedInfo = JSON.parse(storedBlockInfo);
|
||||
blockedInfo.value = parsedInfo;
|
||||
|
||||
// Если форма загружается с query параметром blocked=true,
|
||||
// показываем сообщение об ошибке
|
||||
if (route.query.blocked === 'true') {
|
||||
errorMessage.value = 'Ваш аккаунт был заблокирован администратором.';
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Ошибка при парсинге информации о блокировке:', e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
@ -606,4 +649,78 @@ const handleLogin = async () => {
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.blocked-account-message {
|
||||
background-color: rgba(220, 53, 69, 0.15);
|
||||
border: 1px solid rgba(220, 53, 69, 0.3);
|
||||
border-radius: 10px;
|
||||
padding: 1.25rem 1rem;
|
||||
margin-bottom: 1.5rem;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 1rem;
|
||||
text-align: left;
|
||||
animation: fadeInDown 0.5s ease;
|
||||
border-left: 4px solid rgba(220, 53, 69, 0.7);
|
||||
}
|
||||
|
||||
.blocked-account-message i {
|
||||
font-size: 1.5rem;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
|
||||
.blocked-message-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.blocked-message-content h3 {
|
||||
margin: 0 0 0.5rem 0;
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.blocked-message-content p {
|
||||
margin: 0;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.block-reason {
|
||||
margin-top: 0.5rem !important;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@keyframes fadeInDown {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Адаптивность для блока с информацией о блокировке */
|
||||
@media (max-width: 576px) {
|
||||
.blocked-account-message {
|
||||
padding: 1rem 0.8rem;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.blocked-account-message i {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
.blocked-message-content h3 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.blocked-message-content p {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
x
Reference in New Issue
Block a user