From be403f132d302001945bcbca9d001ee89cb7d0c5 Mon Sep 17 00:00:00 2001 From: "cyril.tsui" Date: Fri, 15 Nov 2024 17:51:31 +0800 Subject: [PATCH] Add auto logout function in frontend (60 mins); need npm i react-idle-timer --- package.json | 1 + src/app/(main)/layout.tsx | 2 + .../AutoLogoutProvider/AutoLogoutProvider.tsx | 89 +++++++++++++++++++ .../AutoLogoutProviderWrapper.tsx | 14 +++ src/components/AutoLogoutProvider/index.ts | 1 + 5 files changed, 107 insertions(+) create mode 100644 src/components/AutoLogoutProvider/AutoLogoutProvider.tsx create mode 100644 src/components/AutoLogoutProvider/AutoLogoutProviderWrapper.tsx create mode 100644 src/components/AutoLogoutProvider/index.ts diff --git a/package.json b/package.json index a8419eb..5ffa637 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "react-dom": "^18", "react-hook-form": "^7.49.2", "react-i18next": "^13.5.0", + "react-idle-timer": "^5.7.2", "react-intl": "^6.5.5", "react-number-format": "^5.3.4", "react-select": "^5.8.0", diff --git a/src/app/(main)/layout.tsx b/src/app/(main)/layout.tsx index 98a0800..6e658cc 100644 --- a/src/app/(main)/layout.tsx +++ b/src/app/(main)/layout.tsx @@ -1,4 +1,5 @@ import AppBar from "@/components/AppBar"; +import AutoLogoutProvider from "@/components/AutoLogoutProvider"; import { getServerSession } from "next-auth"; import { authOptions } from "@/config/authConfig"; import { redirect } from "next/navigation"; @@ -21,6 +22,7 @@ export default async function MainLayout({ return ( <> + >; +} + +export const TimerContext = createContext(undefined); + +interface AutoLogoutProviderProps { + children?: ReactNode; + isUserLoggedIn: boolean; +} + +const AutoLogoutProvider: React.FC = ({ children, isUserLoggedIn }) => { + const [lastRequestTime, setLastRequestTime] = useState(Date.now()); + const [logoutInterval, setLogoutInterval] = useState(1); // minute + const [state, setState] = useState('Active'); + + const onIdle = () => { + setLastRequestTime(Date.now()); + setState('Idle') + } + + const onActive = () => { + setLastRequestTime(Date.now()); + setState('Active') + } + + const { + isLastActiveTab, + } = useIdleTimer({ + onIdle, + onActive, + timeout: 1_000, + throttle: 500, + crossTab: true, + syncTimers: 200, + }) + + const lastActiveTab = isLastActiveTab() === null ? 'loading' : isLastActiveTab() + + const getLogoutInterval = () => { + if (isUserLoggedIn && logoutInterval === 1) { + //TODO: get auto logout time here + setLogoutInterval(60); + } + else { + if (!isUserLoggedIn && logoutInterval > 1) { + setLogoutInterval(1); + } + } + } + + useEffect(() => { + getLogoutInterval() + const interval = setInterval(async () => { + const currentTime = Date.now(); + // if (isPasswordExpiry()) { + // navigate('/user/changePassword'); + // } + if (state !== "Active" && lastActiveTab) { + const timeElapsed = currentTime - lastRequestTime; + if (timeElapsed >= logoutInterval * 60 * 1000) { + // console.log(timeElapsed / 1000); + // console.log(logoutInterval* 60); + // console.log(logoutInterval * 60 * 1000 - timeElapsed) + signOut() + } + } + }, 1000); // Check every second + + return () => { + clearInterval(interval); + }; + }, [lastRequestTime, logoutInterval]); + + + return ( + + {children} + + ); +}; + +export default AutoLogoutProvider; \ No newline at end of file diff --git a/src/components/AutoLogoutProvider/AutoLogoutProviderWrapper.tsx b/src/components/AutoLogoutProvider/AutoLogoutProviderWrapper.tsx new file mode 100644 index 0000000..ffdc593 --- /dev/null +++ b/src/components/AutoLogoutProvider/AutoLogoutProviderWrapper.tsx @@ -0,0 +1,14 @@ +import React from "react"; +import AutoLogoutProvider from "./AutoLogoutProvider"; +import { getServerSession } from "next-auth"; +import { authOptions } from "@/config/authConfig"; + +const AutoLogoutProviderWrapper: React.FC = async () => { + + const session = await getServerSession(authOptions) + const isUserLoggedIn = session?.user !== null + + return ; +}; + +export default AutoLogoutProviderWrapper; diff --git a/src/components/AutoLogoutProvider/index.ts b/src/components/AutoLogoutProvider/index.ts new file mode 100644 index 0000000..2966d05 --- /dev/null +++ b/src/components/AutoLogoutProvider/index.ts @@ -0,0 +1 @@ +export { default } from "./AutoLogoutProviderWrapper"; \ No newline at end of file