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:
@@ -8,6 +8,11 @@
|
||||
import { createAuthClient } from "better-auth/svelte";
|
||||
import { convexClient } from "@convex-dev/better-auth/client/plugins";
|
||||
|
||||
// O baseURL deve apontar para o frontend (SvelteKit), não para o Convex diretamente
|
||||
// O Better Auth usa as rotas HTTP do Convex que são acessadas via proxy do SvelteKit
|
||||
// ou diretamente se configurado. Com o plugin convexClient, o token é gerenciado automaticamente.
|
||||
export const authClient = createAuthClient({
|
||||
// baseURL padrão é window.location.origin, que é o correto para SvelteKit
|
||||
// O Better Auth será acessado via rotas HTTP do Convex registradas em http.ts
|
||||
plugins: [convexClient()],
|
||||
});
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user