Files
cameleer-server/ui/src/auth/use-auth.ts

49 lines
1.4 KiB
TypeScript
Raw Normal View History

import { useEffect, useRef } from 'react';
import { useAuthStore } from './auth-store';
import { configureAuth } from '../api/client';
import { useNavigate } from 'react-router';
export function useAuth() {
const { accessToken, isAuthenticated, refresh, logout } = useAuthStore();
const navigate = useNavigate();
const refreshingRef = useRef(false);
useEffect(() => {
configureAuth({
onUnauthorized: async () => {
if (refreshingRef.current) return;
refreshingRef.current = true;
try {
const ok = await useAuthStore.getState().refresh();
if (!ok) {
useAuthStore.getState().logout();
navigate('/login', { replace: true });
}
} finally {
refreshingRef.current = false;
}
},
});
}, [navigate]);
useEffect(() => {
if (!isAuthenticated) return;
const interval = setInterval(async () => {
const token = useAuthStore.getState().accessToken;
if (!token) return;
try {
const payload = JSON.parse(atob(token.split('.')[1]));
const expiresIn = payload.exp * 1000 - Date.now();
if (expiresIn < 5 * 60 * 1000) {
await refresh();
}
} catch {
// Token parse failure
}
}, 30_000);
return () => clearInterval(interval);
}, [isAuthenticated, refresh]);
return { accessToken, isAuthenticated, logout };
}