From 67d2c8617f5aaa3cda71dbc4734ca7ed391e7b89 Mon Sep 17 00:00:00 2001 From: Erik Jan de Wit Date: Tue, 14 Dec 2021 23:46:19 +0100 Subject: [PATCH] Changed the idP mapper form to use the new Dynamic forms (#1641) --- .../identity_providers_saml_test.spec.ts | 2 +- .../identity_providers/AddMapperPage.ts | 96 +-- src/client-scopes/messages.ts | 4 - src/components/dynamic/BooleanComponent.tsx | 3 +- src/components/dynamic/GroupComponent.tsx | 75 ++ src/components/dynamic/MapComponent.tsx | 23 + src/components/dynamic/RoleComponent.tsx | 165 ++--- src/components/dynamic/components.ts | 6 + src/components/dynamic/labels.ts | 5 + src/identity-providers/add/AddMapper.tsx | 661 ++---------------- src/identity-providers/add/AddMapperForm.tsx | 70 +- src/identity-providers/messages.ts | 12 - src/realm-roles/AssociatedRolesModal.tsx | 7 +- 13 files changed, 300 insertions(+), 829 deletions(-) create mode 100644 src/components/dynamic/GroupComponent.tsx create mode 100644 src/components/dynamic/MapComponent.tsx diff --git a/cypress/integration/identity_providers_saml_test.spec.ts b/cypress/integration/identity_providers_saml_test.spec.ts index 73bd845d56..95b472dff2 100644 --- a/cypress/integration/identity_providers_saml_test.spec.ts +++ b/cypress/integration/identity_providers_saml_test.spec.ts @@ -128,7 +128,7 @@ describe("Identity provider test", () => { masthead.checkNotificationMessage(createMapperSuccessMsg, true); }); - it.skip("should edit Username Template Importer mapper", () => { + it("should edit Username Template Importer mapper", () => { sidebarPage.goToIdentityProviders(); listingPage.goToItemDetails(samlProviderName); addMapperPage.goToMappersTab(); diff --git a/cypress/support/pages/admin_console/manage/identity_providers/AddMapperPage.ts b/cypress/support/pages/admin_console/manage/identity_providers/AddMapperPage.ts index 701fb17bde..b5e73701ea 100644 --- a/cypress/support/pages/admin_console/manage/identity_providers/AddMapperPage.ts +++ b/cypress/support/pages/admin_console/manage/identity_providers/AddMapperPage.ts @@ -7,28 +7,26 @@ export default class AddMapperPage { private mapperNameInput = "#kc-name"; private mapperRoleInput = "mapper-role-input"; - private attributeName = "attribute-name"; - private attributeFriendlyName = "attribute-friendly-name"; + private attribute = "user.attribute"; + private attributeName = "attribute.name"; + private attributeFriendlyName = "attribute.friendly.name"; private attributeValue = "attribute-value"; private claimInput = "claim"; private claimValueInput = "claim-value-input"; - private socialProfileJSONfieldPath = "social-profile-JSON-field-path"; - private userAttribute = "user-attribute"; - private userAttributeName = "user-attribute-name"; - private userAttributeValue = "user-attribute-value"; - private userSessionAttribute = "user-session-attribute"; - private userSessionAttributeValue = "user-session-attribute-value"; + private socialProfileJSONfieldPath = "jsonField"; + private userAttribute = "attribute"; + private userAttributeName = "userAttribute"; + private userAttributeValue = "attribute.value"; + private userSessionAttribute = "attribute"; + private userSessionAttributeValue = "attribute.value"; private newMapperSaveButton = "new-mapper-save-button"; - private regexAttributeValuesSwitch = "regex-values-switch"; + private regexAttributeValuesSwitch = "are.attribute.values.regex"; private syncmodeSelectToggle = "#syncMode"; private attributesKeyInput = 'input[name="config.attributes[0].key"]'; private attributesValueInput = 'input[name="config.attributes[0].value"]'; private template = "template"; private target = "#target"; private targetDropdown = "#target-dropdown"; - private selectRoleButton = "select-role-button"; - private radio = "[type=radio]"; - private addAssociatedRolesModalButton = "add-associated-roles-button"; goToMappersTab() { cy.findByTestId(this.mappersTab).click(); @@ -91,14 +89,16 @@ export default class AddMapperPage { } addRoleToMapperForm() { - const load = "/auth/admin/realms/master/roles"; - cy.intercept(load).as("load"); - - cy.get(this.radio).eq(0).check(); - - cy.findByTestId(this.addAssociatedRolesModalButton).contains("Add").click(); - - cy.findByTestId(this.mapperRoleInput).should("have.value", "admin"); + cy.get("#group-role-select-typeahead") + .click() + .get(".pf-c-select__menu-item") + .first() + .click(); + cy.get("#role-role-select-typeahead") + .click() + .get(".pf-c-select__menu-item") + .first() + .click(); return this; } @@ -115,7 +115,7 @@ export default class AddMapperPage { cy.get(this.idpMapperSelectToggle).click(); cy.findByTestId(this.idpMapperSelect) - .contains("Advanced Attribute To Role") + .contains("Advanced Attribute to Role") .click(); cy.get(this.attributesKeyInput).clear(); @@ -126,8 +126,6 @@ export default class AddMapperPage { this.toggleSwitch(this.regexAttributeValuesSwitch); - cy.findByTestId(this.selectRoleButton).click(); - this.addRoleToMapperForm(); this.saveNewMapper(); @@ -153,9 +151,7 @@ export default class AddMapperPage { cy.findByTestId(this.template).clear(); cy.findByTestId(this.template).type("Template"); - cy.get(this.target).click(); - - cy.get(this.targetDropdown).contains("LOCAL").click(); + cy.get(this.target).click().parent().contains("BROKER_ID").click(); this.saveNewMapper(); @@ -211,8 +207,7 @@ export default class AddMapperPage { cy.findByTestId(this.attributeFriendlyName).clear(); cy.findByTestId(this.attributeFriendlyName).type("attribute friendly name"); - cy.findByTestId(this.userAttributeName).clear(); - cy.findByTestId(this.userAttributeName).type("user attribute name"); + cy.findByTestId(this.attribute).clear().type("user attribute name"); this.saveNewMapper(); @@ -234,11 +229,8 @@ export default class AddMapperPage { .contains("Attribute Importer") .click(); - cy.findByTestId(this.claimInput).clear(); - cy.findByTestId(this.claimInput).type("claim"); - - cy.findByTestId(this.userAttributeName).clear(); - cy.findByTestId(this.userAttributeName).type("user attribute name"); + cy.findByTestId(this.claimInput).clear().type("claim"); + cy.findByTestId(this.attribute).clear().type("user attribute name"); this.saveNewMapper(); @@ -258,9 +250,7 @@ export default class AddMapperPage { cy.findByTestId(this.idpMapperSelect).contains("Hardcoded Role").click(); - cy.findByTestId(this.mapperRoleInput).clear(); - cy.findByTestId(this.mapperRoleInput).type("admin"); - + this.addRoleToMapperForm(); this.saveNewMapper(); return this; @@ -281,13 +271,11 @@ export default class AddMapperPage { .contains("Hardcoded Attribute") .click(); - cy.findByTestId(this.userAttribute).clear(); - cy.findByTestId(this.userAttribute).type("user session attribute"); + cy.findByTestId(this.userAttribute).clear().type("user session attribute"); - cy.findByTestId(this.userAttributeValue).clear(); - cy.findByTestId(this.userAttributeValue).type( - "user session attribute value" - ); + cy.findByTestId(this.userAttributeValue) + .clear() + .type("user session attribute value"); this.saveNewMapper(); @@ -306,11 +294,10 @@ export default class AddMapperPage { cy.get(this.idpMapperSelectToggle).click(); cy.findByTestId(this.idpMapperSelect) - .contains("SAML Attribute To Role") + .contains("SAML Attribute to Role") .click(); - cy.findByTestId(this.mapperRoleInput).clear(); - cy.findByTestId(this.mapperRoleInput).type("admin"); + this.addRoleToMapperForm(); this.saveNewMapper(); @@ -324,9 +311,7 @@ export default class AddMapperPage { cy.findByTestId(this.template).type("_edited"); - cy.get(this.target).click(); - - cy.get(this.targetDropdown).contains("BROKER_ID").click(); + cy.get(this.target).click().parent().contains("BROKER_USERNAME").click(); this.saveNewMapper(); @@ -408,19 +393,14 @@ export default class AddMapperPage { cy.get(this.idpMapperSelectToggle).click(); - cy.findByTestId(this.idpMapperSelect).contains("Claim To Role").click(); + cy.findByTestId(this.idpMapperSelect).contains("Claim to Role").click(); - cy.get(this.attributesKeyInput).clear(); - cy.get(this.attributesKeyInput).type("key"); + cy.findByTestId("attribute-key-input").clear().type("key"); + cy.findByTestId("attribute-value-input").clear().type("value"); - cy.get(this.attributesValueInput).clear(); - cy.get(this.attributesValueInput).type("value"); - - this.toggleSwitch(this.regexAttributeValuesSwitch); - - cy.findByTestId(this.mapperRoleInput).clear(); - cy.findByTestId(this.mapperRoleInput).type("admin"); + this.toggleSwitch("are.claim.values.regex"); + this.addRoleToMapperForm(); this.saveNewMapper(); return this; diff --git a/src/client-scopes/messages.ts b/src/client-scopes/messages.ts index 3f18ceadf8..ae299f6fe0 100644 --- a/src/client-scopes/messages.ts +++ b/src/client-scopes/messages.ts @@ -30,8 +30,6 @@ export default { addMapperExplain: "If you want more fine-grain control, you can create protocol mapper on this client", realmRoles: "Realm roles", - clientRoles: "Client roles", - selectASourceOfRoles: "Select a source of roles", newRoleName: "New role name", searchClientByName: "Search client by name", clients: "Clients", @@ -50,8 +48,6 @@ export default { predefinedMappingDescription: "Choose one of the predefined mappings from this table", mappingTable: "Table with predefined mapping", - roleGroup: "Use a realm role from:", - clientGroup: "Use a client role from:", scope: "Scope", roleMappingUpdatedSuccess: "Role mapping updated", roleMappingUpdatedError: "Could not update role mapping {{error}}", diff --git a/src/components/dynamic/BooleanComponent.tsx b/src/components/dynamic/BooleanComponent.tsx index 46e137ac22..a63eb38955 100644 --- a/src/components/dynamic/BooleanComponent.tsx +++ b/src/components/dynamic/BooleanComponent.tsx @@ -27,7 +27,7 @@ export const BooleanComponent = ({ ( onChange("" + value)} + data-testid={name} /> )} /> diff --git a/src/components/dynamic/GroupComponent.tsx b/src/components/dynamic/GroupComponent.tsx new file mode 100644 index 0000000000..c6f93699cb --- /dev/null +++ b/src/components/dynamic/GroupComponent.tsx @@ -0,0 +1,75 @@ +import React, { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { Controller, useFormContext } from "react-hook-form"; +import { + Button, + Chip, + ChipGroup, + FormGroup, + InputGroup, +} from "@patternfly/react-core"; + +import type { ComponentProps } from "./components"; +import { HelpItem } from "../help-enabler/HelpItem"; +import { GroupPickerDialog } from "../group/GroupPickerDialog"; + +export const GroupComponent = ({ name, label, helpText }: ComponentProps) => { + const { t } = useTranslation("dynamic"); + const [open, setOpen] = useState(false); + const { control } = useFormContext(); + + return ( + ( + <> + {open && ( + { + onChange(groups[0].path); + setOpen(false); + }} + onClose={() => setOpen(false)} + filterGroups={value} + /> + )} + + + } + fieldId={name!} + > + + + {value && ( + onChange(undefined)}>{value} + )} + + + + + + )} + /> + ); +}; diff --git a/src/components/dynamic/MapComponent.tsx b/src/components/dynamic/MapComponent.tsx new file mode 100644 index 0000000000..1ef1aa280b --- /dev/null +++ b/src/components/dynamic/MapComponent.tsx @@ -0,0 +1,23 @@ +import React from "react"; +import { useTranslation } from "react-i18next"; +import { FormGroup } from "@patternfly/react-core"; + +import type { ComponentProps } from "./components"; +import { HelpItem } from "../help-enabler/HelpItem"; +import { AttributeInput } from "../attribute-input/AttributeInput"; + +export const MapComponent = ({ name, label, helpText }: ComponentProps) => { + const { t } = useTranslation("dynamic"); + + return ( + + } + fieldId={name!} + > + + + ); +}; diff --git a/src/components/dynamic/RoleComponent.tsx b/src/components/dynamic/RoleComponent.tsx index de3880a168..cfe17ea456 100644 --- a/src/components/dynamic/RoleComponent.tsx +++ b/src/components/dynamic/RoleComponent.tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { Controller, useFormContext } from "react-hook-form"; import { useTranslation } from "react-i18next"; import { @@ -19,12 +19,17 @@ import { useRealm } from "../../context/realm-context/RealmContext"; import { HelpItem } from "../help-enabler/HelpItem"; import type { ComponentProps } from "./components"; +const RealmClient = (realm: string): ClientRepresentation => ({ + name: "realmRoles", + clientId: realm, +}); + export const RoleComponent = ({ name, label, helpText }: ComponentProps) => { const { t } = useTranslation("dynamic"); const adminClient = useAdminClient(); const { realm } = useRealm(); - const { control, errors } = useFormContext(); + const { control, errors, getValues } = useFormContext(); const [roleOpen, setRoleOpen] = useState(false); const [clientsOpen, setClientsOpen] = useState(false); @@ -51,30 +56,29 @@ export const RoleComponent = ({ name, label, helpText }: ComponentProps) => { (await adminClient.clients.listRoles({ id: client.id! })).length > 0 ); - filteredClients.map( - (client) => - (client.toString = function () { - return this.clientId!; - }) - ); return filteredClients; }, (filteredClients) => setClients(filteredClients), [] ); + useEffect(() => { + const value = getValues(fieldName); + const [client, role] = value?.includes(".") + ? value.split(".") + : ["", value || ""]; + if (client) { + setSelectedClient(clients?.find((c) => c.clientId === client)); + } else { + setSelectedClient(RealmClient(realm)); + } + setSelectedRole({ name: role }); + }, [clients, getValues]); + const createSelectGroup = (clients: ClientRepresentation[]) => { return [ - t("realmRoles"), - } as ClientRepresentation - } - > + {realm} , @@ -133,75 +137,76 @@ export const RoleComponent = ({ name, label, helpText }: ComponentProps) => { name={fieldName} defaultValue="" control={control} - rules={{ required: true }} - render={({ onChange, value }) => { - const [client, role] = value?.split(".") || ["", ""]; - return ( - - - {clients && ( - - )} - - + render={({ onChange }) => ( + + + {clients && ( - - - ); - }} + )} + + + + + + )} /> ); diff --git a/src/components/dynamic/components.ts b/src/components/dynamic/components.ts index f09855ee21..da79a02798 100644 --- a/src/components/dynamic/components.ts +++ b/src/components/dynamic/components.ts @@ -5,10 +5,12 @@ import { StringComponent } from "./StringComponent"; import { BooleanComponent } from "./BooleanComponent"; import { ListComponent } from "./ListComponent"; import { RoleComponent } from "./RoleComponent"; +import { MapComponent } from "./MapComponent"; import { ScriptComponent } from "./ScriptComponent"; import { ClientSelectComponent } from "./ClientSelectComponent"; import { MultiValuedStringComponent } from "./MultivaluedStringComponent"; import { MultiValuedListComponent } from "./MultivaluedListComponent"; +import { GroupComponent } from "./GroupComponent"; export type ComponentProps = Omit; const ComponentTypes = [ @@ -17,6 +19,8 @@ const ComponentTypes = [ "List", "Role", "Script", + "Map", + "Group", "MultivaluedList", "ClientList", "MultivaluedString", @@ -32,6 +36,8 @@ export const COMPONENTS: { List: ListComponent, Role: RoleComponent, Script: ScriptComponent, + Map: MapComponent, + Group: GroupComponent, ClientList: ClientSelectComponent, MultivaluedList: MultiValuedListComponent, MultivaluedString: MultiValuedStringComponent, diff --git a/src/components/dynamic/labels.ts b/src/components/dynamic/labels.ts index 0db7540e82..c1fb3fe572 100644 --- a/src/components/dynamic/labels.ts +++ b/src/components/dynamic/labels.ts @@ -2,6 +2,11 @@ export default { dynamic: { addMultivaluedLabel: "Add {{fieldLabel}}", selectARole: "Select a role", + selectASourceOfRoles: "Select a source of roles", + clientRoles: "Client roles", + roleGroup: "Use a realm role from:", + clientGroup: "Use a client role from:", + selectGroup: "Select group", usermodel: { prop: { label: "Property", diff --git a/src/identity-providers/add/AddMapper.tsx b/src/identity-providers/add/AddMapper.tsx index 289703f731..ae5f0919b8 100644 --- a/src/identity-providers/add/AddMapper.tsx +++ b/src/identity-providers/add/AddMapper.tsx @@ -1,31 +1,23 @@ -import React, { useMemo, useState } from "react"; +import React, { useState } from "react"; import { Link, useHistory, useParams } from "react-router-dom"; import { useTranslation } from "react-i18next"; -import { Controller, FormProvider, useForm } from "react-hook-form"; +import { FormProvider, useForm } from "react-hook-form"; import { ActionGroup, AlertVariant, Button, FormGroup, PageSection, - Select, - SelectOption, - SelectVariant, - Switch, TextInput, ValidatedOptions, } from "@patternfly/react-core"; import { useRealm } from "../../context/realm-context/RealmContext"; -import { HelpItem } from "../../components/help-enabler/HelpItem"; import { ViewHeader } from "../../components/view-header/ViewHeader"; -import { AttributeInput } from "../../components/attribute-input/AttributeInput"; -import type { AttributeForm } from "../../components/attribute-form/AttributeForm"; import { FormAccess } from "../../components/form-access/FormAccess"; import { useAdminClient, useFetch } from "../../context/auth/AdminClient"; import type { IdentityProviderAddMapperParams } from "../routes/AddMapper"; -import { AssociatedRolesModal } from "../../realm-roles/AssociatedRolesModal"; import type { RoleRepresentation } from "../../model/role-model"; import { useAlerts } from "../../components/alert/Alerts"; import { @@ -35,9 +27,11 @@ import { import { convertFormValuesToObject, convertToFormValues } from "../../util"; import { toIdentityProvider } from "../routes/IdentityProvider"; import type IdentityProviderMapperRepresentation from "@keycloak/keycloak-admin-client/lib/defs/identityProviderMapperRepresentation"; +import type { IdentityProviderMapperTypeRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/identityProviderMapperTypeRepresentation"; import { AddMapperForm } from "./AddMapperForm"; -import { useServerInfo } from "../../context/server-info/ServerInfoProvider"; -import { groupBy } from "lodash"; +import { DynamicComponents } from "../../components/dynamic/DynamicComponents"; +import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner"; +import type { AttributeForm } from "../../components/attribute-form/AttributeForm"; export type IdPMapperRepresentationWithAttributes = IdentityProviderMapperRepresentation & AttributeForm; @@ -49,8 +43,10 @@ export type Role = RoleRepresentation & { export default function AddMapper() { const { t } = useTranslation("identity-providers"); - const form = useForm(); - const { handleSubmit, control, register, errors } = form; + const form = useForm({ + shouldUnregister: false, + }); + const { handleSubmit, register, errors } = form; const { addAlert, addError } = useAlerts(); const history = useHistory(); @@ -60,56 +56,38 @@ export default function AddMapper() { const { providerId, alias } = useParams(); const { id } = useParams(); - const serverInfo = useServerInfo(); - const identityProviders = useMemo( - () => groupBy(serverInfo.identityProviders, "groupName"), - [serverInfo] - ); - - const isSocialIdP = useMemo( - () => - identityProviders["Social"] - .map((item) => item.id) - .includes(providerId.toLowerCase()), - [identityProviders, providerId] - ); - const [mapperTypes, setMapperTypes] = - useState>(); - const [mapperType, setMapperType] = useState( - isSocialIdP - ? "attributeImporter" - : providerId === "saml" - ? "advancedAttributeToRole" - : "hardcodedUserSessionAttribute" - ); + useState>(); + const [mapperType, setMapperType] = useState(); const [currentMapper, setCurrentMapper] = useState(); - const [rolesModalOpen, setRolesModalOpen] = useState(false); - const save = async (idpMapper: IdentityProviderMapperRepresentation) => { - const attributes = JSON.stringify(idpMapper.config?.attributes ?? []); - const mapper = convertFormValuesToObject(idpMapper); + const mapper = convertFormValuesToObject( + idpMapper + ) as IdentityProviderMapperRepresentation; + const attributes = JSON.stringify(idpMapper.config.attributes ?? []); + const claims = JSON.stringify(idpMapper.config.claims ?? []); + + const identityProviderMapper = { + ...mapper, + config: { + ...mapper.config, + attributes, + claims, + }, + identityProviderAlias: alias!, + }; if (id) { - const updatedMapper = { - ...mapper, - config: { - attributes, - }, - identityProviderAlias: alias!, - id: id, - name: currentMapper?.name!, - }; try { await adminClient.identityProviders.updateMapper( { id: id!, alias: alias!, }, - updatedMapper + { ...identityProviderMapper, name: currentMapper?.name! } ); addAlert(t("mapperSaveSuccess"), AlertVariant.success); } catch (error) { @@ -118,13 +96,7 @@ export default function AddMapper() { } else { try { const createdMapper = await adminClient.identityProviders.createMapper({ - identityProviderMapper: { - ...mapper, - identityProviderAlias: alias, - config: { - attributes, - }, - }, + identityProviderMapper, alias: alias!, }); @@ -153,6 +125,9 @@ export default function AddMapper() { if (mapper) { setCurrentMapper(mapper); setupForm(mapper); + setMapperType(mapper.identityProviderMapper!); + } else { + setMapperType(Object.keys(mapperTypes)[0]); } setMapperTypes(mapperTypes); @@ -161,58 +136,14 @@ export default function AddMapper() { ); const setupForm = (mapper: IdentityProviderMapperRepresentation) => { - form.reset(); convertToFormValues(mapper, form.setValue); form.setValue("config.attributes", JSON.parse(mapper.config.attributes)); + form.setValue("config.claims", JSON.parse(mapper.config.claims)); }; - const targetOptions = ["local", "brokerId", "brokerUsername"]; - const [targetOptionsOpen, setTargetOptionsOpen] = useState(false); - const [selectedRole, setSelectedRole] = useState([]); - - const formValues = form.getValues(); - - const isSAMLAdvancedAttrToRole = - formValues.identityProviderMapper === "saml-advanced-role-idp-mapper"; - - const isOIDCclaimToRole = - formValues.identityProviderMapper === "oidc-role-idp-mapper"; - - const isOIDCAdvancedClaimToRole = - formValues.identityProviderMapper === "oidc-advanced-role-idp-mapper"; - - const isSAMLAttributeImporter = - formValues.identityProviderMapper === "saml-user-attribute-idp-mapper"; - - const isOIDCAttributeImporter = - formValues.identityProviderMapper === "oidc-user-attribute-idp-mapper"; - - const isHardcodedAttribute = - formValues.identityProviderMapper === "hardcoded-attribute-idp-mapper"; - - const isHardcodedRole = - formValues.identityProviderMapper === "oidc-hardcoded-role-idp-mapper"; - - const isHardcodedUserSessionAttribute = - formValues.identityProviderMapper === - "hardcoded-user-session-attribute-idp-mapper"; - - const isSAMLAttributeToRole = - formValues.identityProviderMapper === "saml-role-idp-mapper"; - - const isSAMLUsernameTemplateImporter = - formValues.identityProviderMapper === "saml-username-idp-mapper"; - - const isOIDCUsernameTemplateImporter = - formValues.identityProviderMapper === "oidc-username-idp-mapper"; - - const isSocialAttributeImporter = useMemo( - () => formValues.identityProviderMapper?.includes("user-attribute-mapper"), - [formValues.identityProviderMapper] - ); - const toggleModal = () => { - setRolesModalOpen(!rolesModalOpen); - }; + if (!mapperTypes) { + return ; + } return ( @@ -231,16 +162,6 @@ export default function AddMapper() { } divider /> - {rolesModalOpen && ( - setSelectedRole(role)} - omitComposites - isRadio - isMapperId - toggleDialog={toggleModal} - /> - )} - <> - {(isSAMLAdvancedAttrToRole || isOIDCAdvancedClaimToRole) && ( - <> - - } - fieldId="kc-gui-order" - > - - - - - - } - fieldId="regexAttributeValues" - > - ( - onChange("" + value)} - /> - )} - /> - - + + {mapperType && mapperTypes[mapperType].properties && ( + )} - {(isSAMLUsernameTemplateImporter || - isOIDCUsernameTemplateImporter) && ( - <> - - } - fieldId="kc-user-session-attribute" - validated={ - errors.name - ? ValidatedOptions.error - : ValidatedOptions.default - } - helperTextInvalid={t("common:required")} - > - - - - } - fieldId="kc-target" - validated={ - errors.name - ? ValidatedOptions.error - : ValidatedOptions.default - } - helperTextInvalid={t("common:required")} - > - ( - - )} - /> - - - )} - - {(isHardcodedAttribute || isHardcodedUserSessionAttribute) && ( - <> - - } - fieldId="kc-user-session-attribute" - validated={ - errors.name - ? ValidatedOptions.error - : ValidatedOptions.default - } - helperTextInvalid={t("common:required")} - > - - - - } - fieldId="kc-user-session-attribute-value" - validated={ - errors.name - ? ValidatedOptions.error - : ValidatedOptions.default - } - helperTextInvalid={t("common:required")} - > - - - - )} - {(isSAMLAttributeImporter || - isOIDCAttributeImporter || - isOIDCclaimToRole) && ( - <> - {isSAMLAttributeImporter ? ( - <> - - } - fieldId="kc-attribute-name" - validated={ - errors.name - ? ValidatedOptions.error - : ValidatedOptions.default - } - helperTextInvalid={t("common:required")} - > - - - - } - fieldId="kc-friendly-name" - validated={ - errors.name - ? ValidatedOptions.error - : ValidatedOptions.default - } - helperTextInvalid={t("common:required")} - > - - - - ) : ( - - } - fieldId="kc-friendly-name" - validated={ - errors.name - ? ValidatedOptions.error - : ValidatedOptions.default - } - helperTextInvalid={t("common:required")} - > - - - )} - - } - fieldId="kc-user-attribute-name" - validated={ - errors.name - ? ValidatedOptions.error - : ValidatedOptions.default - } - helperTextInvalid={t("common:required")} - > - - - - )} - - {isSocialAttributeImporter && ( - <> - - } - fieldId="kc-social-profile-JSON-field-path" - validated={ - errors.name - ? ValidatedOptions.error - : ValidatedOptions.default - } - helperTextInvalid={t("common:required")} - > - - - - } - fieldId="kc-user-session-attribute-value" - validated={ - errors.name - ? ValidatedOptions.error - : ValidatedOptions.default - } - helperTextInvalid={t("common:required")} - > - - - - )} - {(isSAMLAdvancedAttrToRole || - isHardcodedRole || - isSAMLAttributeToRole || - isOIDCAdvancedClaimToRole || - isOIDCclaimToRole) && ( - - } - fieldId="kc-role" - validated={ - errors.config?.role - ? ValidatedOptions.error - : ValidatedOptions.default - } - helperTextInvalid={t("common:required")} - > - - - - )} - +