From 1021e41aa4dab467f5c7f63e4424d57c4bbf4f70 Mon Sep 17 00:00:00 2001 From: Terje Karlsen Date: Tue, 26 Sep 2023 19:48:21 +0200 Subject: [PATCH 1/3] =?UTF-8?q?Grunnleggende=20h=C3=A5ndtering=20av=20feil?= =?UTF-8?q?et=20refresh=20av=20token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tekster/ledetekster.ts | 12 ++++++++++++ src/utils/hooks/useLoginStatus.ts | 16 +++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/tekster/ledetekster.ts b/src/tekster/ledetekster.ts index 05cf7efe5..c595d4978 100644 --- a/src/tekster/ledetekster.ts +++ b/src/tekster/ledetekster.ts @@ -39,6 +39,9 @@ export const ledetekster = { 'logg-inn-knapp': 'Logg inn', 'logg-inn-knapp-en': 'Log in', 'logg-inn-knapp-se': 'Sisačáliheapmi', + 'logg-inn-pa-nytt-knapp': 'Logg inn på nytt', + 'logg-inn-pa-nytt-knapp-en': 'Log in again', + 'logg-inn-pa-nytt-knapp-se': 'Logg inn på nytt', 'logg-ut-knapp': 'Logg ut', 'logg-ut-knapp-en': 'Log out', 'logg-ut-knapp-se': 'Olggosčáliheapmi', @@ -59,6 +62,15 @@ export const ledetekster = { 'snart-session-logget-ut-body': 'Avslutt det du jobber med og logg inn igjen.', 'snart-session-logget-ut-body-en': 'Please wrap up what you are doing and log in again.', 'snart-session-logget-ut-body-se': 'Avslutt det du jobber med og logg inn igjen.', + 'token-feilet-tittel': 'Det har skjedd en feil', + 'token-feilet-tittel-en': 'An error has happened', + 'token-feilet-tittel-se': 'Det har skjedd en feil', + 'token-feilet-body': 'Forsøket på å forlenge innloggingen din feilet, vi beklager.', + 'token-feilet-body-en': 'An attempt to extend your login period failed, we apologize.', + 'token-feilet-body-se': 'Forsøket på å forlenge innloggingen din feilet, vi beklager.', + 'token-feilet-avbryt': `Avbryt`, + 'token-feilet-avbryt-en': `Cancel`, + 'token-feilet-avbryt-se': `Avbryt`, ok: 'OK', 'ok-en': 'OK', 'ok-se': 'OK', diff --git a/src/utils/hooks/useLoginStatus.ts b/src/utils/hooks/useLoginStatus.ts index ecd84c90f..03fbebc65 100644 --- a/src/utils/hooks/useLoginStatus.ts +++ b/src/utils/hooks/useLoginStatus.ts @@ -17,6 +17,7 @@ export const useLoginStatus = () => { const { innloggetStatus, environment } = useSelector(stateSelector); const [isTokenExpiring, setIsTokenExpiring] = useState(null); const [isSessionExpiring, setIsSessionExpiring] = useState(null); + const [hasAuthError, setHasAuthError] = useState(false); const [secondsToSessionExpires, setSecondsToSessionExpires] = useState(0); useLoginDebug(); @@ -25,6 +26,12 @@ export const useLoginStatus = () => { const innloggetStatusRef = useRef(innloggetStatus); innloggetStatusRef.current = innloggetStatus; + useEffect(() => { + window.addEventListener('INVALID-SESSION', () => { + setHasAuthError(true); + }); + }, []); + const getExpirationInSeconds = ({ session, token }: { session: string | null; token: string | null }) => { if (!session || !token) return { secondsToTokenExpires: null, secondsToSessionExpires: null }; @@ -87,5 +94,12 @@ export const useLoginStatus = () => { window.addEventListener('visibilitychange', onVisibilityChange); }, []); - return { isTokenExpiring, isSessionExpiring, refreshTokenHandler, logoutHandler, secondsToSessionExpires }; + return { + isTokenExpiring, + isSessionExpiring, + refreshTokenHandler, + logoutHandler, + secondsToSessionExpires, + hasAuthError, + }; }; From b664b23064d70e5a74805aaf8e221cfa7c90c97e Mon Sep 17 00:00:00 2001 From: Terje Karlsen Date: Wed, 27 Sep 2023 09:20:45 +0200 Subject: [PATCH 2/3] =?UTF-8?q?H=C3=A5ndterer=20feil=20ved=20fornying=20av?= =?UTF-8?q?=20token.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/api.ts | 11 ++-- .../logoutWarning/LogoutWarning.module.scss | 2 +- .../header/logoutWarning/LogoutWarning.tsx | 53 +++++++++++++++---- src/utils/hooks/useLoginStatus.ts | 12 +++-- 4 files changed, 62 insertions(+), 16 deletions(-) diff --git a/src/api/api.ts b/src/api/api.ts index 8485f9967..6abf95343 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -74,9 +74,14 @@ export const fornyInnloggingFetch = (environment: Environment): Promise { - return adaptFulfilledSessionDataFromAPI(result); - }); + }) + .then((result: any) => { + return adaptFulfilledSessionDataFromAPI(result); + }) + .catch((e) => { + window.dispatchEvent(new Event('INVALID_SESSION')); + throw new Error(`Error refreshing session [error: ${e}]`); + }); }; export const hentVarslerFetch = (VARSEL_API_URL: string): Promise => { diff --git a/src/komponenter/header/logoutWarning/LogoutWarning.module.scss b/src/komponenter/header/logoutWarning/LogoutWarning.module.scss index 08ada3079..4f5cf6102 100644 --- a/src/komponenter/header/logoutWarning/LogoutWarning.module.scss +++ b/src/komponenter/header/logoutWarning/LogoutWarning.module.scss @@ -4,7 +4,7 @@ display: flex; flex-direction: column; padding: 1rem; - align-items: center; + align-items: flex-start; box-shadow: var(--a-shadow-large); justify-content: center; opacity: 0; diff --git a/src/komponenter/header/logoutWarning/LogoutWarning.tsx b/src/komponenter/header/logoutWarning/LogoutWarning.tsx index 7c23dc385..786137133 100644 --- a/src/komponenter/header/logoutWarning/LogoutWarning.tsx +++ b/src/komponenter/header/logoutWarning/LogoutWarning.tsx @@ -11,8 +11,15 @@ import { LangKey } from 'tekster/ledetekster'; import styles from './LogoutWarning.module.scss'; export const LogoutWarning = () => { - const { refreshTokenHandler, logoutHandler, isTokenExpiring, isSessionExpiring, secondsToSessionExpires } = - useLoginStatus(); + const { + refreshTokenHandler, + loginHandler, + logoutHandler, + isTokenExpiring, + isSessionExpiring, + secondsToSessionExpires, + hasAuthError, + } = useLoginStatus(); const [isOpen, setIsOpen] = React.useState(false); const { language } = useSelector((state: AppState) => state.language); @@ -34,8 +41,24 @@ export const LogoutWarning = () => { return null; } - const titleId: LangKey = isSessionExpiring ? 'snart-session-logget-ut-tittel' : 'snart-token-logget-ut-tittel'; - const textBodyId: LangKey = isSessionExpiring ? 'snart-session-logget-ut-body' : 'snart-token-logget-ut-body'; + const getTitleId = () => { + if (hasAuthError) { + return 'token-feilet-tittel'; + } + + return isSessionExpiring ? 'snart-session-logget-ut-tittel' : 'snart-token-logget-ut-tittel'; + }; + + const getBodyId = () => { + if (hasAuthError) { + return 'token-feilet-body'; + } + + return isSessionExpiring ? 'snart-session-logget-ut-body' : 'snart-token-logget-ut-body'; + }; + + const titleId: LangKey = getTitleId(); + const textBodyId: LangKey = getBodyId(); const minutesToSessionEnd = Math.ceil(secondsToSessionExpires / 60); @@ -53,19 +76,31 @@ export const LogoutWarning = () => { {finnTekst(textBodyId, language)}
- {isSessionExpiring && ( + {hasAuthError && ( + <> + + + + )} + {!hasAuthError && isSessionExpiring && ( )} - {!isSessionExpiring && isTokenExpiring && ( + {!hasAuthError && !isSessionExpiring && isTokenExpiring && ( )} - + {!hasAuthError && ( + + )}
diff --git a/src/utils/hooks/useLoginStatus.ts b/src/utils/hooks/useLoginStatus.ts index 03fbebc65..9010d403a 100644 --- a/src/utils/hooks/useLoginStatus.ts +++ b/src/utils/hooks/useLoginStatus.ts @@ -2,19 +2,20 @@ import { useEffect, useRef, useState } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { AppState } from 'store/reducers'; import { hentInnloggingsstatus, fornyInnlogging } from 'store/reducers/innloggingsstatus-duck'; -import { getLogOutUrl } from 'utils/login'; +import { getLogOutUrl, getLoginUrl } from 'utils/login'; import { useLoginDebug } from './useLoginDebug'; const stateSelector = (state: AppState) => ({ innloggetStatus: state.innloggingsstatus.data, environment: state.environment, + arbeidsflate: state.arbeidsflate.status, }); let timeoutId: NodeJS.Timeout | null = null; export const useLoginStatus = () => { const dispatch = useDispatch(); - const { innloggetStatus, environment } = useSelector(stateSelector); + const { innloggetStatus, environment, arbeidsflate } = useSelector(stateSelector); const [isTokenExpiring, setIsTokenExpiring] = useState(null); const [isSessionExpiring, setIsSessionExpiring] = useState(null); const [hasAuthError, setHasAuthError] = useState(false); @@ -27,7 +28,7 @@ export const useLoginStatus = () => { innloggetStatusRef.current = innloggetStatus; useEffect(() => { - window.addEventListener('INVALID-SESSION', () => { + window.addEventListener('INVALID_SESSION', () => { setHasAuthError(true); }); }, []); @@ -82,6 +83,10 @@ export const useLoginStatus = () => { window.location.href = getLogOutUrl(environment); }; + const loginHandler = () => { + window.location.href = getLoginUrl(environment, arbeidsflate); + }; + const onVisibilityChange = () => { if (document.visibilityState === 'visible') { checkLoginAndRepeat(); @@ -99,6 +104,7 @@ export const useLoginStatus = () => { isSessionExpiring, refreshTokenHandler, logoutHandler, + loginHandler, secondsToSessionExpires, hasAuthError, }; From b8e95e62e050c53d01ae9b9fd774970dc2a97d4e Mon Sep 17 00:00:00 2001 From: Terje Karlsen Date: Wed, 27 Sep 2023 10:02:19 +0200 Subject: [PATCH 3/3] Legger til lytting ved window focus --- src/utils/hooks/useLoginStatus.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/utils/hooks/useLoginStatus.ts b/src/utils/hooks/useLoginStatus.ts index 9010d403a..12fb2779c 100644 --- a/src/utils/hooks/useLoginStatus.ts +++ b/src/utils/hooks/useLoginStatus.ts @@ -87,7 +87,7 @@ export const useLoginStatus = () => { window.location.href = getLoginUrl(environment, arbeidsflate); }; - const onVisibilityChange = () => { + const onWindowVisibility = () => { if (document.visibilityState === 'visible') { checkLoginAndRepeat(); hentInnloggingsstatus(environment)(dispatch); @@ -96,7 +96,13 @@ export const useLoginStatus = () => { useEffect(() => { checkLoginAndRepeat(); - window.addEventListener('visibilitychange', onVisibilityChange); + window.addEventListener('visibilitychange', onWindowVisibility); + window.addEventListener('focus', onWindowVisibility); + + return () => { + window.removeEventListener('visibilitychange', onWindowVisibility); + window.removeEventListener('focus', onWindowVisibility); + }; }, []); return {