Merge pull request 'fix(dashboard): evitar flash de "Acceso Restringido" al refrescar' (#401) from fix/flash-acceso-restringido-dashboard into development

Reviewed-on: ADUANASOFT/anexo76#401
This commit is contained in:
2026-05-15 21:10:33 +00:00

View File

@@ -61,6 +61,48 @@
// Actualizar el contexto reactive al cambiar data.user (post invalidateAll)
$effect(() => { setContext('user', data.user); });
// ── Sembrar el authStore desde data.user ───────────────────────────────
// Se ejecuta SÍNCRONAMENTE en el script (SSR + hidratación), no en onMount,
// para que `$currentUser` ya esté poblado en el primer render de las páginas
// hijas. Evita el flash de "Acceso restringido" al refrescar cuando las páginas
// derivan `canView` a partir de `$currentUser`.
function syncAuthStoreFromData() {
if (!data.user) return;
if (data.user.token) {
authStore.setToken(data.user.token);
authStore.setAuthenticated(true);
}
const resolvedAvatarUrl =
data.user.workspaceAvatarUrl ||
data.user.workspace_avatar_url ||
data.user.avatarUrl ||
data.user.avatar_url ||
data.user.legacyAvatarUrl ||
data.user.legacy_avatar_url ||
null;
authStore.setUser({
id: data.user.sub ?? data.user.id ?? '',
username: data.user.preferred_username ?? data.user.username ?? '',
email: data.user.email,
name: data.user.name,
avatarUrl: resolvedAvatarUrl,
workspaceAvatarUrl: data.user.workspaceAvatarUrl ?? data.user.workspace_avatar_url ?? null,
legacyAvatarUrl: data.user.legacyAvatarUrl ?? data.user.legacy_avatar_url ?? data.user.avatar_url ?? null,
tenantId: data.user.tenant_id,
roles: data.user.roles ?? [],
permissions: data.user.permissions ?? []
});
}
syncAuthStoreFromData();
// Re-sincronizar si data.user cambia (por ejemplo, tras invalidateAll o cambio de compañía)
$effect(() => {
// Dependencia explícita para que el effect reaccione al swap de data.user
data.user;
syncAuthStoreFromData();
});
// ── Manejar expiración de sesión ────────────────────────────────────────
function handleSessionExpired(e: Event) {
const { reason } = (e as CustomEvent<SessionExpiredDetail>).detail;
@@ -69,37 +111,6 @@
}
onMount(() => {
// ── Inicializar el token en el authStore desde los datos del servidor ──
// El servidor valida la cookie y pasa el access_token a través de data.user.token.
// Lo almacenamos en memoria (authStore) sin tocar localStorage.
if (data.user?.token) {
authStore.setToken(data.user.token);
authStore.setAuthenticated(true);
}
if (data.user) {
const resolvedAvatarUrl =
data.user.workspaceAvatarUrl ||
data.user.workspace_avatar_url ||
data.user.avatarUrl ||
data.user.avatar_url ||
data.user.legacyAvatarUrl ||
data.user.legacy_avatar_url ||
null;
authStore.setUser({
id: data.user.sub ?? data.user.id ?? '',
username: data.user.preferred_username ?? data.user.username ?? '',
email: data.user.email,
name: data.user.name,
avatarUrl: resolvedAvatarUrl,
workspaceAvatarUrl: data.user.workspaceAvatarUrl ?? data.user.workspace_avatar_url ?? null,
legacyAvatarUrl: data.user.legacyAvatarUrl ?? data.user.legacy_avatar_url ?? data.user.avatar_url ?? null,
tenantId: data.user.tenant_id,
roles: data.user.roles ?? [],
permissions: data.user.permissions ?? []
});
}
// ── Inicializar el SessionManager ─────────────────────────────────────
if (data.user?.token) {
const mgr = createSessionManager({