Fix realms fetching in RealmsContext (#4357)

This commit is contained in:
Jon Koops 2023-02-09 13:01:19 +01:00 committed by GitHub
parent 97675177bc
commit 283cbee2da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,13 +1,7 @@
import { NetworkError } from "@keycloak/keycloak-admin-client"; import { NetworkError } from "@keycloak/keycloak-admin-client";
import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation"; import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
import { sortBy } from "lodash-es"; import { sortBy } from "lodash-es";
import { import { PropsWithChildren, useCallback, useMemo, useState } from "react";
PropsWithChildren,
useCallback,
useMemo,
useRef,
useState,
} from "react";
import { createNamedContext } from "../utils/createNamedContext"; import { createNamedContext } from "../utils/createNamedContext";
import useRequiredContext from "../utils/useRequiredContext"; import useRequiredContext from "../utils/useRequiredContext";
@ -28,7 +22,7 @@ export const RealmsContext = createNamedContext<RealmsContextProps | undefined>(
export const RealmsProvider = ({ children }: PropsWithChildren<unknown>) => { export const RealmsProvider = ({ children }: PropsWithChildren<unknown>) => {
const { keycloak, adminClient } = useAdminClient(); const { keycloak, adminClient } = useAdminClient();
const [realms, setRealms] = useState<RealmRepresentation[]>([]); const [realms, setRealms] = useState<RealmRepresentation[]>([]);
const firstRender = useRef(0); const [refreshCount, setRefreshCount] = useState(0);
function updateRealms(realms: RealmRepresentation[]) { function updateRealms(realms: RealmRepresentation[]) {
setRealms(sortBy(realms, "realm")); setRealms(sortBy(realms, "realm"));
@ -36,10 +30,11 @@ export const RealmsProvider = ({ children }: PropsWithChildren<unknown>) => {
useFetch( useFetch(
async () => { async () => {
if (firstRender.current === 0) { // We don't want to fetch until the user has requested it, so let's ignore the initial mount.
firstRender.current = 1; if (refreshCount === 0) {
return []; return [];
} }
try { try {
return await adminClient.realms.find({ briefRepresentation: true }); return await adminClient.realms.find({ briefRepresentation: true });
} catch (error) { } catch (error) {
@ -51,14 +46,14 @@ export const RealmsProvider = ({ children }: PropsWithChildren<unknown>) => {
} }
}, },
(realms) => updateRealms(realms), (realms) => updateRealms(realms),
[] [refreshCount]
); );
const refresh = useCallback(async () => { const refresh = useCallback(async () => {
//this is needed otherwise the realm find function will not return //this is needed otherwise the realm find function will not return
//new or renamed realms because of the cached realms in the token (perhaps?) //new or renamed realms because of the cached realms in the token (perhaps?)
await keycloak.updateToken(Number.MAX_VALUE); await keycloak.updateToken(Number.MAX_VALUE);
updateRealms(await adminClient.realms.find({ briefRepresentation: true })); setRefreshCount((count) => count + 1);
}, []); }, []);
const value = useMemo<RealmsContextProps>( const value = useMemo<RealmsContextProps>(