import axios from 'axios' // Определить базовый URL API export const getApiUrl = () => { // Если указан явно в env if (import.meta.env.VITE_API_URL) { return import.meta.env.VITE_API_URL; } // В production используем относительный путь (HTTPS через nginx) if (import.meta.env.PROD) { return '/api'; } // В development используем порт модерации (только для dev) return 'http://localhost:3001/api'; }; const API_URL = getApiUrl(); const api = axios.create({ baseURL: API_URL, withCredentials: true }) // Получить токен авторизации const getAuthToken = () => { // 1. Сначала пробуем JWT токен из localStorage const jwtToken = localStorage.getItem('moderation_jwt_token'); if (jwtToken) { return { token: jwtToken, type: 'jwt' }; } // 2. Потом пробуем Telegram WebApp const initData = window.Telegram?.WebApp?.initData; if (initData) { return { initData, type: 'telegram' }; } // 3. Старый способ через localStorage const storedToken = localStorage.getItem('moderation_token'); if (storedToken) { return { initData: storedToken, type: 'telegram' }; } return null; }; api.interceptors.request.use((config) => { const auth = getAuthToken(); if (auth) { config.headers = config.headers || {}; if (auth.type === 'jwt' && auth.token) { // JWT токен config.headers.Authorization = `Bearer ${auth.token}`; } else if (auth.initData) { // Telegram initData if (!config.headers.Authorization) { config.headers.Authorization = `tma ${auth.initData}`; } if (!config.headers['x-telegram-init-data']) { config.headers['x-telegram-init-data'] = auth.initData; } } } return config; }); // Response interceptor для обработки устаревших токенов api.interceptors.response.use( (response) => response, (error) => { const status = error?.response?.status; const errorMessage = error?.response?.data?.error || ''; // Если токен устарел или невалиден if (status === 401) { console.warn('[Moderation API] Auth token expired or invalid'); // Очистить все токены из localStorage localStorage.removeItem('moderation_token'); localStorage.removeItem('moderation_jwt_token'); // Показать уведомление пользователю const tg = window.Telegram?.WebApp; if (tg?.showAlert) { tg.showAlert('Сессия устарела. Перезагрузка...', () => { window.location.reload(); }); } else { // Для обычного браузера - перезагрузка страницы (покажет форму входа) window.location.reload(); } } return Promise.reject(error); } ); // Авторизация export const sendVerificationCode = (email) => api.post('/moderation-auth/send-code', { email }).then((res) => res.data) export const registerWithCode = (email, code, password, username) => api.post('/moderation-auth/register', { email, code, password, username }).then((res) => { if (res.data.accessToken) { localStorage.setItem('moderation_jwt_token', res.data.accessToken); } return res.data; }) export const login = (email, password) => api.post('/moderation-auth/login', { email, password }).then((res) => { if (res.data.accessToken) { localStorage.setItem('moderation_jwt_token', res.data.accessToken); } return res.data; }) export const loginTelegram = () => api.post('/moderation-auth/telegram').then((res) => { if (res.data.accessToken) { localStorage.setItem('moderation_jwt_token', res.data.accessToken); } return res.data; }) export const logout = () => { localStorage.removeItem('moderation_jwt_token'); localStorage.removeItem('moderation_token'); return api.post('/moderation-auth/logout').then((res) => res.data); } export const getCurrentUser = () => api.get('/moderation-auth/me').then((res) => res.data.user) export const verifyAuth = () => api.post('/mod-app/auth/verify').then((res) => res.data.user) export const fetchUsers = (params = {}) => api.get('/mod-app/users', { params }).then((res) => res.data) export const banUser = (userId, data) => api.put(`/mod-app/users/${userId}/ban`, data).then((res) => res.data) export const fetchPosts = (params = {}) => api.get('/mod-app/posts', { params }).then((res) => res.data) export const updatePost = (postId, data) => api.put(`/mod-app/posts/${postId}`, data).then((res) => res.data) export const deletePost = (postId) => api.delete(`/mod-app/posts/${postId}`).then((res) => res.data) export const removePostImage = (postId, index) => api.delete(`/mod-app/posts/${postId}/images/${index}`).then((res) => res.data) export const banPostAuthor = (postId, data) => api.post(`/mod-app/posts/${postId}/ban`, data).then((res) => res.data) export const fetchReports = (params = {}) => api.get('/mod-app/reports', { params }).then((res) => res.data) export const updateReportStatus = (reportId, data) => api.put(`/mod-app/reports/${reportId}`, data).then((res) => res.data) export const publishToChannel = (formData) => api.post('/mod-app/channel/publish', formData, { headers: { 'Content-Type': 'multipart/form-data' } }) export const fetchAdmins = () => api.get('/mod-app/admins').then((res) => res.data) export const initiateAddAdmin = (userId, adminNumber) => api.post('/mod-app/admins/initiate-add', { userId, adminNumber }).then((res) => res.data) export const confirmAddAdmin = (userId, code) => api.post('/mod-app/admins/confirm-add', { userId, code }).then((res) => res.data) export const initiateRemoveAdmin = (adminId) => api.post('/mod-app/admins/initiate-remove', { adminId }).then((res) => res.data) export const confirmRemoveAdmin = (adminId, code) => api.post('/mod-app/admins/confirm-remove', { adminId, code }).then((res) => res.data) export const getPostComments = (postId) => api.get(`/mod-app/posts/${postId}`).then((res) => res.data.post) export const deleteComment = (postId, commentId) => api.delete(`/mod-app/posts/${postId}/comments/${commentId}`).then((res) => res.data) export default api