Skip to content

Commit

Permalink
Merge pull request #635 from etn-ccis/feature/update-example-with-log…
Browse files Browse the repository at this point in the history
…in-callback

Updated example with login callback
  • Loading branch information
ektaghag-eaton authored Sep 11, 2024
2 parents 701ee2b + 9b8c722 commit d78026f
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 127 deletions.
1 change: 1 addition & 0 deletions login-workflow/example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const App = (): JSX.Element => {
<AppContext.Provider
value={{
isAuthenticated,
setIsAuthenticated,
onUserAuthenticated: (userData): void => {
setIsAuthenticated(true);
setLoginData(userData);
Expand Down
1 change: 1 addition & 0 deletions login-workflow/example/src/contexts/AppContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type LoginData = {

export type AppContextType = {
isAuthenticated: boolean;
setIsAuthenticated: (isAuthenticated: boolean) => void;
loginData: LoginData;
onUserAuthenticated: (args: { email: string; userId: string; rememberMe: boolean }) => void;
onUserNotAuthenticated: (clearRememberMe?: boolean, overrideRememberMeEmail?: string) => void;
Expand Down
126 changes: 3 additions & 123 deletions login-workflow/example/src/navigation/AppRouter.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,15 @@
import React, { useCallback } from 'react';
import {
AuthContextProvider,
OktaAuthContextProvider,
ContactSupportScreen,
ReactRouterAuthGuard,
ReactRouterGuestGuard,
ForgotPasswordScreen,
RegistrationContextProvider,
ResetPasswordScreen,
RegistrationWorkflow,
} from '@brightlayer-ui/react-auth-workflow';
import { useApp } from '../contexts/AppContextProvider';
import { useNavigate } from 'react-router';
import { ProjectAuthUIActions } from '../actions/AuthUIActions';
import { Navigate, Outlet, Route, Routes, To } from 'react-router-dom';
import { ProjectRegistrationUIActions } from '../actions/RegistrationUIActions';
import { routes } from './Routing';
import { ExampleHome } from '../screens/ExampleHome';
import i18nAppInstance from '../translations/i18n';
import { ChangePassword } from '../components/ChangePassword';
import { To } from 'react-router-dom';
import { Security } from '@okta/okta-react';
import OktaAuth, { OktaAuthOptions, toRelativeUrl } from '@okta/okta-auth-js';
import oktaConfig from '../oktaConfig';
import { OktaLogin } from '../screens/OktaRedirectLogin';
import { MainRouter } from './MainRouter';

const oktaAuth = new OktaAuth(oktaConfig as OktaAuthOptions);

export const AppRouter: React.FC = () => {
const navigation = useNavigate();
const app = useApp();
const { email, rememberMe } = app.loginData;
const navigate = useCallback((destination: -1 | string) => {
navigation(destination as To);
}, []);
Expand All @@ -40,107 +20,7 @@ export const AppRouter: React.FC = () => {

return (
<Security oktaAuth={oktaAuth} restoreOriginalUri={restoreOriginalUri}>
<Routes>
{/* AUTH ROUTES */}
<Route
element={
<AuthContextProvider
actions={ProjectAuthUIActions(app)}
language={app.language}
navigate={navigate}
routeConfig={routes}
i18n={i18nAppInstance}
rememberMeDetails={{ email: rememberMe ? email : '', rememberMe: rememberMe }}
>
<Outlet />
</AuthContextProvider>
}
>
<Route
path={'/login'}
element={
<ReactRouterGuestGuard isAuthenticated={app.isAuthenticated} fallBackUrl={'/'}>
<OktaAuthContextProvider
language={app.language}
navigate={navigate}
routeConfig={routes}
i18n={i18nAppInstance}
>
<OktaLogin />
</OktaAuthContextProvider>
</ReactRouterGuestGuard>
}
/>
<Route
path={'/forgot-password'}
element={
<ReactRouterGuestGuard isAuthenticated={app.isAuthenticated} fallBackUrl={'/'}>
<ForgotPasswordScreen />
</ReactRouterGuestGuard>
}
/>
<Route
path={'/contact-support'}
element={
<ReactRouterGuestGuard isAuthenticated={app.isAuthenticated} fallBackUrl={'/'}>
<ContactSupportScreen />
</ReactRouterGuestGuard>
}
/>
<Route
path={'/reset-password'}
element={
<ReactRouterGuestGuard isAuthenticated={app.isAuthenticated} fallBackUrl={'/'}>
<ResetPasswordScreen />
</ReactRouterGuestGuard>
}
/>
{/* USER APPLICATION ROUTES */}
<Route
element={
<>
<Outlet />
{app.showChangePasswordDialog && <ChangePassword />}
</>
}
>
<Route
path={'/homepage'}
element={
<ReactRouterAuthGuard isAuthenticated={app.isAuthenticated} fallBackUrl={'/login'}>
<ExampleHome />
</ReactRouterAuthGuard>
}
/>
<Route path={'/'} element={<Navigate to={'/homepage'} replace />} />
</Route>
<Route
path={'*'}
element={
<ReactRouterAuthGuard isAuthenticated={app.isAuthenticated} fallBackUrl={'/login'}>
<Navigate to={'/login'} />
</ReactRouterAuthGuard>
}
/>
</Route>
{/* REGISTRATION ROUTES */}
<Route
element={
<RegistrationContextProvider
language={app.language}
routeConfig={routes}
navigate={navigate}
actions={ProjectRegistrationUIActions()}
i18n={i18nAppInstance}
>
<Outlet />
</RegistrationContextProvider>
}
>
<Route path={'/self-registration'} element={<RegistrationWorkflow />} />
<Route path={'/register-by-invite'} element={<RegistrationWorkflow isInviteRegistration />} />
</Route>
</Routes>
<MainRouter />
</Security>
);
};
155 changes: 155 additions & 0 deletions login-workflow/example/src/navigation/MainRouter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import React, { useCallback, useEffect } from 'react';
import {
AuthContextProvider,
OktaAuthContextProvider,
ContactSupportScreen,
ReactRouterAuthGuard,
ReactRouterGuestGuard,
ForgotPasswordScreen,
RegistrationContextProvider,
ResetPasswordScreen,
RegistrationWorkflow,
} from '@brightlayer-ui/react-auth-workflow';
import { useApp } from '../contexts/AppContextProvider';
import { useNavigate } from 'react-router';
import { ProjectAuthUIActions } from '../actions/AuthUIActions';
import { Navigate, Outlet, Route, Routes, To } from 'react-router-dom';
import { ProjectRegistrationUIActions } from '../actions/RegistrationUIActions';
import { routes } from './Routing';
import { ExampleHome } from '../screens/ExampleHome';
import i18nAppInstance from '../translations/i18n';
import { ChangePassword } from '../components/ChangePassword';
import { OktaLogin } from '../screens/OktaRedirectLogin';
import { useOktaAuth, LoginCallback } from '@okta/okta-react';

export const MainRouter: React.FC = () => {
const navigation = useNavigate();
const app = useApp();
const { email, rememberMe } = app.loginData;
const navigate = useCallback((destination: -1 | string) => {
navigation(destination as To);
}, []);
const { authState } = useOktaAuth();

const { setIsAuthenticated } = useApp();

useEffect(() => {
if (authState && authState.isAuthenticated) {
setIsAuthenticated(true);
} else {
setIsAuthenticated(false);
}
}, [authState, setIsAuthenticated]);

return (
<Routes>
{/* AUTH ROUTES */}
<Route
element={
<AuthContextProvider
actions={ProjectAuthUIActions(app)}
language={app.language}
navigate={navigate}
routeConfig={routes}
i18n={i18nAppInstance}
rememberMeDetails={{ email: rememberMe ? email : '', rememberMe: rememberMe }}
>
<Outlet />
</AuthContextProvider>
}
>
<Route
path={'/login'}
element={
<ReactRouterGuestGuard isAuthenticated={app.isAuthenticated} fallBackUrl={'/'}>
<OktaAuthContextProvider
language={app.language}
navigate={navigate}
routeConfig={routes}
i18n={i18nAppInstance}
>
<OktaLogin />
</OktaAuthContextProvider>
</ReactRouterGuestGuard>
}
/>
<Route
path={'/forgot-password'}
element={
<ReactRouterGuestGuard isAuthenticated={app.isAuthenticated} fallBackUrl={'/'}>
<ForgotPasswordScreen />
</ReactRouterGuestGuard>
}
/>
<Route
path={'/contact-support'}
element={
<ReactRouterGuestGuard isAuthenticated={app.isAuthenticated} fallBackUrl={'/'}>
<ContactSupportScreen />
</ReactRouterGuestGuard>
}
/>
<Route
path={'/reset-password'}
element={
<ReactRouterGuestGuard isAuthenticated={app.isAuthenticated} fallBackUrl={'/'}>
<ResetPasswordScreen />
</ReactRouterGuestGuard>
}
/>
{/* USER APPLICATION ROUTES */}
<Route
element={
<>
<Outlet />
{app.showChangePasswordDialog && <ChangePassword />}
</>
}
>
<Route
path={'/login/callback'}
element={
<ReactRouterGuestGuard isAuthenticated={app.isAuthenticated} fallBackUrl={'/'}>
<LoginCallback />
</ReactRouterGuestGuard>
}
/>
<Route
path={'/homepage'}
element={
<ReactRouterAuthGuard isAuthenticated={app.isAuthenticated} fallBackUrl={'/login'}>
<ExampleHome />
</ReactRouterAuthGuard>
}
/>
<Route path={'/'} element={<Navigate to={'/homepage'} replace />} />
</Route>
<Route
path={'*'}
element={
<ReactRouterAuthGuard isAuthenticated={app.isAuthenticated} fallBackUrl={'/login'}>
<Navigate to={'/login'} />
</ReactRouterAuthGuard>
}
/>
</Route>
{/* REGISTRATION ROUTES */}
<Route
element={
<RegistrationContextProvider
language={app.language}
routeConfig={routes}
navigate={navigate}
actions={ProjectRegistrationUIActions()}
i18n={i18nAppInstance}
>
<Outlet />
</RegistrationContextProvider>
}
>
<Route path={'/self-registration'} element={<RegistrationWorkflow />} />
<Route path={'/register-by-invite'} element={<RegistrationWorkflow isInviteRegistration />} />
</Route>
</Routes>
);
};
11 changes: 8 additions & 3 deletions login-workflow/example/src/screens/ExampleHome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import * as Colors from '@brightlayer-ui/colors';
import FormControl from '@mui/material/FormControl';
import { MenuItem, Select, SelectChangeEvent } from '@mui/material';
import i18n from '../translations/i18n';
import { useOktaAuth } from '@okta/okta-react';

export const ExampleHome: React.FC<React.PropsWithChildren> = () => {
const app = useApp();
Expand All @@ -39,7 +40,8 @@ export const ExampleHome: React.FC<React.PropsWithChildren> = () => {
const [open, setOpen] = useState(false);
const navigate = useNavigate();
const theme = useTheme();

const { oktaAuth } = useOktaAuth();

const containerStyles = {
width: '100%',
height: `calc(100vh - ${theme.spacing(8)})`,
Expand All @@ -64,9 +66,12 @@ export const ExampleHome: React.FC<React.PropsWithChildren> = () => {
justifyContent: 'center',
};

const logOut = (): void => {
const logOut = async (): Promise<void> => {
await oktaAuth.signOut();
LocalStorage.clearAuthCredentials();
app.onUserNotAuthenticated();
app.setIsAuthenticated(false);

navigate('/login');
};

Expand Down Expand Up @@ -152,7 +157,7 @@ export const ExampleHome: React.FC<React.PropsWithChildren> = () => {
icon: <ExitToApp />,
title: `${t('USER_MENU.LOG_OUT')}`,
onClick: (): void => {
logOut();
void logOut();
},
},
],
Expand Down
4 changes: 3 additions & 1 deletion login-workflow/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@brightlayer-ui/react-auth-workflow",
"version": "5.0.0-beta.2",
"version": "5.0.0",
"author": "Brightlayer UI <[email protected]> (https://github.com/brightlayer-ui)",
"license": "BSD-3-Clause",
"description": "Re-usable workflow components for Authentication and Registration within Eaton applications.",
Expand Down Expand Up @@ -37,6 +37,8 @@
"@emotion/styled": "^11.6.0",
"@mui/icons-material": "^5.10.15",
"@mui/material": "^5.10.15",
"@okta/okta-auth-js": "^7.7.0",
"@okta/okta-react": "^6.9.0",
"date-fns": "^3.0.6",
"i18next": "^23.0.1",
"react": "^16.13.1 || ^17.0.0 || ^18.0.0",
Expand Down

0 comments on commit d78026f

Please sign in to comment.