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:
2025-11-12 09:46:59 -06:00
parent 70f7d1f868
commit a5c1bab201
27 changed files with 549 additions and 573 deletions

View File

@@ -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>

View 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;
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
};

View File

@@ -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>

View 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
};
};

View File

@@ -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,

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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';