Skip to content

Commit

Permalink
Switch PrivateRoute to RequireAuthentication using newer react-router…
Browse files Browse the repository at this point in the history
… concepts.

Signed-off-by: Michael Nelson <minelson@vmware.com>
  • Loading branch information
absoludity committed Jul 12, 2023
1 parent 1d84082 commit b13c806
Show file tree
Hide file tree
Showing 15 changed files with 269 additions and 191 deletions.
2 changes: 2 additions & 0 deletions dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@paciolan/remote-component": "^2.13.0",
"@tanstack/match-sorter-utils": "^8.7.6",
"@tanstack/react-table": "^8.9.3",
"@testing-library/jest-dom": "^5.16.5",
"@types/react": "^17.0.39",
"ajv": "^8.12.0",
"axios": "^1.3.5",
Expand Down Expand Up @@ -81,6 +82,7 @@
"@bufbuild/protoc-gen-es": "^1.2.1",
"@craco/craco": "^7.0.0",
"@formatjs/cli": "^6.0.4",
"@reduxjs/toolkit": "^1.9.5",
"@testing-library/react": "^12.1.5",
"@types/enzyme": "^3.10.12",
"@types/jest": "^29.5.2",
Expand Down
78 changes: 0 additions & 78 deletions dashboard/src/components/PrivateRoute/PrivateRoute.test.tsx

This file was deleted.

57 changes: 0 additions & 57 deletions dashboard/src/components/PrivateRoute/PrivateRoute.tsx

This file was deleted.

6 changes: 0 additions & 6 deletions dashboard/src/components/PrivateRoute/index.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright 2018-2022 the Kubeapps contributors.
// SPDX-License-Identifier: Apache-2.0

import { createMemoryHistory } from "history";
import { Route, Router } from "react-router-dom";
import { renderWithProviders } from "shared/specs/mountWrapper";
import { RequireAuthentication } from "./RequireAuthentication";
import { screen } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";

it("redirects to the /login route if not authenticated", () => {
renderWithProviders((
<Router history={createMemoryHistory()}>
<RequireAuthentication>
<h1>Authenticated</h1>
</RequireAuthentication>
<Route path="/login">
<h1>Login</h1>
</Route>
</Router>
), {
preloadedState: {
auth: {
authenticated: false,
sessionExpired: false,
}
}
});

expect(screen.getByRole("heading")).toHaveTextContent("Login");
});

it("renders the given component when authenticated", () => {
renderWithProviders((
<Router history={createMemoryHistory()}>
<RequireAuthentication>
<h1>Authenticated</h1>
</RequireAuthentication>
<Route path="/login">
<h1>Login</h1>
</Route>
</Router>
), {
preloadedState: {
auth: {
authenticated: true,
sessionExpired: false,
}
}
});

expect(screen.getByRole("heading")).toHaveTextContent("Authenticated");
});

it("renders modal to reload the page if the session is expired", () => {
renderWithProviders((
<Router history={createMemoryHistory()}>
<RequireAuthentication>
<h1>Authenticated</h1>
</RequireAuthentication>
<Route path="/login">
<h1>Login</h1>
</Route>
</Router>
), {
preloadedState: {
auth: {
authenticated: false,
sessionExpired: true,
}
}
});

expect(screen.getByRole("dialog")).toHaveTextContent("Your session has expired");
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2018-2022 the Kubeapps contributors.
// SPDX-License-Identifier: Apache-2.0

import { CdsButton } from "@cds/react/button";
import { CdsModal, CdsModalActions, CdsModalContent } from "@cds/react/modal";
import { ReactElement } from "react";
import { Redirect, useLocation } from "react-router-dom";
import "./RequireAuthentication.css";
import { useSelector } from "react-redux";
import { IStoreState } from "shared/types";

interface IRequireAuthenticationProps {
children: ReactElement;
}

export function RequireAuthentication({
children,
}: IRequireAuthenticationProps): ReactElement {
const { authenticated, sessionExpired } = useSelector((state: IStoreState) => state.auth)
const refreshPage = () => {
window.location.reload();
};
const location = useLocation();
if (authenticated && children) {
return children;
} else {
return (
<>
{" "}
{sessionExpired ? (
<CdsModal closable={false} onCloseChange={refreshPage}>
<CdsModalContent>
{" "}
<p>
Your session has expired or the connection has been lost, please reload the page.
</p>
</CdsModalContent>
<CdsModalActions>
<CdsButton onClick={refreshPage} type="button">
Reload
</CdsButton>
</CdsModalActions>
</CdsModal>
) : (
<Redirect to={{ pathname: "/login", state: { from: location.pathname } }} />
)
}
</>
);
}
};

export default RequireAuthentication;
6 changes: 6 additions & 0 deletions dashboard/src/components/RequireAuthentication/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright 2018-2022 the Kubeapps contributors.
// SPDX-License-Identifier: Apache-2.0

import RequireAuthentication from "./RequireAuthentication";

export default RequireAuthentication;

This file was deleted.

6 changes: 0 additions & 6 deletions dashboard/src/containers/PrivateRouteContainer/index.ts

This file was deleted.

26 changes: 17 additions & 9 deletions dashboard/src/containers/RoutesContainer/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import {
RouteComponentProps,
RouteProps,
Switch,
useLocation,
useParams,
} from "react-router-dom";
import { app } from "shared/url";
import ApiDocs from "../../components/ApiDocs";
Expand All @@ -32,7 +30,7 @@ import OperatorInstanceViewContainer from "../../containers/OperatorInstanceView
import OperatorNewContainer from "../../containers/OperatorNewContainer";
import OperatorsListContainer from "../../containers/OperatorsListContainer";
import OperatorViewContainer from "../../containers/OperatorViewContainer";
import PrivateRouteContainer from "../../containers/PrivateRouteContainer";
import RequireAuthentication from "components/RequireAuthentication";

type IRouteComponentPropsAndRouteProps = RouteProps & RouteComponentProps<any>;

Expand Down Expand Up @@ -90,19 +88,29 @@ class Routes extends React.Component<IRoutesProps> {
{Object.entries(privateRoutes).map(([route, component]) => {
const Component = component;
return (
<PrivateRouteContainer key={route} exact={true} path={route}>
<Component />
</PrivateRouteContainer>
<Route key={route} exact={true} path={route} render={() => {
return (
<RequireAuthentication>
<Component />
</RequireAuthentication>
)
}
} />
)
}
)}
{this.props.featureFlags?.operators &&
Object.entries(operatorsRoutes).map(([route, component]) => {
const Component = component;
return (
<PrivateRouteContainer key={route} exact={true} path={route}>
<Component />
</PrivateRouteContainer>
<Route key={route} exact={true} path={route} render={() => {
return (
<RequireAuthentication>
<Component />
</RequireAuthentication>
)
}
} />
)
}
)}
Expand Down
Loading

0 comments on commit b13c806

Please sign in to comment.