diff --git a/src/frontend/src/features/auth/api/fetchUser.ts b/src/frontend/src/features/auth/api/fetchUser.ts index aa7031cc..2c1757b8 100644 --- a/src/frontend/src/features/auth/api/fetchUser.ts +++ b/src/frontend/src/features/auth/api/fetchUser.ts @@ -1,7 +1,7 @@ import { ApiError } from '@/api/ApiError' import { fetchApi } from '@/api/fetchApi' import { type ApiUser } from './ApiUser' -import { attemptSilentLogin } from "@/features/auth"; +import { attemptSilentLogin, canAttemptSilentLogin } from '../utils/silentLogin' /** * fetch the logged-in user from the api. @@ -17,8 +17,13 @@ export const fetchUser = (): Promise => { .catch((error) => { // we assume that a 401 means the user is not logged in if (error instanceof ApiError && error.statusCode === 401) { - attemptSilentLogin(3600) - resolve(false) + // make sure to not resolve the promise while trying to silent login + // so that consumers of fetchUser don't think the work already ended + if (canAttemptSilentLogin()) { + attemptSilentLogin(3600) + } else { + resolve(false) + } } else { reject(error) } diff --git a/src/frontend/src/features/auth/api/useUser.tsx b/src/frontend/src/features/auth/api/useUser.tsx index 84f5e601..c665c5ae 100644 --- a/src/frontend/src/features/auth/api/useUser.tsx +++ b/src/frontend/src/features/auth/api/useUser.tsx @@ -1,6 +1,7 @@ import { useQuery } from '@tanstack/react-query' import { keys } from '@/api/queryKeys' import { fetchUser } from './fetchUser' +import { type ApiUser } from './ApiUser' /** * returns info about currently logged in user @@ -13,14 +14,13 @@ export const useUser = () => { queryFn: fetchUser, }) - let isLoggedIn = undefined - if (query.data !== undefined) { - isLoggedIn = query.data !== false - } + const isLoggedIn = + query.status === 'success' ? query.data !== false : undefined + const isLoggedOut = isLoggedIn === false + return { ...query, - // if fetchUser returns false, it means the user is not logged in: expose that - user: query.data === false ? undefined : query.data, + user: isLoggedOut ? undefined : (query.data as ApiUser | undefined), isLoggedIn, } } diff --git a/src/frontend/src/features/auth/index.ts b/src/frontend/src/features/auth/index.ts index 0a597d74..0b533fea 100644 --- a/src/frontend/src/features/auth/index.ts +++ b/src/frontend/src/features/auth/index.ts @@ -2,4 +2,3 @@ export { useUser } from './api/useUser' export { authUrl } from './utils/authUrl' export { logoutUrl } from './utils/logoutUrl' export { RenderIfUserFetched } from './components/RenderIfUserFetched' -export { attemptSilentLogin } from './utils/silentLogin' diff --git a/src/frontend/src/features/auth/utils/authUrl.ts b/src/frontend/src/features/auth/utils/authUrl.ts index be5f4cd6..097eef9b 100644 --- a/src/frontend/src/features/auth/utils/authUrl.ts +++ b/src/frontend/src/features/auth/utils/authUrl.ts @@ -1,5 +1,8 @@ import { apiUrl } from '@/api/apiUrl' -export const authUrl = (silent = false, returnTo = window.location.href) => { +export const authUrl = ({ + silent = false, + returnTo = window.location.href, +} = {}) => { return apiUrl(`/authenticate?silent=${encodeURIComponent(silent)}&returnTo=${encodeURIComponent(returnTo)}`) } diff --git a/src/frontend/src/features/auth/utils/silentLogin.ts b/src/frontend/src/features/auth/utils/silentLogin.ts index c301480b..111cdd5d 100644 --- a/src/frontend/src/features/auth/utils/silentLogin.ts +++ b/src/frontend/src/features/auth/utils/silentLogin.ts @@ -18,7 +18,11 @@ const setNextRetryTime = (retryIntervalInSeconds: number) => { } const initiateSilentLogin = () => { - window.location.href = authUrl(true) + window.location.href = authUrl({ silent: true }) +} + +export const canAttemptSilentLogin = () => { + return isRetryAllowed() } export const attemptSilentLogin = (retryIntervalInSeconds: number) => {