From 240b6fb0b99f3aa55600027a818667e0420fdca1 Mon Sep 17 00:00:00 2001 From: Noah Spannbauer Date: Sun, 19 Jan 2025 20:11:28 -0600 Subject: [PATCH] Refactoring --- app/src/components/siteNav/SiteNav.tsx | 136 ++++++++++++------------- app/src/hooks/auth/UseAuthProvider.tsx | 7 -- app/src/hooks/auth/authConfig.ts | 70 ------------- app/src/hooks/auth/authProvider.tsx | 32 ------ app/src/main.tsx | 46 ++++++++- 5 files changed, 108 insertions(+), 183 deletions(-) delete mode 100644 app/src/hooks/auth/UseAuthProvider.tsx delete mode 100644 app/src/hooks/auth/authConfig.ts delete mode 100644 app/src/hooks/auth/authProvider.tsx diff --git a/app/src/components/siteNav/SiteNav.tsx b/app/src/components/siteNav/SiteNav.tsx index 57e7dfa..0dba599 100644 --- a/app/src/components/siteNav/SiteNav.tsx +++ b/app/src/components/siteNav/SiteNav.tsx @@ -14,14 +14,13 @@ import { useAccessToken } from '../../hooks/accessToken/UseAcessToken'; import { useHttpClient } from '../../hooks/httpClient/UseHttpClient'; import { AxiosInstance, AxiosResponse } from 'axios'; import { User } from '@microsoft/microsoft-graph-types'; -import { loginRequest } from '../../hooks/auth/authConfig'; const SiteNav: React.FC = () => { const [userPhoto, setUserPhoto] = useState(); const httpClient: AxiosInstance = useHttpClient(); const appContext = useAppContext(); - // const isAuthenticated = useIsAuthenticated(); - // const { getAccessToken } = useAccessToken(); + const isAuthenticated = useIsAuthenticated(); + const { getAccessToken } = useAccessToken(); const { instance } = useMsal(); const navigate = useNavigate(); const pages = [ @@ -35,11 +34,10 @@ const SiteNav: React.FC = () => { } ]; - const handleSignInRedirect = async () => { - await instance + const handleSignInRedirect = () => { + instance .loginRedirect({ - ...loginRequest, - // prompt: 'create', + scopes: [`api://${import.meta.env.VITE_CLIENT_ID}/user_impersonation`] }) .catch((error) => console.log(error)); }; @@ -51,39 +49,40 @@ const SiteNav: React.FC = () => { window.location.reload(); } - // const getUserProfile = async (accessToken: string): Promise => { - // try { - // const response: AxiosResponse = await httpClient.get(`api/userProfile`, { - // headers: { - // Authorization: accessToken - // } - // }); - // const userProfile: User = response.data; + const getUserProfile = async (accessToken: string): Promise => { + try { + const response: AxiosResponse = await httpClient.get(`api/userProfile`, { + headers: { + Authorization: accessToken + } + }); + const userProfile: User = response.data; - // return userProfile; - // } catch (error) { - // throw new Error(); - // } - // }; + return userProfile; + } catch (error) { + throw new Error(); + } + }; - // const getUserPhoto = async (accessToken: string): Promise => { - // try { - // const response: AxiosResponse = await httpClient.get(`api/userPhoto`, { - // headers: { - // Authorization: accessToken - // }, - // responseType: 'arraybuffer' - // }); - // const arrayBufferView = new Uint8Array(response.data); - // const blob = new Blob([arrayBufferView], { type: 'image/png' }); - // const imageUrl = window.URL.createObjectURL(blob); + const getUserPhoto = async (accessToken: string): Promise => { + try { + const response: AxiosResponse = await httpClient.get(`api/userPhoto`, { + headers: { + Authorization: accessToken + }, + responseType: 'arraybuffer' + }); + const arrayBufferView = new Uint8Array(response.data); + const blob = new Blob([arrayBufferView], { type: 'image/png' }); + const imageUrl = window.URL.createObjectURL(blob); + + return imageUrl; + } catch (error) { + console.log(error); + throw new Error(); + } + }; - // return imageUrl; - // } catch (error) { - // console.log(error); - // throw new Error(); - // } - // }; const handlePageClick = (url: string) => { navigate(url); }; @@ -99,43 +98,42 @@ const SiteNav: React.FC = () => { ); }; - // useEffect(() => { - // const setUserProfile = async () => { - // try { - // const accessToken: string = await getAccessToken(); - // const userProfile = await getUserProfile(accessToken); - // const userPhoto = await getUserPhoto(accessToken); + useEffect(() => { + const setUserProfile = async () => { + try { + const accessToken: string = await getAccessToken(); + const userProfile = await getUserProfile(accessToken); + const userPhoto = await getUserPhoto(accessToken); - // setUserPhoto(userPhoto); + setUserPhoto(userPhoto); - // appContext.dispatch({ - // type: 'SET_USER_PROFILE', - // payload: userProfile - // }); - // } catch (error) { - // console.log(error); - // } - // }; + appContext.dispatch({ + type: 'SET_USER_PROFILE', + payload: userProfile + }); + } catch (error) { + console.log(error); + } + }; - // if ( - // isAuthenticated && - // Object.keys(appContext.state.userProfile).length === 0 - // ) { - // setUserProfile(); - // } - // }, [isAuthenticated]); + if ( + isAuthenticated && + Object.keys(appContext.state.userProfile).length === 0 + ) { + setUserProfile(); + } + }, [isAuthenticated]); return ( - - // } - // pages={pages} - // settings={} - // userPhoto={userPhoto} - // /> + } + pages={pages} + settings={} + userPhoto={userPhoto} + /> ); }; diff --git a/app/src/hooks/auth/UseAuthProvider.tsx b/app/src/hooks/auth/UseAuthProvider.tsx deleted file mode 100644 index ae954d7..0000000 --- a/app/src/hooks/auth/UseAuthProvider.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { AuthProvider } from "./authProvider" - -export const useAuthProvider = () => { - return { - AuthProvider - } -} \ No newline at end of file diff --git a/app/src/hooks/auth/authConfig.ts b/app/src/hooks/auth/authConfig.ts deleted file mode 100644 index bf1ef48..0000000 --- a/app/src/hooks/auth/authConfig.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - */ - -import { LogLevel } from '@azure/msal-browser'; - -/** - * Configuration object to be passed to MSAL instance on creation. - * For a full list of MSAL.js configuration parameters, visit: - * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md - */ - -export const msalConfig = { - auth: { - clientId: import.meta.env.VITE_CLIENT_ID, // This is the ONLY mandatory field that you need to supply. - authority: `https://login.microsoftonline.com/${import.meta.env.VITE_TENANT_ID}`, // Replace the placeholder with your tenant subdomain - redirectUri: import.meta.env.VITE_REDIRECT_URL, // Points to window.location.origin. You must register this URI on Microsoft Entra admin center/App Registration. - postLogoutRedirectUri: '/', // Indicates the page to navigate after logout. - navigateToLoginRequestUrl: false, // If "true", will navigate back to the original request location before processing the auth code response. - }, - cache: { - cacheLocation: 'sessionStorage', // Configures cache location. "sessionStorage" is more secure, but "localStorage" gives you SSO between tabs. - storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge - }, - system: { - loggerOptions: { - loggerCallback: (level: any, message: any, containsPii: any) => { - if (containsPii) { - return; - } - switch (level) { - case LogLevel.Error: - console.error(message); - return; - case LogLevel.Info: - console.info(message); - return; - case LogLevel.Verbose: - console.debug(message); - return; - case LogLevel.Warning: - console.warn(message); - return; - default: - return; - } - }, - }, - }, -}; - -/** - * Scopes you add here will be prompted for user consent during sign-in. - * By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request. - * For more information about OIDC scopes, visit: - * https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes - */ -export const loginRequest = { - scopes: [`api://${import.meta.env.VITE_CLIENT_ID}/user_impersonation`] -}; - -/** - * An optional silentRequest object can be used to achieve silent SSO - * between applications by providing a "login_hint" property. - */ -// export const silentRequest = { -// scopes: ["openid", "profile"], -// loginHint: "example@domain.net" -// }; \ No newline at end of file diff --git a/app/src/hooks/auth/authProvider.tsx b/app/src/hooks/auth/authProvider.tsx deleted file mode 100644 index 8e1676c..0000000 --- a/app/src/hooks/auth/authProvider.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { AuthenticationResult, EventType, PublicClientApplication } from "@azure/msal-browser"; -import { ReactNode } from "react"; -import { msalConfig } from "./authConfig"; -import { MsalProvider } from "@azure/msal-react"; - -interface AuthProviderProps { - children: ReactNode -} - -export const AuthProvider = ({ children }: AuthProviderProps ) => { - const msalInstance = new PublicClientApplication(msalConfig); - - // Default to using the first account if no account is active on page load - if (!msalInstance.getActiveAccount() && msalInstance.getAllAccounts().length > 0) { - // Account selection logic is app dependent. Adjust as needed for different use cases. - msalInstance.setActiveAccount(msalInstance.getAllAccounts()[0]); - } - - // Listen for sign-in event and set active account - msalInstance.addEventCallback((event) => { - const authenticationResult = event.payload as AuthenticationResult; - const account = authenticationResult?.account; - - if (event.eventType === EventType.LOGIN_SUCCESS && account) { - msalInstance.setActiveAccount(account); - } - }); - - return - {children} - -} \ No newline at end of file diff --git a/app/src/main.tsx b/app/src/main.tsx index b2d16c7..16bc51f 100644 --- a/app/src/main.tsx +++ b/app/src/main.tsx @@ -5,21 +5,57 @@ import AppContextProvider from './context/appContext/AppContextProvider.tsx'; import { BrowserRouter } from 'react-router-dom'; import './index.css'; import '@noahspan/noahspan-components/noahspan-components.css'; -import { EventMessage, EventPayload, EventType, LogLevel, PublicClientApplication } from '@azure/msal-browser'; +import { LogLevel, PublicClientApplication } from '@azure/msal-browser'; import { MsalProvider } from '@azure/msal-react'; -import { useAuthProvider } from './hooks/auth/UseAuthProvider.tsx'; -const { AuthProvider } = useAuthProvider(); +const msalConfig = { + auth: { + clientId: import.meta.env.VITE_CLIENT_ID, + authority: `https://login.microsoftonline.com/${import.meta.env.VITE_TENANT_ID}`, + redirectUri: import.meta.env.VITE_TENANT_ID, + }, + cache: { + cacheLocation: "sessionStorage", // This configures where your cache will be stored + storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge + }, + system: { + loggerOptions: { + loggerCallback: (level: any, message: any, containsPii: any) => { + if (containsPii) { + return; + } + switch (level) { + case LogLevel.Error: + console.error(message); + return; + case LogLevel.Info: + console.info(message); + return; + case LogLevel.Verbose: + console.debug(message); + return; + case LogLevel.Warning: + console.warn(message); + return; + default: + return; + } + } + } + } +}; + +const msalInstance = new PublicClientApplication(msalConfig) ReactDOM.createRoot(document.getElementById('root')!).render( - + - + );