Skip to content

Commit

Permalink
Revert ":bug: Fix session expiry when refresh tokens are disabled (#1614
Browse files Browse the repository at this point in the history
)"

This reverts commit eea7835.
  • Loading branch information
fabianvf authored Dec 13, 2023
1 parent eea7835 commit 6880cad
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 51 deletions.
39 changes: 5 additions & 34 deletions client/src/app/axios-config/apiInit.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,14 @@
import axios from "axios";
import keycloak from "@app/keycloak";

export const initInterceptors = () => {
export const initInterceptors = (getToken: () => Promise<string>) => {
axios.interceptors.request.use(
(config) => {
const token = keycloak.token;
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
async (config) => {
const token = await getToken();

Check warning on line 6 in client/src/app/axios-config/apiInit.ts

View check run for this annotation

Codecov / codecov/patch

client/src/app/axios-config/apiInit.ts#L5-L6

Added lines #L5 - L6 were not covered by tests
if (token) config.headers["Authorization"] = "Bearer " + token;
return config;
},
(error) => {
return Promise.reject(error);
}
);

axios.interceptors.response.use(
(response) => {
return response;
},
async (error) => {
if (error.response && error.response.status === 401) {
try {
const refreshed = await keycloak.updateToken(5);
if (refreshed) {
const retryConfig = {
...error.config,
headers: {
...error.config.headers,
Authorization: `Bearer ${keycloak.token}`,
},
};
return axios(retryConfig);
}
} catch (refreshError) {
keycloak.login();
}
}
return Promise.reject(error);
Promise.reject(error);

Check warning on line 11 in client/src/app/axios-config/apiInit.ts

View check run for this annotation

Codecov / codecov/patch

client/src/app/axios-config/apiInit.ts#L11

Added line #L11 was not covered by tests
}
);
};
98 changes: 83 additions & 15 deletions client/src/app/components/KeycloakProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import React, { Suspense } from "react";
import { ReactKeycloakProvider } from "@react-keycloak/web";
import { initInterceptors } from "@app/axios-config";
import { isAuthRequired } from "@app/Constants";
import i18n from "@app/i18n";
import keycloak from "@app/keycloak";
import { deleteCookie, getCookie, setCookie } from "@app/queries/cookies";
import { AppPlaceholder } from "./AppPlaceholder";
import { initInterceptors } from "@app/axios-config";
import { Flex, FlexItem, Spinner } from "@patternfly/react-core";
import { ReactKeycloakProvider } from "@react-keycloak/web";
import React, { Suspense } from "react";

interface IKeycloakProviderProps {
children: React.ReactNode;
Expand All @@ -11,17 +15,81 @@ interface IKeycloakProviderProps {
export const KeycloakProvider: React.FC<IKeycloakProviderProps> = ({
children,
}) => {
React.useEffect(() => {
initInterceptors();
}, []);
const checkAuthCookie = () => {
if (!getCookie("keycloak_cookie") && keycloak?.token) {
setCookie("keycloak_cookie", keycloak.token, 365);
}
};
if (isAuthRequired) {
return (
<>
<ReactKeycloakProvider
authClient={keycloak}
initOptions={{ onLoad: "login-required" }}
LoadingComponent={
<Flex
spaceItems={{ default: "spaceItemsSm" }}
alignItems={{ default: "alignItemsCenter" }}
flexWrap={{ default: "nowrap" }}
style={{
width: "100%",
height: "100%",
}}
>
<FlexItem
style={{
margin: "auto auto",
textAlign: "center",
}}
>
<Spinner>Loading...</Spinner>
</FlexItem>
</Flex>
}
isLoadingCheck={(keycloak) => {
if (keycloak.authenticated) {
initInterceptors(
() =>
new Promise<string>((resolve, reject) => {
if (keycloak.token) {
if (keycloak.refreshToken) {
keycloak
.updateToken(60)
.then(() => {
deleteCookie("keycloak_cookie");
checkAuthCookie();
return resolve(keycloak.token!);
})
.catch((err) => {
console.log("err", err);
return reject("Failed to refresh token");
});
} else return resolve(keycloak.token!);
} else {
keycloak.login();
reject("Not logged in");
}
})
);

const kcLocale = (keycloak.tokenParsed as any)["locale"];
if (kcLocale) {
i18n.changeLanguage(kcLocale);
}
}

return (
<ReactKeycloakProvider
authClient={keycloak}
initOptions={{ onLoad: "login-required" }}
LoadingComponent={<AppPlaceholder />}
>
<Suspense fallback={<AppPlaceholder />}>{children}</Suspense>
</ReactKeycloakProvider>
);
return !keycloak.authenticated;
}}
>
{children}
</ReactKeycloakProvider>
</>
);
} else {
return (
<>
<Suspense fallback={<AppPlaceholder />}>{children}</Suspense>
</>
);
}
};
5 changes: 3 additions & 2 deletions client/src/app/layout/HeaderApp/SSOMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ export const SSOMenu: React.FC = () => {
id="sso-actions-toggle"
onClick={() => onDropdownToggle(!isDropdownOpen)}
>
{(keycloak?.idTokenParsed as any)?.["preferred_username"] ??
"DefaultUsername"}
{(keycloak?.idTokenParsed as any)["preferred_username"]}
</MenuToggle>
)}
>
Expand All @@ -64,6 +63,8 @@ export const SSOMenu: React.FC = () => {
id="logout"
key="sso_logout"
onClick={() => {
// Clears selected persona from storage without updating it in React state so we don't re-render the persona selector while logging out.
// We have to clear it before logout because the redirect can happen before the logout promise resolves.
window.localStorage.removeItem(
LocalStorageKey.selectedPersona
);
Expand Down

0 comments on commit 6880cad

Please sign in to comment.