From 38e32af072dd53c57bc8efa3253d55e9d7fc60d0 Mon Sep 17 00:00:00 2001 From: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com> Date: Wed, 19 Oct 2022 20:55:31 +0530 Subject: [PATCH] fix(ui): call logout api to invalidate token (#8243) --- .../ui/cypress/constants/constants.js | 4 +++ .../ui/cypress/e2e/Flow/LogoutUser.spec.js | 36 +++++++++++++++++++ .../ui/cypress/e2e/Pages/Login.spec.js | 15 ++++---- .../auth-provider/basic-auth.provider.tsx | 13 +++++-- .../resources/ui/src/axiosAPIs/auth-API.ts | 9 +++++ 5 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/LogoutUser.spec.js diff --git a/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.js b/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.js index aae862514ff..b46e2472e5c 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.js @@ -14,6 +14,10 @@ export const uuid = () => Cypress._.random(0, 1e6); const id = uuid(); +export const BASE_URL = location.origin; + +export const LOGIN_ERROR_MESSAGE = 'You have entered an invalid username or password.'; + export const MYDATA_SUMMARY_OPTIONS = { tables: 'tables', topics: 'topics', diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/LogoutUser.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/LogoutUser.spec.js new file mode 100644 index 00000000000..a91ebeb79c3 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Flow/LogoutUser.spec.js @@ -0,0 +1,36 @@ +/* + * Copyright 2021 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 { interceptURL, login, verifyResponseStatusCode } from "../../common/common"; +import { BASE_URL, LOGIN } from "../../constants/constants"; + +describe("Logout User", () => { + beforeEach(() => { + login(LOGIN.username, LOGIN.password); + cy.goToHomePage(); + }); + + it("After login logout the user and invalidate the token", () => { + + cy.get('[data-testid="avatar"]').should("be.visible").click() + + interceptURL('POST', '/api/v1/users/logout', 'logoutUser'); + + cy.get('[data-testid="menu-item-Logout"]').should("be.visible").click() + + // verify the logout request + verifyResponseStatusCode('@logoutUser', 200); + + cy.url().should('eq', `${BASE_URL}/signin`); + }) +}) \ No newline at end of file diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Login.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Login.spec.js index 4b2a8333e20..0279e286602 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Login.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Login.spec.js @@ -12,6 +12,7 @@ */ import { interceptURL, login, verifyResponseStatusCode } from '../../common/common'; +import { BASE_URL, LOGIN_ERROR_MESSAGE } from '../../constants/constants'; const CREDENTIALS = { firstName: 'Test', @@ -22,10 +23,6 @@ const CREDENTIALS = { const invalidEmail = 'userTest@openmetadata.org'; const invalidPassword = 'testUsers@123'; -const baseURL = location.origin; - -const ERROR_MESSAGE = 'You have entered an invalid username or password.'; - describe('Login flow should work properly', () => { it('Signup and Login with signed up credentials', () => { interceptURL('GET', 'api/v1/config/auth', 'getLoginPage'); @@ -57,13 +54,13 @@ describe('Login flow should work properly', () => { .type(CREDENTIALS.password); //Click on create account button cy.get('.ant-btn').contains('Create Account').should('be.visible').click(); - cy.url().should('eq', `${baseURL}/signin`).and('contain', 'signin'); + cy.url().should('eq', `${BASE_URL}/signin`).and('contain', 'signin'); //Login with the created user login(CREDENTIALS.email, CREDENTIALS.password); cy.goToHomePage(); - cy.url().should('eq', `${baseURL}/my-data`); + cy.url().should('eq', `${BASE_URL}/my-data`); //Verify user profile cy.get('[data-testid="avatar"]').should('be.visible').click(); @@ -89,14 +86,14 @@ describe('Login flow should work properly', () => { cy.get('[data-testid="login-error-container"]') .should('be.visible') .invoke('text') - .should('eq', ERROR_MESSAGE); + .should('eq', LOGIN_ERROR_MESSAGE); //Login with invalid password login(CREDENTIALS.email, invalidPassword); cy.get('[data-testid="login-error-container"]') .should('be.visible') .invoke('text') - .should('eq', ERROR_MESSAGE); + .should('eq', LOGIN_ERROR_MESSAGE); }); it('Forgot password and login with new password', () => { @@ -110,7 +107,7 @@ describe('Login flow should work properly', () => { .click(); cy.url() - .should('eq', `${baseURL}/forgot-password`) + .should('eq', `${BASE_URL}/forgot-password`) .and('contain', 'forgot-password'); //Enter email cy.get('[id="email"]').should('be.visible').clear().type(CREDENTIALS.email); diff --git a/openmetadata-ui/src/main/resources/ui/src/authentication/auth-provider/basic-auth.provider.tsx b/openmetadata-ui/src/main/resources/ui/src/authentication/auth-provider/basic-auth.provider.tsx index cde2e6030db..4d8e04faf75 100644 --- a/openmetadata-ui/src/main/resources/ui/src/authentication/auth-provider/basic-auth.provider.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/authentication/auth-provider/basic-auth.provider.tsx @@ -20,6 +20,7 @@ import { basicAuthSignIn, checkEmailInUse, generatePasswordResetLink, + logoutUser, resetPassword, } from '../../axiosAPIs/auth-API'; import { @@ -192,8 +193,16 @@ const BasicAuthProvider = ({ }; const handleLogout = async () => { - localState.removeOidcToken(); - history.push(ROUTES.SIGNIN); + const token = localState.getOidcToken(); + if (token) { + try { + await logoutUser(token); + localState.removeOidcToken(); + history.push(ROUTES.SIGNIN); + } catch (error) { + showErrorToast(error as AxiosError); + } + } }; const contextValue = { diff --git a/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/auth-API.ts b/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/auth-API.ts index b9c25b2f220..a002edc20d0 100644 --- a/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/auth-API.ts +++ b/openmetadata-ui/src/main/resources/ui/src/axiosAPIs/auth-API.ts @@ -101,3 +101,12 @@ export const generateRandomPwd = async () => { return response.data; }; + +/** + * Logout a User(Only called for saml and basic Auth) + */ +export const logoutUser = async (token: string) => { + const response = await axiosClient.post(`${apiPath}/logout`, { token }); + + return response.data; +};