changed to use ui-shared (#27705)
Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
parent
6967f57f39
commit
131aeedb98
7 changed files with 395 additions and 874 deletions
|
@ -1,3 +1,4 @@
|
|||
import Select from "../../../../forms/Select";
|
||||
import LegacyKeyValueInput from "../LegacyKeyValueInput";
|
||||
|
||||
export default class AddMapperPage {
|
||||
|
@ -7,7 +8,7 @@ export default class AddMapperPage {
|
|||
#idpMapperSelect = "idp-mapper-select";
|
||||
#addMapperButton = "#add-mapper-button";
|
||||
|
||||
#mapperNameInput = "#kc-name";
|
||||
#mapperNameInput = "name";
|
||||
#attribute = "config.user🍺attribute";
|
||||
#attributeName = "attribute.name";
|
||||
#attributeFriendlyName = "attribute.friendly.name";
|
||||
|
@ -64,15 +65,15 @@ export default class AddMapperPage {
|
|||
return this;
|
||||
}
|
||||
|
||||
typeName(name: string) {
|
||||
cy.findByTestId(this.#mapperNameInput).clear();
|
||||
cy.findByTestId(this.#mapperNameInput).type(name);
|
||||
}
|
||||
|
||||
fillSocialMapper(name: string) {
|
||||
cy.get(this.#mapperNameInput).clear();
|
||||
|
||||
cy.get(this.#mapperNameInput).clear().type(name);
|
||||
|
||||
cy.get(this.#syncmodeSelectToggle).click();
|
||||
|
||||
cy.findByTestId("legacy").click();
|
||||
this.typeName(name);
|
||||
|
||||
Select.selectItem(cy.get(this.#syncmodeSelectToggle), "Legacy");
|
||||
cy.get(this.#idpMapperSelectToggle).click();
|
||||
|
||||
cy.findByTestId(this.#idpMapperSelect)
|
||||
|
@ -101,13 +102,8 @@ export default class AddMapperPage {
|
|||
}
|
||||
|
||||
addAdvancedAttrToRoleMapper(name: string) {
|
||||
cy.get(this.#mapperNameInput).clear();
|
||||
|
||||
cy.get(this.#mapperNameInput).clear().type(name);
|
||||
|
||||
cy.get(this.#syncmodeSelectToggle).click();
|
||||
|
||||
cy.findByTestId("inherit").click();
|
||||
this.typeName(name);
|
||||
Select.selectItem(cy.get(this.#syncmodeSelectToggle), "Inherit");
|
||||
|
||||
cy.get(this.#idpMapperSelectToggle).click();
|
||||
|
||||
|
@ -132,13 +128,8 @@ export default class AddMapperPage {
|
|||
}
|
||||
|
||||
addUsernameTemplateImporterMapper(name: string) {
|
||||
cy.get(this.#mapperNameInput).clear();
|
||||
|
||||
cy.get(this.#mapperNameInput).clear().type(name);
|
||||
|
||||
cy.get(this.#syncmodeSelectToggle).click();
|
||||
|
||||
cy.findByTestId("inherit").click();
|
||||
this.typeName(name);
|
||||
Select.selectItem(cy.get(this.#syncmodeSelectToggle), "Inherit");
|
||||
|
||||
cy.get(this.#idpMapperSelectToggle).click();
|
||||
|
||||
|
@ -157,13 +148,8 @@ export default class AddMapperPage {
|
|||
}
|
||||
|
||||
addHardcodedUserSessionAttrMapper(name: string) {
|
||||
cy.get(this.#mapperNameInput).clear();
|
||||
|
||||
cy.get(this.#mapperNameInput).clear().type(name);
|
||||
|
||||
cy.get(this.#syncmodeSelectToggle).click();
|
||||
|
||||
cy.findByTestId("inherit").click();
|
||||
this.typeName(name);
|
||||
Select.selectItem(cy.get(this.#syncmodeSelectToggle), "Inherit");
|
||||
|
||||
cy.get(this.#idpMapperSelectToggle).click();
|
||||
|
||||
|
@ -185,13 +171,9 @@ export default class AddMapperPage {
|
|||
}
|
||||
|
||||
addSAMLAttrImporterMapper(name: string) {
|
||||
cy.get(this.#mapperNameInput).clear();
|
||||
this.typeName(name);
|
||||
|
||||
cy.get(this.#mapperNameInput).clear().type(name);
|
||||
|
||||
cy.get(this.#syncmodeSelectToggle).click();
|
||||
|
||||
cy.findByTestId("inherit").click();
|
||||
Select.selectItem(cy.get(this.#syncmodeSelectToggle), "Inherit");
|
||||
|
||||
cy.get(this.#idpMapperSelectToggle).click();
|
||||
|
||||
|
@ -215,14 +197,9 @@ export default class AddMapperPage {
|
|||
}
|
||||
|
||||
addOIDCAttrImporterMapper(name: string) {
|
||||
cy.get(this.#mapperNameInput).clear();
|
||||
|
||||
cy.get(this.#mapperNameInput).clear().type(name);
|
||||
|
||||
cy.get(this.#syncmodeSelectToggle).click();
|
||||
|
||||
cy.findByTestId("inherit").click();
|
||||
this.typeName(name);
|
||||
|
||||
Select.selectItem(cy.get(this.#syncmodeSelectToggle), "Inherit");
|
||||
cy.get(this.#idpMapperSelectToggle).click();
|
||||
|
||||
cy.findByTestId(this.#idpMapperSelect)
|
||||
|
@ -238,13 +215,8 @@ export default class AddMapperPage {
|
|||
}
|
||||
|
||||
addHardcodedRoleMapper(name: string) {
|
||||
cy.get(this.#mapperNameInput).clear();
|
||||
|
||||
cy.get(this.#mapperNameInput).clear().type(name);
|
||||
|
||||
cy.get(this.#syncmodeSelectToggle).click();
|
||||
|
||||
cy.findByTestId("inherit").click();
|
||||
this.typeName(name);
|
||||
Select.selectItem(cy.get(this.#syncmodeSelectToggle), "Inherit");
|
||||
|
||||
cy.get(this.#idpMapperSelectToggle).click();
|
||||
|
||||
|
@ -257,13 +229,8 @@ export default class AddMapperPage {
|
|||
}
|
||||
|
||||
addHardcodedAttrMapper(name: string) {
|
||||
cy.get(this.#mapperNameInput).clear();
|
||||
|
||||
cy.get(this.#mapperNameInput).clear().type(name);
|
||||
|
||||
cy.get(this.#syncmodeSelectToggle).click();
|
||||
|
||||
cy.findByTestId("inherit").click();
|
||||
this.typeName(name);
|
||||
Select.selectItem(cy.get(this.#syncmodeSelectToggle), "Inherit");
|
||||
|
||||
cy.get(this.#idpMapperSelectToggle).click();
|
||||
|
||||
|
@ -283,13 +250,9 @@ export default class AddMapperPage {
|
|||
}
|
||||
|
||||
addSAMLAttributeToRoleMapper(name: string) {
|
||||
cy.get(this.#mapperNameInput).clear();
|
||||
this.typeName(name);
|
||||
|
||||
cy.get(this.#mapperNameInput).clear().type(name);
|
||||
|
||||
cy.get(this.#syncmodeSelectToggle).click();
|
||||
|
||||
cy.findByTestId("inherit").click();
|
||||
Select.selectItem(cy.get(this.#syncmodeSelectToggle), "Inherit");
|
||||
|
||||
cy.get(this.#idpMapperSelectToggle).click();
|
||||
|
||||
|
@ -305,9 +268,7 @@ export default class AddMapperPage {
|
|||
}
|
||||
|
||||
editUsernameTemplateImporterMapper() {
|
||||
cy.get(this.#syncmodeSelectToggle).click();
|
||||
|
||||
cy.findByTestId("legacy").click();
|
||||
Select.selectItem(cy.get(this.#syncmodeSelectToggle), "Legacy");
|
||||
|
||||
cy.findByTestId(this.#template).type("_edited");
|
||||
|
||||
|
@ -319,9 +280,7 @@ export default class AddMapperPage {
|
|||
}
|
||||
|
||||
editSocialMapper() {
|
||||
cy.get(this.#syncmodeSelectToggle).click();
|
||||
|
||||
cy.findByTestId("inherit").click();
|
||||
Select.selectItem(cy.get(this.#syncmodeSelectToggle), "Inherit");
|
||||
|
||||
cy.findByTestId(this.#socialProfileJSONfieldPath).clear();
|
||||
|
||||
|
@ -339,9 +298,7 @@ export default class AddMapperPage {
|
|||
}
|
||||
|
||||
editSAMLorOIDCMapper() {
|
||||
cy.get(this.#syncmodeSelectToggle).click();
|
||||
|
||||
cy.findByTestId("legacy").click();
|
||||
Select.selectItem(cy.get(this.#syncmodeSelectToggle), "Inherit");
|
||||
|
||||
cy.get(this.#attributesKeyInput).clear();
|
||||
cy.get(this.#attributesKeyInput).type("key_edited");
|
||||
|
@ -357,14 +314,9 @@ export default class AddMapperPage {
|
|||
}
|
||||
|
||||
addOIDCAttributeImporterMapper(name: string) {
|
||||
cy.get(this.#mapperNameInput).clear();
|
||||
|
||||
cy.get(this.#mapperNameInput).clear().type(name);
|
||||
|
||||
cy.get(this.#syncmodeSelectToggle).click();
|
||||
|
||||
cy.findByTestId("inherit").click();
|
||||
this.typeName(name);
|
||||
|
||||
Select.selectItem(cy.get(this.#syncmodeSelectToggle), "Inherit");
|
||||
cy.get(this.#idpMapperSelectToggle).click();
|
||||
|
||||
cy.findByTestId(this.#idpMapperSelect)
|
||||
|
@ -383,13 +335,9 @@ export default class AddMapperPage {
|
|||
}
|
||||
|
||||
addOIDCClaimToRoleMapper(name: string) {
|
||||
cy.get(this.#mapperNameInput).clear();
|
||||
this.typeName(name);
|
||||
|
||||
cy.get(this.#mapperNameInput).clear().type(name);
|
||||
|
||||
cy.get(this.#syncmodeSelectToggle).click();
|
||||
|
||||
cy.findByTestId("inherit").click();
|
||||
Select.selectItem(cy.get(this.#syncmodeSelectToggle), "Inherit");
|
||||
|
||||
cy.get(this.#idpMapperSelectToggle).click();
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import Select from "../../../../../forms/Select";
|
||||
import PageObject from "../../../components/PageObject";
|
||||
import Masthead from "../../../Masthead";
|
||||
|
||||
|
@ -6,44 +7,32 @@ const masthead = new Masthead();
|
|||
export default class ProviderSAMLSettings extends PageObject {
|
||||
#samlSwitch = "Saml-switch";
|
||||
#modalConfirm = "#modal-confirm";
|
||||
#serviceProviderEntityID = "serviceProviderEntityId";
|
||||
#serviceProviderEntityID = "config.entityId";
|
||||
#identityProviderEntityId = "identityProviderEntityId";
|
||||
#ssoServiceUrl = "sso-service-url";
|
||||
#singleLogoutServiceUrl = "single-logout-service-url";
|
||||
#nameIdPolicyFormat = "#kc-nameIdPolicyFormat";
|
||||
#principalType = "#kc-principalType";
|
||||
#principalAttribute = "principalAttribute";
|
||||
#principalSubjectNameId = "subjectNameId-option";
|
||||
#principalAttributeName = "attributeName-option";
|
||||
#principalFriendlyAttribute = "attributeFriendlyName-option";
|
||||
#ssoServiceUrl = "config.singleSignOnServiceUrl";
|
||||
#singleLogoutServiceUrl = "config.singleLogoutServiceUrl";
|
||||
#nameIdPolicyFormat = "#nameIDPolicyFormat";
|
||||
#principalType = "#principalType";
|
||||
|
||||
#transientPolicy = "transient-option";
|
||||
#emailPolicy = "email-option";
|
||||
#kerberosPolicy = "kerberos-option";
|
||||
#x509Policy = "x509-option";
|
||||
#windowsDomainQNPolicy = "windowsDomainQN-option";
|
||||
#unspecifiedPolicy = "unspecified-option";
|
||||
#persistentPolicy = "persistent-option";
|
||||
#allowCreate = "config.allowCreate";
|
||||
#httpPostBindingResponse = "config.postBindingResponse";
|
||||
#httpPostBindingAuthnRequest = "config.postBindingAuthnRequest";
|
||||
#httpPostBindingLogout = "config.postBindingLogout";
|
||||
#wantAuthnRequestsSigned = "config.wantAuthnRequestsSigned";
|
||||
|
||||
#allowCreate = "#allowCreate";
|
||||
#httpPostBindingResponse = "#httpPostBindingResponse";
|
||||
#httpPostBindingAuthnRequest = "#httpPostBindingAuthnRequest";
|
||||
#httpPostBindingLogout = "#httpPostBindingLogout";
|
||||
#wantAuthnRequestsSigned = "#wantAuthnRequestsSigned";
|
||||
#signatureAlgorithm = "#signatureAlgorithm";
|
||||
#samlSignatureKeyName = "#xmlSigKeyInfoKeyNameTransformer";
|
||||
|
||||
#signatureAlgorithm = "#kc-signatureAlgorithm";
|
||||
#samlSignatureKeyName = "#kc-samlSignatureKeyName";
|
||||
|
||||
#wantAssertionsSigned = "#wantAssertionsSigned";
|
||||
#wantAssertionsEncrypted = "#wantAssertionsEncrypted";
|
||||
#forceAuthentication = "#forceAuthentication";
|
||||
#validateSignature = "#validateSignature";
|
||||
#validatingX509Certs = "validatingX509Certs";
|
||||
#signServiceProviderMetadata = "#signServiceProviderMetadata";
|
||||
#passSubject = "#passSubject";
|
||||
#allowedClockSkew = "allowedClockSkew";
|
||||
#attributeConsumingServiceIndex = "attributeConsumingServiceIndex";
|
||||
#attributeConsumingServiceName = "attributeConsumingServiceName";
|
||||
#wantAssertionsSigned = "config.wantAssertionsSigned";
|
||||
#wantAssertionsEncrypted = "config.wantAssertionsEncrypted";
|
||||
#forceAuthentication = "config.forceAuthn";
|
||||
#validateSignature = "config.validateSignature";
|
||||
#validatingX509Certs = "config.signingCertificate";
|
||||
#signServiceProviderMetadata = "config.signSpMetadata";
|
||||
#passSubject = "config.loginHint";
|
||||
#allowedClockSkew = "#config\\.allowedClockSkew";
|
||||
#attributeConsumingServiceIndex = "#config\\.attributeConsumingServiceIndex";
|
||||
#attributeConsumingServiceName = "config.attributeConsumingServiceName";
|
||||
|
||||
#comparison = "#comparison";
|
||||
#saveBtn = "idp-details-save";
|
||||
|
@ -95,26 +84,33 @@ export default class ProviderSAMLSettings extends PageObject {
|
|||
}
|
||||
|
||||
public typeX509Certs(cert: string) {
|
||||
cy.findByTestId(this.#validatingX509Certs).clear().type(cert);
|
||||
cy.findByTestId(this.#validatingX509Certs).clear();
|
||||
cy.findByTestId(this.#validatingX509Certs).type(cert);
|
||||
return this;
|
||||
}
|
||||
|
||||
public selectNamePolicyIdFormat() {
|
||||
cy.get(this.#nameIdPolicyFormat).scrollIntoView().click();
|
||||
public selectNamePolicyIdFormat(option: string) {
|
||||
cy.get(this.#nameIdPolicyFormat).scrollIntoView();
|
||||
Select.selectItem(cy.get(this.#nameIdPolicyFormat), option);
|
||||
Select.assertSelectedItem(cy.get(this.#nameIdPolicyFormat), option);
|
||||
return this;
|
||||
}
|
||||
|
||||
public selectPrincipalFormat() {
|
||||
cy.get(this.#principalType).scrollIntoView().click();
|
||||
public selectPrincipalFormat(option: string) {
|
||||
cy.get(this.#principalType).scrollIntoView();
|
||||
Select.selectItem(cy.get(this.#principalType), option);
|
||||
Select.assertSelectedItem(cy.get(this.#principalType), option);
|
||||
return this;
|
||||
}
|
||||
|
||||
public selectSignatureAlgorithm(algorithm: string) {
|
||||
cy.get(this.#signatureAlgorithm).scrollIntoView().click();
|
||||
cy.findByText(algorithm).click();
|
||||
cy.get(this.#signatureAlgorithm).scrollIntoView();
|
||||
Select.selectItem(cy.get(this.#signatureAlgorithm), algorithm);
|
||||
}
|
||||
|
||||
public selectSAMLSignature(key: string) {
|
||||
cy.get(this.#samlSignatureKeyName).scrollIntoView().click();
|
||||
cy.findByText(key).click();
|
||||
cy.get(this.#samlSignatureKeyName).scrollIntoView();
|
||||
Select.selectItem(cy.get(this.#samlSignatureKeyName), key);
|
||||
}
|
||||
|
||||
public selectComparison(comparison: string) {
|
||||
|
@ -143,25 +139,18 @@ export default class ProviderSAMLSettings extends PageObject {
|
|||
}
|
||||
|
||||
public assertNameIdPolicyFormat() {
|
||||
this.selectNamePolicyIdFormat();
|
||||
cy.findByTestId(this.#transientPolicy).click();
|
||||
this.selectNamePolicyIdFormat();
|
||||
cy.findByTestId(this.#emailPolicy).click();
|
||||
this.selectNamePolicyIdFormat();
|
||||
cy.findByTestId(this.#kerberosPolicy).click();
|
||||
this.selectNamePolicyIdFormat();
|
||||
cy.findByTestId(this.#x509Policy).click();
|
||||
this.selectNamePolicyIdFormat();
|
||||
cy.findByTestId(this.#windowsDomainQNPolicy).click();
|
||||
this.selectNamePolicyIdFormat();
|
||||
cy.findByTestId(this.#unspecifiedPolicy).click();
|
||||
this.selectNamePolicyIdFormat();
|
||||
cy.findByTestId(this.#persistentPolicy).click();
|
||||
this.selectNamePolicyIdFormat("Transient");
|
||||
this.selectNamePolicyIdFormat("Email");
|
||||
this.selectNamePolicyIdFormat("Kerberos");
|
||||
this.selectNamePolicyIdFormat("X.509 Subject Name");
|
||||
this.selectNamePolicyIdFormat("Windows Domain Qualified Name");
|
||||
this.selectNamePolicyIdFormat("Unspecified");
|
||||
this.selectNamePolicyIdFormat("Persistent");
|
||||
return this;
|
||||
}
|
||||
|
||||
public assertSignatureAlgorithm() {
|
||||
cy.get(this.#wantAuthnRequestsSigned).parent().click();
|
||||
cy.findByTestId(this.#wantAuthnRequestsSigned).parent().click();
|
||||
cy.get(this.#signatureAlgorithm).should("not.exist");
|
||||
cy.get(this.#samlSignatureKeyName).should("not.exist");
|
||||
this.clickRevertBtn();
|
||||
|
@ -183,38 +172,32 @@ export default class ProviderSAMLSettings extends PageObject {
|
|||
}
|
||||
|
||||
public assertPrincipalType() {
|
||||
this.selectPrincipalFormat();
|
||||
cy.findByTestId(this.#principalAttributeName).click();
|
||||
cy.findByTestId(this.#principalAttribute).should("exist").scrollIntoView();
|
||||
this.selectPrincipalFormat();
|
||||
cy.findByTestId(this.#principalFriendlyAttribute).click();
|
||||
cy.findByTestId(this.#principalAttribute).should("exist");
|
||||
this.selectPrincipalFormat();
|
||||
cy.findByTestId(this.#principalSubjectNameId).click();
|
||||
cy.findByTestId(this.#principalAttribute).should("not.exist");
|
||||
this.selectPrincipalFormat("Subject NameID");
|
||||
this.selectPrincipalFormat("Attribute [Name]");
|
||||
this.selectPrincipalFormat("Attribute [Friendly Name]");
|
||||
return this;
|
||||
}
|
||||
|
||||
public assertSAMLSwitches() {
|
||||
cy.get(this.#allowCreate).parent().click();
|
||||
cy.get(this.#httpPostBindingResponse).parent().click();
|
||||
cy.get(this.#httpPostBindingLogout).parent().click();
|
||||
cy.get(this.#httpPostBindingAuthnRequest).parent().click();
|
||||
cy.findByTestId(this.#allowCreate).parent().click();
|
||||
cy.findByTestId(this.#httpPostBindingResponse).parent().click();
|
||||
cy.findByTestId(this.#httpPostBindingLogout).parent().click();
|
||||
cy.findByTestId(this.#httpPostBindingAuthnRequest).parent().click();
|
||||
|
||||
cy.get(this.#wantAssertionsSigned).parent().click();
|
||||
cy.get(this.#wantAssertionsEncrypted).parent().click();
|
||||
cy.get(this.#forceAuthentication).parent().click();
|
||||
cy.findByTestId(this.#wantAssertionsSigned).parent().click();
|
||||
cy.findByTestId(this.#wantAssertionsEncrypted).parent().click();
|
||||
cy.findByTestId(this.#forceAuthentication).parent().click();
|
||||
|
||||
cy.get(this.#signServiceProviderMetadata).parent().click();
|
||||
cy.get(this.#passSubject).parent().click();
|
||||
cy.findByTestId(this.#signServiceProviderMetadata).parent().click();
|
||||
cy.findByTestId(this.#passSubject).parent().click();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public assertValidateSignatures() {
|
||||
cy.get(this.#validateSignature).parent().click();
|
||||
cy.findByTestId(this.#validateSignature).parent().click();
|
||||
cy.findByTestId(this.#validatingX509Certs).should("not.exist");
|
||||
cy.get(this.#validateSignature).parent().click();
|
||||
cy.findByTestId(this.#validateSignature).parent().click();
|
||||
this.typeX509Certs("X509 Certificate");
|
||||
this.clickRevertBtn();
|
||||
cy.findByTestId(this.#validatingX509Certs);
|
||||
|
@ -223,13 +206,13 @@ export default class ProviderSAMLSettings extends PageObject {
|
|||
}
|
||||
|
||||
public assertTextFields() {
|
||||
cy.findByTestId(this.#allowedClockSkew)
|
||||
cy.get(this.#allowedClockSkew)
|
||||
.find("input")
|
||||
.should("have.value", 0)
|
||||
.clear()
|
||||
.type("111");
|
||||
|
||||
cy.findByTestId(this.#attributeConsumingServiceIndex)
|
||||
cy.get(this.#attributeConsumingServiceIndex)
|
||||
.find("input")
|
||||
.should("have.value", 0)
|
||||
.clear()
|
||||
|
|
|
@ -7,15 +7,14 @@ import {
|
|||
Button,
|
||||
ButtonVariant,
|
||||
DropdownItem,
|
||||
FormGroup,
|
||||
PageSection,
|
||||
ValidatedOptions,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
|
||||
import { TextControl } from "ui-shared";
|
||||
import { adminClient } from "../../admin-client";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||
|
@ -23,7 +22,6 @@ import { DynamicComponents } from "../../components/dynamic/DynamicComponents";
|
|||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import type { AttributeForm } from "../../components/key-value-form/AttributeForm";
|
||||
import { KeycloakSpinner } from "../../components/keycloak-spinner/KeycloakSpinner";
|
||||
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
|
||||
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
import { convertFormValuesToObject, convertToFormValues } from "../../util";
|
||||
|
@ -50,11 +48,7 @@ export default function AddMapper() {
|
|||
const form = useForm<IdPMapperRepresentationWithAttributes>({
|
||||
shouldUnregister: true,
|
||||
});
|
||||
const {
|
||||
handleSubmit,
|
||||
register,
|
||||
formState: { errors },
|
||||
} = form;
|
||||
const { handleSubmit } = form;
|
||||
const { addAlert, addError } = useAlerts();
|
||||
const navigate = useNavigate();
|
||||
const localeSort = useLocaleSort();
|
||||
|
@ -202,41 +196,31 @@ export default function AddMapper() {
|
|||
onSubmit={handleSubmit(save)}
|
||||
className="pf-u-mt-lg"
|
||||
>
|
||||
{id && (
|
||||
<FormGroup
|
||||
label={t("id")}
|
||||
fieldId="kc-name"
|
||||
validated={
|
||||
errors.name ? ValidatedOptions.error : ValidatedOptions.default
|
||||
}
|
||||
helperTextInvalid={t("required")}
|
||||
>
|
||||
<KeycloakTextInput
|
||||
value={currentMapper.id}
|
||||
id="kc-name"
|
||||
isDisabled={!!id}
|
||||
validated={
|
||||
errors.name ? ValidatedOptions.error : ValidatedOptions.default
|
||||
}
|
||||
{...register("name")}
|
||||
<FormProvider {...form}>
|
||||
{id && (
|
||||
<TextControl
|
||||
name="id"
|
||||
label={t("id")}
|
||||
readOnly
|
||||
rules={{
|
||||
required: t("required"),
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
{currentMapper.properties && (
|
||||
<>
|
||||
<AddMapperForm
|
||||
form={form}
|
||||
id={id}
|
||||
mapperTypes={mapperTypes}
|
||||
updateMapperType={setCurrentMapper}
|
||||
mapperType={currentMapper}
|
||||
/>
|
||||
<FormProvider {...form}>
|
||||
<DynamicComponents properties={currentMapper.properties!} />
|
||||
</FormProvider>
|
||||
</>
|
||||
)}
|
||||
)}
|
||||
{currentMapper.properties && (
|
||||
<>
|
||||
<AddMapperForm
|
||||
form={form}
|
||||
id={id}
|
||||
mapperTypes={mapperTypes}
|
||||
updateMapperType={setCurrentMapper}
|
||||
mapperType={currentMapper}
|
||||
/>
|
||||
|
||||
<DynamicComponents properties={currentMapper.properties!} />
|
||||
</>
|
||||
)}
|
||||
</FormProvider>
|
||||
<ActionGroup>
|
||||
<Button
|
||||
data-testid="new-mapper-save-button"
|
||||
|
|
|
@ -5,14 +5,11 @@ import {
|
|||
Select,
|
||||
SelectOption,
|
||||
SelectVariant,
|
||||
ValidatedOptions,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, UseFormReturn } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "ui-shared";
|
||||
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
|
||||
import { HelpItem, SelectControl, TextControl } from "ui-shared";
|
||||
import type { IdPMapperRepresentationWithAttributes } from "./AddMapper";
|
||||
|
||||
type AddMapperFormProps = {
|
||||
|
@ -34,85 +31,33 @@ export const AddMapperForm = ({
|
|||
}: AddMapperFormProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const {
|
||||
control,
|
||||
register,
|
||||
formState: { errors },
|
||||
} = form;
|
||||
const { control } = form;
|
||||
|
||||
const [mapperTypeOpen, setMapperTypeOpen] = useState(false);
|
||||
|
||||
const syncModes = ["inherit", "import", "legacy", "force"];
|
||||
const [syncModeOpen, setSyncModeOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormGroup
|
||||
<TextControl
|
||||
name="name"
|
||||
label={t("name")}
|
||||
labelIcon={
|
||||
<HelpItem helpText={t("addIdpMapperNameHelp")} fieldLabelId="name" />
|
||||
}
|
||||
fieldId="kc-name"
|
||||
isRequired
|
||||
validated={
|
||||
errors.name ? ValidatedOptions.error : ValidatedOptions.default
|
||||
}
|
||||
helperTextInvalid={t("required")}
|
||||
>
|
||||
<KeycloakTextInput
|
||||
id="kc-name"
|
||||
isDisabled={!!id}
|
||||
validated={
|
||||
errors.name ? ValidatedOptions.error : ValidatedOptions.default
|
||||
}
|
||||
{...register("name", { required: true })}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
labelIcon={t("addIdpMapperNameHelp")}
|
||||
readOnly={!!id}
|
||||
rules={{
|
||||
required: t("required"),
|
||||
}}
|
||||
/>
|
||||
<SelectControl
|
||||
name="config.syncMode"
|
||||
label={t("syncModeOverride")}
|
||||
isRequired
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("syncModeOverrideHelp")}
|
||||
fieldLabelId="syncModeOverride"
|
||||
/>
|
||||
}
|
||||
fieldId="syncMode"
|
||||
>
|
||||
<Controller
|
||||
name="config.syncMode"
|
||||
defaultValue={syncModes[0].toUpperCase()}
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Select
|
||||
toggleId="syncMode"
|
||||
datatest-id="syncmode-select"
|
||||
required
|
||||
direction="down"
|
||||
onToggle={() => setSyncModeOpen(!syncModeOpen)}
|
||||
onSelect={(_, value) => {
|
||||
field.onChange(value.toString().toUpperCase());
|
||||
setSyncModeOpen(false);
|
||||
}}
|
||||
selections={t(`syncModes.${field.value.toLowerCase()}`)}
|
||||
variant={SelectVariant.single}
|
||||
aria-label={t("syncMode")}
|
||||
isOpen={syncModeOpen}
|
||||
>
|
||||
{syncModes.map((option) => (
|
||||
<SelectOption
|
||||
selected={option === field.value}
|
||||
key={option}
|
||||
data-testid={option}
|
||||
value={option.toUpperCase()}
|
||||
>
|
||||
{t(`syncModes.${option}`)}
|
||||
</SelectOption>
|
||||
))}
|
||||
</Select>
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
labelIcon={t("syncModeOverrideHelp")}
|
||||
options={syncModes.map((option) => ({
|
||||
key: option.toUpperCase(),
|
||||
value: t(`syncModes.${option}`),
|
||||
}))}
|
||||
controller={{ defaultValue: syncModes[0].toUpperCase() }}
|
||||
/>
|
||||
<FormGroup
|
||||
label={t("mapperType")}
|
||||
labelIcon={
|
||||
|
|
|
@ -1,22 +1,10 @@
|
|||
import IdentityProviderRepresentation from "@keycloak/keycloak-admin-client/lib/defs/identityProviderRepresentation";
|
||||
import {
|
||||
ExpandableSection,
|
||||
FormGroup,
|
||||
NumberInput,
|
||||
Select,
|
||||
SelectOption,
|
||||
SelectVariant,
|
||||
ValidatedOptions,
|
||||
} from "@patternfly/react-core";
|
||||
import { ExpandableSection } from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, useFormContext, useWatch } from "react-hook-form";
|
||||
import { FormProvider, useFormContext, useWatch } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "ui-shared";
|
||||
import { KeycloakTextArea } from "../../components/keycloak-text-area/KeycloakTextArea";
|
||||
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
|
||||
import { FormGroupField } from "../component/FormGroupField";
|
||||
import { SwitchField } from "../component/SwitchField";
|
||||
import { NumberControl, SelectControl, TextControl } from "ui-shared";
|
||||
import { DefaultSwitchControl } from "../../components/SwitchControl";
|
||||
|
||||
import "./discovery-settings.css";
|
||||
|
||||
|
@ -27,22 +15,8 @@ type DescriptorSettingsProps = {
|
|||
const Fields = ({ readOnly }: DescriptorSettingsProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const {
|
||||
register,
|
||||
control,
|
||||
formState: { errors },
|
||||
} = useFormContext<IdentityProviderRepresentation>();
|
||||
const [namedPolicyDropdownOpen, setNamedPolicyDropdownOpen] = useState(false);
|
||||
const [principalTypeDropdownOpen, setPrincipalTypeDropdownOpen] =
|
||||
useState(false);
|
||||
const [signatureAlgorithmDropdownOpen, setSignatureAlgorithmDropdownOpen] =
|
||||
useState(false);
|
||||
const [encryptionAlgorithmDropdownOpen, setEncryptionAlgorithmDropdownOpen] =
|
||||
useState(false);
|
||||
const [
|
||||
samlSignatureKeyNameDropdownOpen,
|
||||
setSamlSignatureKeyNameDropdownOpen,
|
||||
] = useState(false);
|
||||
const form = useFormContext<IdentityProviderRepresentation>();
|
||||
const { control } = form;
|
||||
|
||||
const wantAuthnSigned = useWatch({
|
||||
control,
|
||||
|
@ -71,595 +45,282 @@ const Fields = ({ readOnly }: DescriptorSettingsProps) => {
|
|||
|
||||
return (
|
||||
<div className="pf-c-form pf-m-horizontal">
|
||||
<FormGroup
|
||||
label={t("serviceProviderEntityId")}
|
||||
fieldId="kc-saml-service-provider-entity-id"
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("serviceProviderEntityIdHelp")}
|
||||
fieldLabelId="serviceProviderEntityId"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<KeycloakTextInput
|
||||
data-testid="serviceProviderEntityId"
|
||||
id="kc-saml-service-provider-entity-id"
|
||||
{...register("config.entityId")}
|
||||
<FormProvider {...form}>
|
||||
<TextControl
|
||||
name="config.entityId"
|
||||
label={t("serviceProviderEntityId")}
|
||||
labelIcon={t("serviceProviderEntityIdHelp")}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={t("identityProviderEntityId")}
|
||||
fieldId="kc-identity-provider-entity-id"
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("identityProviderEntityIdHelp")}
|
||||
fieldLabelId="identityProviderEntityId"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<KeycloakTextInput
|
||||
<TextControl
|
||||
name="config.idpEntityId"
|
||||
label={t("identityProviderEntityId")}
|
||||
labelIcon={t("identityProviderEntityIdHelp")}
|
||||
data-testid="identityProviderEntityId"
|
||||
id="kc-identity-provider-entity-id"
|
||||
{...register("config.idpEntityId")}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={t("ssoServiceUrl")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("ssoServiceUrlHelp")}
|
||||
fieldLabelId="ssoServiceUrl"
|
||||
/>
|
||||
}
|
||||
fieldId="kc-sso-service-url"
|
||||
isRequired
|
||||
validated={
|
||||
errors.config?.singleSignOnServiceUrl
|
||||
? ValidatedOptions.error
|
||||
: ValidatedOptions.default
|
||||
}
|
||||
helperTextInvalid={t("required")}
|
||||
>
|
||||
<KeycloakTextInput
|
||||
<TextControl
|
||||
name="config.singleSignOnServiceUrl"
|
||||
label={t("ssoServiceUrl")}
|
||||
labelIcon={t("ssoServiceUrlHelp")}
|
||||
type="url"
|
||||
data-testid="sso-service-url"
|
||||
id="kc-sso-service-url"
|
||||
validated={
|
||||
errors.config?.singleSignOnServiceUrl
|
||||
? ValidatedOptions.error
|
||||
: ValidatedOptions.default
|
||||
}
|
||||
isReadOnly={readOnly}
|
||||
{...register("config.singleSignOnServiceUrl", { required: true })}
|
||||
readOnly={readOnly}
|
||||
rules={{ required: t("required") }}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={t("singleLogoutServiceUrl")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("singleLogoutServiceUrlHelp")}
|
||||
fieldLabelId="singleLogoutServiceUrl"
|
||||
/>
|
||||
}
|
||||
fieldId="single-logout-service-url"
|
||||
data-testid="single-logout-service-url"
|
||||
validated={
|
||||
errors.config?.singleLogoutServiceUrl
|
||||
? ValidatedOptions.error
|
||||
: ValidatedOptions.default
|
||||
}
|
||||
helperTextInvalid={t("required")}
|
||||
>
|
||||
<KeycloakTextInput
|
||||
<TextControl
|
||||
name="config.singleLogoutServiceUrl"
|
||||
label={t("singleLogoutServiceUrl")}
|
||||
labelIcon={t("singleLogoutServiceUrlHelp")}
|
||||
type="url"
|
||||
id="single-logout-service-url"
|
||||
isReadOnly={readOnly}
|
||||
{...register("config.singleLogoutServiceUrl")}
|
||||
readOnly={readOnly}
|
||||
rules={{ required: t("required") }}
|
||||
/>
|
||||
</FormGroup>
|
||||
<SwitchField
|
||||
field="config.backchannelSupported"
|
||||
label="backchannelLogout"
|
||||
data-testid="backchannelLogout"
|
||||
isReadOnly={readOnly}
|
||||
/>
|
||||
<SwitchField
|
||||
field="config.sendIdTokenOnLogout"
|
||||
label="sendIdTokenOnLogout"
|
||||
data-testid="sendIdTokenOnLogout"
|
||||
defaultValue={"true"}
|
||||
isReadOnly={readOnly}
|
||||
/>
|
||||
<SwitchField
|
||||
field="config.sendClientIdOnLogout"
|
||||
label="sendClientIdOnLogout"
|
||||
data-testid="sendClientIdOnLogout"
|
||||
isReadOnly={readOnly}
|
||||
/>
|
||||
<FormGroup
|
||||
label={t("nameIdPolicyFormat")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("nameIdPolicyFormatHelp")}
|
||||
fieldLabelId="nameIdPolicyFormat"
|
||||
/>
|
||||
}
|
||||
fieldId="kc-nameIdPolicyFormat"
|
||||
helperTextInvalid={t("required")}
|
||||
>
|
||||
<Controller
|
||||
<DefaultSwitchControl
|
||||
name="config.backchannelSupported"
|
||||
label={t("backchannelLogout")}
|
||||
isDisabled={readOnly}
|
||||
stringify
|
||||
/>
|
||||
<DefaultSwitchControl
|
||||
name="config.sendIdTokenOnLogout"
|
||||
label={t("sendIdTokenOnLogout")}
|
||||
defaultValue={"true"}
|
||||
isDisabled={readOnly}
|
||||
stringify
|
||||
/>
|
||||
<DefaultSwitchControl
|
||||
name="config.sendClientIdOnLogout"
|
||||
label={t("sendClientIdOnLogout")}
|
||||
isDisabled={readOnly}
|
||||
stringify
|
||||
/>
|
||||
<SelectControl
|
||||
name="config.nameIDPolicyFormat"
|
||||
defaultValue={"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"}
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Select
|
||||
toggleId="kc-nameIdPolicyFormat"
|
||||
onToggle={(isExpanded) => setNamedPolicyDropdownOpen(isExpanded)}
|
||||
isOpen={namedPolicyDropdownOpen}
|
||||
onSelect={(_, value) => {
|
||||
field.onChange(value as string);
|
||||
setNamedPolicyDropdownOpen(false);
|
||||
}}
|
||||
selections={field.value}
|
||||
variant={SelectVariant.single}
|
||||
isDisabled={readOnly}
|
||||
>
|
||||
<SelectOption
|
||||
data-testid="persistent-option"
|
||||
value={"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"}
|
||||
isPlaceholder
|
||||
>
|
||||
{t("persistent")}
|
||||
</SelectOption>
|
||||
<SelectOption
|
||||
data-testid="transient-option"
|
||||
value="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
|
||||
>
|
||||
{t("transient")}
|
||||
</SelectOption>
|
||||
<SelectOption
|
||||
data-testid="email-option"
|
||||
value="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
|
||||
>
|
||||
{t("email")}
|
||||
</SelectOption>
|
||||
<SelectOption
|
||||
data-testid="kerberos-option"
|
||||
value="urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos"
|
||||
>
|
||||
{t("kerberos")}
|
||||
</SelectOption>
|
||||
|
||||
<SelectOption
|
||||
data-testid="x509-option"
|
||||
value="urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName"
|
||||
>
|
||||
{t("x509")}
|
||||
</SelectOption>
|
||||
|
||||
<SelectOption
|
||||
data-testid="windowsDomainQN-option"
|
||||
value="urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName"
|
||||
>
|
||||
{t("windowsDomainQN")}
|
||||
</SelectOption>
|
||||
|
||||
<SelectOption
|
||||
data-testid="unspecified-option"
|
||||
value={"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"}
|
||||
>
|
||||
{t("unspecified")}
|
||||
</SelectOption>
|
||||
</Select>
|
||||
)}
|
||||
></Controller>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup
|
||||
label={t("principalType")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("principalTypeHelp")}
|
||||
fieldLabelId="principalType"
|
||||
/>
|
||||
}
|
||||
fieldId="kc-principalType"
|
||||
helperTextInvalid={t("required")}
|
||||
>
|
||||
<Controller
|
||||
label={t("nameIdPolicyFormat")}
|
||||
labelIcon={t("nameIdPolicyFormatHelp")}
|
||||
controller={{
|
||||
defaultValue:
|
||||
"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
|
||||
}}
|
||||
isDisabled={readOnly}
|
||||
options={[
|
||||
{
|
||||
key: "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
|
||||
value: t("persistent"),
|
||||
},
|
||||
{
|
||||
key: "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
|
||||
value: t("transient"),
|
||||
},
|
||||
{
|
||||
key: "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
|
||||
value: t("email"),
|
||||
},
|
||||
{
|
||||
key: "urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos",
|
||||
value: t("kerberos"),
|
||||
},
|
||||
{
|
||||
key: "urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName",
|
||||
value: t("x509"),
|
||||
},
|
||||
{
|
||||
key: "urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName",
|
||||
value: t("windowsDomainQN"),
|
||||
},
|
||||
{
|
||||
key: "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
|
||||
value: t("unspecified"),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<SelectControl
|
||||
name="config.principalType"
|
||||
defaultValue={t("subjectNameId")}
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Select
|
||||
toggleId="kc-principalType"
|
||||
onToggle={(isExpanded) =>
|
||||
setPrincipalTypeDropdownOpen(isExpanded)
|
||||
}
|
||||
isOpen={principalTypeDropdownOpen}
|
||||
onSelect={(_, value) => {
|
||||
field.onChange(value.toString());
|
||||
setPrincipalTypeDropdownOpen(false);
|
||||
}}
|
||||
selections={field.value}
|
||||
variant={SelectVariant.single}
|
||||
isDisabled={readOnly}
|
||||
>
|
||||
<SelectOption
|
||||
data-testid="subjectNameId-option"
|
||||
value="SUBJECT"
|
||||
isPlaceholder
|
||||
>
|
||||
{t("subjectNameId")}
|
||||
</SelectOption>
|
||||
<SelectOption
|
||||
data-testid="attributeName-option"
|
||||
value="ATTRIBUTE"
|
||||
>
|
||||
{t("attributeName")}
|
||||
</SelectOption>
|
||||
<SelectOption
|
||||
data-testid="attributeFriendlyName-option"
|
||||
value="FRIENDLY_ATTRIBUTE"
|
||||
>
|
||||
{t("attributeFriendlyName")}
|
||||
</SelectOption>
|
||||
</Select>
|
||||
)}
|
||||
></Controller>
|
||||
</FormGroup>
|
||||
label={t("principalType")}
|
||||
labelIcon={t("principalTypeHelp")}
|
||||
controller={{
|
||||
defaultValue: "SUBJECT",
|
||||
}}
|
||||
isDisabled={readOnly}
|
||||
options={[
|
||||
{ key: "SUBJECT", value: t("subjectNameId") },
|
||||
{ key: "ATTRIBUTE", value: t("attributeName") },
|
||||
{ key: "FRIENDLY_ATTRIBUTE", value: t("attributeFriendlyName") },
|
||||
]}
|
||||
/>
|
||||
|
||||
{principalType?.includes("ATTRIBUTE") && (
|
||||
<FormGroup
|
||||
label={t("principalAttribute")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("principalAttributeHelp")}
|
||||
fieldLabelId="principalAttribute"
|
||||
/>
|
||||
}
|
||||
fieldId="principalAttribute"
|
||||
>
|
||||
<KeycloakTextInput
|
||||
id="principalAttribute"
|
||||
data-testid="principalAttribute"
|
||||
isReadOnly={readOnly}
|
||||
{...register("config.principalAttribute")}
|
||||
{principalType?.includes("ATTRIBUTE") && (
|
||||
<TextControl
|
||||
name="config.principalAttribute"
|
||||
label={t("principalAttribute")}
|
||||
labelIcon={t("principalAttributeHelp")}
|
||||
readOnly={readOnly}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
<SwitchField
|
||||
field="config.allowCreate"
|
||||
label="allowCreate"
|
||||
isReadOnly={readOnly}
|
||||
/>
|
||||
)}
|
||||
<DefaultSwitchControl
|
||||
name="config.allowCreate"
|
||||
label={t("allowCreate")}
|
||||
isDisabled={readOnly}
|
||||
stringify
|
||||
/>
|
||||
|
||||
<SwitchField
|
||||
field="config.postBindingResponse"
|
||||
label="httpPostBindingResponse"
|
||||
isReadOnly={readOnly}
|
||||
/>
|
||||
<DefaultSwitchControl
|
||||
name="config.postBindingResponse"
|
||||
label={t("httpPostBindingResponse")}
|
||||
isDisabled={readOnly}
|
||||
stringify
|
||||
/>
|
||||
|
||||
<SwitchField
|
||||
field="config.postBindingAuthnRequest"
|
||||
label="httpPostBindingAuthnRequest"
|
||||
isReadOnly={readOnly}
|
||||
/>
|
||||
<DefaultSwitchControl
|
||||
name="config.postBindingAuthnRequest"
|
||||
label={t("httpPostBindingAuthnRequest")}
|
||||
isDisabled={readOnly}
|
||||
stringify
|
||||
/>
|
||||
|
||||
<SwitchField
|
||||
field="config.postBindingLogout"
|
||||
label="httpPostBindingLogout"
|
||||
isReadOnly={readOnly}
|
||||
/>
|
||||
<DefaultSwitchControl
|
||||
name="config.postBindingLogout"
|
||||
label={t("httpPostBindingLogout")}
|
||||
isDisabled={readOnly}
|
||||
stringify
|
||||
/>
|
||||
|
||||
<SwitchField
|
||||
field="config.wantAuthnRequestsSigned"
|
||||
label="wantAuthnRequestsSigned"
|
||||
isReadOnly={readOnly}
|
||||
/>
|
||||
<DefaultSwitchControl
|
||||
name="config.wantAuthnRequestsSigned"
|
||||
label={t("wantAuthnRequestsSigned")}
|
||||
isDisabled={readOnly}
|
||||
stringify
|
||||
/>
|
||||
|
||||
{wantAuthnSigned === "true" && (
|
||||
<>
|
||||
<FormGroup
|
||||
label={t("signatureAlgorithm")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("signatureAlgorithmHelp")}
|
||||
fieldLabelId="signatureAlgorithm"
|
||||
/>
|
||||
}
|
||||
fieldId="kc-signatureAlgorithm"
|
||||
>
|
||||
<Controller
|
||||
{wantAuthnSigned === "true" && (
|
||||
<>
|
||||
<SelectControl
|
||||
name="config.signatureAlgorithm"
|
||||
defaultValue="RSA_SHA256"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Select
|
||||
toggleId="kc-signatureAlgorithm"
|
||||
onToggle={(isExpanded) =>
|
||||
setSignatureAlgorithmDropdownOpen(isExpanded)
|
||||
}
|
||||
isOpen={signatureAlgorithmDropdownOpen}
|
||||
onSelect={(_, value) => {
|
||||
field.onChange(value.toString());
|
||||
setSignatureAlgorithmDropdownOpen(false);
|
||||
}}
|
||||
selections={field.value}
|
||||
variant={SelectVariant.single}
|
||||
isDisabled={readOnly}
|
||||
>
|
||||
<SelectOption value="RSA_SHA1" />
|
||||
<SelectOption value="RSA_SHA256" isPlaceholder />
|
||||
<SelectOption value="RSA_SHA256_MGF1" />
|
||||
<SelectOption value="RSA_SHA512" />
|
||||
<SelectOption value="RSA_SHA512_MGF1" />
|
||||
<SelectOption value="DSA_SHA1" />
|
||||
</Select>
|
||||
)}
|
||||
></Controller>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={t("samlSignatureKeyName")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("samlSignatureKeyNameHelp")}
|
||||
fieldLabelId="samlSignatureKeyName"
|
||||
/>
|
||||
}
|
||||
fieldId="kc-samlSignatureKeyName"
|
||||
>
|
||||
<Controller
|
||||
label={t("signatureAlgorithm")}
|
||||
labelIcon={t("signatureAlgorithmHelp")}
|
||||
isDisabled={readOnly}
|
||||
controller={{
|
||||
defaultValue: "RSA_SHA256",
|
||||
}}
|
||||
options={[
|
||||
"RSA_SHA1",
|
||||
"RSA_SHA256",
|
||||
"RSA_SHA256_MGF1",
|
||||
"RSA_SHA512",
|
||||
"RSA_SHA512_MGF1",
|
||||
"DSA_SHA1",
|
||||
]}
|
||||
/>
|
||||
<SelectControl
|
||||
name="config.xmlSigKeyInfoKeyNameTransformer"
|
||||
defaultValue={t("keyID")}
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Select
|
||||
toggleId="kc-samlSignatureKeyName"
|
||||
onToggle={(isExpanded) =>
|
||||
setSamlSignatureKeyNameDropdownOpen(isExpanded)
|
||||
}
|
||||
isOpen={samlSignatureKeyNameDropdownOpen}
|
||||
onSelect={(_, value) => {
|
||||
field.onChange(value.toString());
|
||||
setSamlSignatureKeyNameDropdownOpen(false);
|
||||
}}
|
||||
selections={field.value}
|
||||
variant={SelectVariant.single}
|
||||
isDisabled={readOnly}
|
||||
>
|
||||
<SelectOption value="NONE" />
|
||||
<SelectOption value={t("keyID")} isPlaceholder />
|
||||
<SelectOption value={t("certSubject")} />
|
||||
</Select>
|
||||
)}
|
||||
></Controller>
|
||||
</FormGroup>
|
||||
</>
|
||||
)}
|
||||
|
||||
<SwitchField
|
||||
field="config.wantAssertionsSigned"
|
||||
label="wantAssertionsSigned"
|
||||
isReadOnly={readOnly}
|
||||
/>
|
||||
|
||||
<SwitchField
|
||||
field="config.wantAssertionsEncrypted"
|
||||
label="wantAssertionsEncrypted"
|
||||
isReadOnly={readOnly}
|
||||
/>
|
||||
|
||||
{wantAssertionsEncrypted === "true" && (
|
||||
<FormGroup
|
||||
label={t("encryptionAlgorithm")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("encryptionAlgorithmHelp")}
|
||||
fieldLabelId="encryptionAlgorithm"
|
||||
label={t("samlSignatureKeyName")}
|
||||
labelIcon={t("samlSignatureKeyNameHelp")}
|
||||
isDisabled={readOnly}
|
||||
controller={{
|
||||
defaultValue: t("keyID"),
|
||||
}}
|
||||
options={["NONE", t("keyID"), t("certSubject")]}
|
||||
/>
|
||||
}
|
||||
fieldId="kc-encryptionAlgorithm"
|
||||
>
|
||||
<Controller
|
||||
</>
|
||||
)}
|
||||
<DefaultSwitchControl
|
||||
name="config.wantAssertionsSigned"
|
||||
label={t("wantAssertionsSigned")}
|
||||
isDisabled={readOnly}
|
||||
stringify
|
||||
/>
|
||||
<DefaultSwitchControl
|
||||
name="config.wantAssertionsEncrypted"
|
||||
label={t("wantAssertionsEncrypted")}
|
||||
isDisabled={readOnly}
|
||||
stringify
|
||||
/>
|
||||
{wantAssertionsEncrypted === "true" && (
|
||||
<SelectControl
|
||||
name="config.encryptionAlgorithm"
|
||||
defaultValue="RSA-OAEP"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Select
|
||||
toggleId="kc-encryptionAlgorithm"
|
||||
onToggle={(isExpanded) =>
|
||||
setEncryptionAlgorithmDropdownOpen(isExpanded)
|
||||
}
|
||||
isOpen={encryptionAlgorithmDropdownOpen}
|
||||
onSelect={(_, value) => {
|
||||
field.onChange(value.toString());
|
||||
setEncryptionAlgorithmDropdownOpen(false);
|
||||
}}
|
||||
selections={field.value}
|
||||
variant={SelectVariant.single}
|
||||
isDisabled={readOnly}
|
||||
>
|
||||
<SelectOption value="RSA-OAEP" />
|
||||
<SelectOption value="RSA1_5" />
|
||||
</Select>
|
||||
)}
|
||||
></Controller>
|
||||
</FormGroup>
|
||||
)}
|
||||
label={t("encryptionAlgorithm")}
|
||||
labelIcon={t("encryptionAlgorithmHelp")}
|
||||
isDisabled={readOnly}
|
||||
controller={{
|
||||
defaultValue: "RSA-OAEP",
|
||||
}}
|
||||
options={["RSA-OAEP", "RSA1_5"]}
|
||||
/>
|
||||
)}
|
||||
|
||||
<SwitchField
|
||||
field="config.forceAuthn"
|
||||
label="forceAuthentication"
|
||||
isReadOnly={readOnly}
|
||||
/>
|
||||
|
||||
<SwitchField
|
||||
field="config.validateSignature"
|
||||
label="validateSignature"
|
||||
isReadOnly={readOnly}
|
||||
/>
|
||||
{validateSignature === "true" && (
|
||||
<>
|
||||
<FormGroup
|
||||
label={t("metadataDescriptorUrl")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("metadataDescriptorUrlHelp")}
|
||||
fieldLabelId="metadataDescriptorUrl"
|
||||
/>
|
||||
}
|
||||
isRequired={useMetadataDescriptorUrl === "true"}
|
||||
validated={
|
||||
errors.config?.metadataDescriptorUrl
|
||||
? ValidatedOptions.error
|
||||
: ValidatedOptions.default
|
||||
}
|
||||
fieldId="metadataDescriptorUrl"
|
||||
helperTextInvalid={t("required")}
|
||||
>
|
||||
<KeycloakTextInput
|
||||
<DefaultSwitchControl
|
||||
name="config.forceAuthn"
|
||||
label={t("forceAuthentication")}
|
||||
isDisabled={readOnly}
|
||||
stringify
|
||||
/>
|
||||
<DefaultSwitchControl
|
||||
name="config.validateSignature"
|
||||
label={t("validateSignature")}
|
||||
isDisabled={readOnly}
|
||||
stringify
|
||||
/>
|
||||
{validateSignature === "true" && (
|
||||
<>
|
||||
<TextControl
|
||||
name="config.metadataDescriptorUrl"
|
||||
label={t("metadataDescriptorUrl")}
|
||||
labelIcon={t("metadataDescriptorUrlHelp")}
|
||||
type="url"
|
||||
id="metadataDescriptorUrl"
|
||||
data-testid="metadataDescriptorUrl"
|
||||
isReadOnly={readOnly}
|
||||
validated={
|
||||
errors.config?.metadataDescriptorUrl
|
||||
? ValidatedOptions.error
|
||||
: ValidatedOptions.default
|
||||
}
|
||||
{...register("config.metadataDescriptorUrl", {
|
||||
required: useMetadataDescriptorUrl === "true",
|
||||
})}
|
||||
readOnly={readOnly}
|
||||
rules={{
|
||||
required: {
|
||||
value: useMetadataDescriptorUrl === "true",
|
||||
message: t("required"),
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
<SwitchField
|
||||
field="config.useMetadataDescriptorUrl"
|
||||
label="useMetadataDescriptorUrl"
|
||||
data-testid="useMetadataDescriptorUrl"
|
||||
isReadOnly={readOnly}
|
||||
/>
|
||||
{useMetadataDescriptorUrl !== "true" && (
|
||||
<FormGroupField label="validatingX509Certs">
|
||||
<KeycloakTextArea
|
||||
id="validatingX509Certs"
|
||||
data-testid="validatingX509Certs"
|
||||
isReadOnly={readOnly}
|
||||
{...register("config.signingCertificate")}
|
||||
></KeycloakTextArea>
|
||||
</FormGroupField>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<SwitchField
|
||||
field="config.signSpMetadata"
|
||||
label="signServiceProviderMetadata"
|
||||
data-testid="signServiceProviderMetadata"
|
||||
isReadOnly={readOnly}
|
||||
/>
|
||||
<SwitchField
|
||||
field="config.loginHint"
|
||||
label="passSubject"
|
||||
data-testid="passSubject"
|
||||
isReadOnly={readOnly}
|
||||
/>
|
||||
|
||||
<FormGroup
|
||||
label={t("allowedClockSkew")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("allowedClockSkewHelp")}
|
||||
fieldLabelId="allowedClockSkew"
|
||||
/>
|
||||
}
|
||||
fieldId="allowedClockSkew"
|
||||
helperTextInvalid={t("required")}
|
||||
>
|
||||
<Controller
|
||||
<DefaultSwitchControl
|
||||
name="config.useMetadataDescriptorUrl"
|
||||
label={t("useMetadataDescriptorUrl")}
|
||||
isDisabled={readOnly}
|
||||
/>
|
||||
{useMetadataDescriptorUrl !== "true" && (
|
||||
<TextControl
|
||||
name="config.signingCertificate"
|
||||
label="validatingX509Certs"
|
||||
readOnly={readOnly}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<DefaultSwitchControl
|
||||
name="config.signSpMetadata"
|
||||
label={t("signServiceProviderMetadata")}
|
||||
isDisabled={readOnly}
|
||||
stringify
|
||||
/>
|
||||
<DefaultSwitchControl
|
||||
name="config.loginHint"
|
||||
label={t("passSubject")}
|
||||
isDisabled={readOnly}
|
||||
stringify
|
||||
/>
|
||||
<NumberControl
|
||||
name="config.allowedClockSkew"
|
||||
defaultValue={0}
|
||||
control={control}
|
||||
render={({ field }) => {
|
||||
const v = Number(field.value);
|
||||
return (
|
||||
<NumberInput
|
||||
data-testid="allowedClockSkew"
|
||||
inputName="allowedClockSkew"
|
||||
min={0}
|
||||
max={2147483}
|
||||
value={v}
|
||||
readOnly
|
||||
onPlus={() => field.onChange(v + 1)}
|
||||
onMinus={() => field.onChange(v - 1)}
|
||||
onChange={(event) => {
|
||||
const value = Number(
|
||||
(event.target as HTMLInputElement).value,
|
||||
);
|
||||
field.onChange(value < 0 ? 0 : value);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
label={t("allowedClockSkew")}
|
||||
labelIcon={t("allowedClockSkewHelp")}
|
||||
controller={{ defaultValue: 0, rules: { min: 0, max: 2147483 } }}
|
||||
isDisabled={readOnly}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup
|
||||
label={t("attributeConsumingServiceIndex")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("attributeConsumingServiceIndexHelp")}
|
||||
fieldLabelId="attributeConsumingServiceIndex"
|
||||
/>
|
||||
}
|
||||
fieldId="attributeConsumingServiceIndex"
|
||||
helperTextInvalid={t("required")}
|
||||
>
|
||||
<Controller
|
||||
<NumberControl
|
||||
name="config.attributeConsumingServiceIndex"
|
||||
defaultValue={0}
|
||||
control={control}
|
||||
render={({ field }) => {
|
||||
const v = Number(field.value);
|
||||
return (
|
||||
<NumberInput
|
||||
data-testid="attributeConsumingServiceIndex"
|
||||
inputName="attributeConsumingServiceIndex"
|
||||
min={0}
|
||||
max={2147483}
|
||||
value={v}
|
||||
readOnly
|
||||
onPlus={() => field.onChange(v + 1)}
|
||||
onMinus={() => field.onChange(v - 1)}
|
||||
onChange={(event) => {
|
||||
const value = Number(
|
||||
(event.target as HTMLInputElement).value,
|
||||
);
|
||||
field.onChange(value < 0 ? 0 : value);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
label={t("attributeConsumingServiceIndex")}
|
||||
labelIcon={t("attributeConsumingServiceIndexHelp")}
|
||||
controller={{ defaultValue: 0, rules: { min: 0, max: 2147483 } }}
|
||||
isDisabled={readOnly}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup
|
||||
label={t("attributeConsumingServiceName")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("attributeConsumingServiceNameHelp")}
|
||||
fieldLabelId="attributeConsumingServiceName"
|
||||
/>
|
||||
}
|
||||
fieldId="attributeConsumingServiceName"
|
||||
helperTextInvalid={t("required")}
|
||||
>
|
||||
<KeycloakTextInput
|
||||
id="attributeConsumingServiceName"
|
||||
data-testid="attributeConsumingServiceName"
|
||||
isReadOnly={readOnly}
|
||||
{...register("config.attributeConsumingServiceName")}
|
||||
<TextControl
|
||||
name="config.attributeConsumingServiceName"
|
||||
label={t("attributeConsumingServiceName")}
|
||||
labelIcon={t("attributeConsumingServiceNameHelp")}
|
||||
readOnly={readOnly}
|
||||
/>
|
||||
</FormGroup>
|
||||
</FormProvider>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -73,7 +73,7 @@ export const SelectControl = <
|
|||
selections={
|
||||
typeof options[0] !== "string"
|
||||
? (options as SelectControlOption[])
|
||||
.filter((o) => value.includes(o.key))
|
||||
.filter((o) => value === o.key)
|
||||
.map((o) => o.value)
|
||||
: value
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import { FormLabel } from "./FormLabel";
|
|||
export type SwitchControlProps<
|
||||
T extends FieldValues,
|
||||
P extends FieldPath<T> = FieldPath<T>,
|
||||
> = Omit<SwitchProps, "name" | "defaultValue"> &
|
||||
> = Omit<SwitchProps, "name" | "defaultValue" | "ref"> &
|
||||
UseControllerProps<T, P> & {
|
||||
name: string;
|
||||
label?: string;
|
||||
|
@ -45,10 +45,10 @@ export const SwitchControl = <
|
|||
defaultValue={defaultValue}
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<Switch
|
||||
{...props}
|
||||
id={props.name}
|
||||
data-testid={props.name}
|
||||
label={props.labelOn}
|
||||
labelOff={props.labelOff}
|
||||
isChecked={props.stringify ? value === "true" : value}
|
||||
onChange={(checked, e) => {
|
||||
const value = props.stringify ? checked.toString() : checked;
|
||||
|
|
Loading…
Reference in a new issue