Skip to content

Commit

Permalink
Refresh menu after access token has expired (#5180)
Browse files Browse the repository at this point in the history
Issue: #5099
  • Loading branch information
bilalabbad authored Dec 10, 2024
1 parent e77be99 commit c3aa86a
Show file tree
Hide file tree
Showing 11 changed files with 3,219 additions and 3,155 deletions.
1 change: 1 addition & 0 deletions changelog/5099.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Correctly refresh menu after access token has expired
5 changes: 3 additions & 2 deletions frontend/app/biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
"./coverage",
"./dist",
"./playwright-report",
"./src/generated",
"./test-results",
"./tests/e2e/.auth"
"./tests/e2e/.auth",
"./src/generated",
"./src/infraops.d.ts"
]
},
"formatter": {
Expand Down
40 changes: 28 additions & 12 deletions frontend/app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions frontend/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"cypress:run:component": "cypress run --component",
"cypress:run:spec": "ELECTRON_ENABLE_LOGGING=1 cypress run --spec",
"biome": "biome check .",
"biome:fix": "biome check --apply ."
"biome:fix": "biome check --write ."
},
"dependencies": {
"@apollo/client": "^3.9.10",
Expand Down Expand Up @@ -70,6 +70,7 @@
"handlebars": "^4.7.8",
"jotai": "^2.10.0",
"json-to-graphql-query": "^2.2.5",
"openapi-fetch": "^0.13.3",
"prismjs": "^1.29.0",
"query-string": "^9.0.0",
"ramda": "^0.29.1",
Expand Down Expand Up @@ -119,7 +120,7 @@
"cypress": "^13.15.0",
"jsdom": "^24.0.0",
"lint-staged": "^15.2.10",
"openapi-typescript": "^7.0.2",
"openapi-typescript": "^7.4.4",
"postcss": "^8.4.23",
"react-test-renderer": "^18.2.0",
"tailwindcss": "^3.4.3",
Expand Down
38 changes: 38 additions & 0 deletions frontend/app/src/api/client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { QueryClient } from "@tanstack/react-query";
import createClient, { Middleware } from "openapi-fetch";

import { INFRAHUB_API_SERVER_URL } from "@/config/config";

import { ACCESS_TOKEN_KEY } from "@/config/localStorage";
import { getNewToken } from "@/hooks/useAuth";
import type { paths } from "@/infraops";

export const queryClient = new QueryClient({
defaultOptions: {
Expand All @@ -7,3 +14,34 @@ export const queryClient = new QueryClient({
},
},
});

export const apiClient = createClient<paths>({ baseUrl: INFRAHUB_API_SERVER_URL });

const authMiddleware: Middleware = {
async onRequest({ request }) {
const accessToken = localStorage.getItem(ACCESS_TOKEN_KEY);

if (!accessToken) return request;

request.headers.set("Authorization", `Bearer ${accessToken}`);
return request;
},
async onResponse({ request, response }) {
if (response.status === 401) {
try {
const newToken = await getNewToken();

if (!newToken?.access_token) {
return response;
}

request.headers.set("Authorization", `Bearer ${newToken.access_token}`);
return fetch(request);
} catch (e) {
return response;
}
}
},
};

apiClient.use(authMiddleware);
38 changes: 36 additions & 2 deletions frontend/app/src/components/search/search-actions.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,57 @@
import { SearchAnywhereGroup } from "@/components/search/search-anywhere-group";
import { SearchAnywhereItem } from "@/components/search/search-anywhere-item";
import { Badge } from "@/components/ui/badge";
import { menuQueryOptions } from "@/screens/layout/menu-navigation/get-menu";
import { MenuItem } from "@/screens/layout/menu-navigation/types";
import { IModelSchema, genericsState, menuFlatAtom, schemaState } from "@/state/atoms/schema.atom";
import { IModelSchema, genericsState, schemaState } from "@/state/atoms/schema.atom";
import { constructPath } from "@/utils/fetch";
import { Icon } from "@iconify-icon/react";
import { useQuery } from "@tanstack/react-query";
import { useCommandState } from "cmdk";
import { useAtomValue } from "jotai";
import { useMemo } from "react";

export const SearchActions = () => {
const query = useCommandState((state) => state.search);
const nodes = useAtomValue(schemaState);
const generics = useAtomValue(genericsState);
const models: IModelSchema[] = [...nodes, ...generics];

const menuItems = useAtomValue(menuFlatAtom);
const { data: menuData, isPending, isError } = useQuery(menuQueryOptions());

const menuItems = useMemo(() => {
if (!menuData) return [];

const menuItems: MenuItem[] = [];

const flattenMenuItems = (menuItem: MenuItem) => {
if (menuItem.path !== "") menuItems.push(menuItem);

if (menuItem.children && menuItem.children.length > 0) {
menuItem.children.forEach(flattenMenuItems);
}
};

menuData.sections.object.forEach(flattenMenuItems);
menuData.sections.internal.forEach(flattenMenuItems);

return menuItems;
}, [menuData]);

if (query === "") return null;

if (isPending) {
return (
<SearchAnywhereGroup heading="Go to">
<SearchAnywhereItem to="" disabled>
Loading...
</SearchAnywhereItem>
</SearchAnywhereGroup>
);
}

if (isError || menuItems.length === 0) return null;

const queryLowerCased = query.toLowerCase();
const resultsMenu = menuItems.filter(({ label }) =>
label.toLowerCase().includes(queryLowerCased)
Expand Down
Loading

0 comments on commit c3aa86a

Please sign in to comment.