'use client'; /** * useAuth — Client-side authentication hook for the SentryAgent portal. * * Reads the tenant JWT stored in localStorage under the key * `sentryagent_token`. If no token is present the hook signals that the user * is unauthenticated so the calling page can redirect to `/login`. * * This is intentionally lightweight: the portal calls the AgentIdP API * directly; the JWT is issued by the AgentIdP `/api/tenants/login` endpoint * and stored on successful sign-in. * * @module hooks/useAuth */ import { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; /** The localStorage key under which the tenant JWT is persisted. */ export const AUTH_TOKEN_KEY = 'sentryagent_token'; /** Shape returned by the useAuth hook. */ export interface AuthState { /** The stored JWT, or null if unauthenticated. */ token: string | null; /** True while the hook is reading from localStorage on mount. */ loading: boolean; /** * Sign the user out by removing the stored token and redirecting to /login. */ signOut: () => void; } /** * Returns the current authentication state and provides a sign-out helper. * Redirects to `/login` when no token is found (after the initial mount check). * * @param redirectOnUnauth - When true (default), redirects to /login if * no token is present. Pass false on public pages. * @returns AuthState */ export function useAuth(redirectOnUnauth = true): AuthState { const router = useRouter(); const [token, setToken] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { const stored = typeof window !== 'undefined' ? localStorage.getItem(AUTH_TOKEN_KEY) : null; setToken(stored); setLoading(false); if (!stored && redirectOnUnauth) { router.replace('/login'); } }, [redirectOnUnauth, router]); const signOut = (): void => { if (typeof window !== 'undefined') { localStorage.removeItem(AUTH_TOKEN_KEY); } setToken(null); router.replace('/login'); }; return { token, loading, signOut }; }