session timeout
This commit is contained in:
57
AceJobAgency.client/src/components/SessionTimeout.tsx
Normal file
57
AceJobAgency.client/src/components/SessionTimeout.tsx
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import React, { useState, useEffect, useCallback } from "react";
|
||||||
|
import { ToastContainer, toast } from "react-toastify";
|
||||||
|
import "react-toastify/dist/ReactToastify.css";
|
||||||
|
|
||||||
|
interface SessionTimeoutProps {
|
||||||
|
timeout: number;
|
||||||
|
onLogout: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SessionTimeout: React.FC<SessionTimeoutProps> = ({
|
||||||
|
timeout,
|
||||||
|
onLogout,
|
||||||
|
}) => {
|
||||||
|
const [lastActivityTime, setLastActivityTime] = useState<number>(Date.now());
|
||||||
|
const [notified, setNotified] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const resetTimer = useCallback(() => {
|
||||||
|
setLastActivityTime(Date.now());
|
||||||
|
setNotified(false);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const events = ["click", "mousemove", "keypress", "scroll", "touchstart"];
|
||||||
|
const eventHandler = () => resetTimer();
|
||||||
|
|
||||||
|
events.forEach((event) => window.addEventListener(event, eventHandler));
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
events.forEach((event) =>
|
||||||
|
window.removeEventListener(event, eventHandler)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}, [resetTimer]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
const timeElapsed = Date.now() - lastActivityTime;
|
||||||
|
|
||||||
|
if (timeElapsed >= timeout) {
|
||||||
|
onLogout();
|
||||||
|
} else if (timeElapsed >= timeout - 30000 && !notified) {
|
||||||
|
toast.warn("30 more seconds before automatic logout from idling.");
|
||||||
|
setNotified(true);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, [lastActivityTime, timeout, onLogout, notified]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ToastContainer />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SessionTimeout;
|
||||||
@@ -48,7 +48,7 @@ export function login(token: string) {
|
|||||||
|
|
||||||
export function logout() {
|
export function logout() {
|
||||||
clearAccessToken();
|
clearAccessToken();
|
||||||
window.location.reload();
|
window.location.assign("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAccessToken() {
|
export function getAccessToken() {
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import App from "./App.tsx";
|
|||||||
import "./index.css";
|
import "./index.css";
|
||||||
import { ToastContainer } from "react-toastify";
|
import { ToastContainer } from "react-toastify";
|
||||||
import "react-toastify/dist/ReactToastify.css";
|
import "react-toastify/dist/ReactToastify.css";
|
||||||
|
import SessionTimeout from "./components/SessionTimeout.tsx";
|
||||||
|
import { getAccessToken, logout } from "./http.ts";
|
||||||
|
|
||||||
document.addEventListener("contextmenu", (event) => {
|
document.addEventListener("contextmenu", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@@ -18,6 +20,9 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
|
|||||||
<main>
|
<main>
|
||||||
<App />
|
<App />
|
||||||
<ToastContainer />
|
<ToastContainer />
|
||||||
|
{getAccessToken() && (
|
||||||
|
<SessionTimeout timeout={1 * 60 * 1000} onLogout={logout} />
|
||||||
|
)}
|
||||||
</main>
|
</main>
|
||||||
</HeroUIProvider>
|
</HeroUIProvider>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export default function EditProfilePage() {
|
|||||||
const accessToken = getAccessToken();
|
const accessToken = getAccessToken();
|
||||||
if (!accessToken) {
|
if (!accessToken) {
|
||||||
navigate(-1);
|
navigate(-1);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
http.get("/User/profile").then((response) => {
|
http.get("/User/profile").then((response) => {
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
|
|||||||
Reference in New Issue
Block a user