parent
7d4adc683f
commit
a81164ee2a
5 changed files with 53 additions and 4 deletions
|
@ -1,5 +1,6 @@
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import {
|
import {
|
||||||
|
Alert,
|
||||||
AlertVariant,
|
AlertVariant,
|
||||||
ButtonVariant,
|
ButtonVariant,
|
||||||
DropdownItem,
|
DropdownItem,
|
||||||
|
@ -18,7 +19,10 @@ import _ from "lodash";
|
||||||
|
|
||||||
import { ClientSettings } from "./ClientSettings";
|
import { ClientSettings } from "./ClientSettings";
|
||||||
import { useAlerts } from "../components/alert/Alerts";
|
import { useAlerts } from "../components/alert/Alerts";
|
||||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
import {
|
||||||
|
ConfirmDialogModal,
|
||||||
|
useConfirmDialog,
|
||||||
|
} from "../components/confirm-dialog/ConfirmDialog";
|
||||||
import { DownloadDialog } from "../components/download-dialog/DownloadDialog";
|
import { DownloadDialog } from "../components/download-dialog/DownloadDialog";
|
||||||
import { ViewHeader } from "../components/view-header/ViewHeader";
|
import { ViewHeader } from "../components/view-header/ViewHeader";
|
||||||
import { useAdminClient, asyncStateFetch } from "../context/auth/AdminClient";
|
import { useAdminClient, asyncStateFetch } from "../context/auth/AdminClient";
|
||||||
|
@ -114,6 +118,9 @@ export const ClientDetails = () => {
|
||||||
const { addAlert } = useAlerts();
|
const { addAlert } = useAlerts();
|
||||||
const [downloadDialogOpen, setDownloadDialogOpen] = useState(false);
|
const [downloadDialogOpen, setDownloadDialogOpen] = useState(false);
|
||||||
const toggleDownloadDialog = () => setDownloadDialogOpen(!downloadDialogOpen);
|
const toggleDownloadDialog = () => setDownloadDialogOpen(!downloadDialogOpen);
|
||||||
|
const [changeAuthenticatorOpen, setChangeAuthenticatorOpen] = useState(false);
|
||||||
|
const toggleChangeAuthenticator = () =>
|
||||||
|
setChangeAuthenticatorOpen(!changeAuthenticatorOpen);
|
||||||
const [activeTab2, setActiveTab2] = useState(30);
|
const [activeTab2, setActiveTab2] = useState(30);
|
||||||
|
|
||||||
const form = useForm<ClientForm>();
|
const form = useForm<ClientForm>();
|
||||||
|
@ -173,8 +180,17 @@ export const ClientDetails = () => {
|
||||||
);
|
);
|
||||||
}, [clientId]);
|
}, [clientId]);
|
||||||
|
|
||||||
const save = async () => {
|
const save = async (confirmed: boolean | undefined = false) => {
|
||||||
if (await form.trigger()) {
|
if (await form.trigger()) {
|
||||||
|
if (
|
||||||
|
client?.publicClient &&
|
||||||
|
client?.clientAuthenticatorType !==
|
||||||
|
form.getValues("clientAuthenticatorType") &&
|
||||||
|
!confirmed
|
||||||
|
) {
|
||||||
|
toggleChangeAuthenticator();
|
||||||
|
return;
|
||||||
|
}
|
||||||
const redirectUris = toValue(form.getValues()["redirectUris"]);
|
const redirectUris = toValue(form.getValues()["redirectUris"]);
|
||||||
const webOrigins = toValue(form.getValues()["webOrigins"]);
|
const webOrigins = toValue(form.getValues()["webOrigins"]);
|
||||||
const attributes = convertFormValuesToObject(
|
const attributes = convertFormValuesToObject(
|
||||||
|
@ -208,6 +224,24 @@ export const ClientDetails = () => {
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<ConfirmDialogModal
|
||||||
|
continueButtonLabel="common:yes"
|
||||||
|
titleKey={t("changeAuthenticatorConfirmTitle", {
|
||||||
|
clientAuthenticatorType: form.getValues("clientAuthenticatorType"),
|
||||||
|
})}
|
||||||
|
open={changeAuthenticatorOpen}
|
||||||
|
toggleDialog={toggleChangeAuthenticator}
|
||||||
|
onConfirm={() => save(true)}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
{t("changeAuthenticatorConfirm", {
|
||||||
|
clientAuthenticatorType: form.getValues("clientAuthenticatorType"),
|
||||||
|
})}
|
||||||
|
{form.getValues("clientAuthenticatorType") === "client-jwt" && (
|
||||||
|
<Alert variant="info" isInline title={t("signedJWTConfirm")} />
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
</ConfirmDialogModal>
|
||||||
<DeleteConfirm />
|
<DeleteConfirm />
|
||||||
<DownloadDialog
|
<DownloadDialog
|
||||||
id={client.id!}
|
id={client.id!}
|
||||||
|
|
|
@ -7,6 +7,8 @@ import {
|
||||||
Split,
|
Split,
|
||||||
SplitItem,
|
SplitItem,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
|
import { useFormContext } from "react-hook-form";
|
||||||
|
import { ClientForm } from "../ClientDetails";
|
||||||
|
|
||||||
export type ClientSecretProps = {
|
export type ClientSecretProps = {
|
||||||
secret: string;
|
secret: string;
|
||||||
|
@ -15,6 +17,7 @@ export type ClientSecretProps = {
|
||||||
|
|
||||||
export const ClientSecret = ({ secret, toggle }: ClientSecretProps) => {
|
export const ClientSecret = ({ secret, toggle }: ClientSecretProps) => {
|
||||||
const { t } = useTranslation("clients");
|
const { t } = useTranslation("clients");
|
||||||
|
const { formState } = useFormContext<ClientForm>();
|
||||||
return (
|
return (
|
||||||
<FormGroup label={t("clientSecret")} fieldId="kc-client-secret">
|
<FormGroup label={t("clientSecret")} fieldId="kc-client-secret">
|
||||||
<Split hasGutter>
|
<Split hasGutter>
|
||||||
|
@ -24,7 +27,11 @@ export const ClientSecret = ({ secret, toggle }: ClientSecretProps) => {
|
||||||
</ClipboardCopy>
|
</ClipboardCopy>
|
||||||
</SplitItem>
|
</SplitItem>
|
||||||
<SplitItem>
|
<SplitItem>
|
||||||
<Button variant="secondary" onClick={toggle}>
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
onClick={toggle}
|
||||||
|
isDisabled={formState.isDirty}
|
||||||
|
>
|
||||||
{t("regenerate")}
|
{t("regenerate")}
|
||||||
</Button>
|
</Button>
|
||||||
</SplitItem>
|
</SplitItem>
|
||||||
|
|
|
@ -234,7 +234,11 @@ export const Credentials = ({ clientId, save }: CredentialsProps) => {
|
||||||
</ClipboardCopy>
|
</ClipboardCopy>
|
||||||
</SplitItem>
|
</SplitItem>
|
||||||
<SplitItem>
|
<SplitItem>
|
||||||
<Button variant="secondary" onClick={toggleAccessTokenConfirm}>
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
onClick={toggleAccessTokenConfirm}
|
||||||
|
isDisabled={isDirty}
|
||||||
|
>
|
||||||
{t("regenerate")}
|
{t("regenerate")}
|
||||||
</Button>
|
</Button>
|
||||||
</SplitItem>
|
</SplitItem>
|
||||||
|
|
|
@ -39,6 +39,7 @@ export const SignedJWT = () => {
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<Select
|
<Select
|
||||||
|
maxHeight={200}
|
||||||
toggleId="kc-signature-algorithm"
|
toggleId="kc-signature-algorithm"
|
||||||
onToggle={() => isOpen(!open)}
|
onToggle={() => isOpen(!open)}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
|
|
|
@ -111,6 +111,9 @@
|
||||||
"loginTheme": "Login theme",
|
"loginTheme": "Login theme",
|
||||||
"consentRequired": "Consent required",
|
"consentRequired": "Consent required",
|
||||||
"clientAuthenticator": "Client Authenticator",
|
"clientAuthenticator": "Client Authenticator",
|
||||||
|
"changeAuthenticatorConfirmTitle": "Change to {{clientAuthenticatorType}}",
|
||||||
|
"changeAuthenticatorConfirm": "If you change authenticator to {{clientAuthenticatorType}}, the keycloak database will be updated and you may need to download a new adapter configuration for this client",
|
||||||
|
"signedJWTConfirm": "You should configure JWKS URL or keys in the \"Keys\" tab to change the parameters of Signed JWT authenticator.",
|
||||||
"clientSecret": "Client secret",
|
"clientSecret": "Client secret",
|
||||||
"regenerate": "Regenerate",
|
"regenerate": "Regenerate",
|
||||||
"confirmClientSecretTitle": "Regenerate secret for this client?",
|
"confirmClientSecretTitle": "Regenerate secret for this client?",
|
||||||
|
|
Loading…
Reference in a new issue