import { ref, computed } from 'vue'; import api from './services/api'; // Наш API сервис import router from './router'; // Vue Router для перенаправлений // Реактивные переменные для состояния пользователя и токена const user = ref(null); // Данные пользователя (или null, если не вошел) const token = ref(localStorage.getItem('userToken') || null); // Токен из localStorage или null // Вычисляемое свойство для проверки, аутентифицирован ли пользователь const isAuthenticated = computed(() => !!token.value && !!user.value); // Функция для установки токена и данных пользователя function setUserData(userData, userToken) { user.value = userData; token.value = userToken; localStorage.setItem('userToken', userToken); // Сохраняем токен в localStorage // Устанавливаем токен в заголовки Axios для последующих запросов (если не используется интерсептор) // Однако, наш интерсептор в api.js уже делает это, так что эта строка может быть избыточна, // но не повредит, если интерсептор по какой-то причине не сработает сразу. // api.defaults.headers.common['Authorization'] = `Bearer ${userToken}`; } // Функция для загрузки данных пользователя, если токен есть (например, при обновлении страницы) async function fetchUser() { if (token.value) { try { console.log('Пытаемся загрузить пользователя с токеном из localStorage...'); const response = await api.getMe(); // Используем наш API сервис console.log('Ответ от /auth/me:', response); // Проверяем структуру ответа if (!response.data) { throw new Error('Неверный формат ответа от сервера'); } // Добавляем дополнительное логирование для отладки console.log('Получены данные пользователя:', response.data); console.log('Значение isAdmin в ответе:', response.data.isAdmin); // Сохраняем данные пользователя user.value = response.data; console.log('Пользователь успешно загружен:', user.value); console.log('isAuthenticated после загрузки пользователя:', isAuthenticated.value); console.log('Пользователь является администратором:', user.value.isAdmin ? 'Да' : 'Нет'); } catch (error) { console.error('Не удалось загрузить пользователя по токену:', error.response ? error.response.data : error.message); // Если токен невалиден, очищаем его и данные пользователя await logout(); // Вызываем logout, чтобы очистить всё } } else { console.log('Токен не найден, пользователь не загружен.'); } } // Функция входа async function login(credentials) { try { console.log('Попытка входа с учетными данными:', { email: credentials.email }); const response = await api.login(credentials); console.log('Ответ сервера при входе:', response); // Проверяем структуру данных в ответе if (!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); // Перед сохранением данных 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('Ошибка сети или сервера при входе'); } } // Функция регистрации async function register(userData) { try { const response = await api.register(userData); // response.data должен содержать { _id, name, email, token, message } const { token: userToken, ...newUserData } = response.data; setUserData(newUserData, userToken); // Обычно после регистрации мы либо сразу логиним пользователя, либо просим его войти. // Здесь мы его сразу "залогинили", сохранив токен и данные. router.push('/'); // Перенаправляем на главную (или на страницу подтверждения email, если бы она была) return true; } catch (error) { console.error('Ошибка регистрации:', error.response ? error.response.data : error.message); throw error.response ? error.response.data : new Error('Ошибка сети или сервера при регистрации'); } } // Функция выхода async function logout() { user.value = null; token.value = null; localStorage.removeItem('userToken'); // Удаляем токен из заголовков Axios (если устанавливали его напрямую) // delete apiClient.defaults.headers.common['Authorization']; // apiClient не экспортируется из api.js напрямую для этого // Наш интерсептор запросов в api.js перестанет добавлять токен, так как его не будет в localStorage. router.push('/login'); // Перенаправляем на страницу входа 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 { user, token, isAuthenticated, login, register, logout, fetchUser, // Эту функцию нужно будет вызвать при инициализации приложения handleAccountBlocked, // Добавляем функцию обработки блокировки аккаунта handleAccountUnblocked // Добавляем функцию обработки разблокировки аккаунта }; }