import type {AuthProvider} from '@refinedev/core' import axios, {AxiosError} from 'axios' import {BACKEND_URL} from './lib/constants' import {jwtDecode} from 'jwt-decode' export const TOKEN_KEY = 'refine-auth' interface AuthResponse { token: string user: { id: number name: string email: string is_admin: boolean } } interface ErrorResponse { message: string } class AuthError extends Error { constructor(message: string) { super(message) this.name = 'AuthError' } } interface JWTPayload { user_id: number email: string is_admin: boolean exp: number } export const authProvider: AuthProvider = { login: async ({email, password}) => { try { const response = await axios.post(`${BACKEND_URL}/auth/login`, { email, password, }) const {token, user} = response.data if (token) { localStorage.setItem(TOKEN_KEY, token) localStorage.setItem('user', JSON.stringify(user)) return { success: true, redirectTo: '/', } } throw new AuthError('Неверный email или пароль') } catch (error) { const errorMessage = (error as AxiosError)?.response?.data?.message || 'Неверный email или пароль' return { success: false, error: new AuthError(errorMessage), } } }, logout: async () => { try { await axios.post( `${BACKEND_URL}/auth/logout`, {}, { headers: { Authorization: `Bearer ${localStorage.getItem(TOKEN_KEY)}`, }, }, ) } catch (error) { console.error('Ошибка при выходе:', error) } localStorage.removeItem(TOKEN_KEY) localStorage.removeItem('user') return { success: true, redirectTo: '/login', } }, check: async () => { const token = localStorage.getItem(TOKEN_KEY) if (!token) { return { authenticated: false, redirectTo: '/login', } } try { const response = await axios.get(`${BACKEND_URL}/auth/me`, { headers: { Authorization: `Bearer ${token}`, }, }) if (response.status === 200) { // Обновляем информацию о пользователе localStorage.setItem('user', JSON.stringify(response.data)) return { authenticated: true, } } } catch (error) { localStorage.removeItem(TOKEN_KEY) localStorage.removeItem('user') return { authenticated: false, redirectTo: '/login', error: new AuthError('Сессия истекла, пожалуйста, войдите снова'), } } return { authenticated: false, redirectTo: '/login', } }, getPermissions: async () => { const token = localStorage.getItem(TOKEN_KEY) if (!token) return null try { const decoded = jwtDecode(token) if (decoded.is_admin) { document.body.classList.add('is-admin') } else { document.body.classList.remove('is-admin') } return decoded.is_admin ? ['admin'] : ['user'] } catch { document.body.classList.remove('is-admin') return ['user'] } }, getIdentity: async () => { const token = localStorage.getItem(TOKEN_KEY) const user = localStorage.getItem('user') if (!token || !user) return null try { const decoded = jwtDecode(token) const userData = JSON.parse(user) return { ...userData, is_admin: decoded.is_admin, // всегда используем значение из токена } } catch { return null } }, onError: async (error) => { const status = (error as AxiosError)?.response?.status if (status === 401 || status === 403) { localStorage.removeItem(TOKEN_KEY) localStorage.removeItem('user') return { logout: true, redirectTo: '/login', error: new AuthError('Сессия истекла, пожалуйста, войдите снова'), } } return {error} }, }