fix: auto-redirect to signup/login when auth tokens are stale

This commit is contained in:
Roland Tannous 2026-02-15 08:27:35 +00:00
commit a035e5af10
2 changed files with 30 additions and 3 deletions

View file

@ -10,6 +10,26 @@ type RefreshResponse = {
refresh_token: string;
};
let isRedirecting = false;
async function redirectToAuth(): Promise<void> {
if (isRedirecting) return;
isRedirecting = true;
let target = "/login";
try {
const res = await fetch("/api/auth/status");
if (res.ok) {
const data = (await res.json()) as { initialized: boolean };
if (!data.initialized) target = "/signup";
}
} catch {
// Fall through to /login on error
}
window.location.href = target;
}
export async function refreshSession(): Promise<boolean> {
const refreshToken = getRefreshToken();
if (!refreshToken) return false;
@ -48,7 +68,11 @@ export async function authFetch(
if (response.status !== 401) return response;
const refreshed = await refreshSession();
if (!refreshed) return response;
if (!refreshed) {
clearAuthTokens();
void redirectToAuth();
return response;
}
const retryHeaders = new Headers(init?.headers);
const newToken = getAuthToken();

View file

@ -1,3 +1,4 @@
import { hasAuthToken } from "@/features/auth";
import { useEffect } from "react";
import {
getTrainingMetrics,
@ -48,6 +49,7 @@ export function useTrainingRuntimeLifecycle(): void {
};
const pollMetrics = async () => {
if (!hasAuthToken()) return;
const gen = runtimeStore.getState().resetGeneration;
try {
const metrics = await getTrainingMetrics();
@ -56,13 +58,14 @@ export function useTrainingRuntimeLifecycle(): void {
}
runtimeStore.getState().applyMetrics(metrics);
} catch (error) {
if (!isAbortError(error) && !disposed) {
if (!isAbortError(error) && !disposed && hasAuthToken()) {
runtimeStore.getState().setSseConnected(false);
}
}
};
const pollStatus = async () => {
if (!hasAuthToken()) return;
const gen = runtimeStore.getState().resetGeneration;
try {
const status = await getTrainingStatus();
@ -79,7 +82,7 @@ export function useTrainingRuntimeLifecycle(): void {
stopStream();
}
} catch (error) {
if (!isAbortError(error) && !disposed) {
if (!isAbortError(error) && !disposed && hasAuthToken()) {
runtimeStore.getState().setSseConnected(false);
}
}