Skip to content

Commit

Permalink
feat: 201 - Logout button + cleanup (#214)
Browse files Browse the repository at this point in the history
  • Loading branch information
tim738745 authored Mar 12, 2024
1 parent 4027640 commit 3a66850
Show file tree
Hide file tree
Showing 15 changed files with 157 additions and 132 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ TEST-*xml
venv/
coverage/
minio/minio_files/cthub/
decoder.env
decoder.env
docker-compose-local-dev.yml
22 changes: 8 additions & 14 deletions react/src/App.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import 'regenerator-runtime/runtime';
import axios from 'axios';
import React from 'react';
import {
Redirect,
BrowserRouter as Router,
Route,
Switch,
Expand All @@ -12,18 +10,18 @@ import settings from './app/settings';
import IcbcDataRouter from './icbc_data/router';
import UploadRouter from './uploads/router';
import DashboardContainer from './dashboard/DashboardContainer';
import useKeycloak from './app/utilities/useKeycloak'
import Login from './Login';

const { API_BASE } = settings;

axios.defaults.baseURL = API_BASE;
const { ENABLE_KEYCLOAK } = settings;

const App = () => {
const { sessionStorage } = window;
const redirect = sessionStorage.getItem('redirect');
if (redirect && redirect !== '') {
sessionStorage.removeItem('redirect');
const keycloak = useKeycloak()

if (ENABLE_KEYCLOAK && !keycloak.authenticated) {
const redirectUri = window.location.href
return <Login redirectUri={redirectUri}/>
}

return (
<div className="App">
<header className="App-header">
Expand All @@ -35,10 +33,6 @@ const App = () => {
</header>
<div className="App-body">
<Router>
{redirect && redirect !== '' && (
<Redirect to={redirect} />
)}

<Switch>
{IcbcDataRouter()}
{UploadRouter()}
Expand Down
16 changes: 12 additions & 4 deletions react/src/Login.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import React from 'react';
import CustomPropTypes from './app/utilities/props';
import PropTypes from 'prop-types';
import useKeycloak from './app/utilities/useKeycloak';

const Login = (props) => {
const { keycloak } = props;
const { redirectUri } = props;
const loginOptions = {
idpHint: 'idir'
}
if (redirectUri) {
loginOptions.redirectUri = redirectUri
}
const keycloak = useKeycloak()

return (
<div id="login-page">
Expand All @@ -13,7 +21,7 @@ const Login = (props) => {
<div className="flex-container">
<div className="brand-logo" />
<div className="buttons-section">
<button type="button" onClick={() => keycloak.login({ idpHint: 'idir' })} id="link-idir" className="button">
<button type="button" onClick={() => keycloak.login(loginOptions)} id="link-idir" className="button">
<span className="text"> Login with </span>
<span className="display-name"> IDIR </span>
</button>
Expand All @@ -25,7 +33,7 @@ const Login = (props) => {
};

Login.propTypes = {
keycloak: CustomPropTypes.keycloak.isRequired,
redirectUri: PropTypes.string
};

export default Login;
29 changes: 29 additions & 0 deletions react/src/app/components/KeycloakProvider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, { useState, useEffect } from 'react'
import { KeycloakContext } from '../../contexts'
import settings from '../settings'

const KeycloakProvider = ({authClient, initOptions, LoadingComponent, children}) => {
const keycloakEnabled = settings.ENABLE_KEYCLOAK
const [loading, setLoading] = useState(keycloakEnabled ? true : false)
const [keycloak, setKeycloak] = useState({})

useEffect(() => {
if (keycloakEnabled) {
authClient.init(initOptions).then(() => {
setKeycloak(authClient)
setLoading(false)
})
}
}, [keycloakEnabled, authClient, initOptions])

if (loading) {
return <LoadingComponent/>
}
return (
<KeycloakContext.Provider value={keycloak}>
{children}
</KeycloakContext.Provider>
)
}

export default KeycloakProvider
12 changes: 12 additions & 0 deletions react/src/app/components/Loading.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react'
import { CircularProgress } from '@mui/material'

const Loading = () => {
return (
<div>
<CircularProgress color="inherit" />
</div>
)
}

export default Loading
20 changes: 20 additions & 0 deletions react/src/app/components/Logout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import useKeycloak from '../utilities/useKeycloak'

const Logout = () => {
const keycloak = useKeycloak();
if (keycloak.authenticated) {
return (
<button
onClick={() => {
keycloak.logout()
}}
>
Log out
</button>
)
}
return null
}

export default Logout
30 changes: 30 additions & 0 deletions react/src/app/utilities/useAxios.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import axios from 'axios'
import settings from '../settings';
import useKeycloak from './useKeycloak'

const useAxios = (useDefault = false, opts = {}) => {
if (useDefault) {
return axios.create(opts)
}
const keycloak = useKeycloak()
const instance = axios.create({
baseURL: settings.API_BASE,
...opts,
})
instance.interceptors.request.use(async (config) => {
if (keycloak.authenticated) {
try {
await keycloak.updateToken(30)
config.headers = {
'Authorization': `Bearer ${keycloak.token}`,
}
} catch(error) {
// do something here?
}
}
return config
})
return instance
}

export default useAxios
9 changes: 9 additions & 0 deletions react/src/app/utilities/useKeycloak.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useContext } from 'react'
import { KeycloakContext } from '../../contexts'

const useKeycloak = () => {
const keycloak = useContext(KeycloakContext)
return keycloak
}

export default useKeycloak
3 changes: 3 additions & 0 deletions react/src/contexts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { createContext } from 'react'

export const KeycloakContext = createContext({})
3 changes: 2 additions & 1 deletion react/src/icbc_data/IcbcDataContainer.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import axios from 'axios';
import React, { useCallback, useRef, useState } from 'react';
import { withRouter } from 'react-router-dom';

import { getFilters, getOrderBy } from '../app/utilities/reactTable';
import IcbcDataTable from './components/IcbcDataTable';
import ROUTES from './routes';
import useAxios from '../app/utilities/useAxios';

const IcbcDataContainer = () => {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const [pageCount, setPageCount] = useState(-1);
const [totalRowsCount, setTotalRowsCount] = useState(0);
const fetchIdRef = useRef(0);
const axios = useAxios()

const onFetchData = useCallback((state) => {
setLoading(true);
Expand Down
32 changes: 20 additions & 12 deletions react/src/index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
import React from 'react';
import ReactDOM from 'react-dom';
import ReactDOM from 'react-dom'
import Keycloak from 'keycloak-js';

import Keycloak from './keycloak';
import settings from './app/settings';
import KeycloakProvider from './app/components/KeycloakProvider';
import App from './App';
import Loading from './app/components/Loading';

import './app/styles/index.scss';

import App from './App';

if (settings.ENABLE_KEYCLOAK) {
ReactDOM.render(
<Keycloak />,
document.getElementById('root'),
);
} else {
ReactDOM.render(<App />, document.getElementById('root'));
const keycloak = new Keycloak()
const keycloakInitOptions = {
onLoad: 'check-sso',
pkceMethod: 'S256'
}

ReactDOM.render(
<KeycloakProvider
authClient={keycloak}
initOptions={keycloakInitOptions}
LoadingComponent={Loading}
>
<App />
</KeycloakProvider>,
document.getElementById('root')
)
87 changes: 0 additions & 87 deletions react/src/keycloak.js

This file was deleted.

Loading

0 comments on commit 3a66850

Please sign in to comment.