feat(auth): improve user data fetching on authentication

- Updated AuthCallbackPage to fetch user data after successful authentication and set user context.
- Removed redundant initialization logic in useLogin hook and streamlined user data retrieval post-login.
- Enhanced error handling for user data fetching to improve user experience during authentication.
This commit is contained in:
Daniel Luiz Alves
2025-07-11 00:19:48 -03:00
parent 2e56b7e59f
commit a4bc5ec015
2 changed files with 62 additions and 45 deletions

View File

@@ -4,9 +4,13 @@ import { useEffect } from "react";
import { useRouter, useSearchParams } from "next/navigation"; import { useRouter, useSearchParams } from "next/navigation";
import { toast } from "sonner"; import { toast } from "sonner";
import { useAuth } from "@/contexts/auth-context";
import { getCurrentUser } from "@/http/endpoints";
export default function AuthCallbackPage() { export default function AuthCallbackPage() {
const router = useRouter(); const router = useRouter();
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const { setUser, setIsAuthenticated, setIsAdmin } = useAuth();
useEffect(() => { useEffect(() => {
const token = searchParams.get("token"); const token = searchParams.get("token");
@@ -46,13 +50,33 @@ export default function AuthCallbackPage() {
if (token) { if (token) {
document.cookie = `token=${token}; path=/; max-age=${7 * 24 * 60 * 60}; samesite=lax`; document.cookie = `token=${token}; path=/; max-age=${7 * 24 * 60 * 60}; samesite=lax`;
toast.success("Successfully authenticated!"); // Buscar dados do usuário após definir o cookie
router.push("/dashboard"); const fetchUserData = async () => {
try {
const response = await getCurrentUser();
if (response?.data?.user) {
const { isAdmin, ...userData } = response.data.user;
setUser(userData);
setIsAdmin(isAdmin);
setIsAuthenticated(true);
toast.success("Successfully authenticated!");
router.push("/dashboard");
} else {
throw new Error("No user data received");
}
} catch (error) {
console.error("Error fetching user data:", error);
toast.error("Authentication failed");
router.push("/login");
}
};
fetchUserData();
return; return;
} }
router.push("/login"); router.push("/login");
}, [router, searchParams]); }, [router, searchParams, setUser, setIsAuthenticated, setIsAdmin]);
return ( return (
<div className="min-h-screen flex items-center justify-center"> <div className="min-h-screen flex items-center justify-center">

View File

@@ -27,7 +27,6 @@ export function useLogin() {
const { isAuthenticated, setUser, setIsAdmin, setIsAuthenticated } = useAuth(); const { isAuthenticated, setUser, setIsAdmin, setIsAuthenticated } = useAuth();
const [isVisible, setIsVisible] = useState(false); const [isVisible, setIsVisible] = useState(false);
const [error, setError] = useState<string | undefined>(); const [error, setError] = useState<string | undefined>();
const [isInitialized, setIsInitialized] = useState(false);
const [requiresTwoFactor, setRequiresTwoFactor] = useState(false); const [requiresTwoFactor, setRequiresTwoFactor] = useState(false);
const [twoFactorUserId, setTwoFactorUserId] = useState<string | null>(null); const [twoFactorUserId, setTwoFactorUserId] = useState<string | null>(null);
const [twoFactorCode, setTwoFactorCode] = useState(""); const [twoFactorCode, setTwoFactorCode] = useState("");
@@ -61,43 +60,6 @@ export function useLogin() {
} }
}, [searchParams, t]); }, [searchParams, t]);
useEffect(() => {
const checkAuth = async () => {
try {
const appInfoResponse = await getAppInfo();
const appInfo = appInfoResponse.data;
if (appInfo.firstUserAccess) {
setUser(null);
setIsAdmin(false);
setIsAuthenticated(false);
setIsInitialized(true);
return;
}
const userResponse = await getCurrentUser();
if (!userResponse?.data?.user) {
throw new Error(t("errors.noUserData"));
}
const { isAdmin, ...userData } = userResponse.data.user;
setUser(userData);
setIsAdmin(isAdmin);
setIsAuthenticated(true);
router.push("/dashboard");
} catch (err) {
console.error(err);
setUser(null);
setIsAdmin(false);
setIsAuthenticated(false);
} finally {
setIsInitialized(true);
}
};
checkAuth();
}, [router, setUser, setIsAdmin, setIsAuthenticated, t]);
const toggleVisibility = () => setIsVisible(!isVisible); const toggleVisibility = () => setIsVisible(!isVisible);
const onSubmit = async (data: LoginFormValues) => { const onSubmit = async (data: LoginFormValues) => {
@@ -115,8 +77,24 @@ export function useLogin() {
} }
if (loginData.user) { if (loginData.user) {
// Após login bem-sucedido, buscar dados completos do usuário incluindo a imagem
try {
const userResponse = await getCurrentUser();
if (userResponse?.data?.user) {
const { isAdmin, ...userData } = userResponse.data.user;
setUser(userData);
setIsAdmin(isAdmin);
setIsAuthenticated(true);
router.replace("/dashboard");
return;
}
} catch (userErr) {
console.warn("Failed to fetch complete user data, using login data:", userErr);
}
// Fallback para dados do login se falhar ao buscar dados completos
const { isAdmin, ...userData } = loginData.user; const { isAdmin, ...userData } = loginData.user;
setUser({ ...userData, image: userData.image ?? null }); setUser({ ...userData, image: null });
setIsAdmin(isAdmin); setIsAdmin(isAdmin);
setIsAuthenticated(true); setIsAuthenticated(true);
router.replace("/dashboard"); router.replace("/dashboard");
@@ -151,9 +129,24 @@ export function useLogin() {
rememberDevice: rememberDevice, rememberDevice: rememberDevice,
}); });
const { isAdmin, ...userData } = response.data.user; // Após two-factor login bem-sucedido, buscar dados completos do usuário incluindo a imagem
try {
const userResponse = await getCurrentUser();
if (userResponse?.data?.user) {
const { isAdmin, ...userData } = userResponse.data.user;
setUser(userData);
setIsAdmin(isAdmin);
setIsAuthenticated(true);
router.replace("/dashboard");
return;
}
} catch (userErr) {
console.warn("Failed to fetch complete user data after 2FA, using response data:", userErr);
}
setUser(userData); // Fallback para dados da resposta se falhar ao buscar dados completos
const { isAdmin, ...userData } = response.data.user;
setUser({ ...userData, image: userData.image ?? null });
setIsAdmin(isAdmin); setIsAdmin(isAdmin);
setIsAuthenticated(true); setIsAuthenticated(true);
router.replace("/dashboard"); router.replace("/dashboard");
@@ -169,7 +162,7 @@ export function useLogin() {
}; };
return { return {
isAuthenticated: !isInitialized ? null : isAuthenticated, isAuthenticated,
error, error,
isVisible, isVisible,
toggleVisibility, toggleVisibility,