import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation"; import { ActionGroup, Button, FormGroup, NumberInput, PageSection, Select, SelectOption, SelectVariant, Switch, Text, TextVariants, } from "@patternfly/react-core"; import { useEffect, useState } from "react"; import { Controller, useForm, useWatch } from "react-hook-form"; import { useTranslation } from "react-i18next"; import { FormPanel, HelpItem } from "ui-shared"; import { FormAccess } from "../components/form/FormAccess"; import { KeycloakTextInput } from "../components/keycloak-text-input/KeycloakTextInput"; import { TimeSelector, toHumanFormat, } from "../components/time-selector/TimeSelector"; import { useServerInfo } from "../context/server-info/ServerInfoProvider"; import { useWhoAmI } from "../context/whoami/WhoAmI"; import { convertToFormValues, sortProviders } from "../util"; import useIsFeatureEnabled, { Feature } from "../utils/useIsFeatureEnabled"; import "./realm-settings-section.css"; type RealmSettingsSessionsTabProps = { realm: RealmRepresentation; save: (realm: RealmRepresentation) => void; reset?: () => void; }; export const RealmSettingsTokensTab = ({ realm, reset, save, }: RealmSettingsSessionsTabProps) => { const { t } = useTranslation(); const serverInfo = useServerInfo(); const isFeatureEnabled = useIsFeatureEnabled(); const { whoAmI } = useWhoAmI(); const [defaultSigAlgDrpdwnIsOpen, setDefaultSigAlgDrpdwnOpen] = useState(false); const defaultSigAlgOptions = sortProviders( serverInfo.providers!["signature"].providers, ); const form = useForm(); const { setValue, control } = form; const offlineSessionMaxEnabled = useWatch({ control, name: "offlineSessionMaxLifespanEnabled", defaultValue: realm.offlineSessionMaxLifespanEnabled, }); const ssoSessionIdleTimeout = useWatch({ control, name: "ssoSessionIdleTimeout", defaultValue: 36000, }); const revokeRefreshToken = useWatch({ control, name: "revokeRefreshToken", defaultValue: false, }); useEffect(() => { convertToFormValues(realm, setValue); }, []); return ( } > ( )} /> {isFeatureEnabled(Feature.DeviceFlow) && ( <> } > ( )} /> } > ( field.onChange(field.value || 0 + 1)} onMinus={() => field.onChange(field.value || 0 - 1)} onChange={(event) => { const newValue = Number(event.currentTarget.value); field.onChange(!isNaN(newValue) ? newValue : 0); }} placeholder={t("oAuthDevicePollingInterval")} /> )} /> } > )} } > ( )} /> {revokeRefreshToken && ( } fieldId="refreshTokenMaxReuse" > ( field.onChange(field.value! + 1)} onMinus={() => field.onChange(field.value! - 1)} onChange={(event) => field.onChange( Number((event.target as HTMLInputElement).value), ) } /> )} /> )} } > ( ssoSessionIdleTimeout! ? "warning" : "default" } className="kc-access-token-lifespan" data-testid="access-token-lifespan-input" aria-label="access-token-lifespan" value={field.value!} onChange={field.onChange} units={["minute", "hour", "day"]} /> )} /> } > ( )} /> } > ( )} /> {offlineSessionMaxEnabled && ( } > ( )} /> )} } > ( )} /> } > ( )} /> {t("overrideActionTokens")} ( field.onChange(value.toString())} units={["minute", "hour", "day"]} /> )} /> ( )} /> ( )} /> ( )} /> ); };