import KeycloakAdminClient from "@keycloak/keycloak-admin-client"; import axios from "axios"; import Keycloak from "keycloak-js"; import { DependencyList, useEffect } from "react"; import { useErrorHandler } from "react-error-boundary"; import environment from "../../environment"; import { createNamedContext } from "../../utils/createNamedContext"; import useRequiredContext from "../../utils/useRequiredContext"; export type AdminClientProps = { keycloak: Keycloak; adminClient: KeycloakAdminClient; }; export const AdminClientContext = createNamedContext< AdminClientProps | undefined >("AdminClientContext", undefined); export const useAdminClient = () => useRequiredContext(AdminClientContext); /** * Util function to only set the state when the component is still mounted. * * It takes 2 functions one you do your adminClient call in and the other to set your state * * @example * useFetch( * () => adminClient.components.findOne({ id }), * (component) => setupForm(component), * [] * ); * * @param adminClientCall use this to do your adminClient call * @param callback when the data is fetched this is where you set your state */ export function useFetch( adminClientCall: () => Promise, callback: (param: T) => void, deps?: DependencyList ) { const { adminClient } = useAdminClient(); const onError = useErrorHandler(); useEffect(() => { const source = axios.CancelToken.source(); adminClient.setConfig({ requestConfig: { cancelToken: source.token }, }); adminClientCall() .then((result) => { if (!source.token.reason) { callback(result); } }) .catch((error) => { if (!axios.isCancel(error)) { onError(error); } }); adminClient.setConfig({ requestConfig: { cancelToken: undefined }, }); return () => { source.cancel(); }; }, deps); } export async function initAdminClient() { const keycloak = new Keycloak({ url: environment.authServerUrl, realm: environment.loginRealm, clientId: environment.isRunningAsTheme ? "security-admin-console" : "security-admin-console-v2", }); await keycloak.init({ onLoad: "check-sso", pkceMethod: "S256" }); const adminClient = new KeycloakAdminClient(); adminClient.setConfig({ realmName: environment.loginRealm }); adminClient.baseUrl = environment.authUrl; adminClient.registerTokenProvider({ async getAccessToken() { try { await keycloak.updateToken(5); } catch (error) { keycloak.login(); } return keycloak.token; }, }); return { keycloak, adminClient }; }