bbc177abb8
* fixes realm save currently save on realm screen didn't work as the email settings where required. Fixed this by changing email to be it's own section. Also email section was using the wrong attributes therefor the changes where not reflected in the old console * fix empty realmComponent array * fixed password help text
267 lines
8.2 KiB
TypeScript
267 lines
8.2 KiB
TypeScript
import React, { useEffect, useState } from "react";
|
|
import { useHistory } from "react-router-dom";
|
|
import { useTranslation } from "react-i18next";
|
|
import { Controller, FormProvider, useForm } from "react-hook-form";
|
|
import {
|
|
AlertVariant,
|
|
ButtonVariant,
|
|
DropdownItem,
|
|
DropdownSeparator,
|
|
PageSection,
|
|
Tab,
|
|
Tabs,
|
|
TabTitleText,
|
|
} from "@patternfly/react-core";
|
|
|
|
import type RealmRepresentation from "keycloak-admin/lib/defs/realmRepresentation";
|
|
import { toUpperCase } from "../util";
|
|
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
|
import { useAdminClient, useFetch } from "../context/auth/AdminClient";
|
|
import { useRealm } from "../context/realm-context/RealmContext";
|
|
import { ViewHeader } from "../components/view-header/ViewHeader";
|
|
import { useAlerts } from "../components/alert/Alerts";
|
|
import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs";
|
|
import { RealmSettingsLoginTab } from "./LoginTab";
|
|
import { RealmSettingsGeneralTab } from "./GeneralTab";
|
|
import { PartialImportDialog } from "./PartialImport";
|
|
import { RealmSettingsThemesTab } from "./ThemesTab";
|
|
import { RealmSettingsEmailTab } from "./EmailTab";
|
|
import { KeysListTab } from "./KeysListTab";
|
|
import type ComponentRepresentation from "keycloak-admin/lib/defs/componentRepresentation";
|
|
import { KeysProviderTab } from "./KeysProvidersTab";
|
|
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
|
|
|
type RealmSettingsHeaderProps = {
|
|
onChange: (value: boolean) => void;
|
|
value: boolean;
|
|
save: () => void;
|
|
realmName: string;
|
|
};
|
|
|
|
const RealmSettingsHeader = ({
|
|
save,
|
|
onChange,
|
|
value,
|
|
realmName,
|
|
}: RealmSettingsHeaderProps) => {
|
|
const { t } = useTranslation("realm-settings");
|
|
const adminClient = useAdminClient();
|
|
const { addAlert } = useAlerts();
|
|
const history = useHistory();
|
|
const { refresh } = useRealm();
|
|
const [partialImportOpen, setPartialImportOpen] = useState(false);
|
|
|
|
const [toggleDisableDialog, DisableConfirm] = useConfirmDialog({
|
|
titleKey: "realm-settings:disableConfirmTitle",
|
|
messageKey: "realm-settings:disableConfirm",
|
|
continueButtonLabel: "common:disable",
|
|
onConfirm: () => {
|
|
onChange(!value);
|
|
save();
|
|
},
|
|
});
|
|
|
|
const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({
|
|
titleKey: "realm-settings:deleteConfirmTitle",
|
|
messageKey: "realm-settings:deleteConfirm",
|
|
continueButtonLabel: "common:delete",
|
|
continueButtonVariant: ButtonVariant.danger,
|
|
onConfirm: async () => {
|
|
try {
|
|
await adminClient.realms.del({ realm: realmName });
|
|
addAlert(t("deletedSuccess"), AlertVariant.success);
|
|
history.push("/master/");
|
|
refresh();
|
|
} catch (error) {
|
|
addAlert(t("deleteError", { error }), AlertVariant.danger);
|
|
}
|
|
},
|
|
});
|
|
|
|
return (
|
|
<>
|
|
<DisableConfirm />
|
|
<DeleteConfirm />
|
|
<PartialImportDialog
|
|
open={partialImportOpen}
|
|
toggleDialog={() => setPartialImportOpen(!partialImportOpen)}
|
|
/>
|
|
<ViewHeader
|
|
titleKey={toUpperCase(realmName)}
|
|
divider={false}
|
|
dropdownItems={[
|
|
<DropdownItem
|
|
key="import"
|
|
data-testid="openPartialImportModal"
|
|
onClick={() => {
|
|
setPartialImportOpen(true);
|
|
}}
|
|
>
|
|
{t("partialImport")}
|
|
</DropdownItem>,
|
|
<DropdownItem key="export" onClick={() => {}}>
|
|
{t("partialExport")}
|
|
</DropdownItem>,
|
|
<DropdownSeparator key="separator" />,
|
|
<DropdownItem key="delete" onClick={toggleDeleteDialog}>
|
|
{t("common:delete")}
|
|
</DropdownItem>,
|
|
]}
|
|
isEnabled={value}
|
|
onToggle={(value) => {
|
|
if (!value) {
|
|
toggleDisableDialog();
|
|
} else {
|
|
onChange(value);
|
|
save();
|
|
}
|
|
}}
|
|
/>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export const RealmSettingsSection = () => {
|
|
const { t } = useTranslation("realm-settings");
|
|
const adminClient = useAdminClient();
|
|
const { realm: realmName } = useRealm();
|
|
const { addAlert } = useAlerts();
|
|
const form = useForm();
|
|
const { control, getValues, setValue, reset: resetForm } = form;
|
|
const [realm, setRealm] = useState<RealmRepresentation>();
|
|
const [activeTab, setActiveTab] = useState(0);
|
|
const [realmComponents, setRealmComponents] = useState<
|
|
ComponentRepresentation[]
|
|
>();
|
|
|
|
const kpComponentTypes = useServerInfo().componentTypes![
|
|
"org.keycloak.keys.KeyProvider"
|
|
];
|
|
|
|
useFetch(
|
|
async () => {
|
|
const realm = await adminClient.realms.findOne({ realm: realmName });
|
|
const realmComponents = await adminClient.components.find({
|
|
type: "org.keycloak.keys.KeyProvider",
|
|
realm: realmName,
|
|
});
|
|
|
|
return { realm, realmComponents };
|
|
},
|
|
(result) => {
|
|
setRealm(result.realm);
|
|
setRealmComponents(result.realmComponents);
|
|
},
|
|
[]
|
|
);
|
|
|
|
useEffect(() => {
|
|
if (realm) setupForm(realm);
|
|
}, [realm]);
|
|
|
|
const setupForm = (realm: RealmRepresentation) => {
|
|
resetForm(realm);
|
|
Object.entries(realm).map((entry) => setValue(entry[0], entry[1]));
|
|
};
|
|
|
|
const save = async (realm: RealmRepresentation) => {
|
|
try {
|
|
await adminClient.realms.update({ realm: realmName }, realm);
|
|
setRealm(realm);
|
|
addAlert(t("saveSuccess"), AlertVariant.success);
|
|
} catch (error) {
|
|
addAlert(
|
|
t("saveError", { error: error.response?.data?.errorMessage || error }),
|
|
AlertVariant.danger
|
|
);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Controller
|
|
name="enabled"
|
|
control={control}
|
|
defaultValue={true}
|
|
render={({ onChange, value }) => (
|
|
<RealmSettingsHeader
|
|
value={value}
|
|
onChange={onChange}
|
|
realmName={realmName}
|
|
save={() => save(getValues())}
|
|
/>
|
|
)}
|
|
/>
|
|
<PageSection variant="light" className="pf-u-p-0">
|
|
<FormProvider {...form}>
|
|
<KeycloakTabs isBox>
|
|
<Tab
|
|
eventKey="general"
|
|
title={<TabTitleText>{t("realm-settings:general")}</TabTitleText>}
|
|
data-testid="rs-general-tab"
|
|
>
|
|
<RealmSettingsGeneralTab
|
|
save={save}
|
|
reset={() => setupForm(realm!)}
|
|
/>
|
|
</Tab>
|
|
<Tab
|
|
eventKey="login"
|
|
title={<TabTitleText>{t("realm-settings:login")}</TabTitleText>}
|
|
data-testid="rs-login-tab"
|
|
>
|
|
<RealmSettingsLoginTab save={save} realm={realm!} />
|
|
</Tab>
|
|
<Tab
|
|
eventKey="email"
|
|
title={<TabTitleText>{t("realm-settings:email")}</TabTitleText>}
|
|
data-testid="rs-email-tab"
|
|
>
|
|
{realm && <RealmSettingsEmailTab realm={realm} />}
|
|
</Tab>
|
|
<Tab
|
|
eventKey="themes"
|
|
title={<TabTitleText>{t("realm-settings:themes")}</TabTitleText>}
|
|
data-testid="rs-themes-tab"
|
|
>
|
|
<RealmSettingsThemesTab
|
|
save={save}
|
|
reset={() => setupForm(realm!)}
|
|
/>
|
|
</Tab>
|
|
<Tab
|
|
eventKey="keys"
|
|
title={<TabTitleText>{t("realm-settings:keys")}</TabTitleText>}
|
|
data-testid="rs-keys-tab"
|
|
>
|
|
{realmComponents && (
|
|
<Tabs
|
|
activeKey={activeTab}
|
|
onSelect={(_, key) => setActiveTab(key as number)}
|
|
>
|
|
<Tab
|
|
id="setup"
|
|
eventKey={0}
|
|
title={<TabTitleText>{t("keysList")}</TabTitleText>}
|
|
>
|
|
<KeysListTab realmComponents={realmComponents} />
|
|
</Tab>
|
|
<Tab
|
|
id="evaluate"
|
|
eventKey={1}
|
|
title={<TabTitleText>{t("providers")}</TabTitleText>}
|
|
>
|
|
<KeysProviderTab
|
|
components={realmComponents}
|
|
keyProviderComponentTypes={kpComponentTypes}
|
|
/>
|
|
</Tab>
|
|
</Tabs>
|
|
)}
|
|
</Tab>
|
|
</KeycloakTabs>
|
|
</FormProvider>
|
|
</PageSection>
|
|
</>
|
|
);
|
|
};
|