All files / client/src/hooks use-auth.ts

0% Statements 0/19
0% Branches 0/6
0% Functions 0/4
0% Lines 0/19

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68                                                                                                                                       
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import type { User } from "@shared/models/auth";
 
async function fetchUser(): Promise<User | null> {
  const response = await fetch("/api/auth/user", {
    credentials: "include",
  });
 
  if (response.status === 401) {
    return null;
  }
 
  if (!response.ok) {
    throw new Error(`${response.status}: ${response.statusText}`);
  }
 
  return response.json();
}
 
async function logout(): Promise<void> {
  try {
    const response = await fetch("/api/logout", {
      credentials: "include",
    });
 
    if (!response.ok) {
      // If the server-side logout fails, do not redirect away so the user remains in a consistent state.
      // This also allows error logging/monitoring to capture the failure.
      // eslint-disable-next-line no-console
      console.error(`Logout failed: ${response.status} ${response.statusText}`);
      return;
    }
  } catch (error) {
    // Network or other unexpected error during logout request.
    // eslint-disable-next-line no-console
    console.error("Logout request failed", error);
    return;
  }
 
  // Only redirect after the server-side logout has completed successfully.
  window.location.href = "/";
}
 
export function useAuth() {
  const queryClient = useQueryClient();
  const { data: user, isLoading } = useQuery<User | null>({
    queryKey: ["/api/auth/user"],
    queryFn: fetchUser,
    retry: false,
    staleTime: 1000 * 60 * 5, // 5 minutes
  });
 
  const logoutMutation = useMutation({
    mutationFn: logout,
    onSuccess: () => {
      queryClient.setQueryData(["/api/auth/user"], null);
    },
  });
 
  return {
    user,
    isLoading,
    isAuthenticated: !!user,
    logout: logoutMutation.mutate,
    isLoggingOut: logoutMutation.isPending,
  };
}