mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-03-22 13:47:19 +08:00
Fix: Only show login modal for genuine 401 errors, not connection issues (#8540)
Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
@@ -76,9 +76,9 @@ class OpenHands {
|
||||
): Promise<boolean> {
|
||||
if (appMode === "oss") return true;
|
||||
|
||||
const response =
|
||||
await openHands.post<AuthenticateResponse>("/api/authenticate");
|
||||
return response.status === 200;
|
||||
// Just make the request, if it succeeds (no exception thrown), return true
|
||||
await openHands.post<AuthenticateResponse>("/api/authenticate");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import axios, { AxiosError } from "axios";
|
||||
import OpenHands from "#/api/open-hands";
|
||||
import { useConfig } from "./use-config";
|
||||
import { useIsOnTosPage } from "#/hooks/use-is-on-tos-page";
|
||||
@@ -11,7 +12,23 @@ export const useIsAuthed = () => {
|
||||
|
||||
return useQuery({
|
||||
queryKey: ["user", "authenticated", appMode],
|
||||
queryFn: () => OpenHands.authenticate(appMode!),
|
||||
queryFn: async () => {
|
||||
try {
|
||||
// If in OSS mode or authentication succeeds, return true
|
||||
await OpenHands.authenticate(appMode!);
|
||||
return true;
|
||||
} catch (error) {
|
||||
// If it's a 401 error, return false (not authenticated)
|
||||
if (axios.isAxiosError(error)) {
|
||||
const axiosError = error as AxiosError;
|
||||
if (axiosError.response?.status === 401) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// For any other error, throw it to put the query in error state
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
enabled: !!appMode && !isOnTosPage,
|
||||
staleTime: 1000 * 60 * 5, // 5 minutes
|
||||
gcTime: 1000 * 60 * 15, // 15 minutes
|
||||
|
||||
@@ -58,7 +58,7 @@ export function ErrorBoundary() {
|
||||
export default function MainApp() {
|
||||
const navigate = useNavigate();
|
||||
const { pathname } = useLocation();
|
||||
const tosPageStatus = useIsOnTosPage();
|
||||
const isOnTosPage = useIsOnTosPage();
|
||||
const { data: settings } = useSettings();
|
||||
const { error } = useBalance();
|
||||
const { migrateUserConsent } = useMigrateUserConsent();
|
||||
@@ -68,7 +68,7 @@ export default function MainApp() {
|
||||
const {
|
||||
data: isAuthed,
|
||||
isFetching: isFetchingAuth,
|
||||
isError: authError,
|
||||
isError: isAuthError,
|
||||
} = useIsAuthed();
|
||||
|
||||
// Always call the hook, but we'll only use the result when not on TOS page
|
||||
@@ -78,30 +78,30 @@ export default function MainApp() {
|
||||
});
|
||||
|
||||
// When on TOS page, we don't use the GitHub auth URL
|
||||
const effectiveGitHubAuthUrl = tosPageStatus ? null : gitHubAuthUrl;
|
||||
const effectiveGitHubAuthUrl = isOnTosPage ? null : gitHubAuthUrl;
|
||||
|
||||
const [consentFormIsOpen, setConsentFormIsOpen] = React.useState(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
// Don't change language when on TOS page
|
||||
if (!tosPageStatus && settings?.LANGUAGE) {
|
||||
if (!isOnTosPage && settings?.LANGUAGE) {
|
||||
i18n.changeLanguage(settings.LANGUAGE);
|
||||
}
|
||||
}, [settings?.LANGUAGE, tosPageStatus]);
|
||||
}, [settings?.LANGUAGE, isOnTosPage]);
|
||||
|
||||
React.useEffect(() => {
|
||||
// Don't show consent form when on TOS page
|
||||
if (!tosPageStatus) {
|
||||
if (!isOnTosPage) {
|
||||
const consentFormModalIsOpen =
|
||||
settings?.USER_CONSENTS_TO_ANALYTICS === null;
|
||||
|
||||
setConsentFormIsOpen(consentFormModalIsOpen);
|
||||
}
|
||||
}, [settings, tosPageStatus]);
|
||||
}, [settings, isOnTosPage]);
|
||||
|
||||
React.useEffect(() => {
|
||||
// Don't migrate user consent when on TOS page
|
||||
if (!tosPageStatus) {
|
||||
if (!isOnTosPage) {
|
||||
// Migrate user consent to the server if it was previously stored in localStorage
|
||||
migrateUserConsent({
|
||||
handleAnalyticsWasPresentInLocalStorage: () => {
|
||||
@@ -109,7 +109,7 @@ export default function MainApp() {
|
||||
},
|
||||
});
|
||||
}
|
||||
}, [tosPageStatus]);
|
||||
}, [isOnTosPage]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (settings?.IS_NEW_USER && config.data?.APP_MODE === "saas") {
|
||||
@@ -120,22 +120,16 @@ export default function MainApp() {
|
||||
React.useEffect(() => {
|
||||
// Don't do any redirects when on TOS page
|
||||
// Don't allow users to use the app if it 402s
|
||||
if (!tosPageStatus && error?.status === 402 && pathname !== "/") {
|
||||
if (!isOnTosPage && error?.status === 402 && pathname !== "/") {
|
||||
navigate("/");
|
||||
}
|
||||
}, [error?.status, pathname, tosPageStatus]);
|
||||
}, [error?.status, pathname, isOnTosPage]);
|
||||
|
||||
// When on TOS page, we don't make any API calls, so we need to handle this case
|
||||
const userIsAuthed = tosPageStatus ? false : !!isAuthed && !authError;
|
||||
|
||||
// Only show the auth modal if:
|
||||
// 1. User is not authenticated
|
||||
// 2. We're not currently on the TOS page
|
||||
// 3. We're in SaaS mode
|
||||
const renderAuthModal =
|
||||
!isAuthed &&
|
||||
!isAuthError &&
|
||||
!isFetchingAuth &&
|
||||
!userIsAuthed &&
|
||||
!tosPageStatus &&
|
||||
!isOnTosPage &&
|
||||
config.data?.APP_MODE === "saas";
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user