import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation"; import { ActionGroup, ActionListItem, Alert, AlertActionLink, AlertVariant, Button, Checkbox, FormGroup, PageSection, Switch, } from "@patternfly/react-core"; import { useState } from "react"; import { Controller, useForm, useWatch } from "react-hook-form"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom-v5-compat"; import { useAlerts } from "../components/alert/Alerts"; import { FormAccess } from "../components/form-access/FormAccess"; import { HelpItem } from "../components/help-enabler/HelpItem"; import { KeycloakTextInput } from "../components/keycloak-text-input/KeycloakTextInput"; import { PasswordInput } from "../components/password-input/PasswordInput"; import { FormPanel } from "../components/scroll-form/FormPanel"; import { useAdminClient } from "../context/auth/AdminClient"; import { useRealm } from "../context/realm-context/RealmContext"; import { toUser } from "../user/routes/User"; import { emailRegexPattern } from "../util"; import { useCurrentUser } from "../utils/useCurrentUser"; import "./realm-settings-section.css"; import useToggle from "../utils/useToggle"; type RealmSettingsEmailTabProps = { realm: RealmRepresentation; }; export const RealmSettingsEmailTab = ({ realm: initialRealm, }: RealmSettingsEmailTabProps) => { const { t } = useTranslation("realm-settings"); const { adminClient } = useAdminClient(); const { realm: realmName } = useRealm(); const { addAlert, addError } = useAlerts(); const currentUser = useCurrentUser(); const [realm, setRealm] = useState(initialRealm); const { register, control, handleSubmit, watch, reset: resetForm, getValues, formState: { errors }, } = useForm({ defaultValues: realm }); const reset = () => resetForm(realm); const watchFromValue = watch("smtpServer.from", ""); const watchHostValue = watch("smtpServer.host", ""); const [isTesting, toggleTest] = useToggle(); const authenticationEnabled = useWatch({ control, name: "smtpServer.auth", defaultValue: "", }); const save = async (form: RealmRepresentation) => { try { const savedRealm = { ...realm, ...form }; // For default value, back end is expecting null instead of empty string if (savedRealm.smtpServer?.port === "") savedRealm.smtpServer.port = null; await adminClient.realms.update({ realm: realmName }, savedRealm); setRealm(savedRealm); addAlert(t("saveSuccess"), AlertVariant.success); } catch (error) { addError("realm-settings:saveError", error); } }; const testConnection = async () => { const toNumber = (value: string) => Number(value); const toBoolean = (value: string) => value === true.toString(); const valueMapper = new Map unknown>([ ["port", toNumber], ["ssl", toBoolean], ["starttls", toBoolean], ["auth", toBoolean], ]); const serverSettings = { ...getValues()["smtpServer"] }; for (const [key, mapperFn] of valueMapper.entries()) { serverSettings[key] = mapperFn(serverSettings[key]); } // For default value, back end is expecting null instead of 0 if (serverSettings.port === 0) serverSettings.port = null; try { toggleTest(); await adminClient.realms.testSMTPConnection( { realm: realm.realm! }, serverSettings ); addAlert(t("testConnectionSuccess"), AlertVariant.success); } catch (error) { addError("realm-settings:testConnectionError", error); } toggleTest(); }; return ( } > } > } > ( onChange("" + value)} /> )} /> ( onChange("" + value)} /> )} /> ( { onChange("" + value); }} aria-label={t("authentication")} /> )} /> {authenticationEnabled === "true" && ( <> } > )} {currentUser && ( {currentUser.email ? ( ) : ( ( )} > {t("testConnectionHint.withoutEmailAction")} } /> )} )} ); };