diff --git a/openmetadata-ui/src/main/resources/ui/src/App.tsx b/openmetadata-ui/src/main/resources/ui/src/App.tsx
index d02474d0a55..8dd5d1a159f 100644
--- a/openmetadata-ui/src/main/resources/ui/src/App.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/App.tsx
@@ -13,7 +13,7 @@
import ApplicationConfigProvider from 'components/ApplicationConfigProvider/ApplicationConfigProvider';
import { AuthProvider } from 'components/authentication/auth-provider/AuthProvider';
-import ErrorBoundry from 'components/ErrorBoundry/ErrorBoundry';
+import ErrorBoundary from 'components/ErrorBoundary/ErrorBoundary';
import GlobalSearchProvider from 'components/GlobalSearchProvider/GlobalSearchProvider';
import PermissionProvider from 'components/PermissionProvider/PermissionProvider';
import AppRouter from 'components/router/AppRouter';
@@ -34,7 +34,7 @@ const App: FunctionComponent = () => {
-
+
@@ -50,7 +50,7 @@ const App: FunctionComponent = () => {
-
+
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ErrorBoundry/ErrorBoundry.tsx b/openmetadata-ui/src/main/resources/ui/src/components/ErrorBoundary/ErrorBoundary.tsx
similarity index 76%
rename from openmetadata-ui/src/main/resources/ui/src/components/ErrorBoundry/ErrorBoundry.tsx
rename to openmetadata-ui/src/main/resources/ui/src/components/ErrorBoundary/ErrorBoundary.tsx
index ccb50df9ea3..815d5621b9d 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/ErrorBoundry/ErrorBoundry.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/ErrorBoundary/ErrorBoundary.tsx
@@ -12,7 +12,7 @@
*/
import React from 'react';
-import { ErrorBoundary } from 'react-error-boundary';
+import { ErrorBoundary as ErrorBoundaryWrapper } from 'react-error-boundary';
import { useHistory } from 'react-router-dom';
import { ROUTES } from '../../constants/constants';
import ErrorFallback from './ErrorFallback';
@@ -21,7 +21,7 @@ interface Props {
children: React.ReactNode;
}
-const ErrorBoundry: React.FC
= ({ children }) => {
+const ErrorBoundary: React.FC = ({ children }) => {
const history = useHistory();
const onErrorReset = () => {
@@ -29,10 +29,12 @@ const ErrorBoundry: React.FC = ({ children }) => {
};
return (
-
+
{children}
-
+
);
};
-export default ErrorBoundry;
+export default ErrorBoundary;
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ErrorBoundry/ErrorFallback.tsx b/openmetadata-ui/src/main/resources/ui/src/components/ErrorBoundary/ErrorFallback.tsx
similarity index 100%
rename from openmetadata-ui/src/main/resources/ui/src/components/ErrorBoundry/ErrorFallback.tsx
rename to openmetadata-ui/src/main/resources/ui/src/components/ErrorBoundary/ErrorFallback.tsx
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/PermissionProvider/PermissionProvider.tsx b/openmetadata-ui/src/main/resources/ui/src/components/PermissionProvider/PermissionProvider.tsx
index 5c7dae3d6e3..92d71e53310 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/PermissionProvider/PermissionProvider.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/PermissionProvider/PermissionProvider.tsx
@@ -12,6 +12,7 @@
*/
import { CookieStorage } from 'cookie-storage';
+import { isEmpty, isUndefined } from 'lodash';
import { observer } from 'mobx-react';
import React, {
createContext,
@@ -166,10 +167,19 @@ const PermissionProvider: FC = ({ children }) => {
}
};
+ const resetPermissions = () => {
+ setEntitiesPermission({} as EntityPermissionMap);
+ setPermissions({} as UIPermission);
+ setResourcesPermission({} as UIPermission);
+ };
+
useEffect(() => {
if (isProtectedRoute(location.pathname)) {
fetchLoggedInUserPermissions();
}
+ if (isUndefined(currentUser) || isEmpty(currentUser)) {
+ resetPermissions();
+ }
}, [currentUser]);
return (
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/authentication/auth-provider/AuthProvider.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/authentication/auth-provider/AuthProvider.test.tsx
new file mode 100644
index 00000000000..9e06299f23c
--- /dev/null
+++ b/openmetadata-ui/src/main/resources/ui/src/components/authentication/auth-provider/AuthProvider.test.tsx
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2023 Collate.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import {
+ act,
+ render,
+ screen,
+ waitForElementToBeRemoved,
+} from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import AppState from 'AppState';
+import React from 'react';
+import AuthProvider, { useAuthContext } from './AuthProvider';
+
+jest.mock('react-router-dom', () => ({
+ useHistory: jest.fn().mockReturnValue({ push: jest.fn(), listen: jest.fn() }),
+ useLocation: jest.fn().mockReturnValue({ pathname: 'pathname' }),
+}));
+
+jest.mock('rest/miscAPI', () => ({
+ fetchAuthenticationConfig: jest
+ .fn()
+ .mockImplementation(() => Promise.resolve()),
+ fetchAuthorizerConfig: jest.fn().mockImplementation(() => Promise.resolve()),
+}));
+
+jest.mock('rest/userAPI', () => ({
+ getLoggedInUser: jest.fn().mockImplementation(() => Promise.resolve()),
+ updateUser: jest.fn().mockImplementation(() => Promise.resolve()),
+}));
+
+describe('Test auth provider', () => {
+ it('Logout handler should call the "updateUserDetails" method', async () => {
+ const mockUpdateUserDetails = jest.spyOn(AppState, 'updateUserDetails');
+ const ConsumerComponent = () => {
+ const { onLogoutHandler } = useAuthContext();
+
+ return (
+
+ );
+ };
+
+ render(
+
+
+
+ );
+
+ await waitForElementToBeRemoved(() => screen.getByTestId('loader'));
+
+ const logoutButton = screen.getByTestId('logout-button');
+
+ expect(logoutButton).toBeInTheDocument();
+
+ await act(async () => {
+ userEvent.click(logoutButton);
+ });
+
+ expect(mockUpdateUserDetails).toHaveBeenCalled();
+ expect(mockUpdateUserDetails).toHaveBeenCalledWith({});
+ });
+});
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/authentication/auth-provider/AuthProvider.tsx b/openmetadata-ui/src/main/resources/ui/src/components/authentication/auth-provider/AuthProvider.tsx
index bd6ba42fb6c..ce82a1f8f1c 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/authentication/auth-provider/AuthProvider.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/authentication/auth-provider/AuthProvider.tsx
@@ -16,6 +16,7 @@ import { Auth0Provider } from '@auth0/auth0-react';
import { Configuration } from '@azure/msal-browser';
import { MsalProvider } from '@azure/msal-react';
import { LoginCallback } from '@okta/okta-react';
+import appState from 'AppState';
import { AxiosError } from 'axios';
import { CookieStorage } from 'cookie-storage';
import { AuthorizerConfiguration } from 'generated/configuration/authorizerConfiguration';
@@ -36,7 +37,6 @@ import { useHistory, useLocation } from 'react-router-dom';
import axiosClient from 'rest/index';
import { fetchAuthenticationConfig, fetchAuthorizerConfig } from 'rest/miscAPI';
import { getLoggedInUser, updateUser } from 'rest/userAPI';
-import appState from '../../../AppState';
import { NO_AUTH } from '../../../constants/auth.constants';
import { REDIRECT_PATHNAME, ROUTES } from '../../../constants/constants';
import { ClientErrors } from '../../../enums/axios.enum';
@@ -133,10 +133,13 @@ export const AuthProvider = ({
clearTimeout(timeoutId);
authenticatorRef.current?.invokeLogout();
+ // reset the user details on logout
+ appState.updateUserDetails({} as User);
+
// remove analytics session on logout
removeSession();
setLoading(false);
- }, [timeoutId]);
+ }, [timeoutId, appState]);
const onRenewIdTokenHandler = () => {
return authenticatorRef.current?.renewIdToken();