145 lines
5.5 KiB
JavaScript
145 lines
5.5 KiB
JavaScript
import axios from 'axios'
|
|
|
|
// Create axios instance with base URL from environment variable
|
|
const api = axios.create({
|
|
baseURL: import.meta.env.VITE_API_BASE_URL || 'https://dev.servicefinder.hu',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
})
|
|
|
|
// Request interceptor to add auth token
|
|
api.interceptors.request.use(
|
|
(config) => {
|
|
console.group('📤 Axios Request Interceptor - Flight Recorder');
|
|
console.log('📊 Request Details:');
|
|
console.log(' • URL:', config.url);
|
|
console.log(' • Method:', config.method);
|
|
console.log(' • Base URL:', config.baseURL);
|
|
|
|
// Get token from localStorage (check both 'token' and 'access_token' for compatibility)
|
|
if (typeof window !== 'undefined') {
|
|
let token = localStorage.getItem('token');
|
|
if (!token) {
|
|
token = localStorage.getItem('access_token');
|
|
if (token) {
|
|
console.log('⚠️ Using access_token (legacy) instead of token');
|
|
}
|
|
}
|
|
|
|
if (token) {
|
|
console.log('🔐 Adding Authorization header with token');
|
|
console.log(' • Token present:', token.substring(0, 20) + '...');
|
|
config.headers.Authorization = `Bearer ${token}`;
|
|
} else {
|
|
console.log('⚠️ No auth token found in localStorage');
|
|
console.log(' • token key:', localStorage.getItem('token') ? 'PRESENT' : 'MISSING');
|
|
console.log(' • access_token key:', localStorage.getItem('access_token') ? 'PRESENT' : 'MISSING');
|
|
}
|
|
} else {
|
|
console.log('🌐 Window not available (SSR)');
|
|
}
|
|
|
|
console.groupEnd();
|
|
return config;
|
|
},
|
|
(error) => {
|
|
console.error('❌ Request interceptor error:', error);
|
|
return Promise.reject(error);
|
|
}
|
|
)
|
|
|
|
// Response interceptor for error handling
|
|
api.interceptors.response.use(
|
|
(response) => response,
|
|
(error) => {
|
|
console.group('🚨 Axios Response Interceptor - Flight Recorder');
|
|
console.log('📊 Interceptor triggered for error:', error);
|
|
|
|
if (error.response) {
|
|
console.log('📡 Response Details:');
|
|
console.log(' • Status:', error.response.status);
|
|
console.log(' • URL:', error.config?.url);
|
|
console.log(' • Method:', error.config?.method);
|
|
console.log(' • Headers:', error.config?.headers);
|
|
|
|
if (error.response.status === 401) {
|
|
console.warn('🔐 401 UNAUTHORIZED DETECTED!');
|
|
console.warn(' ↳ This will trigger logout and redirect');
|
|
|
|
// Log current auth state before clearing
|
|
const token = localStorage.getItem('token');
|
|
const accessToken = localStorage.getItem('access_token');
|
|
console.log(' ↳ Current localStorage state:');
|
|
console.log(' - token:', token ? `YES (${token.substring(0, 20)}...)` : 'NO');
|
|
console.log(' - access_token:', accessToken ? `YES (${accessToken.substring(0, 20)}...)` : 'NO');
|
|
|
|
// Handle unauthorized - clear ALL auth tokens and redirect to login
|
|
if (typeof window !== 'undefined') {
|
|
console.log(' ↳ Clearing auth tokens from localStorage...');
|
|
localStorage.removeItem('token');
|
|
localStorage.removeItem('access_token');
|
|
localStorage.removeItem('refresh_token');
|
|
localStorage.removeItem('is_admin');
|
|
localStorage.removeItem('user_email');
|
|
localStorage.removeItem('user_role');
|
|
|
|
// Also try to call auth store logout if available
|
|
try {
|
|
const authStore = window.__pinia?.state.value?.auth;
|
|
if (authStore && authStore.logout) {
|
|
console.log(' ↳ Calling auth store logout()...');
|
|
// We can't call the function directly from here, but we can dispatch an event
|
|
window.dispatchEvent(new CustomEvent('force-logout'));
|
|
}
|
|
} catch (e) {
|
|
console.warn(' ↳ Could not access auth store:', e.message);
|
|
}
|
|
|
|
console.warn(' ↳ Redirecting to /login');
|
|
window.location.href = '/login';
|
|
}
|
|
} else if (error.response.status === 403) {
|
|
console.warn('🔒 403 FORBIDDEN DETECTED');
|
|
console.warn(' ↳ User lacks permissions for this resource');
|
|
} else if (error.response.status === 404) {
|
|
console.warn('🔍 404 NOT FOUND DETECTED');
|
|
console.warn(' ↳ API endpoint or resource not found');
|
|
} else if (error.response.status >= 500) {
|
|
console.error('💥 SERVER ERROR DETECTED (5xx)');
|
|
console.error(' ↳ Backend server issue');
|
|
}
|
|
} else if (error.request) {
|
|
console.error('🌐 NETWORK ERROR: Request was made but no response received');
|
|
console.error(' ↳ Possible network issue or CORS problem');
|
|
} else {
|
|
console.error('⚙️ SETUP ERROR: Error in request configuration');
|
|
console.error(' ↳', error.message);
|
|
}
|
|
|
|
console.groupEnd();
|
|
return Promise.reject(error);
|
|
}
|
|
)
|
|
|
|
export default api
|
|
|
|
// Catalog API functions
|
|
export const catalogApi = {
|
|
async getMakes() {
|
|
const response = await api.get('/catalog/makes')
|
|
return response.data
|
|
},
|
|
async getModels(make) {
|
|
const response = await api.get('/catalog/models', { params: { make } })
|
|
return response.data
|
|
},
|
|
async getGenerations(make, model) {
|
|
const response = await api.get('/catalog/generations', { params: { make, model } })
|
|
return response.data
|
|
},
|
|
async getEngines(make, model, gen) {
|
|
const response = await api.get('/catalog/engines', { params: { make, model, gen } })
|
|
return response.data
|
|
}
|
|
} |