refactor: enhance authentication and access control in ProtectedRoute component

- Updated the ProtectedRoute component to improve access control logic, including a timeout mechanism for handling authentication checks.
- Refactored the checkAccess function to streamline user access verification based on roles and authentication status.
- Added comments for clarity on the authentication flow and the use of the convexClient plugin in the auth.ts file.
- Improved the overall structure and readability of the code in auth.ts and ProtectedRoute.svelte.
This commit is contained in:
2025-11-17 16:27:15 -03:00
parent d4e70b5e52
commit 2c3d231d20
7 changed files with 1399 additions and 970 deletions

View File

@@ -20,26 +20,32 @@
let isChecking = $state(true);
let hasAccess = $state(false);
let timeoutId: ReturnType<typeof setTimeout> | null = null;
const currentUser = useQuery(api.auth.getCurrentUser, {});
onMount(() => {
// Usar $effect para reagir às mudanças na query
$effect(() => {
checkAccess();
});
function checkAccess() {
isChecking = true;
// Limpar timeout anterior se existir
if (timeoutId) {
clearTimeout(timeoutId);
timeoutId = null;
}
// Aguardar um pouco para o authStore carregar do localStorage
setTimeout(() => {
// Verificar autenticação
if (requireAuth && !currentUser?.data) {
const currentPath = window.location.pathname;
window.location.href = `${redirectTo}?error=auth_required&redirect=${encodeURIComponent(currentPath)}`;
return;
}
// Se a query ainda está carregando (undefined), aguardar
if (currentUser === undefined) {
isChecking = true;
hasAccess = false;
return;
}
// Se a query retornou dados, verificar autenticação
if (currentUser?.data) {
// Verificar roles
if (allowedRoles.length > 0 && currentUser?.data) {
if (allowedRoles.length > 0) {
const hasRole = allowedRoles.includes(currentUser.data.role?.nome ?? '');
if (!hasRole) {
const currentPath = window.location.pathname;
@@ -49,19 +55,40 @@
}
// Verificar nível
if (
currentUser?.data &&
currentUser.data.role?.nivel &&
currentUser.data.role.nivel > maxLevel
) {
if (currentUser.data.role?.nivel && currentUser.data.role.nivel > maxLevel) {
const currentPath = window.location.pathname;
window.location.href = `${redirectTo}?error=access_denied&route=${encodeURIComponent(currentPath)}`;
return;
}
// Se chegou aqui, permitir acesso
hasAccess = true;
isChecking = false;
}, 100);
return;
}
// Se não tem dados e requer autenticação, aguardar um pouco antes de redirecionar
// (pode estar carregando ainda)
if (requireAuth && !currentUser?.data) {
isChecking = true;
hasAccess = false;
// Aguardar 3 segundos antes de redirecionar (dar tempo para a query carregar)
timeoutId = setTimeout(() => {
// Verificar novamente antes de redirecionar
if (!currentUser?.data) {
const currentPath = window.location.pathname;
window.location.href = `${redirectTo}?error=auth_required&redirect=${encodeURIComponent(currentPath)}`;
}
}, 3000);
return;
}
// Se não requer autenticação, permitir acesso
if (!requireAuth) {
hasAccess = true;
isChecking = false;
}
}
</script>