This commit is contained in:
Professional 2025-05-26 19:50:52 +07:00
parent 8b42a81414
commit 84cdeb8ff0
2 changed files with 91 additions and 58 deletions

View File

@ -234,8 +234,22 @@ const loginUser = async (req, res, next) => {
// Проверка если аккаунт неактивен (заблокирован)
if (isMatch && !user.isActive && !user.isAdmin) {
console.log('[AuthController] Пользователь заблокирован, но создаем токен для восстановления сессии');
// Создаем токен для последующего восстановления сессии после разблокировки
const restorationToken = generateToken(user._id);
// Обновляем дату последнего входа даже для заблокированного пользователя
user.lastSeen = new Date();
await user.save();
res.status(403);
throw new Error('Ваш аккаунт заблокирован. Пожалуйста, обратитесь в поддержку.');
const error = new Error('Ваш аккаунт заблокирован. Пожалуйста, обратитесь в поддержку.');
error.blocked = true;
error.userId = user._id;
error.restorationToken = restorationToken; // Добавляем токен для восстановления
error.userName = user.name;
throw error;
}
if (isMatch) {
@ -256,6 +270,19 @@ const loginUser = async (req, res, next) => {
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 });
}
};

View File

@ -5,6 +5,7 @@ import router from './router'; // Vue Router для перенаправлен
// Реактивные переменные для состояния пользователя и токена
const user = ref(null); // Данные пользователя (или null, если не вошел)
const token = ref(localStorage.getItem('userToken') || null); // Токен из localStorage или null
const loading = ref(false); // Состояние загрузки для операций аутентификации
// Вычисляемое свойство для проверки, аутентифицирован ли пользователь
const isAuthenticated = computed(() => !!token.value && !!user.value);
@ -142,69 +143,74 @@ async function fetchUser() {
// Функция входа
async function login(credentials) {
try {
console.log('Попытка входа с учетными данными:', { email: credentials.email });
loading.value = true;
const response = await api.login(credentials);
console.log('Ответ сервера при входе:', response);
// Проверяем структуру данных в ответе
if (!response.data || !response.data.token) {
throw new Error('Неверный формат ответа от сервера: отсутствует токен');
if (response?.data) {
setUserData(response.data, response.data.token);
// Очищаем данные о предыдущей блокировке при успешном входе
const wasBlocked = localStorage.getItem('accountBlockedInfo');
const sessionBackup = localStorage.getItem('blockedSessionBackup');
if (wasBlocked || sessionBackup) {
console.log('[Auth] Обнаружена предыдущая блокировка, пользователь теперь может войти - значит разблокирован');
// Очищаем данные о блокировке
localStorage.removeItem('accountBlockedInfo');
localStorage.removeItem('blockedSessionBackup');
// Показываем уведомление о разблокировке
setTimeout(() => {
const notificationEvent = new CustomEvent('show-toast', {
detail: {
message: 'Ваш аккаунт был разблокирован. Добро пожаловать обратно!',
type: 'success',
duration: 5000
}
});
window.dispatchEvent(notificationEvent);
}, 1000);
}
router.push('/'); // Перенаправляем на главную после успешного входа
return response.data;
}
// response.data должен содержать { _id, name, email, token, message }
const { token: userToken, ...userData } = response.data;
// Убедимся, что userData содержит необходимые поля
console.log('Данные пользователя для сохранения:', userData);
// Проверяем, была ли предыдущая блокировка и произошла ли разблокировка
const wasBlocked = localStorage.getItem('accountBlockedInfo');
const sessionBackup = localStorage.getItem('blockedSessionBackup');
if (wasBlocked || sessionBackup) {
console.log('[Auth] Обнаружена предыдущая блокировка, пользователь теперь может войти - значит разблокирован');
// Очищаем данные о блокировке
localStorage.removeItem('accountBlockedInfo');
localStorage.removeItem('blockedSessionBackup');
// Показываем уведомление о разблокировке
setTimeout(() => {
const notificationEvent = new CustomEvent('show-toast', {
detail: {
message: 'Ваш аккаунт был разблокирован. Добро пожаловать обратно!',
type: 'success',
duration: 5000
}
});
window.dispatchEvent(notificationEvent);
}, 1000);
}
// Перед сохранением данных
console.log('isAuthenticated ДО входа:', isAuthenticated.value);
console.log('Данные пользователя ДО входа:', user.value);
// Сохраняем данные пользователя и токен
setUserData(userData, userToken);
// После сохранения данных, но до перенаправления
console.log('isAuthenticated ПОСЛЕ входа:', isAuthenticated.value);
console.log('Данные пользователя ПОСЛЕ входа:', user.value);
console.log('Токен ПОСЛЕ входа:', token.value);
// Принудительное обновление состояния
setTimeout(() => {
console.log('isAuthenticated после таймаута:', isAuthenticated.value);
}, 0);
router.push('/'); // Перенаправляем на главную после входа
return true;
} catch (error) {
console.error('Ошибка входа:', error.response ? error.response.data : error.message);
// Возвращаем сообщение об ошибке, чтобы отобразить в компоненте
throw error.response ? error.response.data : new Error('Ошибка сети или сервера при входе');
console.error('[Auth] Ошибка входа:', error);
// Обработка специального случая блокировки аккаунта
if (error.response?.status === 403 && error.response?.data?.blocked) {
const errorData = error.response.data;
console.log('[Auth] Аккаунт заблокирован, сохраняем данные для восстановления сессии');
// Сохраняем данные о блокировке
const blockedInfo = {
blocked: true,
message: errorData.message || 'Ваш аккаунт заблокирован администратором.',
timestamp: new Date().toISOString()
};
localStorage.setItem('accountBlockedInfo', JSON.stringify(blockedInfo));
// Сохраняем данные для восстановления сессии, если есть токен восстановления
if (errorData.restorationToken && errorData.userId && errorData.userName) {
const sessionBackup = {
userId: errorData.userId,
userName: errorData.userName,
token: errorData.restorationToken,
timestamp: new Date().toISOString(),
lastPath: '/', // По умолчанию главная страница
credentials: credentials // Сохраняем credentials для повторного входа
};
localStorage.setItem('blockedSessionBackup', JSON.stringify(sessionBackup));
console.log('[Auth] Сохранены данные для восстановления сессии заблокированного пользователя');
}
}
throw error;
} finally {
loading.value = false;
}
}