фикс
This commit is contained in:
parent
84cdeb8ff0
commit
1d4567411b
@ -113,7 +113,7 @@ const getUserDetails = async (req, res) => {
|
||||
const toggleUserActive = async (req, res) => {
|
||||
try {
|
||||
const userId = req.params.id;
|
||||
const { reason } = req.body; // Добавляем возможность указать причину блокировки
|
||||
const { reason } = req.body; // Причина блокировки
|
||||
const user = await User.findById(userId);
|
||||
|
||||
if (!user) {
|
||||
@ -132,9 +132,22 @@ const toggleUserActive = async (req, res) => {
|
||||
return res.status(500).json({ message: 'Внутренняя ошибка сервера: Socket.IO недоступен' });
|
||||
}
|
||||
|
||||
// Изменяем статус активности на противоположный
|
||||
const wasActive = user.isActive;
|
||||
user.isActive = !user.isActive;
|
||||
// Изменяем статус блокировки на противоположный
|
||||
const wasBlocked = user.blocked;
|
||||
user.blocked = !user.blocked;
|
||||
|
||||
if (user.blocked) {
|
||||
// Устанавливаем данные блокировки
|
||||
user.blockReason = reason || 'Нарушение правил сервиса';
|
||||
user.blockedAt = new Date();
|
||||
user.blockedBy = req.user._id;
|
||||
} else {
|
||||
// Очищаем данные блокировки
|
||||
user.blockReason = null;
|
||||
user.blockedAt = null;
|
||||
user.blockedBy = null;
|
||||
}
|
||||
|
||||
await user.save();
|
||||
|
||||
// Получаем глобальный массив активных пользователей из server.js
|
||||
@ -142,21 +155,20 @@ const toggleUserActive = async (req, res) => {
|
||||
|
||||
console.log(`[AdminController] Активные пользователи:`, activeUsers);
|
||||
|
||||
// Если пользователь был активным и теперь блокируется
|
||||
if (wasActive && !user.isActive) {
|
||||
console.log(`[AdminController] Блокировка пользователя ${userId}. Причина: ${reason || 'Не указана'}`);
|
||||
// Если пользователь теперь заблокирован
|
||||
if (!wasBlocked && user.blocked) {
|
||||
console.log(`[AdminController] Блокировка пользователя ${userId}. Причина: ${user.blockReason}`);
|
||||
|
||||
// Создаем объект с информацией о блокировке
|
||||
const blockData = {
|
||||
message: 'Ваш аккаунт был заблокирован администратором.',
|
||||
reason: reason || 'Нарушение правил сервиса',
|
||||
reason: user.blockReason,
|
||||
timestamp: new Date().toISOString(),
|
||||
blocked: true,
|
||||
userId: user._id.toString()
|
||||
};
|
||||
|
||||
// Отправляем глобальное событие блокировки всем клиентам
|
||||
// Это обеспечит получение уведомления даже если в activeUsers неактуальная информация
|
||||
io.emit('global_user_blocked', {
|
||||
userId: user._id.toString(),
|
||||
timestamp: new Date().toISOString()
|
||||
@ -180,9 +192,6 @@ const toggleUserActive = async (req, res) => {
|
||||
console.log(`[AdminController] Отправка уведомления о блокировке на сокет: ${userSocket.socketId}`);
|
||||
socket.emit("account_blocked", blockData);
|
||||
notificationSent = true;
|
||||
|
||||
// НЕ отключаем сокет принудительно - пусть пользователь остается подключенным
|
||||
// для получения уведомлений о разблокировке
|
||||
} else {
|
||||
console.log(`[AdminController] Сокет не найден или не подключен для ID: ${userSocket.socketId}`);
|
||||
}
|
||||
@ -197,15 +206,12 @@ const toggleUserActive = async (req, res) => {
|
||||
console.log(`[AdminController] Пользователь ${userId} не найден в активных соединениях`);
|
||||
}
|
||||
|
||||
// НЕ очищаем записи в списке активных пользователей - оставляем их подключенными
|
||||
// для возможности получения уведомлений о разблокировке
|
||||
|
||||
if (!notificationSent) {
|
||||
console.log(`[AdminController] Уведомление о блокировке не было отправлено напрямую, но было отправлено глобальное уведомление`);
|
||||
}
|
||||
}
|
||||
// Если пользователь был неактивным и теперь разблокируется
|
||||
else if (!wasActive && user.isActive) {
|
||||
// Если пользователь был заблокирован и теперь разблокируется
|
||||
else if (wasBlocked && !user.blocked) {
|
||||
console.log(`[AdminController] Разблокировка пользователя ${userId}`);
|
||||
|
||||
// Формируем объект с информацией о разблокировке для отправки через сокет
|
||||
@ -213,27 +219,26 @@ const toggleUserActive = async (req, res) => {
|
||||
message: 'Ваш аккаунт был разблокирован администратором.',
|
||||
timestamp: new Date().toISOString(),
|
||||
userId: user._id.toString(),
|
||||
unblockType: 'admin_action', // Указываем тип разблокировки
|
||||
unblockType: 'admin_action',
|
||||
userName: user.name,
|
||||
unblockData: {
|
||||
canRestoreSession: true, // Флаг возможности восстановления сессии
|
||||
canRestoreSession: true,
|
||||
}
|
||||
};
|
||||
|
||||
// Отправляем событие разблокировки всем клиентам (анонимно)
|
||||
// Отправляем событие разблокировки всем клиентам
|
||||
io.emit('global_user_unblocked', {
|
||||
userId: user._id.toString(),
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
// Ищем пользователя среди активных пользователей (на случай, если он онлайн с другим аккаунтом)
|
||||
// Ищем пользователя среди активных пользователей
|
||||
const userSockets = activeUsers.filter(u => u.userId === userId);
|
||||
let notificationSent = false;
|
||||
|
||||
if (userSockets.length > 0) {
|
||||
for (const userSocket of userSockets) {
|
||||
try {
|
||||
// Безопасно получаем сокет и проверяем его существование
|
||||
if (io.sockets && io.sockets.sockets) {
|
||||
const socket = io.sockets.sockets.get(userSocket.socketId);
|
||||
|
||||
@ -261,8 +266,9 @@ const toggleUserActive = async (req, res) => {
|
||||
}
|
||||
|
||||
res.json({
|
||||
message: user.isActive ? 'Пользователь разблокирован' : 'Пользователь заблокирован',
|
||||
isActive: user.isActive
|
||||
message: user.blocked ? 'Пользователь заблокирован' : 'Пользователь разблокирован',
|
||||
blocked: user.blocked,
|
||||
blockReason: user.blockReason
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Ошибка при изменении статуса пользователя:', error);
|
||||
|
@ -110,7 +110,9 @@ const loginUser = async (req, res, next) => {
|
||||
if (!email || !password) {
|
||||
res.status(400);
|
||||
throw new Error('Пожалуйста, укажите email и пароль.');
|
||||
} // Проверяем наличие специального логина для администратора
|
||||
}
|
||||
|
||||
// Проверяем наличие специального логина для администратора
|
||||
if (email === 'admin') {
|
||||
// Для логина "admin" проверяем аккаунт admin@example.com
|
||||
console.log('Попытка входа с административным логином через "admin"');
|
||||
@ -183,7 +185,9 @@ const loginUser = async (req, res, next) => {
|
||||
throw new Error('Неверный логин или пароль.');
|
||||
}
|
||||
return;
|
||||
} // Перед проверкой обычных пользователей, проверим наличие админа с email
|
||||
}
|
||||
|
||||
// Перед проверкой обычных пользователей, проверим наличие админа с email
|
||||
if (email === 'admin@example.com') {
|
||||
console.log('Попытка входа с email администратора: admin@example.com');
|
||||
// Проверяем наличие админа с email admin@example.com
|
||||
@ -232,57 +236,38 @@ const loginUser = async (req, res, next) => {
|
||||
const isMatch = await user.matchPassword(password);
|
||||
console.log('Результат проверки пароля:', isMatch ? 'Успешно' : 'Неверный пароль');
|
||||
|
||||
// Проверка если аккаунт неактивен (заблокирован)
|
||||
if (isMatch && !user.isActive && !user.isAdmin) {
|
||||
console.log('[AuthController] Пользователь заблокирован, но создаем токен для восстановления сессии');
|
||||
|
||||
// Создаем токен для последующего восстановления сессии после разблокировки
|
||||
const restorationToken = generateToken(user._id);
|
||||
|
||||
// Обновляем дату последнего входа даже для заблокированного пользователя
|
||||
user.lastSeen = new Date();
|
||||
await user.save();
|
||||
|
||||
res.status(403);
|
||||
const error = new Error('Ваш аккаунт заблокирован. Пожалуйста, обратитесь в поддержку.');
|
||||
error.blocked = true;
|
||||
error.userId = user._id;
|
||||
error.restorationToken = restorationToken; // Добавляем токен для восстановления
|
||||
error.userName = user.name;
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (isMatch) {
|
||||
res.status(200).json({
|
||||
_id: user._id,
|
||||
name: user.name,
|
||||
email: user.email,
|
||||
isAdmin: user.isAdmin || false, // Добавляем информацию о правах администратора
|
||||
token: generateToken(user._id),
|
||||
message: 'Вход выполнен успешно!'
|
||||
});
|
||||
} else {
|
||||
if (!isMatch) {
|
||||
res.status(401);
|
||||
throw new Error('Неверный email или пароль.');
|
||||
}
|
||||
|
||||
// Проверяем, заблокирован ли пользователь
|
||||
if (user.blocked && !user.isAdmin) {
|
||||
console.log('[AuthController] Пользователь заблокирован');
|
||||
res.status(403);
|
||||
throw new Error(`Ваш аккаунт заблокирован. ${user.blockReason || 'Обратитесь в поддержку.'}`);
|
||||
}
|
||||
|
||||
// Обновляем дату последнего входа
|
||||
user.lastSeen = new Date();
|
||||
await user.save();
|
||||
|
||||
res.status(200).json({
|
||||
_id: user._id,
|
||||
name: user.name,
|
||||
email: user.email,
|
||||
isAdmin: user.isAdmin || false,
|
||||
blocked: user.blocked || false,
|
||||
token: generateToken(user._id),
|
||||
message: 'Вход выполнен успешно!'
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Ошибка при входе:', error.message);
|
||||
if (!res.statusCode || res.statusCode < 400) {
|
||||
res.status(401);
|
||||
}
|
||||
|
||||
// Специальная обработка для заблокированных аккаунтов
|
||||
if (error.blocked && error.restorationToken) {
|
||||
return res.json({
|
||||
message: error.message,
|
||||
blocked: true,
|
||||
userId: error.userId,
|
||||
restorationToken: error.restorationToken,
|
||||
userName: error.userName,
|
||||
stack: process.env.NODE_ENV === 'production' ? null : error.stack
|
||||
});
|
||||
}
|
||||
|
||||
res.json({ message: error.message, stack: process.env.NODE_ENV === 'production' ? null : error.stack });
|
||||
}
|
||||
};
|
||||
@ -307,7 +292,9 @@ const getMe = async (req, res, next) => {
|
||||
photos: req.user.photos,
|
||||
location: req.user.location,
|
||||
preferences: req.user.preferences,
|
||||
isAdmin: req.user.isAdmin || false, // Добавляем информацию об административных правах
|
||||
isAdmin: req.user.isAdmin || false,
|
||||
blocked: req.user.blocked || false,
|
||||
blockReason: req.user.blockReason,
|
||||
createdAt: req.user.createdAt,
|
||||
updatedAt: req.user.updatedAt,
|
||||
});
|
||||
|
@ -47,12 +47,23 @@ const protect = async (req, res, next) => {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
// Проверяем, не заблокирован ли пользователь
|
||||
if (req.user.blocked && !req.user.isAdmin) {
|
||||
console.log('[DEBUG] protect middleware - User is blocked');
|
||||
const err = new Error('Ваш аккаунт заблокирован администратором.');
|
||||
err.statusCode = 403;
|
||||
err.blocked = true;
|
||||
err.blockReason = req.user.blockReason;
|
||||
return next(err);
|
||||
}
|
||||
|
||||
// Добавляем отладочное логирование для проверки прав администратора
|
||||
console.log('[DEBUG] protect middleware - User loaded:', {
|
||||
id: req.user._id,
|
||||
name: req.user.name,
|
||||
email: req.user.email,
|
||||
isAdmin: req.user.isAdmin
|
||||
isAdmin: req.user.isAdmin,
|
||||
blocked: req.user.blocked
|
||||
});
|
||||
|
||||
console.log('[DEBUG] protect middleware - User authenticated, calling next()');
|
||||
|
@ -69,6 +69,23 @@ const userSchema = new mongoose.Schema(
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
blocked: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
blockReason: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
blockedAt: {
|
||||
type: Date,
|
||||
default: null,
|
||||
},
|
||||
blockedBy: {
|
||||
type: mongoose.Schema.Types.ObjectId,
|
||||
ref: 'User',
|
||||
default: null,
|
||||
},
|
||||
lastSeen: {
|
||||
type: Date,
|
||||
default: Date.now,
|
||||
|
92
src/auth.js
92
src/auth.js
@ -24,38 +24,6 @@ function setUserData(userData, userToken) {
|
||||
// Функция для загрузки данных пользователя, если токен есть (например, при обновлении страницы)
|
||||
async function fetchUser() {
|
||||
if (token.value) {
|
||||
// Проверяем, есть ли информация о блокировке в localStorage
|
||||
const blockedInfoStr = localStorage.getItem('accountBlockedInfo');
|
||||
if (blockedInfoStr) {
|
||||
try {
|
||||
const blockedInfo = JSON.parse(blockedInfoStr);
|
||||
if (blockedInfo.blocked) {
|
||||
console.log('[Auth] Обнаружена информация о блокировке в localStorage, выполняем выход');
|
||||
|
||||
// Показываем уведомление о блокировке
|
||||
const notificationEvent = new CustomEvent('show-toast', {
|
||||
detail: {
|
||||
message: blockedInfo.message || 'Ваш аккаунт заблокирован администратором.',
|
||||
type: 'error',
|
||||
duration: 10000
|
||||
}
|
||||
});
|
||||
window.dispatchEvent(notificationEvent);
|
||||
|
||||
// Выходим из системы
|
||||
await logout();
|
||||
|
||||
// Перенаправляем на страницу входа с параметром блокировки
|
||||
router.replace({ path: '/login', query: { blocked: 'true' } });
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Auth] Ошибка при парсинге информации о блокировке:', error);
|
||||
// Удаляем поврежденные данные
|
||||
localStorage.removeItem('accountBlockedInfo');
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('Пытаемся загрузить пользователя с токеном из localStorage...');
|
||||
const response = await api.getMe(); // Используем наш API сервис
|
||||
@ -70,46 +38,27 @@ async function fetchUser() {
|
||||
// Добавляем дополнительное логирование для отладки
|
||||
console.log('Получены данные пользователя:', response.data);
|
||||
console.log('Значение isAdmin в ответе:', response.data.isAdmin);
|
||||
console.log('Статус блокировки:', response.data.blocked);
|
||||
|
||||
// Проверяем, не заблокирован ли пользователь
|
||||
if (response.data.blocked) {
|
||||
console.log('[Auth] Пользователь заблокирован, выполняем принудительный выход');
|
||||
|
||||
// Сохраняем информацию о блокировке
|
||||
const blockedInfo = {
|
||||
blocked: true,
|
||||
message: 'Ваш аккаунт заблокирован администратором.',
|
||||
reason: response.data.blockReason || 'Нарушение правил сервиса',
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
localStorage.setItem('accountBlockedInfo', JSON.stringify(blockedInfo));
|
||||
// Показываем уведомление о блокировке
|
||||
const notificationEvent = new CustomEvent('show-toast', {
|
||||
detail: {
|
||||
message: `Ваш аккаунт заблокирован. ${response.data.blockReason || 'Обратитесь в поддержку.'}`,
|
||||
type: 'error',
|
||||
duration: 10000
|
||||
}
|
||||
});
|
||||
window.dispatchEvent(notificationEvent);
|
||||
|
||||
// Выходим из системы
|
||||
await logout();
|
||||
return;
|
||||
}
|
||||
|
||||
// Проверяем, была ли разблокировка (если есть информация о предыдущей блокировке)
|
||||
const blockedInfoStr = localStorage.getItem('accountBlockedInfo');
|
||||
if (blockedInfoStr) {
|
||||
console.log('[Auth] Обнаружена предыдущая блокировка, пользователь теперь разблокирован');
|
||||
|
||||
// Удаляем информацию о блокировке
|
||||
localStorage.removeItem('accountBlockedInfo');
|
||||
|
||||
// Показываем уведомление о разблокировке
|
||||
setTimeout(() => {
|
||||
const notificationEvent = new CustomEvent('show-toast', {
|
||||
detail: {
|
||||
message: 'Ваш аккаунт был разблокирован. Добро пожаловать обратно!',
|
||||
type: 'success',
|
||||
duration: 5000
|
||||
}
|
||||
});
|
||||
window.dispatchEvent(notificationEvent);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
// Сохраняем данные пользователя
|
||||
user.value = response.data;
|
||||
console.log('Пользователь успешно загружен:', user.value);
|
||||
@ -119,20 +68,21 @@ async function fetchUser() {
|
||||
console.error('Не удалось загрузить пользователя по токену:', error.response ? error.response.data : error.message);
|
||||
|
||||
// Проверяем, не связана ли ошибка с блокировкой
|
||||
if (error.response && error.response.status === 403 && error.response.data.message && error.response.data.message.includes('заблокирован')) {
|
||||
if (error.response && error.response.status === 403) {
|
||||
console.log('[Auth] Пользователь заблокирован согласно ответу сервера');
|
||||
|
||||
// Сохраняем информацию о блокировке
|
||||
const blockedInfo = {
|
||||
blocked: true,
|
||||
message: error.response.data.message || 'Ваш аккаунт заблокирован администратором.',
|
||||
reason: error.response.data.reason || 'Нарушение правил сервиса',
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
localStorage.setItem('accountBlockedInfo', JSON.stringify(blockedInfo));
|
||||
// Показываем уведомление о блокировке
|
||||
const notificationEvent = new CustomEvent('show-toast', {
|
||||
detail: {
|
||||
message: error.response.data.message || 'Ваш аккаунт заблокирован администратором.',
|
||||
type: 'error',
|
||||
duration: 10000
|
||||
}
|
||||
});
|
||||
window.dispatchEvent(notificationEvent);
|
||||
}
|
||||
|
||||
// Если токен невалиден, очищаем его и данные пользователя
|
||||
// Если токен невалиден или пользователь заблокирован, очищаем его и данные пользователя
|
||||
await logout(); // Вызываем logout, чтобы очистить всё
|
||||
}
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user