feat(security): implement permission checks in tenant CRUD routes and enhance API error handling
This commit is contained in:
@@ -133,7 +133,7 @@ export async function refreshAccessToken(
|
||||
* @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)
|
||||
* @param timeout - Timeout en milisegundos (default: 10000ms)
|
||||
* @param timeout - Timeout en milisegundos (default: 30000ms)
|
||||
*/
|
||||
export async function authenticatedFetch(
|
||||
endpoint: string,
|
||||
@@ -141,7 +141,7 @@ export async function authenticatedFetch(
|
||||
cookies: Cookies,
|
||||
fetch: typeof globalThis.fetch,
|
||||
redirectUrl?: string,
|
||||
timeout: number = 10000
|
||||
timeout: number = 30000
|
||||
): Promise<Response> {
|
||||
try {
|
||||
const baseUrl = getServerApiUrl();
|
||||
@@ -180,6 +180,12 @@ export async function authenticatedFetch(
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
|
||||
// Si es 403, no intentar refrescar - es un problema de permisos
|
||||
if (response.status === 403) {
|
||||
console.warn('🚫 [API] Acceso denegado (403):', endpoint);
|
||||
return response; // Retornar directamente para que el llamador maneje el error
|
||||
}
|
||||
|
||||
// Si es 401, intentar refrescar el token
|
||||
if (response.status === 401) {
|
||||
const newToken = await refreshAccessToken(cookies, fetch);
|
||||
@@ -346,3 +352,32 @@ export async function getActiveCompanyId(
|
||||
|
||||
return companyId || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper para manejar respuestas de API y convertir errores 403 en formato adecuado
|
||||
* para mostrar toasts en el cliente
|
||||
*/
|
||||
export async function handleApiResponse<T = any>(
|
||||
response: Response
|
||||
): Promise<{ data?: T; error?: { detail: string; status: number; isForbidden?: boolean } }> {
|
||||
if (response.ok) {
|
||||
// Para respuestas sin contenido (204)
|
||||
if (response.status === 204) {
|
||||
return { data: null as T };
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return { data };
|
||||
}
|
||||
|
||||
// Manejar errores
|
||||
const errorData = await response.json().catch(() => ({ detail: 'Error desconocido' }));
|
||||
|
||||
const error = {
|
||||
detail: errorData.detail || errorData.message || 'Error en la petición',
|
||||
status: response.status,
|
||||
isForbidden: response.status === 403
|
||||
};
|
||||
|
||||
return { error };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user