mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 05:10:45 +00:00
Refactor authentication handling to pass authentication metadata into App.
eliminates warnings from oauth2 hook by conditionally using its useAuth hook.
This commit is contained in:
22
src/App.tsx
22
src/App.tsx
@ -63,9 +63,14 @@ import {Md5} from "ts-md5/dist/md5";
|
||||
const qController = Client.getInstance();
|
||||
export const SESSION_UUID_COOKIE_NAME = "sessionUUID";
|
||||
|
||||
export default function App()
|
||||
interface Props
|
||||
{
|
||||
const [cookies, setCookie, removeCookie] = useCookies([SESSION_UUID_COOKIE_NAME]);
|
||||
authenticationMetaData: QAuthenticationMetaData;
|
||||
}
|
||||
|
||||
export default function App({authenticationMetaData}: Props)
|
||||
{
|
||||
const [, , removeCookie] = useCookies([SESSION_UUID_COOKIE_NAME]);
|
||||
const [loadingToken, setLoadingToken] = useState(false);
|
||||
const [isFullyAuthenticated, setIsFullyAuthenticated] = useState(false);
|
||||
const [profileRoutes, setProfileRoutes] = useState({});
|
||||
@ -74,11 +79,10 @@ export default function App()
|
||||
const [needLicenseKey, setNeedLicenseKey] = useState(true);
|
||||
const [loggedInUser, setLoggedInUser] = useState({} as { name?: string, email?: string });
|
||||
const [defaultRoute, setDefaultRoute] = useState("/no-apps");
|
||||
const [authenticationMetaData, setAuthenticationMetaData] = useState(null as QAuthenticationMetaData | null);
|
||||
const [earlyReturnForAuth, setEarlyReturnForAuth] = useState(null as JSX.Element);
|
||||
|
||||
const {setupSession: auth0SetupSession, logout: auth0Logout} = useAuth0AuthenticationModule({setIsFullyAuthenticated, setLoggedInUser, setEarlyReturnForAuth});
|
||||
const {setupSession: oauth2SetupSession, logout: oauth2Logout} = useOAuth2AuthenticationModule({setIsFullyAuthenticated, setLoggedInUser, setEarlyReturnForAuth});
|
||||
const {setupSession: oauth2SetupSession, logout: oauth2Logout} = useOAuth2AuthenticationModule({setIsFullyAuthenticated, setLoggedInUser, setEarlyReturnForAuth, inOAuthContext: authenticationMetaData.type === "OAUTH2"});
|
||||
const {setupSession: anonymousSetupSession, logout: anonymousLogout} = useAnonymousAuthenticationModule({setIsFullyAuthenticated, setLoggedInUser, setEarlyReturnForAuth});
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
@ -99,9 +103,6 @@ export default function App()
|
||||
|
||||
(async () =>
|
||||
{
|
||||
const authenticationMetaData: QAuthenticationMetaData = await qController.getAuthenticationMetaData();
|
||||
setAuthenticationMetaData(authenticationMetaData);
|
||||
|
||||
if (authenticationMetaData.type === "AUTH_0")
|
||||
{
|
||||
await auth0SetupSession();
|
||||
@ -134,7 +135,7 @@ export default function App()
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
** call approprite logout function based on authentication meta data type
|
||||
** call appropriate logout function based on authentication meta data type
|
||||
***************************************************************************/
|
||||
function doLogout()
|
||||
{
|
||||
@ -157,7 +158,7 @@ export default function App()
|
||||
}
|
||||
|
||||
const [controller, dispatch] = useMaterialUIController();
|
||||
const {miniSidenav, direction, layout, openConfigurator, sidenavColor} = controller;
|
||||
const {miniSidenav, direction, sidenavColor} = controller;
|
||||
const [onMouseEnter, setOnMouseEnter] = useState(false);
|
||||
const {pathname} = useLocation();
|
||||
const [queryParams] = useSearchParams();
|
||||
@ -450,11 +451,10 @@ export default function App()
|
||||
}
|
||||
}
|
||||
|
||||
let profileRoutes = {};
|
||||
const gravatarBase = "https://www.gravatar.com/avatar/";
|
||||
const hash = Md5.hashStr(loggedInUser?.email || "user");
|
||||
const profilePicture = `${gravatarBase}${hash}`;
|
||||
profileRoutes = {
|
||||
const profileRoutes = {
|
||||
type: "collapse",
|
||||
name: loggedInUser?.name ?? "Anonymous",
|
||||
key: "username",
|
||||
|
@ -52,7 +52,7 @@ authenticationMetaDataPromise.then((authenticationMetaData) =>
|
||||
function Auth0RouterBody()
|
||||
{
|
||||
const {renderAppWrapper} = useAuth0AuthenticationModule({});
|
||||
return (renderAppWrapper(authenticationMetaData, null));
|
||||
return (renderAppWrapper(authenticationMetaData));
|
||||
}
|
||||
|
||||
|
||||
@ -61,10 +61,10 @@ authenticationMetaDataPromise.then((authenticationMetaData) =>
|
||||
***************************************************************************/
|
||||
function OAuth2RouterBody()
|
||||
{
|
||||
const {renderAppWrapper} = useOAuth2AuthenticationModule({});
|
||||
const {renderAppWrapper} = useOAuth2AuthenticationModule({inOAuthContext: false});
|
||||
return (renderAppWrapper(authenticationMetaData, (
|
||||
<MaterialUIControllerProvider>
|
||||
<App />
|
||||
<App authenticationMetaData={authenticationMetaData} />
|
||||
</MaterialUIControllerProvider>
|
||||
)));
|
||||
}
|
||||
@ -78,7 +78,7 @@ authenticationMetaDataPromise.then((authenticationMetaData) =>
|
||||
const {renderAppWrapper} = useAnonymousAuthenticationModule({});
|
||||
return (renderAppWrapper(authenticationMetaData, (
|
||||
<MaterialUIControllerProvider>
|
||||
<App />
|
||||
<App authenticationMetaData={authenticationMetaData} />
|
||||
</MaterialUIControllerProvider>
|
||||
)));
|
||||
}
|
||||
|
@ -41,11 +41,11 @@ interface Props
|
||||
/***************************************************************************
|
||||
** hook for working with the Auth0 authentication module
|
||||
***************************************************************************/
|
||||
export default function useAuth0AuthenticationModule({setIsFullyAuthenticated, setLoggedInUser, setEarlyReturnForAuth}: Props)
|
||||
export default function useAuth0AuthenticationModule({setIsFullyAuthenticated, setLoggedInUser}: Props)
|
||||
{
|
||||
const {user: auth0User, getAccessTokenSilently: auth0GetAccessTokenSilently, logout: useAuth0Logout} = useAuth0();
|
||||
|
||||
const [cookies, setCookie, removeCookie] = useCookies([SESSION_UUID_COOKIE_NAME]);
|
||||
const [cookies, removeCookie] = useCookies([SESSION_UUID_COOKIE_NAME]);
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
@ -119,12 +119,7 @@ export default function useAuth0AuthenticationModule({setIsFullyAuthenticated, s
|
||||
if (shouldStoreNewToken(accessToken, lsAccessToken))
|
||||
{
|
||||
console.log("Sending accessToken to backend, requesting a sessionUUID...");
|
||||
const {uuid: newSessionUuid, values} = await qController.manageSession(accessToken, null);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// the request to the backend should send a header to set the cookie, so we don't need to do it ourselves. //
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// setCookie(SESSION_UUID_COOKIE_NAME, newSessionUuid, {path: "/"});
|
||||
const {uuid: values} = await qController.manageSession(accessToken, null);
|
||||
|
||||
localStorage.setItem("accessToken", accessToken);
|
||||
localStorage.setItem("sessionValues", JSON.stringify(values));
|
||||
@ -199,7 +194,7 @@ export default function useAuth0AuthenticationModule({setIsFullyAuthenticated, s
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
const renderAppWrapper = (authenticationMetaData: QAuthenticationMetaData, children: JSX.Element): JSX.Element =>
|
||||
const renderAppWrapper = (authenticationMetaData: QAuthenticationMetaData): JSX.Element =>
|
||||
{
|
||||
// @ts-ignore
|
||||
let domain: string = authenticationMetaData.data.baseUrl;
|
||||
@ -225,6 +220,15 @@ export default function useAuth0AuthenticationModule({setIsFullyAuthenticated, s
|
||||
domain = domain.replace(/\/$/, "");
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
** simple Functional Component to wrap the <App> and pass the authentication-
|
||||
** MetaData prop in, so a simple Component can be passed into ProtectedRoute
|
||||
***************************************************************************/
|
||||
function WrappedApp()
|
||||
{
|
||||
return <App authenticationMetaData={authenticationMetaData} />
|
||||
}
|
||||
|
||||
return (
|
||||
<Auth0ProviderWithRedirectCallback
|
||||
domain={domain}
|
||||
@ -232,7 +236,7 @@ export default function useAuth0AuthenticationModule({setIsFullyAuthenticated, s
|
||||
audience={audience}
|
||||
redirectUri={`${window.location.origin}/`}>
|
||||
<MaterialUIControllerProvider>
|
||||
<ProtectedRoute component={App} />
|
||||
<ProtectedRoute component={WrappedApp} />
|
||||
</MaterialUIControllerProvider>
|
||||
</Auth0ProviderWithRedirectCallback>
|
||||
);
|
||||
|
@ -23,7 +23,7 @@ import {QAuthenticationMetaData} from "@kingsrook/qqq-frontend-core/lib/model/me
|
||||
import {SESSION_UUID_COOKIE_NAME} from "App";
|
||||
import Client from "qqq/utils/qqq/Client";
|
||||
import {useCookies} from "react-cookie";
|
||||
import {AuthProvider, useAuth} from "react-oidc-context";
|
||||
import {AuthContextProps, AuthProvider, useAuth} from "react-oidc-context";
|
||||
import {useNavigate, useSearchParams} from "react-router-dom";
|
||||
|
||||
const qController = Client.getInstance();
|
||||
@ -33,16 +33,22 @@ interface Props
|
||||
setIsFullyAuthenticated?: (is: boolean) => void;
|
||||
setLoggedInUser?: (user: any) => void;
|
||||
setEarlyReturnForAuth?: (element: JSX.Element | null) => void;
|
||||
inOAuthContext: boolean;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
** hook for working with the OAuth2 authentication module
|
||||
***************************************************************************/
|
||||
export default function useOAuth2AuthenticationModule({setIsFullyAuthenticated, setLoggedInUser, setEarlyReturnForAuth}: Props)
|
||||
export default function useOAuth2AuthenticationModule({setIsFullyAuthenticated, setLoggedInUser, setEarlyReturnForAuth, inOAuthContext}: Props)
|
||||
{
|
||||
const authOidc = useAuth();
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// the useAuth hook should only be called if we're inside the <AuthProvider> element //
|
||||
// so on the page that uses this hook to call renderAppWrapper, we aren't in that //
|
||||
// element/context, thus, don't call that hook. //
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
const authOidc: AuthContextProps | null = inOAuthContext ? useAuth() : null;
|
||||
|
||||
const [cookies, setCookie, removeCookie] = useCookies([SESSION_UUID_COOKIE_NAME]);
|
||||
const [cookies, removeCookie] = useCookies([SESSION_UUID_COOKIE_NAME]);
|
||||
const [searchParams] = useSearchParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
@ -84,7 +90,7 @@ export default function useOAuth2AuthenticationModule({setIsFullyAuthenticated,
|
||||
if (sessionUuid)
|
||||
{
|
||||
console.log(`we have session UUID: ${sessionUuid} - validating it...`);
|
||||
const {uuid: newSessionUuid, values} = await qController.manageSession(null, sessionUuid, null);
|
||||
const {values} = await qController.manageSession(null, sessionUuid, null);
|
||||
|
||||
setIsFullyAuthenticated(true);
|
||||
qController.setGotAuthentication();
|
||||
@ -98,7 +104,7 @@ export default function useOAuth2AuthenticationModule({setIsFullyAuthenticated,
|
||||
console.log(authOidc);
|
||||
localStorage.setItem(preSigninRedirectPathnameKey, window.location.pathname);
|
||||
setEarlyReturnForAuth(<div>Signing in...</div>);
|
||||
authOidc.signinRedirect();
|
||||
authOidc?.signinRedirect();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -151,7 +157,7 @@ export default function useOAuth2AuthenticationModule({setIsFullyAuthenticated,
|
||||
{
|
||||
qController.clearAuthenticationMetaDataLocalStorage();
|
||||
removeCookie(SESSION_UUID_COOKIE_NAME, {path: "/"});
|
||||
authOidc.signoutRedirect();
|
||||
authOidc?.signoutRedirect();
|
||||
};
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user