import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { Controller, useForm, useFormContext, useWatch } from "react-hook-form"; import { ActionGroup, AlertVariant, Button, FormGroup, NumberInput, PageSection, Select, SelectOption, SelectVariant, Switch, Text, TextVariants, } from "@patternfly/react-core"; import type RealmRepresentation from "keycloak-admin/lib/defs/realmRepresentation"; import { FormAccess } from "../components/form-access/FormAccess"; import { HelpItem } from "../components/help-enabler/HelpItem"; import { FormPanel } from "../components/scroll-form/FormPanel"; import { useAdminClient, useFetch } from "../context/auth/AdminClient"; import { useAlerts } from "../components/alert/Alerts"; import { useRealm } from "../context/realm-context/RealmContext"; import "./RealmSettingsSection.css"; import type UserRepresentation from "keycloak-admin/lib/defs/userRepresentation"; import { TimeSelector } from "../components/time-selector/TimeSelector"; import { useServerInfo } from "../context/server-info/ServerInfoProvider"; import { convertToFormValues, forHumans, flatten, convertFormValuesToObject, interpolateTimespan, } from "../util"; type RealmSettingsSessionsTabProps = { realm?: RealmRepresentation; user?: UserRepresentation; reset?: () => void; }; export const RealmSettingsTokensTab = ({ realm: initialRealm, reset, }: RealmSettingsSessionsTabProps) => { const { t } = useTranslation("realm-settings"); const adminClient = useAdminClient(); const { realm: realmName } = useRealm(); const { addAlert, addError } = useAlerts(); const serverInfo = useServerInfo(); const [realm, setRealm] = useState(initialRealm); const [defaultSigAlgDrpdwnIsOpen, setDefaultSigAlgDrpdwnOpen] = useState(false); const allComponentTypes = serverInfo.componentTypes?.["org.keycloak.keys.KeyProvider"] ?? []; const esOptions = ["ES256", "ES384", "ES512"]; const hmacAlgorithmOptions = allComponentTypes[2].properties[4].options; const javaKeystoreAlgOptions = allComponentTypes[3].properties[3].options; const defaultSigAlgOptions = esOptions.concat( hmacAlgorithmOptions!, javaKeystoreAlgOptions! ); const form = useForm(); const { control } = useFormContext(); const offlineSessionMaxEnabled = useWatch({ control, name: "offlineSessionMaxLifespanEnabled", defaultValue: realm?.offlineSessionMaxLifespanEnabled, }); const setupForm = (realm: RealmRepresentation) => { const { ...formValues } = realm; form.reset(formValues); Object.entries(realm).map((entry) => { if (entry[0] === "attributes") { convertToFormValues(entry[1], "attributes", form.setValue); } else { form.setValue(entry[0], entry[1]); } }); }; useFetch( () => adminClient.realms.findOne({ realm: realmName }), (realm) => { setRealm(realm); setupForm(realm); }, [realmName] ); const save = async () => { const firstInstanceOnly = true; const flattenedAttributes = convertFormValuesToObject( flatten(form.getValues()["attributes"]), firstInstanceOnly ); const attributes = { ...flattenedAttributes, ...realm?.attributes }; try { const newRealm: RealmRepresentation = { ...realm, ...form.getValues(), attributes, }; await adminClient.realms.update({ realm: realmName }, newRealm); setupForm(newRealm); setRealm(newRealm); addAlert(t("saveSuccess"), AlertVariant.success); } catch (error) { addError("realm-settings:saveError", error); } }; return ( <> } > ( )} /> } > ( )} /> } fieldId="refreshTokenMaxReuse" > ( onChange(value + 1)} onMinus={() => onChange(value - 1)} onChange={(event) => onChange(Number((event.target as HTMLInputElement).value)) } /> )} /> } > ( realm?.ssoSessionIdleTimeout! ? "warning" : "default" } className="kc-access-token-lifespan" data-testid="access-token-lifespan-input" aria-label="access-token-lifespan" value={value} onChange={onChange} units={["minutes", "hours", "days"]} /> )} /> } > ( )} /> } > ( )} /> {offlineSessionMaxEnabled && ( } > ( )} /> )} } > ( )} /> } > ( )} /> {t("overrideActionTokens")} ( onChange(value.toString())} units={["minutes", "hours", "days"]} /> )} /> ( )} /> ( )} /> ( )} /> ); };