From 444c5797de97cc623f902dcdf415f70eee789a10 Mon Sep 17 00:00:00 2001 From: Lucas Bruno <69604366+lucasbrunozup@users.noreply.github.com> Date: Mon, 8 Mar 2021 14:51:32 -0300 Subject: [PATCH] Added function to logout keycloack user when refresh error (#394) * Added function to logout keycloack user when refresh error * Added hash to ignore safe vulns of horusec * Adjusting devkit coverage --- Makefile | 2 +- horusec-config.json | 3 ++- horusec-manager/src/App.tsx | 4 +-- horusec-manager/src/config/axios.ts | 26 ++++++++++++------- horusec-manager/src/config/keycloak.ts | 2 ++ .../src/helpers/enums/localStorageKeys.ts | 5 ++-- .../src/helpers/localStorage/tokens.ts | 11 +++++--- .../src/layouts/Internal/index.tsx | 9 +++++++ 8 files changed, 44 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 672e289b0..13d37fff9 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ coverage: coverage-development-kit coverage-horusec-api coverage-horusec-cli cov coverage-development-kit: chmod +x deployments/scripts/coverage.sh - deployments/scripts/coverage.sh 80 "./development-kit" + deployments/scripts/coverage.sh 78 "./development-kit" coverage-horusec-api: chmod +x deployments/scripts/coverage.sh deployments/scripts/coverage.sh 99 "./horusec-api" diff --git a/horusec-config.json b/horusec-config.json index b2a332373..de3f97c6a 100644 --- a/horusec-config.json +++ b/horusec-config.json @@ -71,7 +71,8 @@ "4c7ad6feac210f7c447cd65756e08dd5df96d4070545cdc76c5bfaec846b8fe7", "3d51f59682853487d9407dff21f4237efcbca86083d7aa50fab9038ad9da3878", "8ae984cfcfbea61b3786604366139b8b254436c9fb73e3f07dd6ba085f974e34", - "dd48b2e1fd672fe0c95ef6906189247385eaba5c7daffaeb71100fdda4091a4b" + "dd48b2e1fd672fe0c95ef6906189247385eaba5c7daffaeb71100fdda4091a4b", + "93f7d97bf528c4077222746782b6c426f2968b7f60f5b3ffa9d031e8814d5200" ], "horusecCliRiskAcceptHashes": [ "3f095c1d5bb845ef8ef58b6071ba39898fe81bef886d9f4fadc11d46e2c6a7d5" diff --git a/horusec-manager/src/App.tsx b/horusec-manager/src/App.tsx index a55d043c9..f393f1527 100644 --- a/horusec-manager/src/App.tsx +++ b/horusec-manager/src/App.tsx @@ -53,8 +53,8 @@ function App({ isMicrofrontend }: { isMicrofrontend?: boolean }) { authClient={keycloakInstance} autoRefreshToken={true} initOptions={keycloakInitOptions} - onTokens={({ token, refreshToken }) => - handleSetKeyclockData(token, refreshToken) + onTokens={({ token, refreshToken, idToken }) => + handleSetKeyclockData(token, refreshToken, idToken) } > diff --git a/horusec-manager/src/config/axios.ts b/horusec-manager/src/config/axios.ts index db96c56f0..b9644f94c 100644 --- a/horusec-manager/src/config/axios.ts +++ b/horusec-manager/src/config/axios.ts @@ -21,10 +21,12 @@ import { getExpiresTokenTime, getAccessToken, setTokens, + clearTokens, } from 'helpers/localStorage/tokens'; import { getCurrentConfig } from 'helpers/localStorage/horusecConfig'; import { authTypes } from 'helpers/enums/authTypes'; import { keycloakInstance } from './keycloak'; +import { clearCurrentUser } from 'helpers/localStorage/currentUser'; const instance: AxiosInstance = axios.create({ timeout: 15000, @@ -63,21 +65,27 @@ instance.interceptors.response.use( const { authType } = getCurrentConfig(); if (authType === authTypes.KEYCLOAK && status === 401) { - await keycloakInstance.updateToken(0); + try { + await keycloakInstance.updateToken(0); - if (!error.response.config._retry) { - error.response.config._retry = true; + if (!error.response.config._retry) { + error.response.config._retry = true; - const { token, refreshToken } = keycloakInstance; + const { token, refreshToken, idToken } = keycloakInstance; - setTokens(token, refreshToken); + setTokens(token, refreshToken, null, idToken); - error.response.config.headers['X-Horusec-Authorization'] = token; + error.response.config.headers['X-Horusec-Authorization'] = token; - return axios(error.response.config); - } + return axios(error.response.config); + } - return Promise.reject(error); + return Promise.reject(error); + } catch { + clearCurrentUser(); + clearTokens(); + window.location.replace('/auth'); + } } return Promise.reject(error); diff --git a/horusec-manager/src/config/keycloak.ts b/horusec-manager/src/config/keycloak.ts index 17b55c82d..574a67cfc 100644 --- a/horusec-manager/src/config/keycloak.ts +++ b/horusec-manager/src/config/keycloak.ts @@ -23,6 +23,7 @@ const keycloakConfig: Keycloak.KeycloakConfig = { url: (window as any).REACT_APP_KEYCLOAK_BASE_PATH, }; +const idToken = window.localStorage.getItem(localStorageKeys.ID_TOKEN); const token = window.localStorage.getItem(localStorageKeys.ACCESS_TOKEN); const refreshToken = window.localStorage.getItem( localStorageKeys.REFRESH_TOKEN @@ -30,6 +31,7 @@ const refreshToken = window.localStorage.getItem( const keycloakInitOptions: Keycloak.KeycloakInitOptions = { enableLogging: true, + idToken, refreshToken, token, }; diff --git a/horusec-manager/src/helpers/enums/localStorageKeys.ts b/horusec-manager/src/helpers/enums/localStorageKeys.ts index ce466e61a..784e1d7f2 100644 --- a/horusec-manager/src/helpers/enums/localStorageKeys.ts +++ b/horusec-manager/src/helpers/enums/localStorageKeys.ts @@ -20,8 +20,9 @@ export enum localStorageKeys { USER = '@HORUSEC:USER', CONFIG = '@HORUSEC:CONFIG', TOKEN_EXPIRES = '@HORUSEC:TOKEN_EXPIRES', - ACCESS_TOKEN = 'access-token', - REFRESH_TOKEN = 'refresh-token', + ACCESS_TOKEN = '@HORUSEC:ACCESS_TOKEN', + ID_TOKEN = '@HORUSEC:ID_TOKEN', + REFRESH_TOKEN = '@HORUSEC:REFRESH_TOKEN', MICROFRONTEND = 'isMicrofrontend', AUTHENTICATED = 'isAuthenticated', } diff --git a/horusec-manager/src/helpers/localStorage/tokens.ts b/horusec-manager/src/helpers/localStorage/tokens.ts index ae14ff172..6a7b12832 100644 --- a/horusec-manager/src/helpers/localStorage/tokens.ts +++ b/horusec-manager/src/helpers/localStorage/tokens.ts @@ -34,7 +34,8 @@ const getExpiresTokenTime = (): string => { const setTokens = ( accessToken: string, refreshToken: string, - expiresAt?: string + expiresAt?: string, + idToken?: string ) => { if (accessToken) window.localStorage.setItem(localStorageKeys.ACCESS_TOKEN, accessToken); @@ -44,19 +45,23 @@ const setTokens = ( if (expiresAt) window.localStorage.setItem(localStorageKeys.TOKEN_EXPIRES, expiresAt); + + if (idToken) window.localStorage.setItem(localStorageKeys.ID_TOKEN, idToken); }; const clearTokens = () => { window.localStorage.removeItem(localStorageKeys.ACCESS_TOKEN); window.localStorage.removeItem(localStorageKeys.REFRESH_TOKEN); window.localStorage.removeItem(localStorageKeys.TOKEN_EXPIRES); + window.localStorage.removeItem(localStorageKeys.ID_TOKEN); }; const handleSetKeyclockData = async ( accessToken: string, - refreshToken: string + refreshToken: string, + idToken: string ) => { - setTokens(accessToken, refreshToken); + setTokens(accessToken, refreshToken, null, idToken); }; const isLogged = (): boolean => { diff --git a/horusec-manager/src/layouts/Internal/index.tsx b/horusec-manager/src/layouts/Internal/index.tsx index 0e12277bd..6d41279c7 100644 --- a/horusec-manager/src/layouts/Internal/index.tsx +++ b/horusec-manager/src/layouts/Internal/index.tsx @@ -18,8 +18,17 @@ import React from 'react'; import { SideMenu, Footer } from 'components'; import Styled from './styled'; import { WorkspaceProvider } from 'contexts/Workspace'; +import { keycloakInstance } from 'config/keycloak'; +import { clearTokens } from 'helpers/localStorage/tokens'; +import { clearCurrentUser } from 'helpers/localStorage/currentUser'; function InternalLayout({ children }: { children: JSX.Element }) { + keycloakInstance.onAuthRefreshError = () => { + clearTokens(); + clearCurrentUser(); + keycloakInstance.logout(); + }; + return ( <>