From a9c979481c9c23e067da2c19132a4352436d2935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chif=20Gerg=C5=91?= <chifgeri97@gmail.com> Date: Mon, 28 Jun 2021 18:27:11 +0200 Subject: [PATCH] Handle logged in but no profile state --- src/client/auth.ts | 9 ++++++--- src/components/Header.tsx | 4 ++-- src/components/RememberMe.tsx | 6 ++++++ src/context/UserContext.tsx | 11 ++++++++--- src/hooks/useMe.tsx | 6 +++--- 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/client/auth.ts b/src/client/auth.ts index a7e8a69..017fb7f 100644 --- a/src/client/auth.ts +++ b/src/client/auth.ts @@ -1,7 +1,8 @@ import Axios, { AxiosRequestConfig } from 'axios'; +import type { ProfileWithStatus } from '../context'; import { IProfile } from '../types/Profile'; -type MeQuery = () => Promise<IProfile>; +type MeQuery = () => Promise<ProfileWithStatus>; type RegisterQuery = (data: ProfileData) => Promise<any>; export type ProfileData = { @@ -20,8 +21,10 @@ export function auth(config: AxiosRequestConfig): AuthClient { baseURL: `${config.baseURL}/api/v1/`, }); - const me: MeQuery = async (): Promise<IProfile> => { - return (await axios.get<IProfile>('/users/me')).data; + const me: MeQuery = async (): Promise<ProfileWithStatus> => { + const profileResp = await axios.get<IProfile>('/users/me'); + const isLoggedIn = profileResp.status === 404 || profileResp.status === 200; + return { profile: profileResp.data, isLoggedIn }; }; const register: RegisterQuery = async (data: ProfileData): Promise<any> => { diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 688f5ce..67ce166 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -142,7 +142,7 @@ const Header: React.FC<HeaderProps> = ({ customToolbar, menuItems = MENU_ITEMS } /> ))} - {profile.role === 'ADMIN' && ( + {profile.profile && profile.profile.role === 'ADMIN' && ( <> {ADMIN_MENU_ITEMS.map((item) => ( <Tab @@ -174,7 +174,7 @@ const Header: React.FC<HeaderProps> = ({ customToolbar, menuItems = MENU_ITEMS } </IconButton> <Typography variant="h6" align="center" className={classes.texts}> - {profile.name} + {profile.profile && profile.profile.name} </Typography> <a href="/api/v1/logout"> <Box color="secondary.main"> diff --git a/src/components/RememberMe.tsx b/src/components/RememberMe.tsx index 7731549..d9e6dc4 100644 --- a/src/components/RememberMe.tsx +++ b/src/components/RememberMe.tsx @@ -1,4 +1,6 @@ +import { isNil } from 'lodash'; import React, { useEffect } from 'react'; +import { Redirect } from 'react-router-dom'; import useMe from '../hooks/useMe'; import { useUserContext } from '../hooks/useUserContext'; @@ -16,6 +18,10 @@ const RememberMe: React.FC = ({ children }) => { } }, [me, setProfile]); + if (isNil(me?.profile) && me?.isLoggedIn) { + return <Redirect to="/register" />; + } + return <>{children}</>; }; diff --git a/src/context/UserContext.tsx b/src/context/UserContext.tsx index 99051b0..cac0b36 100644 --- a/src/context/UserContext.tsx +++ b/src/context/UserContext.tsx @@ -1,9 +1,14 @@ import React, { createContext, useState } from 'react'; import { IProfile } from '../types/Profile'; +export type ProfileWithStatus = { + profile?: IProfile; + isLoggedIn: boolean; +}; + export interface UserContextType { - profile: IProfile | undefined; - setProfile: (profile: IProfile | undefined) => void; + profile?: ProfileWithStatus; + setProfile: (profile: ProfileWithStatus | undefined) => void; } /* // Context @@ -24,7 +29,7 @@ export const UserContext = createContext({} as UserContextType); const { Provider } = UserContext; export const UserStateProvider: React.FC = ({ children }) => { - const [profile, setProfile] = useState<IProfile | undefined>(); + const [profile, setProfile] = useState<ProfileWithStatus>(); return <Provider value={{ profile, setProfile }}>{children}</Provider>; }; diff --git a/src/hooks/useMe.tsx b/src/hooks/useMe.tsx index 2929427..c52226a 100644 --- a/src/hooks/useMe.tsx +++ b/src/hooks/useMe.tsx @@ -1,9 +1,9 @@ import { useQuery, UseQueryResult } from 'react-query'; -import { IProfile } from '../types/Profile'; +import { ProfileWithStatus } from '../context'; import useClientContext from './useClientContext'; -export default function useMe(): UseQueryResult<IProfile, Error> { +export default function useMe(): UseQueryResult<ProfileWithStatus, Error> { const client = useClientContext(); - return useQuery<IProfile, Error>('me', async () => client.client.auth.me()); + return useQuery<ProfileWithStatus, Error>('me', async () => client.client.auth.me()); } -- GitLab