Skip to content

Commit

Permalink
separate sso from auth context, rename context
Browse files Browse the repository at this point in the history
  • Loading branch information
dbarkowsky committed Sep 24, 2024
1 parent b025343 commit 7be48d4
Show file tree
Hide file tree
Showing 19 changed files with 81 additions and 82 deletions.
12 changes: 7 additions & 5 deletions react-app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import '@/App.css';
import { ThemeProvider } from '@emotion/react';
import appTheme from './themes/appTheme';
import Dev from './pages/DevZone';
import AuthContextProvider, { AuthContext } from './contexts/authContext';
import UserContextProvider, { UserContext } from './contexts/authContext';
import AuthRouteGuard from './guards/AuthRouteGuard';
import BaseLayout from './components/layout/BaseLayout';
import { AccessRequest } from './pages/AccessRequest';
Expand All @@ -31,6 +31,7 @@ import ParcelMap from '@/components/map/ParcelMap';
import LookupContextProvider from '@/contexts/lookupContext';
import BulkUpload from './pages/BulkUpload';
import useHistoryAwareNavigate from './hooks/useHistoryAwareNavigate';
import { useSSO } from '@bcgov/citz-imb-sso-react';

/**
* Renders the main router component for the application.
Expand All @@ -40,7 +41,8 @@ import useHistoryAwareNavigate from './hooks/useHistoryAwareNavigate';
* @returns JSX element representing the main router component
*/
const Router = () => {
const auth = useContext(AuthContext);
const sso = useSSO();
const auth = useContext(UserContext);
const { goToFromStateOrSetRoute } = useHistoryAwareNavigate();

// Reusable piece to show map on many routes
Expand All @@ -63,7 +65,7 @@ const Router = () => {
<Route
index
element={
auth.keycloak.isAuthenticated &&
sso.isAuthenticated &&
auth.pimsUser.data?.Status === 'Active' &&
auth.pimsUser.data?.RoleId ? (
showMap()
Expand Down Expand Up @@ -268,13 +270,13 @@ const App = () => {
return (
<ThemeProvider theme={appTheme}>
<ErrorBoundary FallbackComponent={ErrorFallback}>
<AuthContextProvider>
<UserContextProvider>
<LookupContextProvider>
<SnackBarContextProvider>
<Router />
</SnackBarContextProvider>
</LookupContextProvider>
</AuthContextProvider>
</UserContextProvider>
</ErrorBoundary>
</ThemeProvider>
);
Expand Down
4 changes: 2 additions & 2 deletions react-app/src/components/layout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
import { Link as RouterLink, useNavigate } from 'react-router-dom';
import { useSSO } from '@bcgov/citz-imb-sso-react';
import { Roles } from '@/constants/roles';
import { AuthContext } from '@/contexts/authContext';
import { UserContext } from '@/contexts/authContext';

const AppBrand = () => {
const theme = useTheme();
Expand Down Expand Up @@ -61,7 +61,7 @@ const AppBrand = () => {
};

const Header: React.FC = () => {
const auth = useContext(AuthContext);
const auth = useContext(UserContext);
const { logout, isAuthenticated, login } = useSSO();
const theme = useTheme();
const navigate = useNavigate();
Expand Down
4 changes: 2 additions & 2 deletions react-app/src/components/map/controls/FilterControl.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import MultiselectFormField from '@/components/form/MultiselectFormField';
import TextFormField from '@/components/form/TextFormField';
import { Roles } from '@/constants/roles';
import { AuthContext } from '@/contexts/authContext';
import { UserContext } from '@/contexts/authContext';
import { LookupContext } from '@/contexts/lookupContext';
import useGroupedAgenciesApi from '@/hooks/api/useGroupedAgenciesApi';
import { MapFilter } from '@/hooks/api/usePropertiesApi';
Expand All @@ -27,7 +27,7 @@ interface FilterControlProps {
const FilterControl = (props: FilterControlProps) => {
const { setFilter } = props;
const api = usePimsApi();
const user = useContext(AuthContext);
const user = useContext(UserContext);
const { data: lookupData } = useContext(LookupContext);

// Get lists for dropdowns
Expand Down
4 changes: 2 additions & 2 deletions react-app/src/components/map/parcelPopup/ParcelPopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import KeyboardDoubleArrowRightIcon from '@mui/icons-material/KeyboardDoubleArro
import './parcelPopup.css';
import { TabContext, TabList, TabPanel } from '@mui/lab';
import useDataLoader from '@/hooks/useDataLoader';
import { AuthContext } from '@/contexts/authContext';
import { UserContext } from '@/contexts/authContext';
import { Roles } from '@/constants/roles';
import BCAssessmentDetails from '@/components/map/parcelPopup/BCAssessmentDetails';
import LtsaDetails from '@/components/map/parcelPopup/LtsaDetails';
Expand Down Expand Up @@ -38,7 +38,7 @@ export const ParcelPopup = (props: ParcelPopupProps) => {
const [tabValue, setTabValue] = useState<string>('0');
const { size = 'large', scrollOnClick } = props;

const { pimsUser } = useContext(AuthContext);
const { pimsUser } = useContext(UserContext);

const {
data: ltsaData,
Expand Down
4 changes: 2 additions & 2 deletions react-app/src/components/projects/ProjectDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import { enumReverseLookup } from '@/utilities/helperFunctions';
import { AgencyResponseType } from '@/constants/agencyResponseTypes';
import useDataSubmitter from '@/hooks/useDataSubmitter';
import { Roles } from '@/constants/roles';
import { AuthContext } from '@/contexts/authContext';
import { UserContext } from '@/contexts/authContext';
import { ExpandMoreOutlined } from '@mui/icons-material';
import { columnNameFormatter, dateFormatter, formatMoney } from '@/utilities/formatters';
import { LookupContext } from '@/contexts/lookupContext';
Expand Down Expand Up @@ -71,7 +71,7 @@ interface ProjectInfo extends Project {
const ProjectDetail = (props: IProjectDetail) => {
const navigate = useNavigate();
const { id } = useParams();
const { pimsUser } = useContext(AuthContext);
const { pimsUser } = useContext(UserContext);
const lookup = useContext(LookupContext);
const api = usePimsApi();
const { data: lookupData, getLookupValueById } = useContext(LookupContext);
Expand Down
4 changes: 2 additions & 2 deletions react-app/src/components/projects/ProjectDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import ProjectNotificationsTable from './ProjectNotificationsTable';
import { getStatusString } from '@/constants/chesNotificationStatus';
import { MonetaryType } from '@/constants/monetaryTypes';
import AutocompleteFormField from '../form/AutocompleteFormField';
import { AuthContext } from '@/contexts/authContext';
import { UserContext } from '@/contexts/authContext';
import { Roles } from '@/constants/roles';
import BaseDialog from '../dialog/BaseDialog';
import { NotificationQueue } from '@/hooks/api/useProjectNotificationApi';
Expand All @@ -43,7 +43,7 @@ export const ProjectGeneralInfoDialog = (props: IProjectGeneralInfoDialog) => {
const { open, postSubmit, onCancel, initialValues } = props;
const api = usePimsApi();
const { data: lookupData } = useContext(LookupContext);
const { pimsUser } = useContext(AuthContext);
const { pimsUser } = useContext(UserContext);
const { submit, submitting } = useDataSubmitter(api.projects.updateProject);
const [approvedStatus, setApprovedStatus] = useState<number>(null);
const projectFormMethods = useForm({
Expand Down
4 changes: 2 additions & 2 deletions react-app/src/components/projects/ProjectForms.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Grid, InputAdornment, Typography } from '@mui/material';
import React, { useContext } from 'react';
import AutocompleteFormField from '../form/AutocompleteFormField';
import { AuthContext } from '@/contexts/authContext';
import { UserContext } from '@/contexts/authContext';
import TextFormField from '../form/TextFormField';
import { ISelectMenuItem } from '../form/SelectFormField';
import SingleSelectBoxFormField from '../form/SingleSelectBoxFormField';
Expand All @@ -14,7 +14,7 @@ interface IProjectGeneralInfoForm {

export const ProjectGeneralInfoForm = (props: IProjectGeneralInfoForm) => {
const { data: lookupData } = useContext(LookupContext);
const { pimsUser } = useContext(AuthContext);
const { pimsUser } = useContext(UserContext);
const canEdit = pimsUser.hasOneOfRoles([Roles.ADMIN]);

return (
Expand Down
4 changes: 2 additions & 2 deletions react-app/src/components/property/PropertyDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { Map } from 'leaflet';
import { Room } from '@mui/icons-material';
import TitleOwnership from '../ltsa/TitleOwnership';
import useDataSubmitter from '@/hooks/useDataSubmitter';
import { AuthContext } from '@/contexts/authContext';
import { UserContext } from '@/contexts/authContext';
import { Roles } from '@/constants/roles';
import { LookupContext } from '@/contexts/lookupContext';
import AssociatedProjectsTable from './AssociatedProjectsTable';
Expand All @@ -40,7 +40,7 @@ interface IPropertyDetail {
const PropertyDetail = (props: IPropertyDetail) => {
const navigate = useNavigate();
const params = useParams();
const { pimsUser } = useContext(AuthContext);
const { pimsUser } = useContext(UserContext);
const { getLookupValueById } = useContext(LookupContext);
const parcelId = isNaN(Number(params.parcelId)) ? null : Number(params.parcelId);
const buildingId = isNaN(Number(params.buildingId)) ? null : Number(params.buildingId);
Expand Down
4 changes: 2 additions & 2 deletions react-app/src/components/table/DataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import CircularProgress from '@mui/material/CircularProgress';
import { CommonFiltering } from '@/interfaces/ICommonFiltering';
import { useSearchParams } from 'react-router-dom';
import { Roles } from '@/constants/roles';
import { AuthContext } from '@/contexts/authContext';
import { UserContext } from '@/contexts/authContext';
import { SnackBarContext } from '@/contexts/snackbarContext';

type RenderCellParams = GridRenderCellParams<any, any, any, GridTreeNodeWithRender>;
Expand Down Expand Up @@ -436,7 +436,7 @@ export const FilterSearchDataGrid = (props: FilterSearchDataGridProps) => {
: `(${props.rowCountProp ?? 0} rows)`;
}, [props.tableOperationMode, rowCount, props.rowCountProp]);

const { pimsUser } = useContext(AuthContext);
const { pimsUser } = useContext(UserContext);
const isAuditor = pimsUser.hasOneOfRoles([Roles.AUDITOR]);

return (
Expand Down
4 changes: 2 additions & 2 deletions react-app/src/components/users/UserDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import AutocompleteFormField from '@/components/form/AutocompleteFormField';
import usePimsApi from '@/hooks/usePimsApi';
import useDataLoader from '@/hooks/useDataLoader';
import { User } from '@/hooks/api/useUsersApi';
import { AuthContext } from '@/contexts/authContext';
import { UserContext } from '@/contexts/authContext';
import { Agency } from '@/hooks/api/useAgencyApi';
import TextFormField from '../form/TextFormField';
import DetailViewNavigation from '../display/DetailViewNavigation';
Expand All @@ -29,7 +29,7 @@ interface UserProfile extends User {

const UserDetail = ({ onClose }: IUserDetail) => {
const { id } = useParams();
const { pimsUser } = useContext(AuthContext);
const { pimsUser } = useContext(UserContext);
const { data: lookupData, getLookupValueById } = useContext(LookupContext);
const api = usePimsApi();

Expand Down
22 changes: 9 additions & 13 deletions react-app/src/contexts/authContext.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,28 @@
import usePimsUser, { IPimsUser } from '@/hooks/usePimsUser';
import { AuthService, useSSO } from '@bcgov/citz-imb-sso-react';
import usePimsUser, { IPimsUser as PimsUser } from '@/hooks/usePimsUser';
import React, { createContext } from 'react';
export interface IAuthState {
keycloak: AuthService;
pimsUser: IPimsUser;
export interface PimsUserState {
pimsUser: PimsUser;
}
export const AuthContext = createContext<IAuthState | undefined>(undefined);
export const UserContext = createContext<PimsUserState | undefined>(undefined);

/**
* Provides access to user and authentication (keycloak) data about the logged in user.
* Provides access to user data about the logged in user.
*
* @param {*} props
* @return {*}
*/
export const AuthContextProvider: React.FC<React.PropsWithChildren> = (props) => {
const keycloak = useSSO();
export const UserContextProvider: React.FC<React.PropsWithChildren> = (props) => {
const pimsUser = usePimsUser();

return (
<AuthContext.Provider
<UserContext.Provider
value={{
keycloak,
pimsUser,
}}
>
{props.children}
</AuthContext.Provider>
</UserContext.Provider>
);
};

export default AuthContextProvider;
export default UserContextProvider;
8 changes: 4 additions & 4 deletions react-app/src/contexts/lookupContext.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { AuthContext } from '@/contexts/authContext';
import { LookupAll } from '@/hooks/api/useLookupApi';
import useDataLoader from '@/hooks/useDataLoader';
import usePimsApi from '@/hooks/usePimsApi';
import React, { createContext, useCallback, useContext, useMemo } from 'react';
import { useSSO } from '@bcgov/citz-imb-sso-react';
import React, { createContext, useCallback, useMemo } from 'react';

type LookupContextValue = {
data: LookupAll | undefined;
Expand All @@ -19,8 +19,8 @@ export const LookupContext = createContext<LookupContextValue>(undefined);
export const LookupContextProvider: React.FC<React.PropsWithChildren> = (props) => {
const api = usePimsApi();
const { data, loadOnce } = useDataLoader(api.lookup.getAll);
const { keycloak } = useContext(AuthContext);
if (!data && keycloak.isAuthenticated) {
const sso = useSSO();
if (!data && sso.isAuthenticated) {
loadOnce();
}

Expand Down
18 changes: 8 additions & 10 deletions react-app/src/guards/AuthRouteGuard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Roles } from '@/constants/roles';
import { AuthContext } from '@/contexts/authContext';
import { UserContext } from '@/contexts/authContext';
import { useSSO } from '@bcgov/citz-imb-sso-react';
import { CircularProgress, Paper, Typography } from '@mui/material';
import { PropsWithChildren, useContext, useEffect, useRef } from 'react';
import React from 'react';
Expand All @@ -18,11 +19,12 @@ export interface AuthGuardProps extends PropsWithChildren {
*/
const AuthRouteGuard = (props: AuthGuardProps) => {
const { permittedRoles, redirectRoute, ignoreStatus } = props;
const authStateContext = useContext(AuthContext);
const authStateContext = useContext(UserContext);
const sso = useSSO();
const navigate = useNavigate();

useEffect(() => {
if (authStateContext.keycloak.isAuthenticated) {
if (sso.isAuthenticated) {
if (timeoutId.current) {
clearTimeout(timeoutId.current);
timeoutId.current = null;
Expand All @@ -41,7 +43,7 @@ const AuthRouteGuard = (props: AuthGuardProps) => {
} else {
timeoutId.current = setTimeout(
() =>
authStateContext.keycloak.login({
sso.login({
postLoginRedirectURL: window.location.pathname + window.location.search,
}),
5000,
Expand All @@ -53,13 +55,9 @@ const AuthRouteGuard = (props: AuthGuardProps) => {
clearTimeout(timeoutId.current);
}
};
}, [
authStateContext.pimsUser?.isLoading,
authStateContext.keycloak.isLoggingIn,
authStateContext.keycloak.isAuthenticated,
]);
}, [authStateContext.pimsUser?.isLoading, sso.isLoggingIn, sso.isAuthenticated]);
const timeoutId = useRef(null);
if (!authStateContext.keycloak.isAuthenticated) {
if (!sso.isAuthenticated) {
return (
<Paper
sx={{
Expand Down
4 changes: 2 additions & 2 deletions react-app/src/hooks/api/usePropertiesApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export interface PropertyId {
const usePropertiesApi = (absoluteFetch: IFetch) => {
// const config = useContext(ConfigContext);
const config = getConfig();
const keycloak = useSSO();
const sso = useSSO();

const propertiesFuzzySearch = async (keyword: string) => {
const { parsedBody } = await absoluteFetch.get('/properties/search/fuzzy', {
Expand Down Expand Up @@ -167,7 +167,7 @@ const usePropertiesApi = (absoluteFetch: IFetch) => {
const result = await fetch(config.API_HOST + '/properties/import', {
method: 'POST',
body: form, //Using standard fetch here instead of the wrapper so that we can handle this form-data body without converting to JSON.
headers: { Authorization: keycloak.getAuthorizationHeaderValue() },
headers: { Authorization: sso.getAuthorizationHeaderValue() },
signal: AbortSignal.timeout(5000),
});
const text = await result.text();
Expand Down
12 changes: 7 additions & 5 deletions react-app/src/hooks/api/useUserAgencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,24 @@ import { ISelectMenuItem } from '@/components/form/SelectFormField';
import { Roles } from '@/constants/roles';
import { useContext, useEffect, useMemo } from 'react';
import useDataLoader from '../useDataLoader';
import { AuthContext } from '@/contexts/authContext';
import { UserContext } from '@/contexts/authContext';
import usePimsApi from '../usePimsApi';
import useGroupedAgenciesApi from './useGroupedAgenciesApi';
import { useSSO } from '@bcgov/citz-imb-sso-react';

const useUserAgencies = () => {
const userContext = useContext(AuthContext);
const { pimsUser } = useContext(UserContext);
const sso = useSSO();
const { ungroupedAgencies, agencyOptions } = useGroupedAgenciesApi();
const api = usePimsApi();
const isAdmin = userContext.pimsUser?.hasOneOfRoles([Roles.ADMIN]);
const isAdmin = pimsUser?.hasOneOfRoles([Roles.ADMIN]);
const { data: userAgencies, refreshData: refreshUserAgencies } = useDataLoader(() =>
api.users.getUsersAgencyIds(userContext.keycloak.user.preferred_username),
api.users.getUsersAgencyIds(sso.user.preferred_username),
);

useEffect(() => {
refreshUserAgencies();
}, [userContext.keycloak]);
}, [sso]);

const userAgencyObjects = useMemo(() => {
if (ungroupedAgencies && userAgencies) {
Expand Down
Loading

0 comments on commit 7be48d4

Please sign in to comment.