diff --git a/src/App.tsx b/src/App.tsx index eab6110..ebdaa41 100644 --- a/src/App.tsx +++ b/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", diff --git a/src/index.tsx b/src/index.tsx index 93d22f7..4299bf7 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -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, ( - + ))); } @@ -78,7 +78,7 @@ authenticationMetaDataPromise.then((authenticationMetaData) => const {renderAppWrapper} = useAnonymousAuthenticationModule({}); return (renderAppWrapper(authenticationMetaData, ( - + ))); } diff --git a/src/qqq/authorization/auth0/useAuth0AuthenticationModule.tsx b/src/qqq/authorization/auth0/useAuth0AuthenticationModule.tsx index 939cdcc..aa1c256 100644 --- a/src/qqq/authorization/auth0/useAuth0AuthenticationModule.tsx +++ b/src/qqq/authorization/auth0/useAuth0AuthenticationModule.tsx @@ -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 and pass the authentication- + ** MetaData prop in, so a simple Component can be passed into ProtectedRoute + ***************************************************************************/ + function WrappedApp() + { + return + } + return ( - + ); diff --git a/src/qqq/authorization/oauth2/useOAuth2AuthenticationModule.tsx b/src/qqq/authorization/oauth2/useOAuth2AuthenticationModule.tsx index 4942a92..226ab4c 100644 --- a/src/qqq/authorization/oauth2/useOAuth2AuthenticationModule.tsx +++ b/src/qqq/authorization/oauth2/useOAuth2AuthenticationModule.tsx @@ -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 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(
Signing in...
); - 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(); };