import axios from 'axios'; import { API_CONFIG } from '../config/api'; import { keycloak, KEYCLOAK_TIMEOUTS } from '../config/keycloak'; class ApiService { private api = axios.create({ baseURL: API_CONFIG.baseURL, timeout: API_CONFIG.timeout, headers: API_CONFIG.headers, }); constructor() { // Interceptor pour ajouter le token Keycloak this.api.interceptors.request.use( async (config) => { // Vérifier si Keycloak est initialisé et l'utilisateur authentifié if (keycloak && keycloak.authenticated) { try { // Rafraîchir le token si nécessaire await keycloak.updateToken(KEYCLOAK_TIMEOUTS.TOKEN_REFRESH_BEFORE_EXPIRY); // Ajouter le token Bearer à l'en-tête Authorization if (keycloak.token) { config.headers['Authorization'] = `Bearer ${keycloak.token}`; } } catch (error) { console.error('Erreur lors de la mise à jour du token Keycloak:', error); // En cas d'erreur, rediriger vers la page de connexion keycloak.login(); throw error; } } else { // Fallback vers l'ancien système pour la rétrocompatibilité let token = null; try { const authTokenItem = sessionStorage.getItem('auth_token') || localStorage.getItem('auth_token'); if (authTokenItem) { const parsed = JSON.parse(authTokenItem); token = parsed.value; } } catch (e) { token = localStorage.getItem('token'); } if (token) { config.headers['Authorization'] = `Bearer ${token}`; } } return config; }, (error) => Promise.reject(error) ); // Interceptor pour les réponses this.api.interceptors.response.use( (response) => response, async (error) => { if (error.response?.status === 401) { // Essayer de rafraîchir le token Keycloak if (keycloak && keycloak.authenticated) { try { await keycloak.updateToken(-1); // Force refresh // Retry the original request return this.api.request(error.config); } catch (refreshError) { console.error('Impossible de rafraîchir le token:', refreshError); keycloak.login(); } } else { // Ne pas rediriger si on est en train de traiter un code d'autorisation if (typeof window !== 'undefined') { const currentUrl = window.location.href; const hasAuthCode = currentUrl.includes('code=') && currentUrl.includes('/dashboard'); if (!hasAuthCode) { // Fallback vers l'ancien système localStorage.removeItem('token'); localStorage.removeItem('user'); localStorage.removeItem('auth_token'); sessionStorage.removeItem('auth_token'); window.location.href = '/api/auth/login'; } else { console.log('🔄 ApiService: Erreur 401 ignorée car authentification en cours...'); } } } } return Promise.reject(error); } ); } async get(url: string, config?: any): Promise { const response = await this.api.get(url, config); return response.data; } async post(url: string, data?: any, config?: any): Promise { const response = await this.api.post(url, data, config); return response.data; } async put(url: string, data?: any, config?: any): Promise { const response = await this.api.put(url, data, config); return response.data; } async delete(url: string, config?: any): Promise { const response = await this.api.delete(url, config); return response.data; } async patch(url: string, data?: any, config?: any): Promise { const response = await this.api.patch(url, data, config); return response.data; } } export default new ApiService();