diff --git a/packages/core-components/src/components/AutoLogout/AutoLogout.tsx b/packages/core-components/src/components/AutoLogout/AutoLogout.tsx index ddc457842e..9ba8098c1d 100644 --- a/packages/core-components/src/components/AutoLogout/AutoLogout.tsx +++ b/packages/core-components/src/components/AutoLogout/AutoLogout.tsx @@ -146,14 +146,8 @@ const ConditionalAutoLogout = ({ onPrompt: promptBeforeIdle ? onPrompt : undefined, promptBeforeIdle: promptBeforeIdle ? promptBeforeIdleMillis : undefined, syncTimers: 1000, - leaderElection: true, }); - // Check if the current tab is the only active tab. In practice, this gets checked once per second - if (timer.isLeader()) { - lastSeenOnlineStore.save(new Date()); - } - return ( <> {promptBeforeIdle && ( @@ -237,18 +231,35 @@ const parseConfig = ( export const AutoLogout = (props: AutoLogoutProps): JSX.Element | null => { const identityApi = useApi(identityApiRef); const configApi = useApi(configApiRef); - const [isLogged, setIsLogged] = useState(false); + const [isLogged, setIsLogged] = useState(null); + const lastSeenOnlineStore: TimestampStore = useMemo( + () => new DefaultTimestampStore(LAST_SEEN_ONLINE_STORAGE_KEY), + [], + ); + useEffect(() => { - // if the user is not logged in, the autologout feature won't affect the app even if enabled async function isLoggedIn(identity: IdentityApi) { - if ((await identity.getCredentials()).token) { - setIsLogged(true); - } else { + try { + // Add timeout if identity.getCredentials() hangs/takes too long to return + setTimeout(() => { + if (isLogged === null || isLogged === false) { + lastSeenOnlineStore.delete(); + } + }, 3000); + const creds = await identity.getCredentials(); + if (creds?.token) { + setIsLogged(true); + } else { + setIsLogged(false); + lastSeenOnlineStore.delete(); + } + } catch (err) { setIsLogged(false); + lastSeenOnlineStore.delete(); } } isLoggedIn(identityApi); - }, [identityApi]); + }, [isLogged, lastSeenOnlineStore, identityApi]); const { enabled, @@ -280,10 +291,6 @@ export const AutoLogout = (props: AutoLogoutProps): JSX.Element | null => { } }, [idleTimeoutMinutes, promptBeforeIdleSeconds]); - const lastSeenOnlineStore: TimestampStore = useMemo( - () => new DefaultTimestampStore(LAST_SEEN_ONLINE_STORAGE_KEY), - [], - ); const [promptOpen, setPromptOpen] = useState(false); const [remainingTimeCountdown, setRemainingTimeCountdown] = @@ -291,7 +298,8 @@ export const AutoLogout = (props: AutoLogoutProps): JSX.Element | null => { useLogoutDisconnectedUserEffect({ enableEffect: logoutIfDisconnected, - autologoutIsEnabled: enabled && isLogged, + autologoutIsEnabled: enabled, + isLoggedIn: isLogged, idleTimeoutSeconds: idleTimeoutMinutes * 60, lastSeenOnlineStore, identityApi, diff --git a/packages/core-components/src/components/AutoLogout/disconnectedUsers.ts b/packages/core-components/src/components/AutoLogout/disconnectedUsers.ts index 643664e66f..ebc0cd01f5 100644 --- a/packages/core-components/src/components/AutoLogout/disconnectedUsers.ts +++ b/packages/core-components/src/components/AutoLogout/disconnectedUsers.ts @@ -24,6 +24,7 @@ export const LAST_SEEN_ONLINE_STORAGE_KEY = export type UseLogoutDisconnectedUserEffectProps = { enableEffect: boolean; autologoutIsEnabled: boolean; + isLoggedIn: boolean | null; idleTimeoutSeconds: number; lastSeenOnlineStore: TimestampStore; identityApi: IdentityApi; @@ -32,6 +33,7 @@ export type UseLogoutDisconnectedUserEffectProps = { export const useLogoutDisconnectedUserEffect = ({ enableEffect, autologoutIsEnabled, + isLoggedIn, idleTimeoutSeconds, lastSeenOnlineStore, identityApi, @@ -41,7 +43,12 @@ export const useLogoutDisconnectedUserEffect = ({ * Considers disconnected users as inactive users. * If all Backstage tabs are closed and idleTimeoutMinutes are passed then logout the user anyway. */ - if (autologoutIsEnabled && enableEffect) { + // Prevent lastSeen getting deleted before logged state is checked + if (isLoggedIn === null) { + return; + } + + if (autologoutIsEnabled && isLoggedIn && enableEffect) { const lastSeenOnline = lastSeenOnlineStore.get(); if (lastSeenOnline) { const now = new Date(); @@ -51,15 +58,16 @@ export const useLogoutDisconnectedUserEffect = ({ ); if (nowSeconds - lastSeenOnlineSeconds > idleTimeoutSeconds) { identityApi.signOut(); - // Delete lastSeen time to prevent getting locked out after logout - lastSeenOnlineStore.delete(); - return; } } + lastSeenOnlineStore.save(new Date()); + } else { + lastSeenOnlineStore.delete(); } }, [ autologoutIsEnabled, enableEffect, + isLoggedIn, identityApi, idleTimeoutSeconds, lastSeenOnlineStore,