fix: auto-redirect to signup/login when auth tokens are stale
This commit is contained in:
parent
2c855b7e17
commit
a035e5af10
2 changed files with 30 additions and 3 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue