Refactor authentication handling and API calls in dashboard routes
- Centralized API URL configuration and token management in $lib/server/api.ts. - Replaced direct token access with a centralized method for retrieving tokens. - Updated all dashboard reference data routes to use authenticatedFetch for API calls, improving token refresh handling. - Simplified login route by utilizing centralized token management functions. - Added a new layout file for the dashboard to pass user and company data to the client.
This commit is contained in:
@@ -9,12 +9,7 @@
|
||||
|
||||
const sidebar = useSidebar();
|
||||
|
||||
// Inicializar el store cuando se monta el componente
|
||||
$effect(() => {
|
||||
if (companyStore.companies.length === 0) {
|
||||
companyStore.initialize();
|
||||
}
|
||||
});
|
||||
// Ya no es necesario inicializar aquí, se inicializa en +layout.svelte con datos SSR
|
||||
</script>
|
||||
|
||||
<Sidebar.Menu>
|
||||
|
||||
270
frontend/src/lib/server/api.ts
Normal file
270
frontend/src/lib/server/api.ts
Normal file
@@ -0,0 +1,270 @@
|
||||
/**
|
||||
* Utilidades para llamadas a la API desde el servidor (SSR)
|
||||
* Centraliza la lógica de configuración de URL, autenticación y manejo de tokens
|
||||
*/
|
||||
|
||||
import { redirect, type Cookies } from '@sveltejs/kit';
|
||||
|
||||
/**
|
||||
* Obtiene y normaliza la URL base de la API para llamadas desde el servidor
|
||||
* Automáticamente reemplaza localhost/127.0.0.1 con 'backend' para Docker
|
||||
*/
|
||||
export function getServerApiUrl(): string {
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL: asegurar que termine con '/'
|
||||
return apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene los tokens de autenticación de las cookies
|
||||
*/
|
||||
export function getAuthTokens(cookies: Cookies) {
|
||||
return {
|
||||
accessToken: cookies.get('access_token'),
|
||||
refreshToken: cookies.get('refresh_token')
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Establece los tokens de autenticación en las cookies
|
||||
*/
|
||||
export function setAuthTokens(
|
||||
cookies: Cookies,
|
||||
accessToken: string,
|
||||
refreshToken?: string
|
||||
) {
|
||||
cookies.set('access_token', accessToken, {
|
||||
path: '/',
|
||||
httpOnly: false,
|
||||
sameSite: 'lax',
|
||||
secure: process.env.NODE_ENV === 'production',
|
||||
maxAge: 60 * 60 * 24 * 7 // 7 días
|
||||
});
|
||||
|
||||
if (refreshToken) {
|
||||
cookies.set('refresh_token', refreshToken, {
|
||||
path: '/',
|
||||
httpOnly: false,
|
||||
sameSite: 'lax',
|
||||
secure: process.env.NODE_ENV === 'production',
|
||||
maxAge: 60 * 60 * 24 * 30 // 30 días
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Limpia todos los tokens de autenticación de las cookies
|
||||
*/
|
||||
export function clearAuthTokens(cookies: Cookies) {
|
||||
cookies.delete('access_token', { path: '/' });
|
||||
cookies.delete('refresh_token', { path: '/' });
|
||||
cookies.delete('active_company_id', { path: '/' });
|
||||
}
|
||||
|
||||
/**
|
||||
* Crea headers de autorización con el token Bearer
|
||||
*/
|
||||
export function createAuthHeaders(token: string, additionalHeaders?: Record<string, string>) {
|
||||
return {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
...additionalHeaders
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Intenta refrescar el token de acceso usando el refresh token
|
||||
* @returns El nuevo access token o null si falla
|
||||
*/
|
||||
export async function refreshAccessToken(
|
||||
cookies: Cookies,
|
||||
fetch: typeof globalThis.fetch
|
||||
): Promise<string | null> {
|
||||
const { refreshToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!refreshToken) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const baseUrl = getServerApiUrl();
|
||||
const response = await fetch(`${baseUrl}v1/auth/refresh`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ refresh_token: refreshToken })
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
// Actualizar las cookies con los nuevos tokens
|
||||
setAuthTokens(cookies, data.access_token, data.refresh_token);
|
||||
|
||||
return data.access_token;
|
||||
} catch (error) {
|
||||
console.error('🔄 [API] Error al refrescar token:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Realiza una petición autenticada a la API con manejo automático de refresh
|
||||
* @param endpoint - Endpoint relativo (ej: 'v1/auth/me')
|
||||
* @param options - Opciones de fetch
|
||||
* @param cookies - Objeto de cookies de SvelteKit
|
||||
* @param fetch - Función fetch de SvelteKit
|
||||
* @param redirectUrl - URL a la que redirigir si falla la autenticación (opcional)
|
||||
*/
|
||||
export async function authenticatedFetch(
|
||||
endpoint: string,
|
||||
options: RequestInit = {},
|
||||
cookies: Cookies,
|
||||
fetch: typeof globalThis.fetch,
|
||||
redirectUrl?: string
|
||||
): Promise<Response> {
|
||||
const baseUrl = getServerApiUrl();
|
||||
let { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
// Si no hay token, redirigir o lanzar error
|
||||
if (!accessToken) {
|
||||
if (redirectUrl) {
|
||||
throw redirect(303, redirectUrl);
|
||||
}
|
||||
throw new Error('No access token available');
|
||||
}
|
||||
|
||||
// Construir URL completa
|
||||
const url = endpoint.startsWith('http') ? endpoint : `${baseUrl}${endpoint}`;
|
||||
|
||||
// Realizar la petición inicial
|
||||
const headers = createAuthHeaders(accessToken, options.headers as Record<string, string>);
|
||||
let response = await fetch(url, {
|
||||
...options,
|
||||
headers
|
||||
});
|
||||
|
||||
// Si es 401, intentar refrescar el token
|
||||
if (response.status === 401) {
|
||||
const newToken = await refreshAccessToken(cookies, fetch);
|
||||
|
||||
if (newToken) {
|
||||
// Reintentar la petición con el nuevo token
|
||||
const newHeaders = createAuthHeaders(newToken, options.headers as Record<string, string>);
|
||||
response = await fetch(url, {
|
||||
...options,
|
||||
headers: newHeaders
|
||||
});
|
||||
} else {
|
||||
// No se pudo refrescar, limpiar y redirigir
|
||||
clearAuthTokens(cookies);
|
||||
if (redirectUrl) {
|
||||
throw redirect(303, redirectUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Valida que el usuario esté autenticado y obtiene sus datos
|
||||
* @returns Los datos del usuario o null si no está autenticado
|
||||
*/
|
||||
export async function validateAuth(
|
||||
cookies: Cookies,
|
||||
fetch: typeof globalThis.fetch,
|
||||
redirectOnFail?: string
|
||||
): Promise<any> {
|
||||
try {
|
||||
const response = await authenticatedFetch(
|
||||
'v1/auth/me',
|
||||
{},
|
||||
cookies,
|
||||
fetch,
|
||||
redirectOnFail
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
if (redirectOnFail) {
|
||||
clearAuthTokens(cookies);
|
||||
throw redirect(303, redirectOnFail);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
// Si es un redirect, re-lanzarlo
|
||||
if (error && typeof error === 'object' && 'status' in error && 'location' in error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
console.error('🔐 [API] Error validando autenticación:', error);
|
||||
|
||||
if (redirectOnFail) {
|
||||
clearAuthTokens(cookies);
|
||||
throw redirect(303, redirectOnFail);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene las compañías del usuario autenticado
|
||||
*/
|
||||
export async function getUserCompanies(
|
||||
cookies: Cookies,
|
||||
fetch: typeof globalThis.fetch
|
||||
): Promise<any[]> {
|
||||
try {
|
||||
const response = await authenticatedFetch(
|
||||
'v1/a76/company/my-companies',
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
console.error('🏢 [API] Error cargando compañías:', response.status);
|
||||
return [];
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error('🏢 [API] Error cargando compañías:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene el ID de la compañía activa, o la primera disponible si no hay ninguna seleccionada
|
||||
*/
|
||||
export async function getActiveCompanyId(
|
||||
cookies: Cookies,
|
||||
fetch: typeof globalThis.fetch
|
||||
): Promise<string | null> {
|
||||
let companyId = cookies.get('active_company_id');
|
||||
|
||||
// Si no hay companyId en cookie, obtener las compañías del usuario y usar la primera
|
||||
if (!companyId) {
|
||||
const companies = await getUserCompanies(cookies, fetch);
|
||||
if (companies.length > 0) {
|
||||
companyId = companies[0].id.toString();
|
||||
}
|
||||
}
|
||||
|
||||
return companyId || null;
|
||||
}
|
||||
@@ -31,8 +31,42 @@ class CompanyStore {
|
||||
|
||||
/**
|
||||
* Carga las compañías del tenant del usuario desde el backend
|
||||
* @param preloadedCompanies - Compañías pre-cargadas desde el servidor (SSR)
|
||||
*/
|
||||
async loadCompanies() {
|
||||
async loadCompanies(preloadedCompanies?: Company[]) {
|
||||
// Si tenemos compañías pre-cargadas, usarlas directamente
|
||||
if (preloadedCompanies && preloadedCompanies.length > 0) {
|
||||
// Detectar si el tenant ha cambiado
|
||||
const newTenantId = preloadedCompanies[0].tenant_id;
|
||||
|
||||
// Si el tenant cambió, limpiar el store primero
|
||||
if (this._currentTenantId !== null && this._currentTenantId !== newTenantId) {
|
||||
this.clear();
|
||||
}
|
||||
|
||||
this._currentTenantId = newTenantId;
|
||||
this._companies = preloadedCompanies;
|
||||
|
||||
// Si hay compañías y no hay una activa, seleccionar la primera o la guardada
|
||||
if (this._companies.length > 0 && !this._activeCompany) {
|
||||
// Intentar restaurar la compañía guardada
|
||||
if (typeof window !== 'undefined') {
|
||||
const savedId = localStorage.getItem('activeCompanyId');
|
||||
if (savedId) {
|
||||
const company = this._companies.find(c => c.id === parseInt(savedId));
|
||||
if (company) {
|
||||
this.setActiveCompany(company);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Si no hay guardada, seleccionar la primera
|
||||
this.setActiveCompany(this._companies[0]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Si no hay datos pre-cargados, hacer fetch (fallback)
|
||||
this._loading = true;
|
||||
try {
|
||||
const response = await fetch('/api/company/my-companies');
|
||||
@@ -133,10 +167,14 @@ class CompanyStore {
|
||||
|
||||
/**
|
||||
* Inicializa el store cargando las compañías
|
||||
* @param preloadedCompanies - Compañías pre-cargadas desde el servidor (SSR)
|
||||
*/
|
||||
async initialize() {
|
||||
await this.loadCompanies();
|
||||
this.restoreActiveCompany();
|
||||
async initialize(preloadedCompanies?: Company[]) {
|
||||
await this.loadCompanies(preloadedCompanies);
|
||||
// Si no hay compañías pre-cargadas, intentar restaurar de localStorage
|
||||
if (!preloadedCompanies) {
|
||||
this.restoreActiveCompany();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,35 +1,27 @@
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch, clearAuthTokens } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch }) => {
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
// Si hay token, validar que sea válido antes de redirigir
|
||||
if (token) {
|
||||
if (accessToken) {
|
||||
try {
|
||||
// Configurar la URL de la API
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
// Verificar si el token es válido
|
||||
const response = await fetch(`${baseUrl}v1/auth/me`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
// Verificar si el token es válido usando authenticatedFetch
|
||||
const response = await authenticatedFetch(
|
||||
'v1/auth/me',
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
// Solo redirigir al dashboard si el token es válido
|
||||
if (response.ok) {
|
||||
throw redirect(303, '/dashboard');
|
||||
} else {
|
||||
// Token inválido, limpiar cookies y mostrar la página pública
|
||||
cookies.delete('access_token', { path: '/' });
|
||||
cookies.delete('refresh_token', { path: '/' });
|
||||
clearAuthTokens(cookies);
|
||||
}
|
||||
} catch (error) {
|
||||
// Si es un redirect, re-lanzarlo
|
||||
@@ -37,8 +29,7 @@ export const load: PageServerLoad = async ({ cookies, fetch }) => {
|
||||
throw error;
|
||||
}
|
||||
// Para otros errores, limpiar cookies y continuar
|
||||
cookies.delete('access_token', { path: '/' });
|
||||
cookies.delete('refresh_token', { path: '/' });
|
||||
clearAuthTokens(cookies);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,109 +1,36 @@
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import type { LayoutServerLoad } from './$types';
|
||||
import {
|
||||
validateAuth,
|
||||
getUserCompanies,
|
||||
getAuthTokens,
|
||||
clearAuthTokens
|
||||
} from '$lib/server/api';
|
||||
|
||||
export const load: LayoutServerLoad = async ({ cookies, url, fetch }) => {
|
||||
// Verificar si existe el token en las cookies
|
||||
let token = cookies.get('access_token');
|
||||
const refreshToken = cookies.get('refresh_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
// Si no hay token, redirigir al login
|
||||
if (!token) {
|
||||
// Guardar la URL a la que intentaba acceder para redirigir después del login
|
||||
throw redirect(303, `/login?redirect=${encodeURIComponent(url.pathname)}`);
|
||||
if (!accessToken) {
|
||||
const redirectUrl = `/login?redirect=${encodeURIComponent(url.pathname)}`;
|
||||
throw redirect(303, redirectUrl);
|
||||
}
|
||||
|
||||
// Configurar la URL de la API
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
// Validar el token con el backend y obtener datos del usuario
|
||||
// La función validateAuth maneja automáticamente el refresh de tokens
|
||||
const redirectOnFail = `/login?redirect=${encodeURIComponent(url.pathname)}`;
|
||||
|
||||
// Normalizar la URL: asegurar que termine con '/'
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
// Validar el token con el backend para asegurar que sea válido
|
||||
try {
|
||||
const response = await fetch(`${baseUrl}v1/auth/me`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
try {
|
||||
const userData = await validateAuth(cookies, fetch, redirectOnFail);
|
||||
|
||||
// Si el token está expirado (401) y tenemos refresh token, intentar refrescar
|
||||
if (response.status === 401 && refreshToken) {
|
||||
try {
|
||||
const refreshResponse = await fetch(`${baseUrl}v1/auth/refresh`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ refresh_token: refreshToken })
|
||||
});
|
||||
|
||||
if (refreshResponse.ok) {
|
||||
const refreshData = await refreshResponse.json();
|
||||
|
||||
// Actualizar las cookies con los nuevos tokens
|
||||
cookies.set('access_token', refreshData.access_token, {
|
||||
path: '/',
|
||||
httpOnly: false,
|
||||
sameSite: 'lax',
|
||||
secure: process.env.NODE_ENV === 'production',
|
||||
maxAge: 60 * 60 * 24 * 7 // 7 días
|
||||
});
|
||||
|
||||
if (refreshData.refresh_token) {
|
||||
cookies.set('refresh_token', refreshData.refresh_token, {
|
||||
path: '/',
|
||||
httpOnly: false,
|
||||
sameSite: 'lax',
|
||||
secure: process.env.NODE_ENV === 'production',
|
||||
maxAge: 60 * 60 * 24 * 30 // 30 días
|
||||
});
|
||||
}
|
||||
|
||||
// Usar el nuevo token para obtener la info del usuario
|
||||
token = refreshData.access_token;
|
||||
|
||||
// Reintentar la validación con el nuevo token
|
||||
const retryResponse = await fetch(`${baseUrl}v1/auth/me`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
if (retryResponse.ok) {
|
||||
const userData = await retryResponse.json();
|
||||
return {
|
||||
authenticated: true,
|
||||
user: userData
|
||||
};
|
||||
}
|
||||
}
|
||||
} catch (refreshError) {
|
||||
console.error('🔐 [Dashboard] Error al refrescar token:', refreshError);
|
||||
}
|
||||
|
||||
// Si llegamos aquí, el refresh falló
|
||||
cookies.delete('access_token', { path: '/' });
|
||||
cookies.delete('refresh_token', { path: '/' });
|
||||
throw redirect(303, `/login?redirect=${encodeURIComponent(url.pathname)}`);
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
// Token inválido y no se pudo refrescar, limpiar y redirigir
|
||||
cookies.delete('access_token', { path: '/' });
|
||||
cookies.delete('refresh_token', { path: '/' });
|
||||
throw redirect(303, `/login?redirect=${encodeURIComponent(url.pathname)}`);
|
||||
}
|
||||
|
||||
const userData = await response.json();
|
||||
// Cargar las compañías del usuario en el servidor (SSR)
|
||||
const companies = await getUserCompanies(cookies, fetch);
|
||||
|
||||
return {
|
||||
authenticated: true,
|
||||
user: userData
|
||||
user: userData,
|
||||
companies // Pasar las compañías al cliente
|
||||
};
|
||||
} catch (error) {
|
||||
// Si es un redirect, re-lanzarlo sin tocar las cookies
|
||||
@@ -113,8 +40,7 @@ export const load: LayoutServerLoad = async ({ cookies, url, fetch }) => {
|
||||
|
||||
// Para cualquier otro error (conexión, etc), limpiar token y redirigir
|
||||
console.error('🔐 [Dashboard] Error validando token:', error);
|
||||
cookies.delete('access_token', { path: '/' });
|
||||
cookies.delete('refresh_token', { path: '/' });
|
||||
throw redirect(303, `/login?redirect=${encodeURIComponent(url.pathname)}`);
|
||||
clearAuthTokens(cookies);
|
||||
throw redirect(303, redirectOnFail);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
<script lang="ts">
|
||||
import { setContext } from 'svelte';
|
||||
import { setContext, onMount } from 'svelte';
|
||||
import type { LayoutData } from './$types';
|
||||
import AppSidebar from "$lib/components/sidebar/app-sidebar.svelte";
|
||||
import * as Breadcrumb from "$lib/components/ui/breadcrumb/index.js";
|
||||
import { Separator } from "$lib/components/ui/separator/index.js";
|
||||
import * as Sidebar from "$lib/components/ui/sidebar/index.js";
|
||||
import { companyStore } from "$lib/stores/company.svelte";
|
||||
|
||||
let { data, children }: { data: LayoutData; children: any } = $props();
|
||||
|
||||
// Hacer disponible el usuario en el contexto para los componentes hijos
|
||||
setContext('user', data.user);
|
||||
|
||||
// Inicializar el store con las compañías pre-cargadas desde el servidor
|
||||
onMount(() => {
|
||||
if (data.companies) {
|
||||
companyStore.initialize(data.companies);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<Sidebar.Provider>
|
||||
|
||||
10
frontend/src/routes/dashboard/+layout.ts
Normal file
10
frontend/src/routes/dashboard/+layout.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { LayoutLoad } from './$types';
|
||||
|
||||
export const load: LayoutLoad = async ({ data }) => {
|
||||
// Pasar los datos del servidor al cliente
|
||||
return {
|
||||
user: data.user,
|
||||
companies: data.companies,
|
||||
authenticated: data.authenticated
|
||||
};
|
||||
};
|
||||
@@ -1,46 +1,22 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import {
|
||||
getAuthTokens,
|
||||
getActiveCompanyId,
|
||||
authenticatedFetch
|
||||
} from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ fetch, cookies }) => {
|
||||
// Verificar autenticación
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
throw redirect(302, '/login');
|
||||
}
|
||||
|
||||
try {
|
||||
// Cargar datos iniciales de pedimentos
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
// Obtener el company_id de la cookie o usar la primera disponible
|
||||
let companyId = cookies.get('active_company_id');
|
||||
|
||||
// Si no hay companyId en cookie, obtener las compañías del usuario y usar la primera
|
||||
if (!companyId) {
|
||||
const companiesResponse = await fetch(`${baseUrl}v1/a76/company/my-companies`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (companiesResponse.ok) {
|
||||
const companies = await companiesResponse.json();
|
||||
if (companies.length > 0) {
|
||||
companyId = companies[0].id.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
const companyId = await getActiveCompanyId(cookies, fetch);
|
||||
|
||||
// Si aún no hay companyId, mostrar error
|
||||
if (!companyId) {
|
||||
@@ -53,18 +29,16 @@ export const load: PageServerLoad = async ({ fetch, cookies }) => {
|
||||
};
|
||||
}
|
||||
|
||||
const response = await fetch(`${baseUrl}v1/a76/pedimentos?company_id=${companyId}&page=1&page_size=50`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/a76/pedimentos?company_id=${companyId}&page=1&page_size=50`,
|
||||
{},
|
||||
cookies,
|
||||
fetch,
|
||||
'/login'
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
throw redirect(302, '/login');
|
||||
}
|
||||
|
||||
return {
|
||||
items: [],
|
||||
total: 0,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { error, redirect } from '@sveltejs/kit';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ params, cookies }) => {
|
||||
const accessToken = cookies.get('access_token');
|
||||
export const load: PageServerLoad = async ({ params, cookies, fetch }) => {
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!accessToken) {
|
||||
throw redirect(302, '/login');
|
||||
@@ -23,26 +24,12 @@ export const load: PageServerLoad = async ({ params, cookies }) => {
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
// Cargar el pedimento desde el backend
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/a76/pedimentos/${pedimentoId}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Cargar el pedimento desde el backend usando authenticatedFetch
|
||||
const response = await authenticatedFetch(
|
||||
`v1/a76/pedimentos/${pedimentoId}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
await parent();
|
||||
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
return {
|
||||
error: 'No authenticated',
|
||||
items: [],
|
||||
@@ -21,25 +22,12 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '50');
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/public/refrence_data/code-pedimento-regimens?page=${page}&page_size=${pageSize}`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/public/refrence_data/code-pedimento-regimens?page=${page}&page_size=${pageSize}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
await parent();
|
||||
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
return {
|
||||
error: 'No authenticated',
|
||||
items: [],
|
||||
@@ -21,25 +22,12 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '50');
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/public/refrence_data/containers?page=${page}&page_size=${pageSize}`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/public/refrence_data/containers?page=${page}&page_size=${pageSize}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
await parent();
|
||||
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
return {
|
||||
error: 'No authenticated',
|
||||
items: [],
|
||||
@@ -21,25 +22,12 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '50');
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/public/refrence_data/countries?page=${page}&page_size=${pageSize}`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/public/refrence_data/countries?page=${page}&page_size=${pageSize}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
await parent();
|
||||
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
return {
|
||||
error: 'No authenticated',
|
||||
items: [],
|
||||
@@ -21,25 +22,12 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '50');
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/public/refrence_data/currency-types?page=${page}&page_size=${pageSize}`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/public/refrence_data/currency-types?page=${page}&page_size=${pageSize}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
await parent();
|
||||
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
return {
|
||||
error: 'No authenticated',
|
||||
items: [],
|
||||
@@ -21,25 +22,12 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '50');
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/public/refrence_data/customs-sections?page=${page}&page_size=${pageSize}`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/public/refrence_data/customs-sections?page=${page}&page_size=${pageSize}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
await parent();
|
||||
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
return {
|
||||
error: 'No authenticated',
|
||||
items: [],
|
||||
@@ -21,25 +22,12 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '50');
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/public/refrence_data/customs-warehouses?page=${page}&page_size=${pageSize}`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/public/refrence_data/customs-warehouses?page=${page}&page_size=${pageSize}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
await parent();
|
||||
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
return {
|
||||
error: 'No authenticated',
|
||||
items: [],
|
||||
@@ -21,25 +22,12 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '50');
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/public/refrence_data/incoterms?page=${page}&page_size=${pageSize}`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/public/refrence_data/incoterms?page=${page}&page_size=${pageSize}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
await parent();
|
||||
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
return {
|
||||
error: 'No authenticated',
|
||||
items: [],
|
||||
@@ -21,25 +22,12 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '50');
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/public/refrence_data/invoice-types?page=${page}&page_size=${pageSize}`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/public/refrence_data/invoice-types?page=${page}&page_size=${pageSize}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
await parent();
|
||||
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
return {
|
||||
error: 'No authenticated',
|
||||
items: [],
|
||||
@@ -21,25 +22,12 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '50');
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/public/refrence_data/material-types?page=${page}&page_size=${pageSize}`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/public/refrence_data/material-types?page=${page}&page_size=${pageSize}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
await parent();
|
||||
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
return {
|
||||
error: 'No authenticated',
|
||||
items: [],
|
||||
@@ -21,25 +22,12 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '50');
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/public/refrence_data/payment-methods?page=${page}&page_size=${pageSize}`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/public/refrence_data/payment-methods?page=${page}&page_size=${pageSize}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
await parent();
|
||||
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
return {
|
||||
error: 'No authenticated',
|
||||
items: [],
|
||||
@@ -21,25 +22,12 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '50');
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/public/refrence_data/pedimento-codes?page=${page}&page_size=${pageSize}`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/public/refrence_data/pedimento-codes?page=${page}&page_size=${pageSize}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
await parent();
|
||||
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
return {
|
||||
error: 'No authenticated',
|
||||
items: [],
|
||||
@@ -21,25 +22,12 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '50');
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/public/refrence_data/pedimento-regimens?page=${page}&page_size=${pageSize}`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/public/refrence_data/pedimento-regimens?page=${page}&page_size=${pageSize}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
await parent();
|
||||
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
return {
|
||||
error: 'No authenticated',
|
||||
items: [],
|
||||
@@ -21,25 +22,12 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '50');
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/public/refrence_data/sectors?page=${page}&page_size=${pageSize}`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/public/refrence_data/sectors?page=${page}&page_size=${pageSize}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
await parent();
|
||||
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
return {
|
||||
error: 'No authenticated',
|
||||
items: [],
|
||||
@@ -21,25 +22,12 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '50');
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/public/refrence_data/states?page=${page}&page_size=${pageSize}`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/public/refrence_data/states?page=${page}&page_size=${pageSize}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
await parent();
|
||||
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
return {
|
||||
error: 'No authenticated',
|
||||
items: [],
|
||||
@@ -21,25 +22,12 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '50');
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/public/refrence_data/transport-modes?page=${page}&page_size=${pageSize}`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/public/refrence_data/transport-modes?page=${page}&page_size=${pageSize}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
await parent();
|
||||
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
return {
|
||||
error: 'No authenticated',
|
||||
items: [],
|
||||
@@ -21,25 +22,12 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '50');
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/public/refrence_data/transport-types?page=${page}&page_size=${pageSize}`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/public/refrence_data/transport-types?page=${page}&page_size=${pageSize}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
await parent();
|
||||
|
||||
const token = cookies.get('access_token');
|
||||
const { accessToken } = getAuthTokens(cookies);
|
||||
|
||||
if (!token) {
|
||||
if (!accessToken) {
|
||||
return {
|
||||
error: 'No authenticated',
|
||||
items: [],
|
||||
@@ -21,25 +22,12 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '50');
|
||||
|
||||
// Configurar la URL de la API para SSR
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
if (!apiUrl) {
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
// Reemplazar 'localhost' con 'backend' para llamadas desde el servidor (SSR)
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
// Normalizar la URL
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}v1/public/refrence_data/valuation-methods?page=${page}&page_size=${pageSize}`,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
// Usar authenticatedFetch para manejar automáticamente el refresh de tokens
|
||||
const response = await authenticatedFetch(
|
||||
`v1/public/refrence_data/valuation-methods?page=${page}&page_size=${pageSize}`,
|
||||
{},
|
||||
cookies,
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
import { redirect, fail } from '@sveltejs/kit';
|
||||
import type { Actions, PageServerLoad } from './$types';
|
||||
import { clearAuthTokens, setAuthTokens, getServerApiUrl } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, url }) => {
|
||||
// Si hay un parámetro 'logout' en la URL, limpiar las cookies
|
||||
if (url.searchParams.has('logout')) {
|
||||
cookies.delete('access_token', { path: '/' });
|
||||
cookies.delete('refresh_token', { path: '/' });
|
||||
cookies.delete('active_company_id', { path: '/' });
|
||||
clearAuthTokens(cookies);
|
||||
return {};
|
||||
}
|
||||
|
||||
// Limpiar siempre las cookies de sesión anterior al cargar login
|
||||
// Esto evita que se queden datos del tenant anterior
|
||||
cookies.delete('access_token', { path: '/' });
|
||||
cookies.delete('refresh_token', { path: '/' });
|
||||
cookies.delete('active_company_id', { path: '/' });
|
||||
clearAuthTokens(cookies);
|
||||
|
||||
// Permitir acceso al login sin redirigir automáticamente
|
||||
// Esto evita bucles de redirección cuando el token existe pero puede estar expirado
|
||||
@@ -33,17 +30,7 @@ export const actions = {
|
||||
}
|
||||
|
||||
try {
|
||||
// En Docker, el servidor debe usar el nombre del servicio 'backend' en lugar de 'localhost'
|
||||
// Intentar primero con INTERNAL_API_URL, luego VITE_API_URL modificado
|
||||
let apiUrl = process.env.INTERNAL_API_URL;
|
||||
|
||||
if (!apiUrl) {
|
||||
// Si no hay INTERNAL_API_URL, modificar VITE_API_URL para Docker
|
||||
apiUrl = import.meta.env.VITE_API_URL;
|
||||
apiUrl = apiUrl?.replace('localhost', 'backend').replace('127.0.0.1', 'backend');
|
||||
}
|
||||
|
||||
const baseUrl = apiUrl?.endsWith('/') ? apiUrl : `${apiUrl}/`;
|
||||
const baseUrl = getServerApiUrl();
|
||||
const loginUrl = `${baseUrl}v1/auth/login`;
|
||||
|
||||
const requestBody = {
|
||||
@@ -71,14 +58,8 @@ export const actions = {
|
||||
}
|
||||
|
||||
if (result.access_token) {
|
||||
// Establecer cookie en el servidor
|
||||
cookies.set('access_token', result.access_token, {
|
||||
path: '/',
|
||||
httpOnly: false, // Permitir acceso desde JavaScript
|
||||
secure: process.env.NODE_ENV === 'production',
|
||||
sameSite: 'lax',
|
||||
maxAge: 60 * 60 * 24 * 7 // 7 días
|
||||
});
|
||||
// Establecer tokens usando la función centralizada
|
||||
setAuthTokens(cookies, result.access_token, result.refresh_token);
|
||||
|
||||
// Redirigir al dashboard o a la URL original
|
||||
const redirectUrl = url.searchParams.get('redirect') || '/dashboard';
|
||||
|
||||
Reference in New Issue
Block a user