From 2259e99a6ebe902e2b12355da3ba07dae0eb34d2 Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Sat, 18 Oct 2025 12:27:06 +0900 Subject: [PATCH 01/11] fix: auto-logout not working when closing tabs and reopening Signed-off-by: Juan Escalada --- .../src/components/AutoLogout/AutoLogout.tsx | 6 ++++++ .../src/components/AutoLogout/disconnectedUsers.ts | 11 +++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/core-components/src/components/AutoLogout/AutoLogout.tsx b/packages/core-components/src/components/AutoLogout/AutoLogout.tsx index 932ac7432b..ddc457842e 100644 --- a/packages/core-components/src/components/AutoLogout/AutoLogout.tsx +++ b/packages/core-components/src/components/AutoLogout/AutoLogout.tsx @@ -146,8 +146,14 @@ 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 && ( diff --git a/packages/core-components/src/components/AutoLogout/disconnectedUsers.ts b/packages/core-components/src/components/AutoLogout/disconnectedUsers.ts index c09e272eaa..643664e66f 100644 --- a/packages/core-components/src/components/AutoLogout/disconnectedUsers.ts +++ b/packages/core-components/src/components/AutoLogout/disconnectedUsers.ts @@ -51,16 +51,11 @@ export const useLogoutDisconnectedUserEffect = ({ ); if (nowSeconds - lastSeenOnlineSeconds > idleTimeoutSeconds) { identityApi.signOut(); + // Delete lastSeen time to prevent getting locked out after logout + lastSeenOnlineStore.delete(); + return; } } - /** - * save for the first time when app is loaded, so that - * if user logs in and does nothing we still have a - * lastSeenOnline value in store - */ - lastSeenOnlineStore.save(new Date()); - } else { - lastSeenOnlineStore.delete(); } }, [ autologoutIsEnabled, From 18430adf404ec30eb04c6a749f8a4cbcc53d54c5 Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Sat, 18 Oct 2025 21:06:38 +0900 Subject: [PATCH 02/11] fix: amend AutoLogout logic to work with any provider and correctly logout Signed-off-by: Juan Escalada --- .../src/components/AutoLogout/AutoLogout.tsx | 42 +++++++++++-------- .../AutoLogout/disconnectedUsers.ts | 16 +++++-- 2 files changed, 37 insertions(+), 21 deletions(-) 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, From 61e0844bdeee505e742424cdedff922fe725be2f Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Sat, 18 Oct 2025 21:08:11 +0900 Subject: [PATCH 03/11] test: amend existing disconnectedUsers tests and add new one for unresolved isLoggedIn Signed-off-by: Juan Escalada --- .../AutoLogout/disconnectedUsers.test.ts | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/core-components/src/components/AutoLogout/disconnectedUsers.test.ts b/packages/core-components/src/components/AutoLogout/disconnectedUsers.test.ts index 3d097dcc7f..80da5bca93 100644 --- a/packages/core-components/src/components/AutoLogout/disconnectedUsers.test.ts +++ b/packages/core-components/src/components/AutoLogout/disconnectedUsers.test.ts @@ -35,10 +35,27 @@ const mockTimestampStore = { }; describe('useLogoutDisconnectedUserEffect', () => { - it('should not do anything if effect is not enabled', () => { + it('should not do anything if isLoggedIn has not yet resolved', () => { + const props: UseLogoutDisconnectedUserEffectProps = { + enableEffect: true, + autologoutIsEnabled: true, + isLoggedIn: null, + idleTimeoutSeconds: 300, + lastSeenOnlineStore: mockTimestampStore, + identityApi: mockIdentityApi, + }; + + renderHook(() => useLogoutDisconnectedUserEffect(props)); + + expect(mockTimestampStore.get).not.toHaveBeenCalled(); + expect(mockIdentityApi.signOut).not.toHaveBeenCalled(); + }); + + it('should not do anything if effect is not enabled and isLoggedIn is false', () => { const props: UseLogoutDisconnectedUserEffectProps = { enableEffect: false, autologoutIsEnabled: true, + isLoggedIn: false, idleTimeoutSeconds: 300, lastSeenOnlineStore: mockTimestampStore, identityApi: mockIdentityApi, @@ -54,6 +71,7 @@ describe('useLogoutDisconnectedUserEffect', () => { const props: UseLogoutDisconnectedUserEffectProps = { enableEffect: true, autologoutIsEnabled: false, + isLoggedIn: true, idleTimeoutSeconds: 300, lastSeenOnlineStore: mockTimestampStore, identityApi: mockIdentityApi, @@ -70,6 +88,7 @@ describe('useLogoutDisconnectedUserEffect', () => { const props: UseLogoutDisconnectedUserEffectProps = { enableEffect: true, autologoutIsEnabled: true, + isLoggedIn: true, idleTimeoutSeconds: 1, lastSeenOnlineStore: { ...mockTimestampStore, @@ -93,6 +112,7 @@ describe('useLogoutDisconnectedUserEffect', () => { const props: UseLogoutDisconnectedUserEffectProps = { enableEffect: true, autologoutIsEnabled: true, + isLoggedIn: true, idleTimeoutSeconds: 300, lastSeenOnlineStore: mockTimestampStore, identityApi: mockIdentityApi, From dbe93a7aee293d9ae72d6ed193d82ffb99a77d73 Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Mon, 20 Oct 2025 09:29:12 +0900 Subject: [PATCH 04/11] chore: add changeset Signed-off-by: Juan Escalada --- .changeset/pretty-parts-admire.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/pretty-parts-admire.md diff --git a/.changeset/pretty-parts-admire.md b/.changeset/pretty-parts-admire.md new file mode 100644 index 0000000000..b1c507cee8 --- /dev/null +++ b/.changeset/pretty-parts-admire.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': minor +--- + +Fix autologout not working correctly when closing all tabs From 19a79d3f801c737c239f5ceeb2f8e039a251611d Mon Sep 17 00:00:00 2001 From: Juan Escalada <97265671+jescalada@users.noreply.github.com> Date: Sat, 22 Nov 2025 00:47:38 +0000 Subject: [PATCH 05/11] Update .changeset/pretty-parts-admire.md Co-authored-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com> Signed-off-by: Juan Escalada <97265671+jescalada@users.noreply.github.com> Signed-off-by: Juan Escalada --- .changeset/pretty-parts-admire.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/pretty-parts-admire.md b/.changeset/pretty-parts-admire.md index b1c507cee8..87c27295d5 100644 --- a/.changeset/pretty-parts-admire.md +++ b/.changeset/pretty-parts-admire.md @@ -1,5 +1,5 @@ --- -'@backstage/core-components': minor +'@backstage/core-components': patch --- Fix autologout not working correctly when closing all tabs From 6b965577181c41d50dead1ec699a59db1b232390 Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Thu, 30 Apr 2026 11:45:39 +0900 Subject: [PATCH 06/11] fix: add isLoggedRef and modify login checking logic Signed-off-by: Juan Escalada --- .../src/components/AutoLogout/AutoLogout.tsx | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/packages/core-components/src/components/AutoLogout/AutoLogout.tsx b/packages/core-components/src/components/AutoLogout/AutoLogout.tsx index 9ba8098c1d..47d13d4605 100644 --- a/packages/core-components/src/components/AutoLogout/AutoLogout.tsx +++ b/packages/core-components/src/components/AutoLogout/AutoLogout.tsx @@ -21,7 +21,7 @@ import { identityApiRef, useApi, } from '@backstage/core-plugin-api'; -import { useEffect, useMemo, useState } from 'react'; +import { useEffect, useMemo, useRef, useState } from 'react'; import { EventsType, IIdleTimer, @@ -231,6 +231,7 @@ const parseConfig = ( export const AutoLogout = (props: AutoLogoutProps): JSX.Element | null => { const identityApi = useApi(identityApiRef); const configApi = useApi(configApiRef); + const isLoggedRef = useRef(null); const [isLogged, setIsLogged] = useState(null); const lastSeenOnlineStore: TimestampStore = useMemo( () => new DefaultTimestampStore(LAST_SEEN_ONLINE_STORAGE_KEY), @@ -238,15 +239,23 @@ export const AutoLogout = (props: AutoLogoutProps): JSX.Element | null => { ); useEffect(() => { - async function isLoggedIn(identity: IdentityApi) { + isLoggedRef.current = isLogged; + }, [isLogged]); + + useEffect(() => { + let cancelled = false; + + const timeoutId = setTimeout(() => { + if (cancelled) return; + if (isLoggedRef.current === null || isLoggedRef.current === false) { + lastSeenOnlineStore.delete(); + } + }, 3000); + + async function checkLogin(identity: IdentityApi) { 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 (cancelled) return; if (creds?.token) { setIsLogged(true); } else { @@ -254,12 +263,18 @@ export const AutoLogout = (props: AutoLogoutProps): JSX.Element | null => { lastSeenOnlineStore.delete(); } } catch (err) { + if (cancelled) return; setIsLogged(false); lastSeenOnlineStore.delete(); } } - isLoggedIn(identityApi); - }, [isLogged, lastSeenOnlineStore, identityApi]); + checkLogin(identityApi); + + return () => { + cancelled = true; + clearTimeout(timeoutId); + }; + }, [lastSeenOnlineStore, identityApi]); const { enabled, From c3e07a5cb3792e98b2f62a4cea1a8a8deb092be3 Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Thu, 30 Apr 2026 12:03:50 +0900 Subject: [PATCH 07/11] fix: prevent unexpected signouts when disabling autologout Signed-off-by: Juan Escalada --- .../src/components/AutoLogout/disconnectedUsers.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/core-components/src/components/AutoLogout/disconnectedUsers.ts b/packages/core-components/src/components/AutoLogout/disconnectedUsers.ts index ebc0cd01f5..65093333be 100644 --- a/packages/core-components/src/components/AutoLogout/disconnectedUsers.ts +++ b/packages/core-components/src/components/AutoLogout/disconnectedUsers.ts @@ -43,12 +43,14 @@ export const useLogoutDisconnectedUserEffect = ({ * Considers disconnected users as inactive users. * If all Backstage tabs are closed and idleTimeoutMinutes are passed then logout the user anyway. */ + const shouldCheckDisconnectedUser = autologoutIsEnabled && enableEffect; + // Prevent lastSeen getting deleted before logged state is checked - if (isLoggedIn === null) { + if (shouldCheckDisconnectedUser && isLoggedIn === null) { return; } - if (autologoutIsEnabled && isLoggedIn && enableEffect) { + if (shouldCheckDisconnectedUser && isLoggedIn) { const lastSeenOnline = lastSeenOnlineStore.get(); if (lastSeenOnline) { const now = new Date(); From 327cc8b09c13204db5e177297111bef2954e01d4 Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Wed, 13 May 2026 11:41:40 +0900 Subject: [PATCH 08/11] fix: remove timeout for deleting lastOnline store Signed-off-by: Juan Escalada --- .../src/components/AutoLogout/AutoLogout.tsx | 13 ------------- .../components/AutoLogout/disconnectedUsers.test.ts | 2 ++ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/packages/core-components/src/components/AutoLogout/AutoLogout.tsx b/packages/core-components/src/components/AutoLogout/AutoLogout.tsx index 47d13d4605..098215ba5f 100644 --- a/packages/core-components/src/components/AutoLogout/AutoLogout.tsx +++ b/packages/core-components/src/components/AutoLogout/AutoLogout.tsx @@ -231,27 +231,15 @@ const parseConfig = ( export const AutoLogout = (props: AutoLogoutProps): JSX.Element | null => { const identityApi = useApi(identityApiRef); const configApi = useApi(configApiRef); - const isLoggedRef = useRef(null); const [isLogged, setIsLogged] = useState(null); const lastSeenOnlineStore: TimestampStore = useMemo( () => new DefaultTimestampStore(LAST_SEEN_ONLINE_STORAGE_KEY), [], ); - useEffect(() => { - isLoggedRef.current = isLogged; - }, [isLogged]); - useEffect(() => { let cancelled = false; - const timeoutId = setTimeout(() => { - if (cancelled) return; - if (isLoggedRef.current === null || isLoggedRef.current === false) { - lastSeenOnlineStore.delete(); - } - }, 3000); - async function checkLogin(identity: IdentityApi) { try { const creds = await identity.getCredentials(); @@ -272,7 +260,6 @@ export const AutoLogout = (props: AutoLogoutProps): JSX.Element | null => { return () => { cancelled = true; - clearTimeout(timeoutId); }; }, [lastSeenOnlineStore, identityApi]); diff --git a/packages/core-components/src/components/AutoLogout/disconnectedUsers.test.ts b/packages/core-components/src/components/AutoLogout/disconnectedUsers.test.ts index 80da5bca93..090cd197d9 100644 --- a/packages/core-components/src/components/AutoLogout/disconnectedUsers.test.ts +++ b/packages/core-components/src/components/AutoLogout/disconnectedUsers.test.ts @@ -48,6 +48,8 @@ describe('useLogoutDisconnectedUserEffect', () => { renderHook(() => useLogoutDisconnectedUserEffect(props)); expect(mockTimestampStore.get).not.toHaveBeenCalled(); + expect(mockTimestampStore.delete).not.toHaveBeenCalled(); + expect(mockTimestampStore.save).not.toHaveBeenCalled(); expect(mockIdentityApi.signOut).not.toHaveBeenCalled(); }); From 92c3435d9efa6d1b529701f8804d9c299864b6e1 Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Wed, 13 May 2026 12:43:25 +0900 Subject: [PATCH 09/11] fix: state bug in onIdle Signed-off-by: Juan Escalada --- .../core-components/src/components/AutoLogout/AutoLogout.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core-components/src/components/AutoLogout/AutoLogout.tsx b/packages/core-components/src/components/AutoLogout/AutoLogout.tsx index 098215ba5f..bd2cd05b9e 100644 --- a/packages/core-components/src/components/AutoLogout/AutoLogout.tsx +++ b/packages/core-components/src/components/AutoLogout/AutoLogout.tsx @@ -114,6 +114,7 @@ const ConditionalAutoLogout = ({ // Events will be rebound as long as `stopOnMount` is not set. setPromptOpen(false); setRemainingTimeCountdown(0); + lastSeenOnlineStore.delete(); identityApi.signOut(); }; From 19b5047c12e439180fbec4edb240386c7953db6b Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Wed, 13 May 2026 12:50:12 +0900 Subject: [PATCH 10/11] fix: refactor disconnectedUsers for readability Signed-off-by: Juan Escalada --- .../AutoLogout/disconnectedUsers.ts | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/packages/core-components/src/components/AutoLogout/disconnectedUsers.ts b/packages/core-components/src/components/AutoLogout/disconnectedUsers.ts index 65093333be..4d1d8bf833 100644 --- a/packages/core-components/src/components/AutoLogout/disconnectedUsers.ts +++ b/packages/core-components/src/components/AutoLogout/disconnectedUsers.ts @@ -46,26 +46,27 @@ export const useLogoutDisconnectedUserEffect = ({ const shouldCheckDisconnectedUser = autologoutIsEnabled && enableEffect; // Prevent lastSeen getting deleted before logged state is checked - if (shouldCheckDisconnectedUser && isLoggedIn === null) { + if (isLoggedIn === null) { return; } - if (shouldCheckDisconnectedUser && isLoggedIn) { - const lastSeenOnline = lastSeenOnlineStore.get(); - if (lastSeenOnline) { - const now = new Date(); - const nowSeconds = Math.ceil(now.getTime() / 1000); - const lastSeenOnlineSeconds = Math.ceil( - lastSeenOnline.getTime() / 1000, - ); - if (nowSeconds - lastSeenOnlineSeconds > idleTimeoutSeconds) { - identityApi.signOut(); - } - } - lastSeenOnlineStore.save(new Date()); - } else { + if (!shouldCheckDisconnectedUser || !isLoggedIn) { lastSeenOnlineStore.delete(); + return; } + + const lastSeenOnline = lastSeenOnlineStore.get(); + if (lastSeenOnline) { + const now = new Date(); + const nowSeconds = Math.ceil(now.getTime() / 1000); + const lastSeenOnlineSeconds = Math.ceil(lastSeenOnline.getTime() / 1000); + if (nowSeconds - lastSeenOnlineSeconds > idleTimeoutSeconds) { + lastSeenOnlineStore.delete(); + identityApi.signOut(); + return; + } + } + lastSeenOnlineStore.save(new Date()); }, [ autologoutIsEnabled, enableEffect, From e8c67ea82c9b118c71da1be45ea5ac87c6e29de7 Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Wed, 13 May 2026 13:18:20 +0900 Subject: [PATCH 11/11] test: add test for deleting store on autologout timeout, remove unused import Signed-off-by: Juan Escalada --- .../src/components/AutoLogout/AutoLogout.tsx | 2 +- .../AutoLogout/disconnectedUsers.test.ts | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/packages/core-components/src/components/AutoLogout/AutoLogout.tsx b/packages/core-components/src/components/AutoLogout/AutoLogout.tsx index bd2cd05b9e..4f53ce4bd7 100644 --- a/packages/core-components/src/components/AutoLogout/AutoLogout.tsx +++ b/packages/core-components/src/components/AutoLogout/AutoLogout.tsx @@ -21,7 +21,7 @@ import { identityApiRef, useApi, } from '@backstage/core-plugin-api'; -import { useEffect, useMemo, useRef, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { EventsType, IIdleTimer, diff --git a/packages/core-components/src/components/AutoLogout/disconnectedUsers.test.ts b/packages/core-components/src/components/AutoLogout/disconnectedUsers.test.ts index 090cd197d9..e6fbbc7161 100644 --- a/packages/core-components/src/components/AutoLogout/disconnectedUsers.test.ts +++ b/packages/core-components/src/components/AutoLogout/disconnectedUsers.test.ts @@ -84,6 +84,27 @@ describe('useLogoutDisconnectedUserEffect', () => { expect(mockTimestampStore.delete).toHaveBeenCalled(); }); + it('should delete the store and sign out when idle timeout has passed', () => { + const staleStore = { + ...mockTimestampStore, + get: jest.fn().mockReturnValue(new Date(Date.now() - 2000)), + }; + const props: UseLogoutDisconnectedUserEffectProps = { + enableEffect: true, + autologoutIsEnabled: true, + isLoggedIn: true, + idleTimeoutSeconds: 1, + lastSeenOnlineStore: staleStore, + identityApi: mockIdentityApi, + }; + + renderHook(() => useLogoutDisconnectedUserEffect(props)); + + expect(staleStore.delete).toHaveBeenCalled(); + expect(mockIdentityApi.signOut).toHaveBeenCalled(); + expect(staleStore.save).not.toHaveBeenCalled(); + }); + it('should call signOut if idle timeout passed', () => { jest.useFakeTimers();