Skip to content

Commit

Permalink
Merge pull request #255 from MetroStar/persist-auth
Browse files Browse the repository at this point in the history
Persist SSO Auth
  • Loading branch information
jbouder committed Jun 24, 2024
2 parents 74e3a58 + 16f6e50 commit 87ab05b
Show file tree
Hide file tree
Showing 11 changed files with 46 additions and 4 deletions.
3 changes: 3 additions & 0 deletions src/components/header/header.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ describe('Header', () => {
test('should navigate away from home', async () => {
jest.spyOn(useAuthMock, 'default').mockReturnValue({
isSignedIn: true,
isLoading: false,
currentUserData: {} as User,
error: null,
signIn: jest.fn(),
Expand All @@ -50,6 +51,7 @@ describe('Header', () => {
test('should handle sign in', async () => {
jest.spyOn(useAuthMock, 'default').mockReturnValue({
isSignedIn: false,
isLoading: false,
currentUserData: {} as User,
error: null,
signIn: jest.fn(),
Expand All @@ -66,6 +68,7 @@ describe('Header', () => {
test('should handle sign out', async () => {
jest.spyOn(useAuthMock, 'default').mockReturnValue({
isSignedIn: true,
isLoading: false,
currentUserData: {} as User,
error: null,
signIn: jest.fn(),
Expand Down
18 changes: 18 additions & 0 deletions src/components/protected-route/protected-route.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ describe('ProtectedRoute', () => {
test('should render successfully when signed in', async () => {
jest.spyOn(useAuthMock, 'default').mockReturnValue({
isSignedIn: true,
isLoading: false,
currentUserData: {} as User,
error: null,
signIn: jest.fn(),
Expand All @@ -38,4 +39,21 @@ describe('ProtectedRoute', () => {
expect(baseElement).toBeTruthy();
});
});

test('should render loading when not signed in and loading', async () => {
jest.spyOn(useAuthMock, 'default').mockReturnValue({
isSignedIn: false,
isLoading: true,
currentUserData: {} as User,
error: null,
signIn: jest.fn(),
signOut: jest.fn(),
});

const { baseElement, getByText } = render(wrapperComponent);
await act(async () => {
expect(baseElement).toBeTruthy();
expect(getByText('Loading...')).toBeTruthy();
});
});
});
9 changes: 8 additions & 1 deletion src/components/protected-route/protected-route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ import useAuth from '@src/hooks/use-auth';
import { Navigate, Outlet } from 'react-router-dom';

export const ProtectedRoute = (): React.ReactElement => {
const { isSignedIn } = useAuth();
const { isSignedIn, isLoading } = useAuth();
if (isLoading)
return (
<div className="grid-container">
<div>Loading...</div>
</div>
);

return isSignedIn ? <Outlet /> : <Navigate to="/signin" />;
};
7 changes: 6 additions & 1 deletion src/hooks/use-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { User } from '../types/user';
const useAuth = () => {
const auth = useKeycloakAuth();
const [isSignedIn, setIsSignedIn] = useRecoilState<boolean>(signedIn);
const [isLoading, setIsLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>();
const [currentUserData, setCurrentUserDate] = useRecoilState<
User | undefined
Expand All @@ -29,6 +30,10 @@ const useAuth = () => {
}
}, [auth.isAuthenticated, setIsSignedIn]);

useEffect(() => {
setIsLoading(auth.isLoading);
}, [auth.isLoading, setIsSignedIn]);

useEffect(() => {
const profile = auth.user?.profile;
if (profile) {
Expand Down Expand Up @@ -72,7 +77,7 @@ const useAuth = () => {
}
};

return { isSignedIn, currentUserData, error, signIn, signOut };
return { isSignedIn, isLoading, currentUserData, error, signIn, signOut };
};

export default useAuth;
1 change: 1 addition & 0 deletions src/pages/dashboard/dashboard.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ describe('Dashboard', () => {
mock.onGet(new RegExp('/spacecraft')).reply(200, mockData);
jest.spyOn(useAuthMock, 'default').mockReturnValue({
isSignedIn: true,
isLoading: false,
currentUserData: {} as User,
error: null,
signIn: jest.fn(),
Expand Down
1 change: 1 addition & 0 deletions src/pages/details/details.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ describe('Details', () => {
mock.onGet(new RegExp('/spacecraft/*')).reply(200, mockData.items[0]);
jest.spyOn(useAuthMock, 'default').mockReturnValue({
isSignedIn: true,
isLoading: false,
currentUserData: {} as User,
error: null,
signIn: jest.fn(),
Expand Down
1 change: 1 addition & 0 deletions src/pages/home/home.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ describe('Home', () => {
test('should render with mock data', async () => {
jest.spyOn(useAuthMock, 'default').mockReturnValue({
isSignedIn: true,
isLoading: false,
currentUserData: { firstName: 'John', lastName: 'Doe' } as User,
error: null,
signIn: jest.fn(),
Expand Down
4 changes: 4 additions & 0 deletions src/pages/sign-in/sign-in.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ describe('SignIn', () => {
test('should simulate a successful login attempt', async () => {
jest.spyOn(useAuthMock, 'default').mockReturnValue({
isSignedIn: false,
isLoading: false,
currentUserData: {} as User,
error: null,
signIn: jest.fn(),
Expand All @@ -82,6 +83,7 @@ describe('SignIn', () => {
test('should simulate a successful login attempt when signed in', async () => {
jest.spyOn(useAuthMock, 'default').mockReturnValue({
isSignedIn: true,
isLoading: false,
currentUserData: {} as User,
error: null,
signIn: jest.fn(),
Expand All @@ -101,6 +103,7 @@ describe('SignIn', () => {
test('should simulate an unsuccessful login attempt', async () => {
jest.spyOn(useAuthMock, 'default').mockReturnValue({
isSignedIn: false,
isLoading: false,
currentUserData: {} as User,
error: 'Error',
signIn: jest.fn(),
Expand Down Expand Up @@ -128,6 +131,7 @@ describe('SignIn', () => {
test('should simulate an sso login', async () => {
jest.spyOn(useAuthMock, 'default').mockReturnValue({
isSignedIn: false,
isLoading: false,
currentUserData: {} as User,
error: null,
signIn: jest.fn(),
Expand Down
2 changes: 1 addition & 1 deletion src/utils/auth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe('Auth Helpers', () => {
});

const url = getSignInRedirectUrl();
expect(url).toEqual('http://localhost/signin');
expect(url).toEqual('http://localhost/dashboard');
});

test('should verify no SSL config', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const getDisplayName = (user: User): string => {
};

export const getSignInRedirectUrl = (): string => {
return `${window.location.origin}/signin`;
return `${window.location.origin}/dashboard`;
};

export const hasSsoConfig = (): boolean => {
Expand Down
2 changes: 2 additions & 0 deletions src/utils/keycloak.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { WebStorageStateStore } from 'oidc-client-ts';
import { getSignInRedirectUrl } from './auth';

const keycloak = {
authority: process.env.SSO_AUTHORITY ? process.env.SSO_AUTHORITY : '',
client_id: process.env.SSO_CLIENT_ID ? process.env.SSO_CLIENT_ID : '',
redirect_uri: getSignInRedirectUrl(),
userStore: new WebStorageStateStore({ store: window.localStorage }),
};

export default keycloak;

0 comments on commit 87ab05b

Please sign in to comment.