diff --git a/src/Routes.js b/src/Routes.js index 90fc4557..c3d783ca 100644 --- a/src/Routes.js +++ b/src/Routes.js @@ -31,6 +31,8 @@ const ReportView = asyncComponent(() => import(/* webpackChunkName: "ReportView" */ './pages/ReportView')); const ErrorPage = asyncComponent(() => import(/* webpackChunkName: "ErrorPage" */ './pages/ErrorPage')); +const ErrorPage403 = asyncComponent(() => + import(/* webpackChunkName: "ErrorPage403" */ './pages/ErrorPage403')); const paths = { gettingStarted: '/getting-started', @@ -38,7 +40,8 @@ const paths = { noReports: '/no-reports', reportsUpload: '/reports/upload', reportView: '/reports/:reportId', - error: '/error' + error: '/error', + error403: '/error403' }; type Props = { @@ -83,6 +86,7 @@ export const Routes = (props: Props) => { + { /* Finally, catch all unmatched routes */ } some(paths, p => p === path) ? null : () }/> diff --git a/src/api/apiInit.tsx b/src/api/apiInit.tsx index 2df7f9e0..560dec97 100644 --- a/src/api/apiInit.tsx +++ b/src/api/apiInit.tsx @@ -1,4 +1,5 @@ -import axios, { AxiosRequestConfig } from 'axios'; +import axios, { AxiosRequestConfig, AxiosError } from 'axios'; +import getBaseName from '../Utilities/getBaseName'; export const API_BASE_URL = '/api/xavier'; declare var insights: any; @@ -12,4 +13,11 @@ export const authInterceptor = (reqConfig: AxiosRequestConfig): AxiosRequestConf export const initApi = () => { axios.defaults.baseURL = `${API_BASE_URL}`; axios.interceptors.request.use(authInterceptor); + + axios.interceptors.response.use(undefined, (error: AxiosError) => { + if (error && error.response && (error.response.status === 403)) { + window.location.href = getBaseName(window.location.pathname) + '/error403'; + } + return Promise.reject(error); + }); }; diff --git a/src/pages/ErrorPage403/ErrorPage.test.tsx b/src/pages/ErrorPage403/ErrorPage.test.tsx new file mode 100644 index 00000000..1fa3e3e9 --- /dev/null +++ b/src/pages/ErrorPage403/ErrorPage.test.tsx @@ -0,0 +1,14 @@ +import React from "react"; +import { shallow } from "enzyme"; +import ErrorPage from "./ErrorPage403"; + +describe("ErrorPage403", () => { + + it("expect to render", () => { + const wrapper = shallow( + + ); + expect(wrapper).toMatchSnapshot(); + }); + +}); diff --git a/src/pages/ErrorPage403/ErrorPage403.tsx b/src/pages/ErrorPage403/ErrorPage403.tsx new file mode 100644 index 00000000..b3e8f455 --- /dev/null +++ b/src/pages/ErrorPage403/ErrorPage403.tsx @@ -0,0 +1,53 @@ +import React from 'react'; +import { Main, PageHeader, PageHeaderTitle } from '@redhat-cloud-services/frontend-components'; +import { + Bullseye, + EmptyState, + EmptyStateVariant, + EmptyStateIcon, + Title, + TitleLevel, + EmptyStateBody +} from '@patternfly/react-core'; +import { PrivateIcon } from '@patternfly/react-icons'; +import { Link } from 'react-router-dom'; + +interface StateToProps {} + +interface DispatchToProps {} + +interface Props extends StateToProps, DispatchToProps {} + +interface State {} + +class ErrorPage403 extends React.Component { + constructor(props: Props) { + super(props); + } + + public render() { + return ( + + + + +
+ + + + + Error: 403 Forbidden + + You tried to access a forbidden resource!. + + Home + + + +
+
+ ); + } +} + +export default ErrorPage403; diff --git a/src/pages/ErrorPage403/__snapshots__/ErrorPage.test.tsx.snap b/src/pages/ErrorPage403/__snapshots__/ErrorPage.test.tsx.snap new file mode 100644 index 00000000..a840bc1a --- /dev/null +++ b/src/pages/ErrorPage403/__snapshots__/ErrorPage.test.tsx.snap @@ -0,0 +1,39 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ErrorPage403 expect to render 1`] = ` + + + + + + + + + + Error: 403 Forbidden + + + You tried to access a forbidden resource!. + + + Home + + + + + +`; diff --git a/src/pages/ErrorPage403/index.tsx b/src/pages/ErrorPage403/index.tsx new file mode 100644 index 00000000..a10a6664 --- /dev/null +++ b/src/pages/ErrorPage403/index.tsx @@ -0,0 +1,3 @@ +import ErrorPage403 from './ErrorPage403'; + +export default ErrorPage403;