2024-04-05 14:37:05 +00:00
|
|
|
import { FormGroup, Spinner, Switch } from "@patternfly/react-core";
|
2024-03-12 15:28:08 +00:00
|
|
|
import debouncePromise from "p-debounce";
|
|
|
|
import { ReactNode, useMemo, useState } from "react";
|
2023-01-26 09:31:07 +00:00
|
|
|
import { useFormContext } from "react-hook-form";
|
2021-11-01 07:49:23 +00:00
|
|
|
import { useTranslation } from "react-i18next";
|
2024-04-19 18:10:34 +00:00
|
|
|
import { HelpItem, TextControl } from "@keycloak/keycloak-ui-shared";
|
2024-05-08 08:23:43 +00:00
|
|
|
import { useAdminClient } from "../../admin-client";
|
2021-11-01 07:49:23 +00:00
|
|
|
|
|
|
|
type DiscoveryEndpointFieldProps = {
|
|
|
|
id: string;
|
|
|
|
fileUpload: ReactNode;
|
|
|
|
children: (readOnly: boolean) => ReactNode;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const DiscoveryEndpointField = ({
|
|
|
|
id,
|
|
|
|
fileUpload,
|
|
|
|
children,
|
|
|
|
}: DiscoveryEndpointFieldProps) => {
|
2024-05-08 08:23:43 +00:00
|
|
|
const { adminClient } = useAdminClient();
|
|
|
|
|
2023-09-08 13:17:17 +00:00
|
|
|
const { t } = useTranslation();
|
2022-04-08 12:37:31 +00:00
|
|
|
const {
|
|
|
|
setValue,
|
|
|
|
clearErrors,
|
|
|
|
formState: { errors },
|
|
|
|
} = useFormContext();
|
2021-11-01 07:49:23 +00:00
|
|
|
const [discovery, setDiscovery] = useState(true);
|
|
|
|
const [discovering, setDiscovering] = useState(false);
|
|
|
|
const [discoveryResult, setDiscoveryResult] =
|
|
|
|
useState<Record<string, string>>();
|
|
|
|
|
|
|
|
const setupForm = (result: Record<string, string>) => {
|
|
|
|
Object.keys(result).map((k) => setValue(`config.${k}`, result[k]));
|
|
|
|
};
|
|
|
|
|
2024-03-12 15:28:08 +00:00
|
|
|
const discover = async (fromUrl: string) => {
|
|
|
|
setDiscovering(true);
|
|
|
|
try {
|
|
|
|
const result = await adminClient.identityProviders.importFromUrl({
|
|
|
|
providerId: id,
|
|
|
|
fromUrl,
|
|
|
|
});
|
|
|
|
setupForm(result);
|
|
|
|
setDiscoveryResult(result);
|
|
|
|
} catch (error) {
|
|
|
|
return (error as Error).message;
|
|
|
|
} finally {
|
2021-11-01 07:49:23 +00:00
|
|
|
setDiscovering(false);
|
|
|
|
}
|
2024-03-12 15:28:08 +00:00
|
|
|
};
|
2021-11-01 07:49:23 +00:00
|
|
|
|
2024-03-12 15:28:08 +00:00
|
|
|
const discoverDebounced = useMemo(() => debouncePromise(discover, 1000), []);
|
2021-11-01 07:49:23 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<FormGroup
|
2022-02-21 13:55:02 +00:00
|
|
|
label={t(
|
2023-07-11 14:03:21 +00:00
|
|
|
id === "oidc" ? "useDiscoveryEndpoint" : "useEntityDescriptor",
|
2022-02-21 13:55:02 +00:00
|
|
|
)}
|
|
|
|
fieldId="kc-discovery-endpoint"
|
2021-11-01 07:49:23 +00:00
|
|
|
labelIcon={
|
|
|
|
<HelpItem
|
2023-09-08 13:17:17 +00:00
|
|
|
helpText={t(
|
|
|
|
id === "oidc"
|
|
|
|
? "useDiscoveryEndpointHelp"
|
|
|
|
: "useEntityDescriptorHelp",
|
|
|
|
)}
|
2023-09-25 07:06:56 +00:00
|
|
|
fieldLabelId="discoveryEndpoint"
|
2021-11-01 07:49:23 +00:00
|
|
|
/>
|
|
|
|
}
|
|
|
|
>
|
|
|
|
<Switch
|
|
|
|
id="kc-discovery-endpoint-switch"
|
2023-09-14 09:01:15 +00:00
|
|
|
label={t("on")}
|
|
|
|
labelOff={t("off")}
|
2021-11-01 07:49:23 +00:00
|
|
|
isChecked={discovery}
|
2024-04-05 14:37:05 +00:00
|
|
|
onChange={(_event, checked) => {
|
2022-02-21 16:06:35 +00:00
|
|
|
clearErrors("discoveryError");
|
|
|
|
setDiscovery(checked);
|
|
|
|
}}
|
2022-08-30 13:07:51 +00:00
|
|
|
aria-label={t(
|
2023-07-11 14:03:21 +00:00
|
|
|
id === "oidc" ? "useDiscoveryEndpoint" : "useEntityDescriptor",
|
2022-08-30 13:07:51 +00:00
|
|
|
)}
|
2021-11-01 07:49:23 +00:00
|
|
|
/>
|
|
|
|
</FormGroup>
|
|
|
|
{discovery && (
|
2024-03-12 15:28:08 +00:00
|
|
|
<TextControl
|
|
|
|
name="discoveryEndpoint"
|
2022-02-21 13:55:02 +00:00
|
|
|
label={t(
|
2023-07-11 14:03:21 +00:00
|
|
|
id === "oidc" ? "discoveryEndpoint" : "samlEntityDescriptor",
|
2022-02-21 13:55:02 +00:00
|
|
|
)}
|
2024-03-12 15:28:08 +00:00
|
|
|
labelIcon={t(
|
|
|
|
id === "oidc"
|
|
|
|
? "discoveryEndpointHelp"
|
|
|
|
: "samlEntityDescriptorHelp",
|
|
|
|
)}
|
|
|
|
type="url"
|
|
|
|
placeholder={
|
|
|
|
id === "oidc"
|
|
|
|
? "https://hostname/auth/realms/master/.well-known/openid-configuration"
|
|
|
|
: ""
|
2021-11-01 07:49:23 +00:00
|
|
|
}
|
|
|
|
validated={
|
|
|
|
errors.discoveryError || errors.discoveryEndpoint
|
|
|
|
? "error"
|
|
|
|
: !discoveryResult
|
2023-11-14 17:59:24 +00:00
|
|
|
? "default"
|
|
|
|
: "success"
|
2021-11-01 07:49:23 +00:00
|
|
|
}
|
2024-04-05 14:37:05 +00:00
|
|
|
customIcon={discovering ? <Spinner isInline /> : undefined}
|
2024-03-12 15:28:08 +00:00
|
|
|
rules={{
|
|
|
|
required: t("required"),
|
|
|
|
validate: (value: string) => discoverDebounced(value),
|
|
|
|
}}
|
|
|
|
/>
|
2021-11-01 07:49:23 +00:00
|
|
|
)}
|
|
|
|
{!discovery && fileUpload}
|
|
|
|
{discovery && !errors.discoveryError && children(true)}
|
|
|
|
{!discovery && children(false)}
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|