use context for adminClient (#28693)

* use context for adminClient

Now we can reuse the components as we can use the adminClient from the context

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

* split environment into base, admin and account

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

* added type to useEnvironment

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>

---------

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
Erik Jan de Wit 2024-05-08 10:23:43 +02:00 committed by GitHub
parent dde2746595
commit e28aa90fcb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
218 changed files with 1110 additions and 756 deletions

View file

@ -12,11 +12,9 @@ import {
} from "@patternfly/react-core";
import { LinkIcon, UnlinkIcon } from "@patternfly/react-icons";
import { useTranslation } from "react-i18next";
import { IconMapper, useAlerts } from "@keycloak/keycloak-ui-shared";
import { IconMapper, useAlerts, useEnvironment } from "@keycloak/keycloak-ui-shared";
import { linkAccount, unLinkAccount } from "../api/methods";
import { LinkedAccountRepresentation } from "../api/representations";
import { useEnvironment } from "../root/KeycloakContext";
type AccountRowProps = {
account: LinkedAccountRepresentation;

View file

@ -23,7 +23,7 @@ import {
} from "@patternfly/react-icons";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { ContinueCancelModal, useAlerts } from "@keycloak/keycloak-ui-shared";
import { ContinueCancelModal, useAlerts, useEnvironment } from "@keycloak/keycloak-ui-shared";
import { deleteSession, getDevices } from "../api/methods";
import {
ClientRepresentation,
@ -32,7 +32,6 @@ import {
} from "../api/representations";
import { Page } from "../components/page/Page";
import { TFuncKey } from "../i18n";
import { useEnvironment } from "../root/KeycloakContext";
import { formatDate } from "../utils/formatDate";
import { usePromise } from "../utils/usePromise";

View file

@ -7,7 +7,7 @@ import { EmptyRow } from "../components/datalist/EmptyRow";
import { Page } from "../components/page/Page";
import { usePromise } from "../utils/usePromise";
import { AccountRow } from "./AccountRow";
import { useEnvironment } from "../root/KeycloakContext";
import { useEnvironment } from "@keycloak/keycloak-ui-shared";
export const LinkedAccounts = () => {
const { t } = useTranslation();

View file

@ -18,6 +18,7 @@ import {
import { EllipsisVIcon } from "@patternfly/react-icons";
import { CSSProperties, useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import { useEnvironment } from "@keycloak/keycloak-ui-shared";
import { getCredentials } from "../api/methods";
import {
CredentialContainer,
@ -26,7 +27,6 @@ import {
import { EmptyRow } from "../components/datalist/EmptyRow";
import { Page } from "../components/page/Page";
import { TFuncKey } from "../i18n";
import { useEnvironment } from "../root/KeycloakContext";
import { formatDate } from "../utils/formatDate";
import { usePromise } from "../utils/usePromise";

View file

@ -1,9 +1,10 @@
import { KeycloakContext } from "@keycloak/keycloak-ui-shared";
import { BaseEnvironment } from "@keycloak/keycloak-ui-shared/dist/context/environment";
import { CallOptions } from "./api/methods";
import { Links, parseLinks } from "./api/parse-links";
import { parseResponse } from "./api/parse-response";
import { Permission, Resource, Scope } from "./api/representations";
import { request } from "./api/request";
import { KeycloakContext } from "./root/KeycloakContext";
export const fetchResources = async (
{ signal, context }: CallOptions,
@ -43,7 +44,7 @@ export const fetchPermission = async (
};
export const updateRequest = (
context: KeycloakContext,
context: KeycloakContext<BaseEnvironment>,
resourceId: string,
username: string,
scopes: Scope[] | string[],
@ -54,7 +55,7 @@ export const updateRequest = (
});
export const updatePermissions = (
context: KeycloakContext,
context: KeycloakContext<BaseEnvironment>,
resourceId: string,
permissions: Permission[],
) =>

View file

@ -1,4 +1,8 @@
import { KeycloakContext } from "../root/KeycloakContext";
import {
AccountEnvironment,
KeycloakContext,
} from "@keycloak/keycloak-ui-shared";
import { BaseEnvironment } from "@keycloak/keycloak-ui-shared/dist/context/environment";
import { joinPath } from "../utils/joinPath";
import { parseResponse } from "./parse-response";
import {
@ -13,7 +17,7 @@ import {
import { request } from "./request";
export type CallOptions = {
context: KeycloakContext;
context: KeycloakContext<BaseEnvironment>;
signal?: AbortSignal;
};
@ -41,7 +45,7 @@ export async function getSupportedLocales({
}
export async function savePersonalInfo(
context: KeycloakContext,
context: KeycloakContext<AccountEnvironment>,
info: UserRepresentation,
): Promise<void> {
const response = await request("/", context, { body: info, method: "POST" });
@ -81,11 +85,17 @@ export async function getApplications({
return parseResponse<ClientRepresentation[]>(response);
}
export async function deleteConsent(context: KeycloakContext, id: string) {
export async function deleteConsent(
context: KeycloakContext<BaseEnvironment>,
id: string,
) {
return request(`/applications/${id}/consent`, context, { method: "DELETE" });
}
export async function deleteSession(context: KeycloakContext, id?: string) {
export async function deleteSession(
context: KeycloakContext<BaseEnvironment>,
id?: string,
) {
return request(`/sessions${id ? `/${id}` : ""}`, context, {
method: "DELETE",
});
@ -104,7 +114,7 @@ export async function getLinkedAccounts({ signal, context }: CallOptions) {
}
export async function unLinkAccount(
context: KeycloakContext,
context: KeycloakContext<BaseEnvironment>,
account: LinkedAccountRepresentation,
) {
const response = await request(
@ -119,7 +129,7 @@ export async function unLinkAccount(
}
export async function linkAccount(
context: KeycloakContext,
context: KeycloakContext<BaseEnvironment>,
account: LinkedAccountRepresentation,
) {
const redirectUri = encodeURIComponent(

View file

@ -1,8 +1,8 @@
import { Environment } from "../environment";
import { KeycloakContext } from "@keycloak/keycloak-ui-shared";
import { BaseEnvironment } from "@keycloak/keycloak-ui-shared/dist/context/environment";
import Keycloak from "keycloak-js";
import { CONTENT_TYPE_HEADER, CONTENT_TYPE_JSON } from "./constants";
import { joinPath } from "../utils/joinPath";
import { KeycloakContext } from "../root/KeycloakContext";
import { CONTENT_TYPE_HEADER, CONTENT_TYPE_JSON } from "./constants";
export type RequestOptions = {
signal?: AbortSignal;
@ -35,7 +35,7 @@ async function _request(
export async function request(
path: string,
{ environment, keycloak }: KeycloakContext,
{ environment, keycloak }: KeycloakContext<BaseEnvironment>,
opts: RequestOptions = {},
) {
return _request(url(environment, path), {
@ -44,7 +44,7 @@ export async function request(
});
}
export const url = (environment: Environment, path: string) =>
export const url = (environment: BaseEnvironment, path: string) =>
new URL(
joinPath(environment.authUrl, "realms", environment.realm, "account", path),
);

View file

@ -22,12 +22,11 @@ import {
} from "@patternfly/react-icons";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { ContinueCancelModal, useAlerts } from "@keycloak/keycloak-ui-shared";
import { ContinueCancelModal, useAlerts, useEnvironment } from "@keycloak/keycloak-ui-shared";
import { deleteConsent, getApplications } from "../api/methods";
import { ClientRepresentation } from "../api/representations";
import { Page } from "../components/page/Page";
import { TFuncKey } from "../i18n";
import { useEnvironment } from "../root/KeycloakContext";
import { formatDate } from "../utils/formatDate";
import { usePromise } from "../utils/usePromise";

View file

@ -1,7 +1,7 @@
import { Spinner } from "@patternfly/react-core";
import { Suspense, lazy, useMemo, useState } from "react";
import { useParams } from "react-router-dom";
import { useEnvironment } from "../root/KeycloakContext";
import { useEnvironment } from "@keycloak/keycloak-ui-shared";
import { MenuItem } from "../root/PageNav";
import { ContentComponentParams } from "../routes";
import { joinPath } from "../utils/joinPath";

View file

@ -8,10 +8,10 @@ import {
} from "@patternfly/react-core";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useEnvironment } from "@keycloak/keycloak-ui-shared";
import { getGroups } from "../api/methods";
import { Group } from "../api/representations";
import { Page } from "../components/page/Page";
import { useEnvironment } from "../root/KeycloakContext";
import { usePromise } from "../utils/usePromise";
export const Groups = () => {

View file

@ -1,8 +1,7 @@
import { LanguageDetectorModule, createInstance } from "i18next";
import HttpBackend from "i18next-http-backend";
import { initReactI18next } from "react-i18next";
import { environment } from "./environment";
import { environment } from "@keycloak/keycloak-ui-shared";
import { joinPath } from "./utils/joinPath";
const DEFAULT_LOCALE = "en";

View file

@ -1,7 +1,6 @@
export { PersonalInfo } from "./personal-info/PersonalInfo";
export { ErrorPage } from "./root/ErrorPage";
export { Header } from "./root/Header";
export { KeycloakProvider, useEnvironment } from "./root/KeycloakContext";
export { PageNav } from "./root/PageNav";
export { DeviceActivity } from "./account-security/DeviceActivity";
export { LinkedAccounts } from "./account-security/LinkedAccounts";

View file

@ -1,9 +1,11 @@
import {
AccountEnvironment,
UserProfileFields,
beerify,
debeerify,
setUserProfileServerError,
useAlerts,
useEnvironment,
} from "@keycloak/keycloak-ui-shared";
import {
ActionGroup,
@ -18,7 +20,6 @@ import { TFunction } from "i18next";
import { useState } from "react";
import { ErrorOption, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import {
getPersonalInfo,
getSupportedLocales,
@ -29,14 +30,12 @@ import {
UserRepresentation,
} from "../api/representations";
import { Page } from "../components/page/Page";
import { environment } from "../environment";
import { TFuncKey, i18n } from "../i18n";
import { useEnvironment } from "../root/KeycloakContext";
import { usePromise } from "../utils/usePromise";
export const PersonalInfo = () => {
const { t } = useTranslation();
const context = useEnvironment();
const context = useEnvironment<AccountEnvironment>();
const [userProfileMetadata, setUserProfileMetadata] =
useState<UserProfileMetadata>();
const [supportedLocales, setSupportedLocales] = useState<string[]>([]);
@ -106,7 +105,7 @@ export const PersonalInfo = () => {
form={form}
userProfileMetadata={userProfileMetadata}
supportedLocales={supportedLocales}
currentLocale={environment.locale}
currentLocale={context.environment.locale}
t={
((key: unknown, params) =>
t(key as TFuncKey, params as any)) as TFunction

View file

@ -2,15 +2,14 @@ import { Button, Form, Modal } from "@patternfly/react-core";
import { Fragment, useEffect } from "react";
import { FormProvider, useFieldArray, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import {
SelectControl,
TextControl,
useAlerts,
useEnvironment,
} from "@keycloak/keycloak-ui-shared";
import { updatePermissions } from "../api";
import type { Permission, Resource } from "../api/representations";
import { useEnvironment } from "../root/KeycloakContext";
type EditTheResourceProps = {
resource: Resource;

View file

@ -11,11 +11,9 @@ import { UserCheckIcon } from "@patternfly/react-icons";
import { Table, Tbody, Td, Th, Thead, Tr } from "@patternfly/react-table";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useAlerts } from "@keycloak/keycloak-ui-shared";
import { useAlerts, useEnvironment } from "@keycloak/keycloak-ui-shared";
import { fetchPermission, updateRequest } from "../api";
import { Permission, Resource } from "../api/representations";
import { useEnvironment } from "../root/KeycloakContext";
type PermissionRequestProps = {
resource: Resource;

View file

@ -32,13 +32,11 @@ import {
} from "@patternfly/react-table";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { ContinueCancelModal, useAlerts } from "@keycloak/keycloak-ui-shared";
import { ContinueCancelModal, useAlerts, useEnvironment } from "@keycloak/keycloak-ui-shared";
import { fetchPermission, fetchResources, updatePermissions } from "../api";
import { getPermissionRequests } from "../api/methods";
import { Links } from "../api/parse-links";
import { Permission, Resource } from "../api/representations";
import { useEnvironment } from "../root/KeycloakContext";
import { usePromise } from "../utils/usePromise";
import { EditTheResource } from "./EditTheResource";
import { PermissionRequest } from "./PermissionRequest";

View file

@ -22,10 +22,10 @@ import {
FormErrorText,
SelectControl,
useAlerts,
useEnvironment,
} from "@keycloak/keycloak-ui-shared";
import { updateRequest } from "../api";
import { Permission, Resource } from "../api/representations";
import { useEnvironment } from "../root/KeycloakContext";
import { SharedWith } from "./SharedWith";
type ShareTheResourceProps = {

View file

@ -2,11 +2,13 @@ import { Button } from "@patternfly/react-core";
import { ExternalLinkSquareAltIcon } from "@patternfly/react-icons";
import { useTranslation } from "react-i18next";
import { useHref } from "react-router-dom";
import { KeycloakMasthead, label } from "@keycloak/keycloak-ui-shared";
import { environment } from "../environment";
import {
KeycloakMasthead,
environment,
label,
useEnvironment,
} from "@keycloak/keycloak-ui-shared";
import { joinPath } from "../utils/joinPath";
import { useEnvironment } from "./KeycloakContext";
import style from "./header.module.css";

View file

@ -1,93 +0,0 @@
import { Spinner } from "@patternfly/react-core";
import Keycloak from "keycloak-js";
import {
PropsWithChildren,
createContext,
useContext,
useEffect,
useMemo,
useRef,
useState,
} from "react";
import { AlertProvider, Help } from "@keycloak/keycloak-ui-shared";
import { Environment } from "../environment";
import { ErrorPage } from "./ErrorPage";
export type KeycloakContext = KeycloakContextProps & {
keycloak: Keycloak;
};
const KeycloakEnvContext = createContext<KeycloakContext | undefined>(
undefined,
);
export const useEnvironment = () => {
const context = useContext(KeycloakEnvContext);
if (!context)
throw Error(
"no environment provider in the hierarchy make sure to add the provider",
);
return context;
};
type KeycloakContextProps = {
environment: Environment;
};
export const KeycloakProvider = ({
environment,
children,
}: PropsWithChildren<KeycloakContextProps>) => {
const calledOnce = useRef(false);
const [init, setInit] = useState(false);
const [error, setError] = useState<unknown>();
const keycloak = useMemo(
() => {
const keycloak = new Keycloak({
url: environment.authUrl,
realm: environment.realm,
clientId: environment.clientId,
});
keycloak.onAuthLogout = () => keycloak.login();
return keycloak;
},
[environment],
);
useEffect(() => {
// only needed in dev mode
if (calledOnce.current) {
return;
}
const init = () => keycloak.init({
onLoad: "check-sso",
pkceMethod: "S256",
responseMode: "query",
});
init()
.then(() => setInit(true))
.catch((error) => setError(error));
calledOnce.current = true;
}, [keycloak]);
if (error) {
return <ErrorPage error={error} />;
}
if (!init) {
return <Spinner />;
}
return (
<KeycloakEnvContext.Provider value={{ environment, keycloak }}>
<AlertProvider>
<Help>{children}</Help>
</AlertProvider>
</KeycloakEnvContext.Provider>
);
};

View file

@ -4,8 +4,8 @@ import {
NavItem,
NavList,
PageSidebar,
Spinner,
PageSidebarBody,
Spinner,
} from "@patternfly/react-core";
import {
PropsWithChildren,
@ -22,11 +22,15 @@ import {
useLinkClickHandler,
useLocation,
} from "react-router-dom";
import {
AccountEnvironment,
environment,
useEnvironment,
type Feature,
} from "@keycloak/keycloak-ui-shared";
import fetchContentJson from "../content/fetchContent";
import { environment, type Feature } from "../environment";
import { TFuncKey } from "../i18n";
import { usePromise } from "../utils/usePromise";
import { useEnvironment } from "./KeycloakContext";
type RootMenuItem = {
label: TFuncKey;
@ -45,7 +49,7 @@ export type MenuItem = RootMenuItem | MenuItemWithChildren;
export const PageNav = () => {
const [menuItems, setMenuItems] = useState<MenuItem[]>();
const context = useEnvironment();
const context = useEnvironment<AccountEnvironment>();
usePromise((signal) => fetchContentJson({ signal, context }), setMenuItems);
return (
@ -82,7 +86,7 @@ function NavMenuItem({ menuItem }: NavMenuItemProps) {
const { t } = useTranslation();
const {
environment: { features },
} = useEnvironment();
} = useEnvironment<AccountEnvironment>();
const { pathname } = useLocation();
const isActive = useMemo(
() => matchMenuItem(pathname, menuItem),

View file

@ -1,9 +1,8 @@
import { KeycloakProvider, environment } from "@keycloak/keycloak-ui-shared";
import { Page, Spinner } from "@patternfly/react-core";
import { Suspense } from "react";
import { Outlet } from "react-router-dom";
import { environment } from "../environment";
import { Header } from "./Header";
import { KeycloakProvider } from "./KeycloakContext";
import { PageNav } from "./PageNav";
export const Root = () => {

View file

@ -1,9 +1,8 @@
import { lazy } from "react";
import type { IndexRouteObject, RouteObject } from "react-router-dom";
import { environment } from "@keycloak/keycloak-ui-shared";
import { ErrorPage } from "./root/ErrorPage";
import { Root } from "./root/Root";
import { environment } from "./environment";
const DeviceActivity = lazy(() => import("./account-security/DeviceActivity"));
const LinkedAccounts = lazy(() => import("./account-security/LinkedAccounts"));

View file

@ -124,7 +124,7 @@
<![CDATA[
<script id="environment" type="application/json">
{
"loginRealm": "${loginRealm!"master"}",
"realm": "${loginRealm!"master"}",
"clientId": "${clientId}",
"authServerUrl": "${authServerUrl}",
"authUrl": "${authUrl}",

View file

@ -1,10 +1,14 @@
import KeycloakAdminClient from "@keycloak/keycloak-admin-client";
import { Page } from "@patternfly/react-core";
import { PropsWithChildren, Suspense } from "react";
import { PropsWithChildren, Suspense, useEffect, useState } from "react";
import { Outlet } from "react-router-dom";
import { Help, mainPageContentId } from "@keycloak/keycloak-ui-shared";
import {
mainPageContentId,
useEnvironment,
} from "@keycloak/keycloak-ui-shared";
import { Header } from "./PageHeader";
import { PageNav } from "./PageNav";
import { AdminClientContext, initAdminClient } from "./admin-client";
import { AlertProvider } from "./components/alert/Alerts";
import { PageBreadCrumbs } from "./components/bread-crumb/PageBreadCrumbs";
import { ErrorRenderer } from "./components/error/ErrorRenderer";
@ -30,11 +34,9 @@ const AppContexts = ({ children }: PropsWithChildren) => (
<RealmsProvider>
<RecentRealmsProvider>
<AccessContextProvider>
<Help>
<AlertProvider>
<SubGroups>{children}</SubGroups>
</AlertProvider>
</Help>
<AlertProvider>
<SubGroups>{children}</SubGroups>
</AlertProvider>
</AccessContextProvider>
</RecentRealmsProvider>
</RealmsProvider>
@ -45,23 +47,37 @@ const AppContexts = ({ children }: PropsWithChildren) => (
);
export const App = () => {
const { keycloak, environment } = useEnvironment();
const [adminClient, setAdminClient] = useState<KeycloakAdminClient>();
useEffect(() => {
const init = async () => {
const client = await initAdminClient(keycloak, environment);
setAdminClient(client);
};
init().catch(console.error);
}, []);
if (!adminClient) return <KeycloakSpinner />;
return (
<AppContexts>
<Page
header={<Header />}
isManagedSidebar
sidebar={<PageNav />}
breadcrumb={<PageBreadCrumbs />}
mainContainerId={mainPageContentId}
>
<ErrorBoundaryFallback fallback={ErrorRenderer}>
<Suspense fallback={<KeycloakSpinner />}>
<AuthWall>
<Outlet />
</AuthWall>
</Suspense>
</ErrorBoundaryFallback>
</Page>
</AppContexts>
<AdminClientContext.Provider value={{ keycloak, adminClient }}>
<AppContexts>
<Page
header={<Header />}
isManagedSidebar
sidebar={<PageNav />}
breadcrumb={<PageBreadCrumbs />}
mainContainerId={mainPageContentId}
>
<ErrorBoundaryFallback fallback={ErrorRenderer}>
<Suspense fallback={<KeycloakSpinner />}>
<AuthWall>
<Outlet />
</AuthWall>
</Suspense>
</ErrorBoundaryFallback>
</Page>
</AppContexts>
</AdminClientContext.Provider>
);
};

View file

@ -18,16 +18,15 @@ import { BarsIcon, EllipsisVIcon, HelpIcon } from "@patternfly/react-icons";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link, useHref } from "react-router-dom";
import { useHelp } from "@keycloak/keycloak-ui-shared";
import { useEnvironment, useHelp } from "@keycloak/keycloak-ui-shared";
import { HelpHeader } from "./components/help-enabler/HelpHeader";
import { useRealm } from "./context/realm-context/RealmContext";
import { useWhoAmI } from "./context/whoami/WhoAmI";
import { toDashboard } from "./dashboard/routes/Dashboard";
import environment from "./environment";
import { keycloak } from "./keycloak";
const ManageAccountDropdownItem = () => {
const { keycloak } = useEnvironment();
const { t } = useTranslation();
return (
<DropdownItem
@ -41,6 +40,7 @@ const ManageAccountDropdownItem = () => {
};
const SignOutDropdownItem = () => {
const { keycloak } = useEnvironment();
const { t } = useTranslation();
return (
<DropdownItem
@ -146,6 +146,7 @@ const UserDropdown = () => {
};
export const Header = () => {
const { environment, keycloak } = useEnvironment();
const { t } = useTranslation();
const { realm } = useRealm();

View file

@ -0,0 +1,8 @@
import { KeycloakProvider, environment } from "@keycloak/keycloak-ui-shared";
import { App } from "./App";
export const Root = () => (
<KeycloakProvider environment={environment}>
<App />
</KeycloakProvider>
);

View file

@ -1,20 +1,41 @@
import KeycloakAdminClient from "@keycloak/keycloak-admin-client";
import {
createNamedContext,
useRequiredContext,
} from "@keycloak/keycloak-ui-shared";
import { BaseEnvironment } from "@keycloak/keycloak-ui-shared/dist/context/environment";
import type Keycloak from "keycloak-js";
import environment from "./environment";
import { keycloak } from "./keycloak";
export type AdminClientProps = {
keycloak: Keycloak;
adminClient: KeycloakAdminClient;
};
export const adminClient = new KeycloakAdminClient();
export const AdminClientContext = createNamedContext<
AdminClientProps | undefined
>("AdminClientContext", undefined);
adminClient.setConfig({ realmName: environment.loginRealm });
adminClient.baseUrl = environment.authUrl;
adminClient.registerTokenProvider({
async getAccessToken() {
try {
await keycloak.updateToken(5);
} catch (error) {
keycloak.login();
}
export const useAdminClient = () => useRequiredContext(AdminClientContext);
return keycloak.token;
},
});
export async function initAdminClient(
keycloak: Keycloak,
environment: BaseEnvironment,
) {
const adminClient = new KeycloakAdminClient();
adminClient.setConfig({ realmName: environment.realm });
adminClient.baseUrl = environment.authUrl;
adminClient.registerTokenProvider({
async getAccessToken() {
try {
await keycloak.updateToken(5);
} catch (error) {
keycloak.login();
}
return keycloak.token;
},
});
return adminClient;
}

View file

@ -15,8 +15,6 @@ import { sortBy } from "lodash-es";
import { useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { adminClient } from "../admin-client";
import { useAlerts } from "../components/alert/Alerts";
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner";
@ -42,6 +40,7 @@ import { Policies } from "./policies/Policies";
import { AuthenticationTab, toAuthentication } from "./routes/Authentication";
import { toCreateFlow } from "./routes/CreateFlow";
import { toFlow } from "./routes/Flow";
import { useAdminClient } from "../admin-client";
type UsedBy = "SPECIFIC_CLIENTS" | "SPECIFIC_PROVIDERS" | "DEFAULT";
@ -83,6 +82,7 @@ const AliasRenderer = ({ id, alias, usedBy, builtIn }: AuthenticationType) => {
};
export default function AuthenticationSection() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { realm: realmName } = useRealm();
const [key, setKey] = useState(0);

View file

@ -10,11 +10,10 @@ import { SelectVariant } from "@patternfly/react-core/deprecated";
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { SelectControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../admin-client";
import { useAlerts } from "../components/alert/Alerts";
import { useRealm } from "../context/realm-context/RealmContext";
import { REALM_FLOWS } from "./AuthenticationSection";
import { useAdminClient } from "../admin-client";
type BindingForm = {
bindingType: keyof RealmRepresentation;
@ -26,6 +25,8 @@ type BindFlowDialogProps = {
};
export const BindFlowDialog = ({ flowAlias, onClose }: BindFlowDialogProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const form = useForm<BindingForm>();
const { addAlert, addError } = useAlerts();

View file

@ -11,8 +11,7 @@ import { useEffect } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { adminClient } from "../admin-client";
import { useAdminClient } from "../admin-client";
import { useAlerts } from "../components/alert/Alerts";
import { useRealm } from "../context/realm-context/RealmContext";
import { NameDescription } from "./form/NameDescription";
@ -31,6 +30,8 @@ export const DuplicateFlowModal = ({
toggleDialog,
onComplete,
}: DuplicateFlowModalProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const form = useForm<AuthenticationFlowRepresentation>({ mode: "onChange" });
const { setValue, getValues, handleSubmit } = form;

View file

@ -9,9 +9,8 @@ import {
} from "@patternfly/react-core";
import { useEffect } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { adminClient } from "../admin-client";
import { useAdminClient } from "../admin-client";
import { useAlerts } from "../components/alert/Alerts";
import { NameDescription } from "./form/NameDescription";
@ -21,6 +20,8 @@ type EditFlowModalProps = {
};
export const EditFlowModal = ({ flow, toggleDialog }: EditFlowModalProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();
const form = useForm<AuthenticationFlowRepresentation>({ mode: "onChange" });

View file

@ -21,7 +21,7 @@ import { DomainIcon, TableIcon } from "@patternfly/react-icons";
import { useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import { useNavigate, useParams } from "react-router-dom";
import { adminClient } from "../admin-client";
import { useAdminClient } from "../admin-client";
import { useAlerts } from "../components/alert/Alerts";
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
import { ViewHeader } from "../components/view-header/ViewHeader";
@ -52,6 +52,8 @@ export const providerConditionFilter = (
) => value.displayName?.startsWith("Condition ");
export default function FlowDetails() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { realm } = useRealm();
const { addAlert, addError } = useAlerts();

View file

@ -3,8 +3,7 @@ import type RequiredActionProviderSimpleRepresentation from "@keycloak/keycloak-
import { AlertVariant, Switch } from "@patternfly/react-core";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { adminClient } from "../admin-client";
import { useAdminClient } from "../admin-client";
import { useAlerts } from "../components/alert/Alerts";
import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner";
import { toKey } from "../util";
@ -22,6 +21,8 @@ type Row = {
};
export const RequiredActions = () => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();

View file

@ -8,8 +8,7 @@ import {
import { PlusIcon } from "@patternfly/react-icons";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useFetch } from "../../utils/useFetch";
import type { ExpandableExecution } from "../execution-model";
import { AddStepModal, FlowType } from "./modals/AddStepModal";
@ -29,6 +28,8 @@ export const AddFlowDropdown = ({
onAddExecution,
onAddFlow,
}: AddFlowDropdownProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const [open, setOpen] = useState(false);

View file

@ -15,7 +15,7 @@ import { useEffect, useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { TextControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { DynamicComponents } from "../../components/dynamic/DynamicComponents";
import { convertFormValuesToObject, convertToFormValues } from "../../util";
@ -34,6 +34,8 @@ type ExecutionConfigModalProps = {
export const ExecutionConfigModal = ({
execution,
}: ExecutionConfigModalProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();

View file

@ -10,7 +10,7 @@ import {
} from "@patternfly/react-core";
import { CheckCircleIcon } from "@patternfly/react-icons";
import { useTranslation } from "react-i18next";
import { useAdminClient } from "../../admin-client";
import { fetchUsedBy } from "../../components/role-mapping/resource";
import { KeycloakDataTable } from "../../components/table-toolbar/KeycloakDataTable";
import useToggle from "../../utils/useToggle";
@ -36,6 +36,8 @@ type UsedByModalProps = {
};
const UsedByModal = ({ id, isSpecificClient, onClose }: UsedByModalProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const loader = async (
@ -43,7 +45,7 @@ const UsedByModal = ({ id, isSpecificClient, onClose }: UsedByModalProps) => {
max?: number,
search?: string,
): Promise<{ name: string }[]> => {
const result = await fetchUsedBy({
const result = await fetchUsedBy(adminClient, {
id,
type: isSpecificClient ? "clients" : "idp",
first: first || 0,

View file

@ -10,12 +10,11 @@ import {
} from "@patternfly/react-core";
import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { adminClient } from "../../../admin-client";
import { PaginatingTableToolbar } from "../../../components/table-toolbar/PaginatingTableToolbar";
import { useFetch } from "../../../utils/useFetch";
import useLocaleSort, { mapByKey } from "../../../utils/useLocaleSort";
import { providerConditionFilter } from "../../FlowDetails";
import { useAdminClient } from "../../../admin-client";
type AuthenticationProviderListProps = {
list?: AuthenticationProviderRepresentation[];
@ -56,6 +55,8 @@ type AddStepModalProps = {
};
export const AddStepModal = ({ name, type, onSelect }: AddStepModalProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const [value, setValue] = useState<AuthenticationProviderRepresentation>();

View file

@ -10,7 +10,7 @@ import { useEffect, useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { SelectControl, TextControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../../admin-client";
import { useAdminClient } from "../../../admin-client";
import { useFetch } from "../../../utils/useFetch";
type AddSubFlowProps = {
@ -33,6 +33,8 @@ export const AddSubFlowModal = ({
onConfirm,
onCancel,
}: AddSubFlowProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const form = useForm<Flow>();
const [formProviders, setFormProviders] =

View file

@ -8,9 +8,8 @@ import {
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { SelectControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { FormAccess } from "../../components/form/FormAccess";
import { ViewHeader } from "../../components/view-header/ViewHeader";
@ -22,6 +21,8 @@ import { NameDescription } from "./NameDescription";
const TYPES = ["basic-flow", "client-flow"] as const;
export default function CreateFlow() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const navigate = useNavigate();
const { realm } = useRealm();

View file

@ -10,7 +10,7 @@ import { useEffect } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { SelectControl, TextControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { FormAccess } from "../../components/form/FormAccess";
import { useRealm } from "../../context/realm-context/RealmContext";
@ -33,6 +33,8 @@ type FormFields = Omit<
>;
export const CibaPolicy = ({ realm, realmUpdated }: CibaPolicyProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const form = useForm<FormFields>({ mode: "onChange" });
const { realm: realmName } = useRealm();

View file

@ -19,7 +19,7 @@ import {
SelectControl,
SwitchControl,
} from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { FormAccess } from "../../components/form/FormAccess";
import { TimeSelectorControl } from "../../components/time-selector/TimeSelectorControl";
@ -43,6 +43,8 @@ type FormFields = Omit<
>;
export const OtpPolicy = ({ realm, realmUpdated }: OtpPolicyProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const form = useForm<FormFields>({ mode: "onChange", defaultValues: realm });
const {

View file

@ -7,15 +7,15 @@ import {
ButtonVariant,
Divider,
EmptyState,
EmptyStateActions,
EmptyStateBody,
EmptyStateFooter,
EmptyStateHeader,
EmptyStateIcon,
PageSection,
Toolbar,
ToolbarContent,
ToolbarItem,
EmptyStateActions,
EmptyStateHeader,
EmptyStateFooter,
Select,
SelectOption,
MenuToggle,
@ -25,8 +25,7 @@ import { PlusCircleIcon } from "@patternfly/react-icons";
import { useEffect, useMemo, useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { FormAccess } from "../../components/form/FormAccess";
import { useRealm } from "../../context/realm-context/RealmContext";
@ -94,6 +93,8 @@ export const PasswordPolicy = ({
realm,
realmUpdated,
}: PasswordPolicyProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { passwordPolicies } = useServerInfo();

View file

@ -2,8 +2,7 @@ import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/r
import { Tab, Tabs, TabTitleText } from "@patternfly/react-core";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
import { useRealm } from "../../context/realm-context/RealmContext";
import { useFetch } from "../../utils/useFetch";
@ -13,6 +12,8 @@ import { PasswordPolicy } from "./PasswordPolicy";
import { WebauthnPolicy } from "./WebauthnPolicy";
export const Policies = () => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const [subTab, setSubTab] = useState(1);
const { realm: realmName } = useRealm();

View file

@ -22,7 +22,6 @@ import {
TextControl,
useHelp,
} from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { FormAccess } from "../../components/form/FormAccess";
import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput";
@ -30,6 +29,7 @@ import { TimeSelectorControl } from "../../components/time-selector/TimeSelector
import { useRealm } from "../../context/realm-context/RealmContext";
import { convertFormValuesToObject, convertToFormValues } from "../../util";
import { useAdminClient } from "../../admin-client";
import "./webauthn-policy.css";
const SIGNATURE_ALGORITHMS = [
@ -108,6 +108,8 @@ export const WebauthnPolicy = ({
realmUpdated,
isPasswordLess = false,
}: WebauthnPolicyProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();
const { realm: realmName } = useRealm();

View file

@ -2,7 +2,7 @@ import { AlertVariant } from "@patternfly/react-core";
import { Select } from "@patternfly/react-core/deprecated";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useAdminClient } from "../admin-client";
import type { Row } from "../clients/scopes/ClientScopes";
import { useAlerts } from "../components/alert/Alerts";
import {
@ -24,6 +24,8 @@ export const ChangeTypeDropdown = ({
selectedRows,
refresh,
}: ChangeTypeDropdownProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const [open, setOpen] = useState(false);
@ -44,12 +46,13 @@ export const ChangeTypeDropdown = ({
selectedRows.map((row) => {
return clientId
? changeClientScope(
adminClient,
clientId,
row,
row.type,
value as ClientScope,
)
: changeScope(row, value as ClientScope);
: changeScope(adminClient, row, value as ClientScope);
}),
);
setOpen(false);

View file

@ -14,8 +14,7 @@ import { cellWidth } from "@patternfly/react-table";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { adminClient } from "../admin-client";
import { useAdminClient } from "../admin-client";
import type { Row } from "../clients/scopes/ClientScopes";
import { getProtocolName } from "../clients/utils";
import { useAlerts } from "../components/alert/Alerts";
@ -56,6 +55,8 @@ type TypeSelectorProps = ClientScopeDefaultOptionalType & {
};
const TypeSelector = (scope: TypeSelectorProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();
@ -66,7 +67,7 @@ const TypeSelector = (scope: TypeSelectorProps) => {
all
onSelect={async (value) => {
try {
await changeScope(scope, value as AllClientScopeType);
await changeScope(adminClient, scope, value as AllClientScopeType);
addAlert(t("clientScopeSuccess"), AlertVariant.success);
scope.refresh();
} catch (error) {
@ -90,6 +91,8 @@ const ClientScopeDetailLink = ({
};
export default function ClientScopesSection() {
const { adminClient } = useAdminClient();
const { realm } = useRealm();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();
@ -165,7 +168,7 @@ export default function ClientScopesSection() {
try {
for (const scope of selectedScopes) {
try {
await removeScope(scope);
await removeScope(adminClient, scope);
} catch (error: any) {
console.warn(
"could not remove scope",

View file

@ -1,8 +1,7 @@
import { AlertVariant, PageSection } from "@patternfly/react-core";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { adminClient } from "../admin-client";
import { useAdminClient } from "../admin-client";
import { useAlerts } from "../components/alert/Alerts";
import {
ClientScopeDefaultOptionalType,
@ -15,6 +14,8 @@ import { ScopeForm } from "./details/ScopeForm";
import { toClientScope } from "./routes/ClientScope";
export default function CreateClientScope() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const navigate = useNavigate();
const { realm } = useRealm();
@ -37,7 +38,11 @@ export default function CreateClientScope() {
throw new Error(t("notFound"));
}
await changeScope({ ...clientScope, id: scope.id }, clientScope.type);
await changeScope(
adminClient,
{ ...clientScope, id: scope.id },
clientScope.type,
);
addAlert(t("createClientScopeSuccess", AlertVariant.success));

View file

@ -15,8 +15,7 @@ import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { useHelp } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../admin-client";
import { useAdminClient } from "../admin-client";
import { useAlerts } from "../components/alert/Alerts";
import {
AllClientScopes,
@ -43,10 +42,12 @@ import {
ClientScopeTab,
toClientScope,
} from "./routes/ClientScope";
import { toMapper } from "./routes/Mapper";
import { toClientScopes } from "./routes/ClientScopes";
import { toMapper } from "./routes/Mapper";
export default function EditClientScope() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const navigate = useNavigate();
const { realm } = useRealm();
@ -118,7 +119,7 @@ export default function EditClientScope() {
try {
await adminClient.clientScopes.update({ id }, clientScope);
await changeScope({ ...clientScope, id }, clientScope.type);
await changeScope(adminClient, { ...clientScope, id }, clientScope.type);
addAlert(t("updateSuccessClientScope"), AlertVariant.success);
} catch (error) {

View file

@ -15,7 +15,8 @@ import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Link, useMatch, useNavigate } from "react-router-dom";
import { TextControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { toDedicatedScope } from "../../clients/routes/DedicatedScopeDetails";
import { useAlerts } from "../../components/alert/Alerts";
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
import { DynamicComponents } from "../../components/dynamic/DynamicComponents";
@ -28,9 +29,10 @@ import { useFetch } from "../../utils/useFetch";
import { useParams } from "../../utils/useParams";
import { toClientScope } from "../routes/ClientScope";
import { MapperParams, MapperRoute } from "../routes/Mapper";
import { toDedicatedScope } from "../../clients/routes/DedicatedScopeDetails";
export default function MappingDetails() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();

View file

@ -16,8 +16,7 @@ import { useMemo, useState } from "react";
import { Controller, FormProvider, useForm, useWatch } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { adminClient } from "../admin-client";
import { useAdminClient } from "../admin-client";
import { useAlerts } from "../components/alert/Alerts";
import {
ConfirmDialogModal,
@ -188,6 +187,8 @@ export type FormFields = Omit<
>;
export default function ClientDetails() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();
const { realm } = useRealm();

View file

@ -2,7 +2,7 @@ import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/
import type UserSessionRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userSessionRepresentation";
import { PageSection } from "@patternfly/react-core";
import { useTranslation } from "react-i18next";
import { adminClient } from "../admin-client";
import { useAdminClient } from "../admin-client";
import type { LoaderFunction } from "../components/table-toolbar/KeycloakDataTable";
import SessionsTable from "../sessions/SessionsTable";
@ -11,6 +11,8 @@ type ClientSessionsProps = {
};
export const ClientSessions = ({ client }: ClientSessionsProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const loader: LoaderFunction<UserSessionRepresentation> = async (

View file

@ -14,8 +14,7 @@ import { IRowData, TableText, cellWidth } from "@patternfly/react-table";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { adminClient } from "../admin-client";
import { useAdminClient } from "../admin-client";
import { useAlerts } from "../components/alert/Alerts";
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
import { FormattedLink } from "../components/external-link/FormattedLink";
@ -74,6 +73,7 @@ const ClientDescription = (client: ClientRepresentation) => (
);
const ClientHomeLink = (client: ClientRepresentation) => {
const { adminClient } = useAdminClient();
const href = convertClientToUrl(client, adminClient.baseUrl);
if (!href) {
@ -117,6 +117,8 @@ const ToolbarItems = () => {
};
export default function ClientsSection() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();
const { realm } = useRealm();

View file

@ -8,8 +8,7 @@ import { useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { FormAccess } from "../../components/form/FormAccess";
import { ViewHeader } from "../../components/view-header/ViewHeader";
@ -23,6 +22,8 @@ import { GeneralSettings } from "./GeneralSettings";
import { LoginSettings } from "./LoginSettings";
export default function NewClientForm() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { realm } = useRealm();
const navigate = useNavigate();

View file

@ -8,7 +8,7 @@ import {
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { TextControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
type FormFields = {
@ -28,6 +28,8 @@ export const AddHostDialog = ({
onAdded,
onClose,
}: AddHostDialogProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const form = useForm<FormFields>();
const {

View file

@ -8,21 +8,20 @@ import {
import { useState } from "react";
import { Controller, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { FormAccess } from "../../components/form/FormAccess";
import { HelpItem } from "@keycloak/keycloak-ui-shared";
import { useAdminClient } from "../../admin-client";
import { DefaultSwitchControl } from "../../components/SwitchControl";
import { adminClient } from "../../admin-client";
import { FormAccess } from "../../components/form/FormAccess";
import { KeyValueInput } from "../../components/key-value-form/KeyValueInput";
import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput";
import { TimeSelector } from "../../components/time-selector/TimeSelector";
import { useRealm } from "../../context/realm-context/RealmContext";
import { convertAttributeNameToForm } from "../../util";
import { useFetch } from "../../utils/useFetch";
import useIsFeatureEnabled, { Feature } from "../../utils/useIsFeatureEnabled";
import { FormFields } from "../ClientDetails";
import { TokenLifespan } from "./TokenLifespan";
import useIsFeatureEnabled, { Feature } from "../../utils/useIsFeatureEnabled";
type AdvancedSettingsProps = {
save: () => void;
reset: () => void;
@ -36,6 +35,8 @@ export const AdvancedSettings = ({
protocol,
hasConfigureAccess,
}: AdvancedSettingsProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const [open, setOpen] = useState(false);

View file

@ -4,7 +4,7 @@ import { sortBy } from "lodash-es";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { SelectControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { FormAccess } from "../../components/form/FormAccess";
import { useFetch } from "../../utils/useFetch";
@ -21,6 +21,8 @@ export const AuthenticationOverrides = ({
reset,
hasConfigureAccess,
}: AuthenticationOverridesProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const [flows, setFlows] = useState<AuthenticationFlowRepresentation[]>([]);

View file

@ -11,8 +11,7 @@ import {
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { HelpItem } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
import { FormAccess } from "../../components/form/FormAccess";
@ -35,6 +34,8 @@ export const ClusteringPanel = ({
save,
client: { id, registeredNodes, access },
}: AdvancedProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();
const formatDate = useFormatDate();

View file

@ -30,9 +30,8 @@ import {
HelpItem,
TextControl,
} from "@keycloak/keycloak-ui-shared";
import { ForbiddenSection } from "../../ForbiddenSection";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { ClientSelect } from "../../components/client/ClientSelect";
import { FormAccess } from "../../components/form/FormAccess";
@ -98,6 +97,8 @@ export const AuthorizationEvaluate = (props: Props) => {
};
const AuthorizationEvaluateContent = ({ client }: Props) => {
const { adminClient } = useAdminClient();
const form = useForm<EvaluateFormInputs>({ mode: "onChange" });
const {
control,

View file

@ -9,16 +9,18 @@ import { saveAs } from "file-saver";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { TextAreaControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { FormAccess } from "../../components/form/FormAccess";
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
import { useFetch } from "../../utils/useFetch";
import { prettyPrintJSON } from "../../util";
import { useFetch } from "../../utils/useFetch";
import { useParams } from "../../utils/useParams";
import type { ClientParams } from "../routes/Client";
export const AuthorizationExport = () => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { clientId } = useParams<ClientParams>();
const { addAlert, addError } = useAlerts();

View file

@ -1,8 +1,7 @@
import type ScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/scopeRepresentation";
import { Alert, AlertVariant } from "@patternfly/react-core";
import { useTranslation } from "react-i18next";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { ConfirmDialogModal } from "../../components/confirm-dialog/ConfirmDialog";
import type { PermissionScopeRepresentation } from "./Scopes";
@ -25,6 +24,8 @@ export const DeleteScopeDialog = ({
open,
toggleDialog,
}: DeleteScopeDialogProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();

View file

@ -1,11 +1,10 @@
import type ResourceServerRepresentation from "@keycloak/keycloak-admin-client/lib/defs/resourceServerRepresentation";
import { DescriptionList } from "@patternfly/react-core";
import { useState } from "react";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
import { useFetch } from "../../utils/useFetch";
import { useRealm } from "../../context/realm-context/RealmContext";
import { useFetch } from "../../utils/useFetch";
import { toPermissionDetails } from "../routes/PermissionDetails";
import { toScopeDetails } from "../routes/Scope";
import { DetailDescription, DetailDescriptionLink } from "./DetailDescription";
@ -21,6 +20,8 @@ type DetailCellProps = {
};
export const DetailCell = ({ id, clientId, uris }: DetailCellProps) => {
const { adminClient } = useAdminClient();
const { realm } = useRealm();
const [scope, setScope] = useState<Scope>();
const [permissions, setPermissions] =

View file

@ -21,8 +21,7 @@ import {
TextAreaControl,
TextControl,
} from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
import { FormAccess } from "../../components/form/FormAccess";
@ -46,6 +45,8 @@ type FormFields = PolicyRepresentation & {
};
export default function PermissionDetails() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const form = useForm<FormFields>({

View file

@ -26,8 +26,7 @@ import {
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
@ -73,6 +72,8 @@ export const AuthorizationPermissions = ({
clientId,
isDisabled = false,
}: PermissionsProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const navigate = useNavigate();
const { addAlert, addError } = useAlerts();

View file

@ -20,8 +20,7 @@ import {
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
@ -66,6 +65,8 @@ export const AuthorizationPolicies = ({
clientId,
isDisabled = false,
}: PoliciesProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();
const { realm } = useRealm();

View file

@ -16,23 +16,23 @@ import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { HelpItem, TextControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { DefaultSwitchControl } from "../../components/SwitchControl";
import { useAlerts } from "../../components/alert/Alerts";
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
import { FormAccess } from "../../components/form/FormAccess";
import type { KeyValueType } from "../../components/key-value-form/key-value-convert";
import { KeyValueInput } from "../../components/key-value-form/KeyValueInput";
import type { KeyValueType } from "../../components/key-value-form/key-value-convert";
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput";
import { ViewHeader } from "../../components/view-header/ViewHeader";
import { useAccess } from "../../context/access/Access";
import { convertFormValuesToObject, convertToFormValues } from "../../util";
import { useFetch } from "../../utils/useFetch";
import { useParams } from "../../utils/useParams";
import { toAuthorizationTab } from "../routes/AuthenticationTab";
import { ResourceDetailsParams, toResourceDetails } from "../routes/Resource";
import { ScopePicker } from "./ScopePicker";
import { DefaultSwitchControl } from "../../components/SwitchControl";
import { useAccess } from "../../context/access/Access";
import "./resource-details.css";
type SubmittedResource = Omit<
@ -43,6 +43,8 @@ type SubmittedResource = Omit<
};
export default function ResourceDetails() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const [client, setClient] = useState<ClientRepresentation>();
const [resource, setResource] = useState<ResourceRepresentation>();

View file

@ -19,8 +19,7 @@ import {
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
@ -54,6 +53,8 @@ export const AuthorizationResources = ({
clientId,
isDisabled = false,
}: ResourcesProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const navigate = useNavigate();
const { addAlert, addError } = useAlerts();

View file

@ -1,3 +1,4 @@
import PolicyProviderRepresentation from "@keycloak/keycloak-admin-client/lib/defs/policyProviderRepresentation";
import type PolicyRepresentation from "@keycloak/keycloak-admin-client/lib/defs/policyRepresentation";
import type ResourceRepresentation from "@keycloak/keycloak-admin-client/lib/defs/resourceRepresentation";
import type {
@ -17,18 +18,16 @@ import {
useFormContext,
} from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
import { useRealm } from "../../context/realm-context/RealmContext";
import { useFetch } from "../../utils/useFetch";
import { toPolicyDetails } from "../routes/PolicyDetails";
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
import { toCreatePolicy } from "../routes/NewPolicy";
import { NewPolicyDialog } from "./NewPolicyDialog";
import useToggle from "../../utils/useToggle";
import PolicyProviderRepresentation from "@keycloak/keycloak-admin-client/lib/defs/policyProviderRepresentation";
import { toCreatePolicy } from "../routes/NewPolicy";
import { toPolicyDetails } from "../routes/PolicyDetails";
import { toResourceDetails } from "../routes/Resource";
import { NewPolicyDialog } from "./NewPolicyDialog";
type Type = "resources" | "policies";
@ -76,6 +75,8 @@ export const ResourcesPolicySelect = ({
preSelected,
isRequired = false,
}: ResourcesPolicySelectProps) => {
const { adminClient } = useAdminClient();
const { realm } = useRealm();
const { t } = useTranslation();
const navigate = useNavigate();

View file

@ -12,7 +12,7 @@ import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { TextControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { FormAccess } from "../../components/form/FormAccess";
import { ViewHeader } from "../../components/view-header/ViewHeader";
@ -26,6 +26,8 @@ import { DeleteScopeDialog } from "./DeleteScopeDialog";
type FormFields = Omit<ScopeRepresentation, "resources">;
export default function ScopeDetails() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { id, scopeId, realm } = useParams<ScopeDetailsParams>();
const navigate = useNavigate();

View file

@ -9,8 +9,7 @@ import { useState } from "react";
import { Controller, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { HelpItem } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useFetch } from "../../utils/useFetch";
type Scope = {
@ -19,6 +18,8 @@ type Scope = {
};
export const ScopePicker = ({ clientId }: { clientId: string }) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { control } = useFormContext();

View file

@ -7,8 +7,7 @@ import {
import { useRef, useState } from "react";
import { Controller, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useFetch } from "../../utils/useFetch";
type ScopeSelectProps = {
@ -22,6 +21,8 @@ export const ScopeSelect = ({
resourceId,
preSelected,
}: ScopeSelectProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const {

View file

@ -18,8 +18,7 @@ import {
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
import { ListEmptyState } from "../../components/list-empty-state/ListEmptyState";
import { PaginatingTableToolbar } from "../../components/table-toolbar/PaginatingTableToolbar";
@ -53,6 +52,8 @@ export const AuthorizationScopes = ({
clientId,
isDisabled = false,
}: ScopesProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const navigate = useNavigate();
const { realm } = useRealm();

View file

@ -11,7 +11,7 @@ import { useState } from "react";
import { Controller, FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { HelpItem } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { DefaultSwitchControl } from "../../components/SwitchControl";
import { useAlerts } from "../../components/alert/Alerts";
import { FixedButtonsGroup } from "../../components/form/FixedButtonGroup";
@ -35,6 +35,8 @@ export type FormFields = Omit<
>;
export const AuthorizationSettings = ({ clientId }: { clientId: string }) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const [resource, setResource] = useState<ResourceServerRepresentation>();
const [importDialog, toggleImportDialog] = useToggle();

View file

@ -6,8 +6,7 @@ import { useState } from "react";
import { Controller, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { FormErrorText, HelpItem } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../../admin-client";
import { useAdminClient } from "../../../admin-client";
import { useFetch } from "../../../utils/useFetch";
import useLocaleSort, { mapByKey } from "../../../utils/useLocaleSort";
import { AddScopeDialog } from "../../scopes/AddScopeDialog";
@ -18,6 +17,8 @@ export type RequiredIdValue = {
};
export const ClientScope = () => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const {
control,

View file

@ -1,17 +1,16 @@
import type GroupRepresentation from "@keycloak/keycloak-admin-client/lib/defs/groupRepresentation";
import {
FormErrorText,
HelpItem,
TextControl,
} from "@keycloak/keycloak-ui-shared";
import { Button, Checkbox, FormGroup } from "@patternfly/react-core";
import { MinusCircleIcon } from "@patternfly/react-icons";
import { Table, Tbody, Td, Th, Thead, Tr } from "@patternfly/react-table";
import { useState } from "react";
import { Controller, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import {
FormErrorText,
HelpItem,
TextControl,
} from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../../admin-client";
import { useAdminClient } from "../../../admin-client";
import { GroupPickerDialog } from "../../../components/group/GroupPickerDialog";
import { useFetch } from "../../../utils/useFetch";
@ -26,6 +25,8 @@ export type GroupValue = {
};
export const Group = () => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const {
control,

View file

@ -11,8 +11,7 @@ import { useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { adminClient } from "../../../admin-client";
import { useAdminClient } from "../../../admin-client";
import { useAlerts } from "../../../components/alert/Alerts";
import { useConfirmDialog } from "../../../components/confirm-dialog/ConfirmDialog";
import { FormAccess } from "../../../components/form/FormAccess";
@ -62,6 +61,8 @@ const COMPONENTS: {
export const isValidComponentType = (value: string) => value in COMPONENTS;
export default function PolicyDetails() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { id, realm, policyId, policyType } = useParams<PolicyDetailsParams>();
const navigate = useNavigate();

View file

@ -5,8 +5,7 @@ import { useState } from "react";
import { Controller, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { FormErrorText, HelpItem } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../../admin-client";
import { useAdminClient } from "../../../admin-client";
import { DefaultSwitchControl } from "../../../components/SwitchControl";
import { AddRoleMappingModal } from "../../../components/role-mapping/AddRoleMappingModal";
import { Row, ServiceRole } from "../../../components/role-mapping/RoleMapping";
@ -14,6 +13,8 @@ import { useFetch } from "../../../utils/useFetch";
import type { RequiredIdValue } from "./ClientScope";
export const Role = () => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const {
control,

View file

@ -4,15 +4,15 @@ import {
Button,
FormGroup,
InputGroup,
InputGroupItem,
Split,
SplitItem,
InputGroupItem,
} from "@patternfly/react-core";
import { useState } from "react";
import { useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { PasswordInput } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
import { useAccess } from "../../context/access/Access";
@ -89,6 +89,8 @@ const ExpireDateFormatter = ({ time }: { time: number }) => {
};
export const ClientSecret = ({ client, secret, toggle }: ClientSecretProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();

View file

@ -19,7 +19,7 @@ import { useState } from "react";
import { useFormContext, useWatch } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { HelpItem, SelectControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
import { FormAccess } from "../../components/form/FormAccess";
@ -40,6 +40,8 @@ export type CredentialsProps = {
};
export const Credentials = ({ client, save, refresh }: CredentialsProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();
const clientId = client.id!;

View file

@ -12,8 +12,7 @@ import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { TextControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { FormAccess } from "../../components/form/FormAccess";
import { FileUploadForm } from "../../components/json-file-upload/FileUploadForm";
@ -34,6 +33,8 @@ import { toClients } from "../routes/Clients";
const isXml = (text: string) => text.match(/(<.[^(><.)]+>)/g);
export default function ImportForm() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const navigate = useNavigate();
const { realm } = useRealm();

View file

@ -10,7 +10,7 @@ import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { NumberControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { FormAccess } from "../../components/form/FormAccess";
import { TimeSelectorControl } from "../../components/time-selector/TimeSelectorControl";
@ -20,6 +20,8 @@ import { toClients } from "../routes/Clients";
import { AccessTokenDialog } from "./AccessTokenDialog";
export default function CreateInitialAccessToken() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const form = useForm({ mode: "onChange" });
const {

View file

@ -4,8 +4,7 @@ import { wrappable } from "@patternfly/react-table";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
import { ListEmptyState } from "../../components/list-empty-state/ListEmptyState";
@ -18,6 +17,8 @@ import useFormatDate, { FORMAT_DATE_AND_TIME } from "../../utils/useFormatDate";
import { toCreateInitialAccessToken } from "../routes/CreateInitialAccessToken";
export const InitialAccessTokenList = () => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();

View file

@ -3,8 +3,7 @@ import { Button, Form, Modal } from "@patternfly/react-core";
import { saveAs } from "file-saver";
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { useRealm } from "../../context/realm-context/RealmContext";
import { KeyForm, getFileExtension } from "./GenerateKeyDialog";
@ -21,6 +20,8 @@ export const ExportSamlKeyDialog = ({
close,
keyType,
}: ExportSamlKeyDialogProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { realm } = useRealm();

View file

@ -17,7 +17,7 @@ import { useState } from "react";
import { useFormContext, useWatch } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { TextControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { DefaultSwitchControl } from "../../components/SwitchControl";
import { useAlerts } from "../../components/alert/Alerts";
import { FormAccess } from "../../components/form/FormAccess";
@ -38,6 +38,8 @@ type KeysProps = {
const attr = "jwt.credential";
export const Keys = ({ clientId, save, hasConfigureAccess }: KeysProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const {
control,

View file

@ -1,7 +1,7 @@
import { AlertVariant } from "@patternfly/react-core";
import { FormProvider, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { ConfirmDialogModal } from "../../components/confirm-dialog/ConfirmDialog";
import { KeyForm } from "./GenerateKeyDialog";
@ -19,6 +19,8 @@ export const SamlImportKeyDialog = ({
attr,
onClose,
}: SamlImportKeyDialogProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const form = useFormContext<SamlKeysDialogForm>();
const { handleSubmit } = form;
@ -26,7 +28,7 @@ export const SamlImportKeyDialog = ({
const { addAlert, addError } = useAlerts();
const submit = (form: SamlKeysDialogForm) => {
submitForm(form, id, attr, (error) => {
submitForm(adminClient, form, id, attr, (error) => {
if (error) {
addError("importError", error);
} else {

View file

@ -17,7 +17,7 @@ import { Fragment, useState } from "react";
import { Controller, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { FormPanel, HelpItem } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
import { FormAccess } from "../../components/form/FormAccess";
@ -154,6 +154,8 @@ const KeySection = ({
};
export const SamlKeys = ({ clientId, save }: SamlKeysProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const [isChanged, setIsChanged] = useState<KeyTypes>();
const [keyInfo, setKeyInfo] = useState<CertificateRepresentation[]>();

View file

@ -1,3 +1,4 @@
import KeycloakAdminClient from "@keycloak/keycloak-admin-client";
import type CertificateRepresentation from "@keycloak/keycloak-admin-client/lib/defs/certificateRepresentation";
import type KeyStoreConfig from "@keycloak/keycloak-admin-client/lib/defs/keystoreConfig";
import {
@ -22,8 +23,7 @@ import { useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { HelpItem } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { Certificate } from "./Certificate";
import { KeyForm } from "./GenerateKeyDialog";
@ -41,6 +41,7 @@ export type SamlKeysDialogForm = KeyStoreConfig & {
};
export const submitForm = async (
adminClient: KeycloakAdminClient,
form: SamlKeysDialogForm,
id: string,
attr: KeyTypes,
@ -70,6 +71,8 @@ export const SamlKeysDialog = ({
onClose,
onCancel,
}: SamlKeysDialogProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const [type, setType] = useState(false);
const [keys, setKeys] = useState<CertificateRepresentation>();
@ -82,7 +85,7 @@ export const SamlKeysDialog = ({
const { addAlert, addError } = useAlerts();
const submit = (form: SamlKeysDialogForm) => {
submitForm(form, id, attr, (error) => {
submitForm(adminClient, form, id, attr, (error) => {
if (error) {
addError("importError", error);
} else {

View file

@ -3,8 +3,7 @@ import { Button, ButtonVariant, ToolbarItem } from "@patternfly/react-core";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link, useNavigate, useParams } from "react-router-dom";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
import {
@ -44,6 +43,8 @@ const DetailLink = (comp: ComponentRepresentation) => {
export const ClientRegistrationList = ({
subType,
}: ClientRegistrationListProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { subTab } = useParams<ClientRegistrationParams>();
const navigate = useNavigate();

View file

@ -12,7 +12,7 @@ import { FormProvider, useForm, useWatch } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { TextControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
import { DynamicComponents } from "../../components/dynamic/DynamicComponents";
@ -29,6 +29,8 @@ import {
import { toClientRegistration } from "../routes/ClientRegistration";
export default function DetailProvider() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { id, providerId, subTab } = useParams<RegistrationProviderParams>();
const navigate = useNavigate();

View file

@ -3,8 +3,7 @@ import { AlertVariant } from "@patternfly/react-core";
import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { useNavigate, useParams } from "react-router-dom";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { AttributeForm } from "../../components/key-value-form/AttributeForm";
import { RoleForm } from "../../components/role-form/RoleForm";
@ -14,6 +13,8 @@ import { toClientRole } from "../routes/ClientRole";
import { NewRoleParams } from "../routes/NewRole";
export default function CreateClientRole() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const form = useForm<AttributeForm>({ mode: "onChange" });
const navigate = useNavigate();

View file

@ -13,8 +13,7 @@ import {
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { ChangeTypeDropdown } from "../../client-scopes/ChangeTypeDropdown";
import {
SearchDropdown,
@ -73,6 +72,8 @@ const TypeSelector = ({
fineGrainedAccess,
...scope
}: TypeSelectorProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();
@ -89,6 +90,7 @@ const TypeSelector = ({
onSelect={async (value) => {
try {
await changeClientScope(
adminClient,
clientId,
scope,
scope.type,
@ -110,6 +112,8 @@ export const ClientScopes = ({
clientName,
fineGrainedAccess,
}: ClientScopesProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();
const { realm } = useRealm();
@ -205,6 +209,7 @@ export const ClientScopes = ({
onConfirm: async () => {
try {
await removeClientScope(
adminClient,
clientId,
selectedRows[0],
selectedRows[0].type as ClientScope,
@ -230,7 +235,12 @@ export const ClientScopes = ({
await Promise.all(
scopes.map(
async (scope) =>
await addClientScope(clientId, scope.scope, scope.type!),
await addClientScope(
adminClient,
clientId,
scope.scope,
scope.type!,
),
),
);
addAlert(t("clientScopeSuccess"), AlertVariant.success);
@ -301,6 +311,7 @@ export const ClientScopes = ({
await Promise.all(
selectedRows.map((row) =>
removeClientScope(
adminClient,
clientId,
{ ...row },
row.type as ClientScope,

View file

@ -9,12 +9,10 @@ import {
} from "@patternfly/react-core";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { FormAccess } from "../../components/form/FormAccess";
import { HelpItem } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { FormAccess } from "../../components/form/FormAccess";
import { RoleMapping, Row } from "../../components/role-mapping/RoleMapping";
import { useAccess } from "../../context/access/Access";
@ -25,6 +23,8 @@ type DedicatedScopeProps = {
export const DedicatedScope = ({
client: initialClient,
}: DedicatedScopeProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();

View file

@ -10,8 +10,7 @@ import {
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { MapperList } from "../../client-scopes/details/MapperList";
import { useAlerts } from "../../components/alert/Alerts";
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
@ -31,6 +30,8 @@ import { toMapper } from "../routes/Mapper";
import { DedicatedScope } from "./DedicatedScope";
export default function DedicatedScopes() {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const navigate = useNavigate();
const { realm, clientId } = useParams<DedicatedScopeDetailsParams>();

View file

@ -28,16 +28,15 @@ import { useEffect, useRef, useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { HelpItem, useHelp } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { KeycloakDataTable } from "../../components/table-toolbar/KeycloakDataTable";
import { UserSelect } from "../../components/users/UserSelect";
import { useAccess } from "../../context/access/Access";
import { useRealm } from "../../context/realm-context/RealmContext";
import { useServerInfo } from "../../context/server-info/ServerInfoProvider";
import { prettyPrintJSON } from "../../util";
import { useFetch } from "../../utils/useFetch";
import { GeneratedCodeTab } from "./GeneratedCodeTab";
import { useAccess } from "../../context/access/Access";
import "./evaluate.css";
@ -116,6 +115,8 @@ const EffectiveRoles = ({
};
export const EvaluateScopes = ({ clientId, protocol }: EvaluateScopesProps) => {
const { adminClient } = useAdminClient();
const prefix = "openid";
const { t } = useTranslation();
const { enabled } = useHelp();

View file

@ -6,8 +6,7 @@ import { InfoCircleIcon } from "@patternfly/react-icons";
import { useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useAlerts } from "../../components/alert/Alerts";
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
import { RoleMapping, Row } from "../../components/role-mapping/RoleMapping";
@ -23,6 +22,8 @@ type ServiceAccountProps = {
};
export const ServiceAccount = ({ client }: ServiceAccountProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const { addAlert, addError } = useAlerts();
const { realm } = useRealm();

View file

@ -1,5 +1,6 @@
import type ClientScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientScopeRepresentation";
import KeycloakAdminClient from "@keycloak/keycloak-admin-client";
import {
DropdownItem,
Select,
@ -9,8 +10,6 @@ import {
import type { TFunction } from "i18next";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { adminClient } from "../../admin-client";
import { toUpperCase } from "../../util";
export enum ClientScope {
@ -96,23 +95,25 @@ export type ClientScopeDefaultOptionalType = ClientScopeRepresentation & {
};
export const changeScope = async (
adminClient: KeycloakAdminClient,
clientScope: ClientScopeDefaultOptionalType,
changeTo: AllClientScopeType,
) => {
await removeScope(clientScope);
await addScope(clientScope, changeTo);
await removeScope(adminClient, clientScope);
await addScope(adminClient, clientScope, changeTo);
};
const castAdminClient = () =>
const castAdminClient = (adminClient: KeycloakAdminClient) =>
adminClient.clientScopes as unknown as {
[index: string]: Function;
};
export const removeScope = async (
adminClient: KeycloakAdminClient,
clientScope: ClientScopeDefaultOptionalType,
) => {
if (clientScope.type !== AllClientScopes.none)
await castAdminClient()[
await castAdminClient(adminClient)[
`delDefault${
clientScope.type === ClientScope.optional ? "Optional" : ""
}ClientScope`
@ -122,11 +123,12 @@ export const removeScope = async (
};
const addScope = async (
adminClient: KeycloakAdminClient,
clientScope: ClientScopeDefaultOptionalType,
type: AllClientScopeType,
) => {
if (type !== AllClientScopes.none)
await castAdminClient()[
await castAdminClient(adminClient)[
`addDefault${type === ClientScope.optional ? "Optional" : ""}ClientScope`
]({
id: clientScope.id!,
@ -134,18 +136,20 @@ const addScope = async (
};
export const changeClientScope = async (
adminClient: KeycloakAdminClient,
clientId: string,
clientScope: ClientScopeRepresentation,
type: AllClientScopeType,
changeTo: ClientScopeType,
) => {
if (type !== "none") {
await removeClientScope(clientId, clientScope, type);
await removeClientScope(adminClient, clientId, clientScope, type);
}
await addClientScope(clientId, clientScope, changeTo);
await addClientScope(adminClient, clientId, clientScope, changeTo);
};
export const removeClientScope = async (
adminClient: KeycloakAdminClient,
clientId: string,
clientScope: ClientScopeRepresentation,
type: ClientScope,
@ -159,6 +163,7 @@ export const removeClientScope = async (
};
export const addClientScope = async (
adminClient: KeycloakAdminClient,
clientId: string,
clientScope: ClientScopeRepresentation,
type: ClientScopeType,

View file

@ -4,8 +4,7 @@ import { SelectProps, SelectVariant } from "@patternfly/react-core/deprecated";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { SelectControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useFetch } from "../../utils/useFetch";
import type { ComponentProps } from "../dynamic/components";
@ -20,6 +19,8 @@ export const ClientSelect = ({
required = false,
variant = SelectVariant.typeahead,
}: ClientSelectProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const [clients, setClients] = useState<ClientRepresentation[]>([]);

View file

@ -16,8 +16,7 @@ import { saveAs } from "file-saver";
import { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { HelpItem, useHelp } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useRealm } from "../../context/realm-context/RealmContext";
import { useServerInfo } from "../../context/server-info/ServerInfoProvider";
import { addTrailingSlash, prettyPrintJSON } from "../../util";
@ -38,6 +37,8 @@ export const DownloadDialog = ({
toggleDialog,
protocol = "openid-connect",
}: DownloadDialogProps) => {
const { adminClient } = useAdminClient();
const { realm } = useRealm();
const { t } = useTranslation();
const { enabled } = useHelp();

View file

@ -4,8 +4,7 @@ import { useState } from "react";
import { useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { FormErrorText, HelpItem } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useFetch } from "../../utils/useFetch";
import { KeySelect } from "../key-value-form/KeySelect";
import { convertToName } from "./DynamicComponents";
@ -17,6 +16,8 @@ export const UserProfileAttributeListComponent = ({
helpText,
required = false,
}: ComponentProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const {
formState: { errors },

View file

@ -20,7 +20,7 @@ import {
import { AngleRightIcon } from "@patternfly/react-icons";
import { Fragment, useState } from "react";
import { useTranslation } from "react-i18next";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { useFetch } from "../../utils/useFetch";
import { ListEmptyState } from "../list-empty-state/ListEmptyState";
import { PaginatingTableToolbar } from "../table-toolbar/PaginatingTableToolbar";
@ -53,6 +53,8 @@ export const GroupPickerDialog = ({
onClose,
onConfirm,
}: GroupPickerDialogProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const [selectedRows, setSelectedRows] = useState<SelectableGroup[]>([]);

View file

@ -21,8 +21,7 @@ import { useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom";
import { HelpItem } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
import { useAdminClient } from "../../admin-client";
import { toPermissionDetails } from "../../clients/routes/PermissionDetails";
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
import { useRealm } from "../../context/realm-context/RealmContext";
@ -45,6 +44,8 @@ type PermissionsTabProps = {
};
export const PermissionsTab = ({ id, type }: PermissionsTabProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const navigate = useNavigate();
const { realm } = useRealm();

Some files were not shown because too many files have changed in this diff Show more