nakama/moderation/frontend/src/utils/api.js

194 lines
6.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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