feat(security): implement permission checks in tenant CRUD routes and enhance API error handling
This commit is contained in:
@@ -2,8 +2,18 @@
|
||||
import '../app.css';
|
||||
import favicon from '$lib/assets/favicon.svg';
|
||||
import { Toaster } from 'svelte-sonner';
|
||||
import { page } from '$app/stores';
|
||||
import { handleApiError } from '$lib/utils/error-handler';
|
||||
|
||||
let { children } = $props();
|
||||
|
||||
// Detectar errores de CUALQUIER página (layout o page)
|
||||
$effect(() => {
|
||||
const pageData = $page.data as any;
|
||||
if (pageData?.error) {
|
||||
handleApiError(pageData.error);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
||||
@@ -30,7 +30,8 @@ export const load: LayoutServerLoad = async ({ cookies, url, fetch }) => {
|
||||
return {
|
||||
authenticated: true,
|
||||
user: userData,
|
||||
companies // Pasar las compañías al cliente
|
||||
companies, // Pasar las compañías al cliente
|
||||
error: undefined // Agregar error opcional para compatibilidad con error-handler
|
||||
};
|
||||
} catch (error) {
|
||||
// Si es un redirect, re-lanzarlo sin tocar las cookies
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getAuthTokens, authenticatedFetch } from '$lib/server/api';
|
||||
import { getAuthTokens, authenticatedFetch, handleApiResponse } from '$lib/server/api';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
// Esperar a que el layout padre valide/refresque el token
|
||||
@@ -63,16 +63,13 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
fetch
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error('📊 [Clients&Providers] API Error:', {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
error: errorText
|
||||
});
|
||||
const result = await handleApiResponse(response);
|
||||
|
||||
if (result.error) {
|
||||
console.error('📊 [Clients&Providers] API Error:', result.error);
|
||||
|
||||
return {
|
||||
error: `Error ${response.status}: ${response.statusText}`,
|
||||
error: result.error,
|
||||
items: [],
|
||||
total: 0,
|
||||
page: page,
|
||||
@@ -82,7 +79,7 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => {
|
||||
};
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const data = result.data;
|
||||
|
||||
return {
|
||||
items: data.items || [],
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
import type { PageData } from './$types';
|
||||
import { browser } from '$app/environment';
|
||||
import { companyStore } from '$lib/stores/company.svelte';
|
||||
import type { ApiError } from '$lib/utils/error-handler';
|
||||
|
||||
// Los datos iniciales vienen del servidor
|
||||
let { data }: { data: PageData } = $props();
|
||||
@@ -84,7 +85,7 @@
|
||||
let totalItems = $state(data.total || 0);
|
||||
let loading = $state(false);
|
||||
let hasMore = $derived(allItems.length < totalItems);
|
||||
let error = $state<string | null>(data.error || null);
|
||||
let error = $state<string | ApiError | null>(data.error || null);
|
||||
|
||||
async function loadMore() {
|
||||
if (loading || !hasMore || !companyStore.activeCompany) return;
|
||||
@@ -205,7 +206,9 @@
|
||||
<Card.Root class="border-destructive">
|
||||
<Card.Header>
|
||||
<Card.Title class="text-destructive">Error</Card.Title>
|
||||
<Card.Description>{error}</Card.Description>
|
||||
<Card.Description>
|
||||
{typeof error === 'string' ? error : error.detail}
|
||||
</Card.Description>
|
||||
</Card.Header>
|
||||
</Card.Root>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user