From 2b4221b03a565eeae68d7505b42c8f6698e42a96 Mon Sep 17 00:00:00 2001 From: Oraldo Doci Date: Tue, 25 Jul 2023 12:33:05 +0200 Subject: [PATCH 01/10] Authentication using session storage --- .../[locale]/(pages)/validateSession/page.tsx | 17 +++----- .../[locale]/_component/sessionProvider.tsx | 43 +++++++++++++++++++ src/app/[locale]/_hooks/useToken.tsx | 15 +------ src/app/[locale]/_utils/storage.ts | 4 +- src/app/[locale]/layout.tsx | 14 +++--- src/middleware.ts | 15 +------ 6 files changed, 64 insertions(+), 44 deletions(-) create mode 100644 src/app/[locale]/_component/sessionProvider.tsx diff --git a/src/app/[locale]/(pages)/validateSession/page.tsx b/src/app/[locale]/(pages)/validateSession/page.tsx index dbac57c0..8af5b391 100644 --- a/src/app/[locale]/(pages)/validateSession/page.tsx +++ b/src/app/[locale]/(pages)/validateSession/page.tsx @@ -1,21 +1,16 @@ 'use client'; -import { redirect } from 'next/navigation'; import { useEffect } from 'react'; -import { ROUTES } from '../../_utils/routes'; -import useToken from '../../_hooks/useToken'; import Loader from '../../_component/loader/loader'; +import { extractToken, parseJwt, userFromJwtToken } from '../../_utils/jwt'; +import { storageTokenOps, storageUserOps } from '../../_utils/storage'; const Check = (): React.ReactElement => { - const { tokenError } = useToken(); - useEffect(() => { - if (tokenError === 'ERROR') { - redirect(ROUTES.LOGOUT_AUTH_KO); - } - if (tokenError === 'OK') { - redirect(ROUTES.SESSION); + if (parseJwt(extractToken())) { + storageTokenOps.write(extractToken()); + storageUserOps.write(userFromJwtToken(extractToken())); } - }, [tokenError]); + }, []); return ( <> diff --git a/src/app/[locale]/_component/sessionProvider.tsx b/src/app/[locale]/_component/sessionProvider.tsx new file mode 100644 index 00000000..9fd32fae --- /dev/null +++ b/src/app/[locale]/_component/sessionProvider.tsx @@ -0,0 +1,43 @@ +'use client'; + +import { useRouter } from 'next/navigation'; +import { useEffect } from 'react'; +import { LOGIN_ROUTES, PUBBLIC_ROUTES, ROUTES } from '../_utils/routes'; +// import { storageTokenOps, storageUserOps } from '../_utils/storage'; +import useToken from '../_hooks/useToken'; + +const SessionProviderComponent = ({ children }: { readonly children: React.ReactNode }) => { + const router = useRouter(); + + // const cleanPath = (path: string): string => path.replace(/^(\/(en|it))\/(.*)$/, ''); + + const { token } = useToken(); + + useEffect(() => { + if (!token) { + router.push(ROUTES.LOGIN); + } + if (token) { + router.push(ROUTES.SESSION); + } + }, [token]); + /* + useEffect(() => { + if (LOGIN_ROUTES.includes(cleanPath(window.location.pathname))) { + storageTokenOps.delete(); + storageUserOps.delete(); + } + /* + if (!PUBBLIC_ROUTES.includes(cleanPath(window.location.pathname)) && LoginStatus.UNAUTHORIZED) { + return router.push(ROUTES.LOGIN); + } + + // eslint-disable-next-line no-console + console.log('tokenFromSessionHook', token); + }, [window.location.pathname]); +*/ + + return <>{children}; +}; + +export default SessionProviderComponent; diff --git a/src/app/[locale]/_hooks/useToken.tsx b/src/app/[locale]/_hooks/useToken.tsx index b40fc494..a51a3ac8 100644 --- a/src/app/[locale]/_hooks/useToken.tsx +++ b/src/app/[locale]/_hooks/useToken.tsx @@ -1,31 +1,20 @@ 'use client'; import { useEffect, useState } from 'react'; -import { extractToken, parseJwt, userFromJwtToken } from '../_utils/jwt'; -import { cookieTokenOps, cookieUserOps } from '../_utils/cookie'; +import { storageTokenOps } from '../_utils/storage'; interface Token { token: string; - tokenError: 'PENDING' | 'OK' | 'ERROR'; } const useToken = (): Token => { const [token, setToken] = useState(''); - const [tokenError, setTokenError] = useState<'PENDING' | 'OK' | 'ERROR'>('PENDING'); useEffect(() => { - if (parseJwt(extractToken())) { - setToken(extractToken()); - setTokenError('OK'); - cookieTokenOps.write(extractToken()); - cookieUserOps.write(userFromJwtToken(extractToken())); - } else { - setTokenError('ERROR'); - } + setToken(storageTokenOps.read()); }, []); return { token, - tokenError, }; }; diff --git a/src/app/[locale]/_utils/storage.ts b/src/app/[locale]/_utils/storage.ts index 42e44bfa..7aca83bb 100644 --- a/src/app/[locale]/_utils/storage.ts +++ b/src/app/[locale]/_utils/storage.ts @@ -2,6 +2,6 @@ import { User } from '../_model/User'; import { storageOpsBuilder } from './storage-utils'; /** An object containing a complete set of operation on the storage regarding the key used to store in the storage the loggedUser token in selfcare projects */ -export const storageTokenOps = storageOpsBuilder('token', 'string', true); +export const storageTokenOps = storageOpsBuilder('token', 'string', false); /** An object containing a complete set of operation on the storage regarding the key used to store in the storage the loggedUser in selfcare projects */ -export const storageUserOps = storageOpsBuilder('user', 'object', true); +export const storageUserOps = storageOpsBuilder('user', 'object', false); diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx index 58377dc2..8e485211 100644 --- a/src/app/[locale]/layout.tsx +++ b/src/app/[locale]/layout.tsx @@ -1,8 +1,9 @@ import { NextIntlClientProvider } from 'next-intl'; import { notFound } from 'next/navigation'; -import ThemeProviderComponent from './_component/themeProvider/themeProvider'; -import Header from './_component/header/header'; import Footer from './_component/footer/footer'; +import Header from './_component/header/header'; +import SessionProviderComponent from './_component/sessionProvider'; +import ThemeProviderComponent from './_component/themeProvider/themeProvider'; import { Providers } from './_redux/provider'; export async function generateStaticParams() { @@ -25,15 +26,18 @@ const RootLayoutWithLocaleAndTheme = async ({ } catch (error) { notFound(); } + return ( -
- {children} -