Fix unauthenticate user not redirect to login page

fix #31

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-03-11 14:33:24 +01:00
parent cc1c843d0a
commit b41f417af6
9 changed files with 358 additions and 431 deletions

View File

@@ -1,5 +1,7 @@
import { Component, ErrorInfo, ReactNode } from "react";
import { ErrorPage } from "@/pages/ErrorPage";
import { UnAuthenticatedError } from "@/RelayEnvironment";
import { Navigate } from "react-router";
interface ErrorBoundaryProps {
children: ReactNode;
@@ -9,16 +11,20 @@ interface ErrorBoundaryProps {
interface ErrorBoundaryState {
hasError: boolean;
error?: Error;
isUnAuthenticated: boolean;
}
class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
constructor(props: ErrorBoundaryProps) {
super(props);
this.state = { hasError: false };
this.state = { hasError: false, isUnAuthenticated: false };
}
static getDerivedStateFromError(error: Error): ErrorBoundaryState {
return { hasError: true, error };
if (error instanceof UnAuthenticatedError) {
return { hasError: true, error, isUnAuthenticated: true };
}
return { hasError: true, error, isUnAuthenticated: false };
}
componentDidCatch(error: Error, info: ErrorInfo): void {
@@ -27,6 +33,10 @@ class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
}
render(): ReactNode {
if (this.state.isUnAuthenticated) {
return <Navigate to="/login" replace state={{ authRequired: true }} />;
}
if (this.state.hasError) {
if (this.props.fallback) {
return this.props.fallback;

View File

@@ -27,9 +27,9 @@ import {
SidebarMenuItem,
useSidebar,
} from "@/components/ui/sidebar";
import { useAuth } from "@/contexts/AuthContext";
import { NavUser_viewer$key } from "./__generated__/NavUser_viewer.graphql";
import { NavUserSkeleton } from "./NavUserSkeleton";
import { buildEndpoint } from "@/utils";
export const navUserFragment = graphql`
fragment NavUser_viewer on User {
@@ -42,13 +42,16 @@ export const navUserFragment = graphql`
export function NavUser({ viewer }: { viewer: NavUser_viewer$key }) {
const { isMobile } = useSidebar();
const currentUser = useFragment(navUserFragment, viewer);
const { logout } = useAuth();
const navigate = useNavigate();
const { organizationId } = useParams();
const handleLogout = async () => {
await logout();
navigate("/login");
fetch(buildEndpoint("/auth/logout"), {
method: "POST",
credentials: "include",
}).then(() => {
navigate("/login");
});
};
if (!organizationId) {

View File

@@ -1,20 +0,0 @@
import { Navigate, Outlet, useLocation } from "react-router";
import { useAuth } from "@/contexts/AuthContext";
export function ProtectedRoute() {
const { isAuthenticated, isLoading } = useAuth();
const location = useLocation();
// Show nothing while checking authentication
if (isLoading) {
return null;
}
// Redirect to login if not authenticated
if (!isAuthenticated) {
return <Navigate to="/login" replace state={{ from: location }} />;
}
// Render the protected content
return <Outlet />;
}