Se mejoro el disenio de partes, se genero la informacion mas precisa en los reportes y se carga el logo en las instanacias de las empresas
This commit is contained in:
@@ -45,7 +45,7 @@ async function refreshToken(): Promise<string | null> {
|
||||
if (!browser) return null;
|
||||
|
||||
let refreshTokenValue = localStorage.getItem('refresh_token');
|
||||
|
||||
|
||||
// Si no está en localStorage, intentar obtenerlo de las cookies
|
||||
if (!refreshTokenValue) {
|
||||
const getCookie = (name: string): string | null => {
|
||||
@@ -54,18 +54,18 @@ async function refreshToken(): Promise<string | null> {
|
||||
if (parts.length === 2) return parts.pop()?.split(';').shift() || null;
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
refreshTokenValue = getCookie('refresh_token');
|
||||
if (refreshTokenValue) {
|
||||
if (refreshTokenValue) {
|
||||
localStorage.setItem('refresh_token', refreshTokenValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!refreshTokenValue) {
|
||||
console.error('❌ [API] No hay refresh token disponible');
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/v1/auth/refresh`, {
|
||||
method: 'POST',
|
||||
@@ -93,25 +93,25 @@ async function refreshToken(): Promise<string | null> {
|
||||
return null;
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const data = await response.json();
|
||||
|
||||
// Guardar los nuevos tokens
|
||||
if (data.access_token) {
|
||||
localStorage.setItem('access_token', data.access_token);
|
||||
|
||||
|
||||
if (data.refresh_token) {
|
||||
localStorage.setItem('refresh_token', data.refresh_token);
|
||||
}
|
||||
|
||||
|
||||
// Actualizar también las cookies
|
||||
const isSecure = window.location.protocol === 'https:';
|
||||
const secureFlag = isSecure ? '; Secure' : '';
|
||||
|
||||
|
||||
document.cookie = `access_token=${data.access_token}; path=/; max-age=${60 * 60 * 24 * 7}; SameSite=Lax${secureFlag}`;
|
||||
if (data.refresh_token) {
|
||||
document.cookie = `refresh_token=${data.refresh_token}; path=/; max-age=${60 * 60 * 24 * 30}; SameSite=Lax${secureFlag}`;
|
||||
}
|
||||
|
||||
|
||||
// Actualizar el authStore si está disponible
|
||||
try {
|
||||
const { authStore } = await import('./auth');
|
||||
@@ -120,7 +120,7 @@ async function refreshToken(): Promise<string | null> {
|
||||
// Si no se puede importar authStore, no es crítico
|
||||
console.warn('⚠️ [API] No se pudo actualizar authStore:', e);
|
||||
}
|
||||
|
||||
|
||||
return data.access_token;
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ async function fetchApi<T = any>(
|
||||
retryCount = 0
|
||||
): Promise<ApiResponse<T>> {
|
||||
// Si ya estamos refrescando el token, esperar
|
||||
if (isRefreshing && retryCount === 0) {
|
||||
if (isRefreshing && retryCount === 0) {
|
||||
return new Promise((resolve) => {
|
||||
subscribeTokenRefresh((newToken) => {
|
||||
resolve(fetchApi<T>(endpoint, options, 1));
|
||||
@@ -149,16 +149,20 @@ async function fetchApi<T = any>(
|
||||
}
|
||||
|
||||
const token = getToken();
|
||||
|
||||
|
||||
if (!token && !endpoint.includes('/auth/login')) {
|
||||
console.warn('⚠️ [API] No hay token disponible para', endpoint);
|
||||
}
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
'Content-Type': 'application/json',
|
||||
...((options.headers as Record<string, string>) || {})
|
||||
};
|
||||
|
||||
// Only set Content-Type to application/json if not already set and body is not FormData
|
||||
if (!headers['Content-Type'] && !(options.body instanceof FormData)) {
|
||||
headers['Content-Type'] = 'application/json';
|
||||
}
|
||||
|
||||
if (token) {
|
||||
headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
@@ -171,7 +175,7 @@ async function fetchApi<T = any>(
|
||||
});
|
||||
|
||||
// Si recibimos 401 o 403 y no es el endpoint de refresh, intentar refrescar el token
|
||||
if ((response.status === 401 || response.status === 403) && !endpoint.includes('/auth/refresh') && retryCount === 0) {
|
||||
if ((response.status === 401 || response.status === 403) && !endpoint.includes('/auth/refresh') && retryCount === 0) {
|
||||
isRefreshing = true;
|
||||
|
||||
try {
|
||||
@@ -226,7 +230,7 @@ async function fetchApi<T = any>(
|
||||
// Errores de validación de FastAPI (con detail)
|
||||
else if (data.detail) {
|
||||
let errorMessage = 'Error de validación: ';
|
||||
|
||||
|
||||
// FastAPI devuelve errores de validación en data.detail como array
|
||||
if (Array.isArray(data.detail)) {
|
||||
const errors = data.detail.map((err: any) => {
|
||||
@@ -239,14 +243,14 @@ async function fetchApi<T = any>(
|
||||
} else {
|
||||
errorMessage += JSON.stringify(data.detail);
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
error: errorMessage,
|
||||
status: response.status
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
error: data.message || data.detail || 'Error en la petición',
|
||||
status: response.status
|
||||
@@ -281,7 +285,7 @@ export const api = {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(body)
|
||||
}),
|
||||
|
||||
|
||||
patch: <T = any>(endpoint: string, body: any) =>
|
||||
fetchApi<T>(endpoint, {
|
||||
method: 'PATCH',
|
||||
@@ -314,5 +318,8 @@ export const api = {
|
||||
myLicense: () => api.get('/v1/licenses/my-license'),
|
||||
usage: (tenantId: number) => api.get(`/v1/licenses/usage/${tenantId}`),
|
||||
validate: (tenantId: number) => api.get(`/v1/licenses/validate/${tenantId}`)
|
||||
}
|
||||
},
|
||||
|
||||
// Generic request for custom needs (like file uploads)
|
||||
request: <T = any>(endpoint: string, options: RequestInit = {}) => fetchApi<T>(endpoint, options)
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user