Skip to content

Commit 734d3be

Browse files
authored
Merge pull request #765 from bcgov/anton/use-auto-sign-in-hook
feat: SRS-859 - useAutoSignin hook + auth flow fixes
2 parents 0ea21e0 + 9d5d2ac commit 734d3be

File tree

10 files changed

+115
-91
lines changed

10 files changed

+115
-91
lines changed

cats-frontend/package-lock.json

Lines changed: 28 additions & 37 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cats-frontend/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"graphql-tag": "^2.12.6",
2121
"keycloak-js": "^19.0.2",
2222
"leaflet": "^1.9.3",
23-
"oidc-client-ts": "^2.1.0",
23+
"oidc-client-ts": "3.1.0",
2424
"prettier": "^3.3.3",
2525
"react": "^18.2.0",
2626
"react-aria-components": "^1.6.0",
@@ -30,7 +30,7 @@
3030
"react-icons": "^4.12.0",
3131
"react-leaflet": "^4.2.1",
3232
"react-leaflet-cluster": "^2.1.0",
33-
"react-oidc-context": "^2.3.1",
33+
"react-oidc-context": "3.2.0",
3434
"react-parcelmap-bc": "^1.1.4",
3535
"react-redux": "^8.0.2",
3636
"react-router-dom": "^6.4.1",

cats-frontend/src/App.tsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ import "./App.css";
22
import Header from "./app/components/navigation/Header";
33
import { Outlet } from "react-router-dom";
44
import { ToastContainer } from "react-toastify";
5-
import "react-toastify/dist/ReactToastify.css";
65
import SideBar from "./app/components/navigation/SideBar";
7-
import '@bcgov/bc-sans/css/BC_Sans.css'
86
import { useState } from "react";
7+
import { useAutoSignin } from "./hooks/useAutoSignIn";
8+
9+
import "react-toastify/dist/ReactToastify.css";
10+
import "@bcgov/design-tokens/css/variables.css";
11+
import "@bcgov/bc-sans/css/BC_Sans.css";
912

1013
function App() {
1114
const [isSidebarExpanded, setIsSidebarExpanded] = useState(false);
@@ -14,21 +17,27 @@ function App() {
1417
const handleMouseEnter = () => setIsSidebarExpanded(true);
1518
const handleMouseLeave = () => setIsSidebarExpanded(false);
1619

17-
18-
1920
// Toggle sidebar expand/collapse on hover or click
2021
const handleSidebarToggle = () => {
2122
setIsSidebarExpanded((prevState) => !prevState);
2223
};
2324

25+
useAutoSignin();
26+
2427
return (
2528
<div className="container-fluid p-0">
2629
<Header />
2730
<div className="container m-0 p-0">
28-
<div className={`sidebar-container display-from-medium ${isSidebarExpanded ? "expanded" : ""}`} onMouseEnter={handleSidebarToggle} onMouseLeave={handleSidebarToggle}>
29-
<SideBar />
31+
<div
32+
className={`sidebar-container display-from-medium ${isSidebarExpanded ? "expanded" : ""}`}
33+
onMouseEnter={handleSidebarToggle}
34+
onMouseLeave={handleSidebarToggle}
35+
>
36+
<SideBar />
3037
</div>
31-
<div className={`p-0 main-content-container ${isSidebarExpanded ? "shifted" : ""}`}>
38+
<div
39+
className={`p-0 main-content-container ${isSidebarExpanded ? "shifted" : ""}`}
40+
>
3241
<Outlet />
3342
</div>
3443
</div>

cats-frontend/src/app/components/account/UserAccount.tsx

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,18 @@ import Dropdown from 'react-bootstrap/Dropdown';
33
import './UserAccount.css';
44
import { DropdownIcon, DropdownUpIcon } from '../common/icon';
55
import { useAuth } from 'react-oidc-context';
6-
import { getUser } from '../../helpers/utility';
76
import Avatar from '../avatar/Avatar';
87
import { useDispatch } from 'react-redux';
98
import { AppDispatch } from '../../Store';
109
import { fetchRecentViews } from '../../features/dashboard/DashboardSlice';
1110

1211
const UserAccount = (props: any) => {
1312
const dispatch = useDispatch<AppDispatch>();
14-
const authRedirectUri =
15-
((window as any)._env_ &&
16-
(window as any)._env_.REACT_APP_AUTH_LOGOUT_REDIRECT_URI) ||
17-
process.env.REACT_APP_AUTH_LOGOUT_REDIRECT_URI ||
18-
'http://localhost:4000/';
1913
const auth = useAuth();
20-
const loggedInUser = getUser();
2114
// Sample user data
2215
const userObj = {
23-
firstname: loggedInUser?.profile.given_name,
24-
lastName: loggedInUser?.profile.family_name,
16+
firstname: auth.user?.profile.given_name,
17+
lastName: auth.user?.profile.family_name,
2518
};
2619

2720
const [user, setUser] = useState(userObj);
@@ -32,13 +25,21 @@ const UserAccount = (props: any) => {
3225
};
3326

3427
useEffect(() => {
35-
dispatch(fetchRecentViews(loggedInUser?.profile.preferred_username ?? ''));
28+
dispatch(fetchRecentViews(auth.user?.profile.preferred_username ?? ''));
3629
setUser({
37-
firstname: loggedInUser?.profile.given_name,
38-
lastName: loggedInUser?.profile.family_name,
30+
firstname: auth.user?.profile.given_name,
31+
lastName: auth.user?.profile.family_name,
3932
});
4033
}, []);
4134

35+
const signOut = () => {
36+
auth.removeUser();
37+
auth.signoutRedirect({
38+
id_token_hint: auth.user?.id_token,
39+
});
40+
auth.clearStaleState();
41+
}
42+
4243
if (props.mobileView) {
4344
return (
4445
<>
@@ -95,11 +96,7 @@ const UserAccount = (props: any) => {
9596
aria-label="Log Out"
9697
tabIndex={0} // Make focusable with keyboard
9798
className="account-custom-item-mobile"
98-
onClick={() => {
99-
auth.removeUser().then(() => {
100-
window.location.href = authRedirectUri;
101-
});
102-
}}
99+
onClick={signOut}
103100
>
104101
Log Out
105102
</div>
@@ -176,12 +173,7 @@ const UserAccount = (props: any) => {
176173
role="menuitem"
177174
className="account-custom-item"
178175
aria-label="Log Out"
179-
onClick={() => {
180-
auth.removeUser().then(() => {
181-
window.location.href = authRedirectUri;
182-
localStorage.removeItem('siteFilterPills');
183-
});
184-
}}
176+
onClick={signOut}
185177
>
186178
Log Out
187179
</Dropdown.Item>

cats-frontend/src/app/components/login/LoginDropdown.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Dropdown } from 'react-bootstrap';
22
import { useAuth } from 'react-oidc-context';
33
import './LoginDropdown.css';
44

5-
export const LoginDropdown = (title: string, width_override?: number) => {
5+
export const LoginDropdown = ({title}: {title: string}) => {
66
const auth = useAuth();
77
return (
88
<Dropdown id="login-selector-dropdown">

cats-frontend/src/app/components/navigation/Header.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
1-
import "@bcgov/design-tokens/css/variables.css";
21
import logo from "../../../app/images/logos/logo-banner.png";
32

43
import "./Header.css";
5-
import moon from "../../images/moon.png";
64
import { BarsIcon } from "../common/icon";
75
import { useState } from "react";
86
import MobileNavMenu from "./MobileNavMenu";
9-
import LanguageSwitcher from "../language/LanguageSwitcher";
107
import UserAccount from "../account/UserAccount";
118
import { LoginDropdown } from "../login/LoginDropdown";
12-
import { getUser } from "../../helpers/utility";
9+
import { useAuth } from "react-oidc-context";
1310

1411
const Header = () => {
1512
const [isOpen, setIsOpen] = useState(false);
1613

17-
const user = getUser();
14+
const auth = useAuth()
1815

1916
const toggleNavbar = () => {
2017
setIsOpen(!isOpen);
@@ -48,8 +45,8 @@ const Header = () => {
4845
{/* <div className="d-sm-none d-md-flex d-none">
4946
<img src={moon} alt="Moon image for theme." />
5047
</div> */}
51-
{user == null && LoginDropdown("Sign in")}
52-
{!isOpen && user !== null && <UserAccount mobileView={isOpen} />}
48+
{!auth.isAuthenticated && <LoginDropdown title="Sign in" />}
49+
{!isOpen && auth.isAuthenticated && <UserAccount mobileView={isOpen} />}
5350
</div>
5451
<div
5552
role="menu"

cats-frontend/src/app/features/people/Search.tsx

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React, { useState, useEffect } from "react";
22
import "./Search.css";
3-
import "@bcgov/design-tokens/css/variables.css";
43
import { useSelector, useDispatch } from "react-redux";
54
import {
65
fetchPeoples,
@@ -109,17 +108,6 @@ const Search = () => {
109108
);
110109
};
111110

112-
useEffect(() => {
113-
const loggedInUser = getUser();
114-
if (loggedInUser === null) {
115-
auth.signinRedirect({ extraQueryParams: { kc_idp_hint: "idir" } });
116-
}
117-
if (currSearchVal.searchQuery !== "") {
118-
setUserAction(false);
119-
setSearchText(currSearchVal.searchQuery);
120-
dispatch(fetchPeoples({ searchParam: currSearchVal.searchQuery }));
121-
}
122-
}, []);
123111

124112
// useEffect(() => {
125113
// fetchPeoples(searchText);

cats-frontend/src/app/helpers/utility.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ export const flattenFormRows = (arr: IFormField[][]): IFormField[] => {
8484
return flattened;
8585
};
8686

87+
// This should only be used outside of the <AuthContext> component tree (redux slice, axios calls, etc)
88+
// In React components, use `const {user} = useAuth()`
8789
export function getUser() {
8890
const oidcStorage = sessionStorage.getItem(
8991
`oidc.user:` +

0 commit comments

Comments
 (0)