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) { if (isMatch && !user.isActive && !user.isAdmin) {
console.log('[AuthController] Пользователь заблокирован, но создаем токен для восстановления сессии');
// Создаем токен для последующего восстановления сессии после разблокировки
const restorationToken = generateToken(user._id);
// Обновляем дату последнего входа даже для заблокированного пользователя
user.lastSeen = new Date();
await user.save();
res.status(403); 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) { if (isMatch) {
@ -256,6 +270,19 @@ const loginUser = async (req, res, next) => {
if (!res.statusCode || res.statusCode < 400) { if (!res.statusCode || res.statusCode < 400) {
res.status(401); 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 }); 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 user = ref(null); // Данные пользователя (или null, если не вошел)
const token = ref(localStorage.getItem('userToken') || null); // Токен из localStorage или null const token = ref(localStorage.getItem('userToken') || null); // Токен из localStorage или null
const loading = ref(false); // Состояние загрузки для операций аутентификации
// Вычисляемое свойство для проверки, аутентифицирован ли пользователь // Вычисляемое свойство для проверки, аутентифицирован ли пользователь
const isAuthenticated = computed(() => !!token.value && !!user.value); const isAuthenticated = computed(() => !!token.value && !!user.value);
@ -142,23 +143,13 @@ async function fetchUser() {
// Функция входа // Функция входа
async function login(credentials) { async function login(credentials) {
try { try {
console.log('Попытка входа с учетными данными:', { email: credentials.email }); loading.value = true;
const response = await api.login(credentials); const response = await api.login(credentials);
console.log('Ответ сервера при входе:', response);
// Проверяем структуру данных в ответе if (response?.data) {
if (!response.data || !response.data.token) { setUserData(response.data, response.data.token);
throw new Error('Неверный формат ответа от сервера: отсутствует токен');
}
// response.data должен содержать { _id, name, email, token, message } // Очищаем данные о предыдущей блокировке при успешном входе
const { token: userToken, ...userData } = response.data;
// Убедимся, что userData содержит необходимые поля
console.log('Данные пользователя для сохранения:', userData);
// Проверяем, была ли предыдущая блокировка и произошла ли разблокировка
const wasBlocked = localStorage.getItem('accountBlockedInfo'); const wasBlocked = localStorage.getItem('accountBlockedInfo');
const sessionBackup = localStorage.getItem('blockedSessionBackup'); const sessionBackup = localStorage.getItem('blockedSessionBackup');
@ -182,29 +173,44 @@ async function login(credentials) {
}, 1000); }, 1000);
} }
// Перед сохранением данных router.push('/'); // Перенаправляем на главную после успешного входа
console.log('isAuthenticated ДО входа:', isAuthenticated.value); return response.data;
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) { } catch (error) {
console.error('Ошибка входа:', error.response ? error.response.data : error.message); console.error('[Auth] Ошибка входа:', error);
// Возвращаем сообщение об ошибке, чтобы отобразить в компоненте
throw error.response ? error.response.data : new 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;
} }
} }