feat(auth): synchronize access token from cookies to localStorage if not present
refactor(dashboard): create dynamic columns for CodePedimentoRegimen with onSuccess callback feat(dashboard): implement create, edit, and delete dialogs for CodePedimentoRegimen feat(dialogs): add reusable dialog components for confirmation and details display style(alert-dialog): improve styling and structure for alert dialog components style(dialog): enhance styling and structure for dialog components
This commit is contained in:
@@ -36,11 +36,31 @@ function onTokenRefreshed(token: string) {
|
||||
async function refreshToken(): Promise<string | null> {
|
||||
if (!browser) return null;
|
||||
|
||||
const refreshTokenValue = localStorage.getItem('refresh_token');
|
||||
let refreshTokenValue = localStorage.getItem('refresh_token');
|
||||
|
||||
// Si no está en localStorage, intentar obtenerlo de las cookies
|
||||
if (!refreshTokenValue) {
|
||||
const getCookie = (name: string): string | null => {
|
||||
const value = `; ${document.cookie}`;
|
||||
const parts = value.split(`; ${name}=`);
|
||||
if (parts.length === 2) return parts.pop()?.split(';').shift() || null;
|
||||
return null;
|
||||
};
|
||||
|
||||
refreshTokenValue = getCookie('refresh_token');
|
||||
if (refreshTokenValue) {
|
||||
console.log('📝 [API] Refresh token encontrado en cookies, sincronizando a localStorage');
|
||||
localStorage.setItem('refresh_token', refreshTokenValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (!refreshTokenValue) {
|
||||
console.error('❌ [API] No hay refresh token disponible');
|
||||
return null;
|
||||
}
|
||||
|
||||
console.log('🔄 [API] Intentando refrescar token...');
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/v1/auth/refresh`, {
|
||||
method: 'POST',
|
||||
@@ -52,7 +72,7 @@ async function refreshToken(): Promise<string | null> {
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
console.error('❌ [API] Refresh token expirado o inválido');
|
||||
console.error('❌ [API] Refresh token expirado o inválido, status:', response.status);
|
||||
// Si el refresh token también está expirado, limpiar todo
|
||||
localStorage.removeItem('access_token');
|
||||
localStorage.removeItem('refresh_token');
|
||||
@@ -69,6 +89,7 @@ async function refreshToken(): Promise<string | null> {
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log('✅ [API] Token refrescado correctamente');
|
||||
|
||||
// Guardar los nuevos tokens
|
||||
if (data.access_token) {
|
||||
@@ -116,6 +137,7 @@ async function fetchApi<T = any>(
|
||||
): Promise<ApiResponse<T>> {
|
||||
// Si ya estamos refrescando el token, esperar
|
||||
if (isRefreshing && retryCount === 0) {
|
||||
console.log('⏳ [API] Esperando refresh del token...');
|
||||
return new Promise((resolve) => {
|
||||
subscribeTokenRefresh((newToken) => {
|
||||
resolve(fetchApi<T>(endpoint, options, 1));
|
||||
@@ -124,6 +146,10 @@ 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',
|
||||
@@ -143,6 +169,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) {
|
||||
console.log('🔄 [API] Recibido 401/403, intentando refrescar token...');
|
||||
isRefreshing = true;
|
||||
|
||||
try {
|
||||
@@ -150,11 +177,13 @@ async function fetchApi<T = any>(
|
||||
|
||||
if (newToken) {
|
||||
// Token refrescado exitosamente
|
||||
console.log('✅ [API] Token refrescado exitosamente');
|
||||
onTokenRefreshed(newToken);
|
||||
isRefreshing = false;
|
||||
// Reintentar la petición original con el nuevo token
|
||||
return await fetchApi<T>(endpoint, options, 1);
|
||||
} else {
|
||||
console.error('❌ [API] No se pudo refrescar el token');
|
||||
isRefreshing = false;
|
||||
// Retornar error 401 para que la capa superior lo maneje
|
||||
return {
|
||||
@@ -163,6 +192,7 @@ async function fetchApi<T = any>(
|
||||
};
|
||||
}
|
||||
} catch (refreshError) {
|
||||
console.error('❌ [API] Error al refrescar:', refreshError);
|
||||
isRefreshing = false;
|
||||
return {
|
||||
error: 'Error al refrescar la sesión',
|
||||
|
||||
Reference in New Issue
Block a user