Fix mission not loading when accessed via URL before authentication
When loading a mission via URL param (?mission=...), the initial API fetch would fail with 401 before the user authenticated. After login, nothing triggered a re-fetch of the mission data. Added auth retry mechanism: - Add signalAuthSuccess() to dispatch event after successful login - Add authRetryTrigger state and listener in control-client - Re-fetch mission and providers when auth succeeds
This commit is contained in:
@@ -864,7 +864,18 @@ export default function ControlClient() {
|
||||
});
|
||||
}, []);
|
||||
|
||||
// Load mission from URL param on mount
|
||||
// Load mission from URL param on mount (and retry on auth success)
|
||||
const [authRetryTrigger, setAuthRetryTrigger] = useState(0);
|
||||
|
||||
// Listen for auth success to retry loading
|
||||
useEffect(() => {
|
||||
const onAuthSuccess = () => {
|
||||
setAuthRetryTrigger((prev) => prev + 1);
|
||||
};
|
||||
window.addEventListener("openagent:auth:success", onAuthSuccess);
|
||||
return () => window.removeEventListener("openagent:auth:success", onAuthSuccess);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const missionId = searchParams.get("mission");
|
||||
if (missionId) {
|
||||
@@ -877,7 +888,10 @@ export default function ControlClient() {
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Failed to load mission:", err);
|
||||
toast.error("Failed to load mission");
|
||||
// Only show error toast if this wasn't due to auth (authRetryTrigger > 0 means we already retried)
|
||||
if (authRetryTrigger > 0) {
|
||||
toast.error("Failed to load mission");
|
||||
}
|
||||
})
|
||||
.finally(() => setMissionLoading(false));
|
||||
} else {
|
||||
@@ -893,7 +907,7 @@ export default function ControlClient() {
|
||||
console.error("Failed to get current mission:", err);
|
||||
});
|
||||
}
|
||||
}, [searchParams, router, missionHistoryToItems]);
|
||||
}, [searchParams, router, missionHistoryToItems, authRetryTrigger]);
|
||||
|
||||
// Poll for running parallel missions
|
||||
useEffect(() => {
|
||||
@@ -916,7 +930,7 @@ export default function ControlClient() {
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
// Fetch available providers and models for mission creation
|
||||
// Fetch available providers and models for mission creation (retry on auth success)
|
||||
useEffect(() => {
|
||||
listProviders()
|
||||
.then((data) => {
|
||||
@@ -925,7 +939,7 @@ export default function ControlClient() {
|
||||
.catch((err) => {
|
||||
console.error("Failed to fetch providers:", err);
|
||||
});
|
||||
}, []);
|
||||
}, [authRetryTrigger]);
|
||||
|
||||
// Fetch server configuration (max_iterations) from health endpoint
|
||||
useEffect(() => {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { login, getHealth } from '@/lib/api';
|
||||
import { clearJwt, getValidJwt, setJwt } from '@/lib/auth';
|
||||
import { clearJwt, getValidJwt, setJwt, signalAuthSuccess } from '@/lib/auth';
|
||||
import { Lock } from 'lucide-react';
|
||||
|
||||
export function AuthGate({ children }: { children: React.ReactNode }) {
|
||||
@@ -61,6 +61,7 @@ export function AuthGate({ children }: { children: React.ReactNode }) {
|
||||
setJwt(res.token, res.exp);
|
||||
setIsAuthed(true);
|
||||
setPassword('');
|
||||
signalAuthSuccess();
|
||||
} catch {
|
||||
setError('Invalid password');
|
||||
} finally {
|
||||
|
||||
@@ -50,3 +50,8 @@ export function signalAuthRequired(): void {
|
||||
if (typeof window === 'undefined') return;
|
||||
window.dispatchEvent(new CustomEvent('openagent:auth:required'));
|
||||
}
|
||||
|
||||
export function signalAuthSuccess(): void {
|
||||
if (typeof window === 'undefined') return;
|
||||
window.dispatchEvent(new CustomEvent('openagent:auth:success'));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user