better form convert (#1640)
* better form convert * fixed other forms * changed to use npm package * better form convert * merge fix * fixed mapper test
This commit is contained in:
parent
1f568d8888
commit
242c1d8445
53 changed files with 433 additions and 484 deletions
27
package-lock.json
generated
27
package-lock.json
generated
|
@ -15,6 +15,7 @@
|
||||||
"@patternfly/react-table": "^4.44.4",
|
"@patternfly/react-table": "^4.44.4",
|
||||||
"dagre": "^0.8.5",
|
"dagre": "^0.8.5",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
|
"flat": "^5.0.2",
|
||||||
"i18next": "^21.5.5",
|
"i18next": "^21.5.5",
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
|
@ -41,6 +42,7 @@
|
||||||
"@testing-library/react-hooks": "^7.0.2",
|
"@testing-library/react-hooks": "^7.0.2",
|
||||||
"@types/dagre": "^0.7.45",
|
"@types/dagre": "^0.7.45",
|
||||||
"@types/file-saver": "^2.0.4",
|
"@types/file-saver": "^2.0.4",
|
||||||
|
"@types/flat": "^5.0.2",
|
||||||
"@types/lodash": "^4.14.177",
|
"@types/lodash": "^4.14.177",
|
||||||
"@types/node": "^16.11.12",
|
"@types/node": "^16.11.12",
|
||||||
"@types/react": "^17.0.37",
|
"@types/react": "^17.0.37",
|
||||||
|
@ -4873,6 +4875,12 @@
|
||||||
"integrity": "sha512-sPZYQEIF/SOnLAvaz9lTuydniP+afBMtElRTdYkeV1QtEgvtJ7qolCPjly6O32QI8CbEmP5O/fztMXEDWfEcrg==",
|
"integrity": "sha512-sPZYQEIF/SOnLAvaz9lTuydniP+afBMtElRTdYkeV1QtEgvtJ7qolCPjly6O32QI8CbEmP5O/fztMXEDWfEcrg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/flat": {
|
||||||
|
"version": "5.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/flat/-/flat-5.0.2.tgz",
|
||||||
|
"integrity": "sha512-3zsplnP2djeps5P9OyarTxwRpMLoe5Ash8aL9iprw0JxB+FAHjY+ifn4yZUuW4/9hqtnmor6uvjSRzJhiVbrEQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/geojson": {
|
"node_modules/@types/geojson": {
|
||||||
"version": "7946.0.8",
|
"version": "7946.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz",
|
||||||
|
@ -10616,6 +10624,14 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/flat": {
|
||||||
|
"version": "5.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
|
||||||
|
"integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
|
||||||
|
"bin": {
|
||||||
|
"flat": "cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/flat-cache": {
|
"node_modules/flat-cache": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
|
||||||
|
@ -25327,6 +25343,12 @@
|
||||||
"integrity": "sha512-sPZYQEIF/SOnLAvaz9lTuydniP+afBMtElRTdYkeV1QtEgvtJ7qolCPjly6O32QI8CbEmP5O/fztMXEDWfEcrg==",
|
"integrity": "sha512-sPZYQEIF/SOnLAvaz9lTuydniP+afBMtElRTdYkeV1QtEgvtJ7qolCPjly6O32QI8CbEmP5O/fztMXEDWfEcrg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/flat": {
|
||||||
|
"version": "5.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/flat/-/flat-5.0.2.tgz",
|
||||||
|
"integrity": "sha512-3zsplnP2djeps5P9OyarTxwRpMLoe5Ash8aL9iprw0JxB+FAHjY+ifn4yZUuW4/9hqtnmor6uvjSRzJhiVbrEQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/geojson": {
|
"@types/geojson": {
|
||||||
"version": "7946.0.8",
|
"version": "7946.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz",
|
||||||
|
@ -29871,6 +29893,11 @@
|
||||||
"path-exists": "^4.0.0"
|
"path-exists": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flat": {
|
||||||
|
"version": "5.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
|
||||||
|
"integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ=="
|
||||||
|
},
|
||||||
"flat-cache": {
|
"flat-cache": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
"@patternfly/react-table": "^4.44.4",
|
"@patternfly/react-table": "^4.44.4",
|
||||||
"dagre": "^0.8.5",
|
"dagre": "^0.8.5",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
|
"flat": "^5.0.2",
|
||||||
"i18next": "^21.5.5",
|
"i18next": "^21.5.5",
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
|
@ -57,6 +58,7 @@
|
||||||
"@testing-library/react-hooks": "^7.0.2",
|
"@testing-library/react-hooks": "^7.0.2",
|
||||||
"@types/dagre": "^0.7.45",
|
"@types/dagre": "^0.7.45",
|
||||||
"@types/file-saver": "^2.0.4",
|
"@types/file-saver": "^2.0.4",
|
||||||
|
"@types/flat": "^5.0.2",
|
||||||
"@types/lodash": "^4.14.177",
|
"@types/lodash": "^4.14.177",
|
||||||
"@types/node": "^16.11.12",
|
"@types/node": "^16.11.12",
|
||||||
"@types/react": "^17.0.37",
|
"@types/react": "^17.0.37",
|
||||||
|
|
|
@ -115,12 +115,7 @@ export default function MappingDetails() {
|
||||||
setConfig(config);
|
setConfig(config);
|
||||||
setMapping(mapping);
|
setMapping(mapping);
|
||||||
if (data) {
|
if (data) {
|
||||||
Object.entries(data).map(([key, value]) => {
|
convertToFormValues(data, setValue);
|
||||||
if (key === "config") {
|
|
||||||
convertToFormValues(value, "config", setValue);
|
|
||||||
}
|
|
||||||
setValue(key, value);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
|
@ -153,10 +148,9 @@ export default function MappingDetails() {
|
||||||
});
|
});
|
||||||
|
|
||||||
const save = async (formMapping: ProtocolMapperRepresentation) => {
|
const save = async (formMapping: ProtocolMapperRepresentation) => {
|
||||||
const configAttributes = convertFormValuesToObject(formMapping.config);
|
|
||||||
const key = isUpdating ? "Updated" : "Created";
|
const key = isUpdating ? "Updated" : "Created";
|
||||||
try {
|
try {
|
||||||
const mapping = { ...formMapping, ...config, config: configAttributes };
|
const mapping = { ...config, ...convertFormValuesToObject(formMapping) };
|
||||||
if (isUpdating) {
|
if (isUpdating) {
|
||||||
isOnClientScope
|
isOnClientScope
|
||||||
? await adminClient.clientScopes.updateProtocolMapper(
|
? await adminClient.clientScopes.updateProtocolMapper(
|
||||||
|
|
|
@ -40,7 +40,7 @@ export const ScopeForm = ({ clientScope, save }: ScopeFormProps) => {
|
||||||
const { t: tc } = useTranslation("clients");
|
const { t: tc } = useTranslation("clients");
|
||||||
const { register, control, handleSubmit, errors, setValue } =
|
const { register, control, handleSubmit, errors, setValue } =
|
||||||
useForm<ClientScopeRepresentation>({
|
useForm<ClientScopeRepresentation>({
|
||||||
defaultValues: { attributes: { "display-on-consent-screen": "true" } },
|
defaultValues: { attributes: { "display.on.consent.screen": "true" } },
|
||||||
});
|
});
|
||||||
const { realm } = useRealm();
|
const { realm } = useRealm();
|
||||||
|
|
||||||
|
@ -51,16 +51,11 @@ export const ScopeForm = ({ clientScope, save }: ScopeFormProps) => {
|
||||||
|
|
||||||
const displayOnConsentScreen = useWatch({
|
const displayOnConsentScreen = useWatch({
|
||||||
control,
|
control,
|
||||||
name: "attributes.display-on-consent-screen",
|
name: "attributes.display.on.consent.screen",
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Object.entries(clientScope).map((entry) => {
|
convertToFormValues(clientScope, setValue);
|
||||||
if (entry[0] === "attributes") {
|
|
||||||
convertToFormValues(entry[1], "attributes", setValue);
|
|
||||||
}
|
|
||||||
setValue(entry[0], entry[1]);
|
|
||||||
});
|
|
||||||
}, [clientScope]);
|
}, [clientScope]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -213,7 +208,7 @@ export const ScopeForm = ({ clientScope, save }: ScopeFormProps) => {
|
||||||
fieldId="kc-display.on.consent.screen"
|
fieldId="kc-display.on.consent.screen"
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.display-on-consent-screen"
|
name="attributes.display.on.consent.screen"
|
||||||
control={control}
|
control={control}
|
||||||
defaultValue="true"
|
defaultValue="true"
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -243,7 +238,7 @@ export const ScopeForm = ({ clientScope, save }: ScopeFormProps) => {
|
||||||
ref={register}
|
ref={register}
|
||||||
type="text"
|
type="text"
|
||||||
id="kc-consent-screen-text"
|
id="kc-consent-screen-text"
|
||||||
name="attributes.consent-screen-text"
|
name="attributes.consent.screen.text"
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
|
@ -260,7 +255,7 @@ export const ScopeForm = ({ clientScope, save }: ScopeFormProps) => {
|
||||||
fieldId="includeInTokenScope"
|
fieldId="includeInTokenScope"
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.include-in-token-scope"
|
name="attributes.include.in.token.scope"
|
||||||
control={control}
|
control={control}
|
||||||
defaultValue="true"
|
defaultValue="true"
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -286,7 +281,7 @@ export const ScopeForm = ({ clientScope, save }: ScopeFormProps) => {
|
||||||
fieldId="kc-gui-order"
|
fieldId="kc-gui-order"
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.gui-order"
|
name="attributes.gui.order"
|
||||||
defaultValue={1}
|
defaultValue={1}
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => {
|
render={({ onChange, value }) => {
|
||||||
|
|
|
@ -107,9 +107,9 @@ export default function ClientScopeForm() {
|
||||||
const save = async (clientScopes: ClientScopeDefaultOptionalType) => {
|
const save = async (clientScopes: ClientScopeDefaultOptionalType) => {
|
||||||
try {
|
try {
|
||||||
clientScopes.name = clientScopes.name?.trim();
|
clientScopes.name = clientScopes.name?.trim();
|
||||||
clientScopes.attributes = convertFormValuesToObject(
|
clientScopes = convertFormValuesToObject(
|
||||||
clientScopes.attributes!
|
clientScopes
|
||||||
);
|
) as ClientScopeDefaultOptionalType;
|
||||||
|
|
||||||
if (id) {
|
if (id) {
|
||||||
await adminClient.clientScopes.update({ id }, clientScopes);
|
await adminClient.clientScopes.update({ id }, clientScopes);
|
||||||
|
|
|
@ -104,9 +104,7 @@ export const AdvancedTab = ({
|
||||||
const resetFields = (names: string[]) => {
|
const resetFields = (names: string[]) => {
|
||||||
const values: { [name: string]: string } = {};
|
const values: { [name: string]: string } = {};
|
||||||
for (const name of names) {
|
for (const name of names) {
|
||||||
values[`attributes.${name}`] = attributes
|
values[`attributes.${name}`] = attributes?.[name];
|
||||||
? attributes[name.replace(/-/g, ".")] || ""
|
|
||||||
: "";
|
|
||||||
}
|
}
|
||||||
reset(values);
|
reset(values);
|
||||||
};
|
};
|
||||||
|
@ -385,7 +383,9 @@ export const AdvancedTab = ({
|
||||||
control={control}
|
control={control}
|
||||||
save={() => save()}
|
save={() => save()}
|
||||||
reset={() =>
|
reset={() =>
|
||||||
convertToFormValues(attributes, "attributes", setValue)
|
convertToFormValues(attributes, (key, value) =>
|
||||||
|
setValue(`attributes.${key}`, value)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
@ -399,7 +399,9 @@ export const AdvancedTab = ({
|
||||||
control={control}
|
control={control}
|
||||||
save={() => save()}
|
save={() => save()}
|
||||||
reset={() =>
|
reset={() =>
|
||||||
convertToFormValues(attributes, "attributes", setValue)
|
convertToFormValues(attributes, (key, value) =>
|
||||||
|
setValue(`attributes.${key}`, value)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
@ -414,7 +416,7 @@ export const AdvancedTab = ({
|
||||||
control={control}
|
control={control}
|
||||||
save={() => save()}
|
save={() => save()}
|
||||||
reset={() =>
|
reset={() =>
|
||||||
resetFields(["exclude-session-state-from-auth-response"])
|
resetFields(["exclude.session.state.from.auth.response"])
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
@ -429,10 +431,10 @@ export const AdvancedTab = ({
|
||||||
save={() => save()}
|
save={() => save()}
|
||||||
reset={() => {
|
reset={() => {
|
||||||
resetFields([
|
resetFields([
|
||||||
"saml-assertion-lifespan",
|
"saml.assertion.lifespan",
|
||||||
"access-token-lifespan",
|
"access.token.lifespan",
|
||||||
"tls-client-certificate-bound-access-tokens",
|
"tls.client.certificate.bound.access.tokens",
|
||||||
"pkce-code-challenge-method",
|
"pkce.code.challenge.method",
|
||||||
]);
|
]);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import { InfoCircleIcon } from "@patternfly/react-icons";
|
import { InfoCircleIcon } from "@patternfly/react-icons";
|
||||||
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
|
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
|
||||||
import _ from "lodash";
|
import _, { cloneDeep } from "lodash";
|
||||||
import React, { useMemo, useState } from "react";
|
import React, { useMemo, useState } from "react";
|
||||||
import { Controller, FormProvider, useForm, useWatch } from "react-hook-form";
|
import { Controller, FormProvider, useForm, useWatch } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
@ -25,11 +25,7 @@ import {
|
||||||
} from "../components/confirm-dialog/ConfirmDialog";
|
} from "../components/confirm-dialog/ConfirmDialog";
|
||||||
import { DownloadDialog } from "../components/download-dialog/DownloadDialog";
|
import { DownloadDialog } from "../components/download-dialog/DownloadDialog";
|
||||||
import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs";
|
import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs";
|
||||||
import {
|
import type { MultiLine } from "../components/multi-line-input/multi-line-convert";
|
||||||
convertToMultiline,
|
|
||||||
MultiLine,
|
|
||||||
toValue,
|
|
||||||
} from "../components/multi-line-input/MultiLineInput";
|
|
||||||
import {
|
import {
|
||||||
ViewHeader,
|
ViewHeader,
|
||||||
ViewHeaderBadge,
|
ViewHeaderBadge,
|
||||||
|
@ -219,18 +215,7 @@ export default function ClientDetails() {
|
||||||
});
|
});
|
||||||
|
|
||||||
const setupForm = (client: ClientRepresentation) => {
|
const setupForm = (client: ClientRepresentation) => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
convertToFormValues(client, form.setValue, ["redirectUris", "webOrigins"]);
|
||||||
const { redirectUris, webOrigins, ...formValues } = client;
|
|
||||||
form.reset(formValues);
|
|
||||||
Object.entries(client).map((entry) => {
|
|
||||||
if (entry[0] === "redirectUris" || entry[0] === "webOrigins") {
|
|
||||||
form.setValue(entry[0], convertToMultiline(entry[1]));
|
|
||||||
} else if (entry[0] === "attributes") {
|
|
||||||
convertToFormValues(entry[1], "attributes", form.setValue);
|
|
||||||
} else {
|
|
||||||
form.setValue(entry[0], entry[1]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useFetch(
|
useFetch(
|
||||||
|
@ -239,7 +224,7 @@ export default function ClientDetails() {
|
||||||
if (!fetchedClient) {
|
if (!fetchedClient) {
|
||||||
throw new Error(t("common:notFound"));
|
throw new Error(t("common:notFound"));
|
||||||
}
|
}
|
||||||
setClient(fetchedClient);
|
setClient(cloneDeep(fetchedClient));
|
||||||
setupForm(fetchedClient);
|
setupForm(fetchedClient);
|
||||||
},
|
},
|
||||||
[clientId]
|
[clientId]
|
||||||
|
@ -260,19 +245,15 @@ export default function ClientDetails() {
|
||||||
toggleChangeAuthenticatorOpen();
|
toggleChangeAuthenticatorOpen();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const redirectUris = toValue(form.getValues()["redirectUris"]);
|
const submittedClient = convertFormValuesToObject(form.getValues(), [
|
||||||
const webOrigins = toValue(form.getValues()["webOrigins"]);
|
"redirectUris",
|
||||||
const attributes = convertFormValuesToObject(
|
"webOrigins",
|
||||||
form.getValues()["attributes"]
|
]);
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const newClient: ClientRepresentation = {
|
const newClient: ClientRepresentation = {
|
||||||
...client,
|
...client,
|
||||||
...form.getValues(),
|
...submittedClient,
|
||||||
redirectUris,
|
|
||||||
webOrigins,
|
|
||||||
attributes,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
newClient.clientId = newClient.clientId?.trim();
|
newClient.clientId = newClient.clientId?.trim();
|
||||||
|
@ -282,7 +263,7 @@ export default function ClientDetails() {
|
||||||
setClient(newClient);
|
setClient(newClient);
|
||||||
addAlert(t(messageKey), AlertVariant.success);
|
addAlert(t(messageKey), AlertVariant.success);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
addError("client:clientSaveError", error);
|
addError("clients:clientSaveError", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,7 +43,7 @@ export const ClientSettings = ({
|
||||||
const loginThemes = useServerInfo().themes!["login"];
|
const loginThemes = useServerInfo().themes!["login"];
|
||||||
const consentRequired = watch("consentRequired");
|
const consentRequired = watch("consentRequired");
|
||||||
const displayOnConsentScreen: string = watch(
|
const displayOnConsentScreen: string = watch(
|
||||||
"attributes.display-on-consent-screen"
|
"attributes.display.on.consent.screen"
|
||||||
);
|
);
|
||||||
const protocol = watch("protocol");
|
const protocol = watch("protocol");
|
||||||
|
|
||||||
|
@ -250,7 +250,7 @@ export const ClientSettings = ({
|
||||||
hasNoPaddingTop
|
hasNoPaddingTop
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.display-on-consent-screen"
|
name="attributes.display.on.consent.screen"
|
||||||
defaultValue={false}
|
defaultValue={false}
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -278,7 +278,7 @@ export const ClientSettings = ({
|
||||||
>
|
>
|
||||||
<TextArea
|
<TextArea
|
||||||
id="kc-consent-screen-text"
|
id="kc-consent-screen-text"
|
||||||
name="attributes.consent-screen-text"
|
name="attributes.consent.screen.text"
|
||||||
ref={register}
|
ref={register}
|
||||||
isDisabled={!(consentRequired && displayOnConsentScreen === "true")}
|
isDisabled={!(consentRequired && displayOnConsentScreen === "true")}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -248,7 +248,7 @@ export const CapabilityConfig = ({
|
||||||
hasNoPaddingTop
|
hasNoPaddingTop
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.saml-encrypt"
|
name="attributes.saml.encrypt"
|
||||||
control={control}
|
control={control}
|
||||||
defaultValue="false"
|
defaultValue="false"
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -276,7 +276,7 @@ export const CapabilityConfig = ({
|
||||||
hasNoPaddingTop
|
hasNoPaddingTop
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.saml-client-signature"
|
name="attributes.saml.client.signature"
|
||||||
control={control}
|
control={control}
|
||||||
defaultValue="false"
|
defaultValue="false"
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
|
|
@ -44,15 +44,10 @@ export default function NewClientForm() {
|
||||||
const methods = useForm<ClientRepresentation>({ defaultValues: client });
|
const methods = useForm<ClientRepresentation>({ defaultValues: client });
|
||||||
|
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
const attributes = client.attributes
|
|
||||||
? convertFormValuesToObject(client.attributes)
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const newClient = await adminClient.clients.create({
|
const newClient = await adminClient.clients.create({
|
||||||
...client,
|
...convertFormValuesToObject(client),
|
||||||
clientId: client.clientId?.trim(),
|
clientId: client.clientId?.trim(),
|
||||||
attributes,
|
|
||||||
});
|
});
|
||||||
addAlert(t("createSuccess"), AlertVariant.success);
|
addAlert(t("createSuccess"), AlertVariant.success);
|
||||||
history.push(
|
history.push(
|
||||||
|
@ -65,15 +60,21 @@ export default function NewClientForm() {
|
||||||
|
|
||||||
const forward = async (onNext?: () => void) => {
|
const forward = async (onNext?: () => void) => {
|
||||||
if (await methods.trigger()) {
|
if (await methods.trigger()) {
|
||||||
setClient({ ...client, ...methods.getValues() });
|
setClient({
|
||||||
|
...client,
|
||||||
|
...convertFormValuesToObject(methods.getValues()),
|
||||||
|
});
|
||||||
setShowCapabilityConfig(true);
|
setShowCapabilityConfig(true);
|
||||||
onNext?.();
|
onNext?.();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const back = () => {
|
const back = () => {
|
||||||
setClient({ ...client, ...methods.getValues() });
|
setClient({ ...client, ...convertFormValuesToObject(methods.getValues()) });
|
||||||
methods.reset({ ...client, ...methods.getValues() });
|
methods.reset({
|
||||||
|
...client,
|
||||||
|
...convertFormValuesToObject(methods.getValues()),
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onGoToStep = (newStep: { id?: string | number }) => {
|
const onGoToStep = (newStep: { id?: string | number }) => {
|
||||||
|
|
|
@ -100,23 +100,23 @@ export const SamlConfig = () => {
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<Toggle
|
<Toggle
|
||||||
name="attributes.saml_force_name_id_format"
|
name="attributes.saml.force.name.id.format"
|
||||||
label="forceNameIdFormat"
|
label="forceNameIdFormat"
|
||||||
/>
|
/>
|
||||||
<Toggle
|
<Toggle
|
||||||
name="attributes.saml-force-post-binding"
|
name="attributes.saml.force.post.binding"
|
||||||
label="forcePostBinding"
|
label="forcePostBinding"
|
||||||
/>
|
/>
|
||||||
<Toggle
|
<Toggle
|
||||||
name="attributes.saml-artifact-binding"
|
name="attributes.saml.artifact.binding"
|
||||||
label="forceArtifactBinding"
|
label="forceArtifactBinding"
|
||||||
/>
|
/>
|
||||||
<Toggle
|
<Toggle
|
||||||
name="attributes.saml-onetimeuse-condition"
|
name="attributes.saml.onetimeuse.condition"
|
||||||
label="includeOneTimeUseCondition"
|
label="includeOneTimeUseCondition"
|
||||||
/>
|
/>
|
||||||
<Toggle
|
<Toggle
|
||||||
name="attributes.saml-server-signature-keyinfo-ext"
|
name="attributes.saml.server.signature.keyinfo.ext"
|
||||||
label="optimizeLookup"
|
label="optimizeLookup"
|
||||||
/>
|
/>
|
||||||
</FormAccess>
|
</FormAccess>
|
||||||
|
|
|
@ -48,8 +48,8 @@ export const SamlSignature = () => {
|
||||||
|
|
||||||
const { control, watch } = useFormContext<ClientForm>();
|
const { control, watch } = useFormContext<ClientForm>();
|
||||||
|
|
||||||
const signDocs = watch("attributes.saml-server-signature");
|
const signDocs = watch("attributes.saml.server.signature");
|
||||||
const signAssertion = watch("attributes.saml-assertion-signature");
|
const signAssertion = watch("attributes.saml.assertion.signature");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormAccess
|
<FormAccess
|
||||||
|
@ -57,9 +57,9 @@ export const SamlSignature = () => {
|
||||||
role="manage-clients"
|
role="manage-clients"
|
||||||
className="keycloak__capability-config__form"
|
className="keycloak__capability-config__form"
|
||||||
>
|
>
|
||||||
<Toggle name="attributes.saml-server-signature" label="signDocuments" />
|
<Toggle name="attributes.saml.server.signature" label="signDocuments" />
|
||||||
<Toggle
|
<Toggle
|
||||||
name="attributes.saml-assertion-signature"
|
name="attributes.saml.assertion.signature"
|
||||||
label="signAssertions"
|
label="signAssertions"
|
||||||
/>
|
/>
|
||||||
{(signDocs === "true" || signAssertion === "true") && (
|
{(signDocs === "true" || signAssertion === "true") && (
|
||||||
|
@ -78,7 +78,7 @@ export const SamlSignature = () => {
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.saml-signature-algorithm"
|
name="attributes.saml.signature.algorithm"
|
||||||
defaultValue={SIGNATURE_ALGORITHMS[0]}
|
defaultValue={SIGNATURE_ALGORITHMS[0]}
|
||||||
Key
|
Key
|
||||||
control={control}
|
control={control}
|
||||||
|
@ -120,7 +120,7 @@ export const SamlSignature = () => {
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.saml-server-signature-keyinfo-xmlSigKeyInfoKeyNameTransformer"
|
name="attributes.saml.server.signature.keyinfo.xmlSigKeyInfoKeyNameTransformer"
|
||||||
defaultValue={KEYNAME_TRANSFORMER[0]}
|
defaultValue={KEYNAME_TRANSFORMER[0]}
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
|
|
@ -46,7 +46,7 @@ export const AdvancedSettings = ({
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.saml-assertion-lifespan"
|
name="attributes.saml.assertion.lifespan"
|
||||||
defaultValue=""
|
defaultValue=""
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -63,7 +63,7 @@ export const AdvancedSettings = ({
|
||||||
<>
|
<>
|
||||||
<TokenLifespan
|
<TokenLifespan
|
||||||
id="accessTokenLifespan"
|
id="accessTokenLifespan"
|
||||||
name="attributes.access-token-lifespan"
|
name="attributes.access.token.lifespan"
|
||||||
defaultValue=""
|
defaultValue=""
|
||||||
units={["minutes", "days", "hours"]}
|
units={["minutes", "days", "hours"]}
|
||||||
control={control}
|
control={control}
|
||||||
|
@ -111,7 +111,7 @@ export const AdvancedSettings = ({
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.pkce-code-challenge-method"
|
name="attributes.pkce.code.challenge.method"
|
||||||
defaultValue=""
|
defaultValue=""
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
|
|
@ -100,10 +100,6 @@ export const FineGrainOpenIdConnect = ({
|
||||||
</SelectOption>
|
</SelectOption>
|
||||||
));
|
));
|
||||||
|
|
||||||
const selectOptionToString = (value: string, options: JSX.Element[]) => {
|
|
||||||
const selectOption = options.find((s) => s.props.value === value);
|
|
||||||
return selectOption?.props.children || selectOption?.props.value;
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<FormAccess role="manage-clients" isHorizontal>
|
<FormAccess role="manage-clients" isHorizontal>
|
||||||
<FormGroup
|
<FormGroup
|
||||||
|
@ -118,7 +114,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.access-token-signed-response-alg"
|
name="attributes.access.token.signed.response.alg"
|
||||||
defaultValue=""
|
defaultValue=""
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -131,7 +127,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
onChange(value);
|
onChange(value);
|
||||||
setAccessTokenOpen(false);
|
setAccessTokenOpen(false);
|
||||||
}}
|
}}
|
||||||
selections={[selectOptionToString(value, keyOptions)]}
|
selections={value}
|
||||||
>
|
>
|
||||||
{keyOptions}
|
{keyOptions}
|
||||||
</Select>
|
</Select>
|
||||||
|
@ -150,7 +146,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.id-token-signed-response-alg"
|
name="attributes.id.token.signed.response.alg"
|
||||||
defaultValue=""
|
defaultValue=""
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -163,7 +159,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
onChange(value);
|
onChange(value);
|
||||||
setIdTokenOpen(false);
|
setIdTokenOpen(false);
|
||||||
}}
|
}}
|
||||||
selections={[selectOptionToString(value, keyOptions)]}
|
selections={value}
|
||||||
>
|
>
|
||||||
{keyOptions}
|
{keyOptions}
|
||||||
</Select>
|
</Select>
|
||||||
|
@ -182,7 +178,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.id-token-encrypted-response-alg"
|
name="attributes.id.token.encrypted.response.alg"
|
||||||
defaultValue=""
|
defaultValue=""
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -195,7 +191,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
onChange(value);
|
onChange(value);
|
||||||
setIdTokenKeyManagementOpen(false);
|
setIdTokenKeyManagementOpen(false);
|
||||||
}}
|
}}
|
||||||
selections={[selectOptionToString(value, cekManagementOptions)]}
|
selections={value}
|
||||||
>
|
>
|
||||||
{cekManagementOptions}
|
{cekManagementOptions}
|
||||||
</Select>
|
</Select>
|
||||||
|
@ -214,7 +210,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.id-token-encrypted-response-enc"
|
name="attributes.id.token.encrypted.response.enc"
|
||||||
defaultValue=""
|
defaultValue=""
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -227,7 +223,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
onChange(value);
|
onChange(value);
|
||||||
setIdTokenContentOpen(false);
|
setIdTokenContentOpen(false);
|
||||||
}}
|
}}
|
||||||
selections={[selectOptionToString(value, contentOptions)]}
|
selections={value}
|
||||||
>
|
>
|
||||||
{contentOptions}
|
{contentOptions}
|
||||||
</Select>
|
</Select>
|
||||||
|
@ -246,7 +242,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.user-info-response-signature-alg"
|
name="attributes.user.info.response.signature.alg"
|
||||||
defaultValue=""
|
defaultValue=""
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -259,7 +255,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
onChange(value);
|
onChange(value);
|
||||||
setUserInfoSignedResponseOpen(false);
|
setUserInfoSignedResponseOpen(false);
|
||||||
}}
|
}}
|
||||||
selections={[selectOptionToString(value, signatureOptions)]}
|
selections={value}
|
||||||
>
|
>
|
||||||
{signatureOptions}
|
{signatureOptions}
|
||||||
</Select>
|
</Select>
|
||||||
|
@ -291,7 +287,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
onChange(value);
|
onChange(value);
|
||||||
setRequestObjectSignatureOpen(false);
|
setRequestObjectSignatureOpen(false);
|
||||||
}}
|
}}
|
||||||
selections={[selectOptionToString(value, requestObjectOptions)]}
|
selections={value}
|
||||||
>
|
>
|
||||||
{requestObjectOptions}
|
{requestObjectOptions}
|
||||||
</Select>
|
</Select>
|
||||||
|
@ -310,7 +306,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.request-object-required"
|
name="attributes.request.object.required"
|
||||||
defaultValue=""
|
defaultValue=""
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -323,9 +319,7 @@ export const FineGrainOpenIdConnect = ({
|
||||||
onChange(value);
|
onChange(value);
|
||||||
setRequestObjectRequiredOpen(false);
|
setRequestObjectRequiredOpen(false);
|
||||||
}}
|
}}
|
||||||
selections={[
|
selections={value}
|
||||||
selectOptionToString(value, requestObjectRequiredOptions),
|
|
||||||
]}
|
|
||||||
>
|
>
|
||||||
{requestObjectRequiredOptions}
|
{requestObjectRequiredOptions}
|
||||||
</Select>
|
</Select>
|
||||||
|
|
|
@ -27,19 +27,12 @@ import { ViewHeader } from "../../components/view-header/ViewHeader";
|
||||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||||
import { useAlerts } from "../../components/alert/Alerts";
|
import { useAlerts } from "../../components/alert/Alerts";
|
||||||
import { FormAccess } from "../../components/form-access/FormAccess";
|
import { FormAccess } from "../../components/form-access/FormAccess";
|
||||||
import {
|
import type { MultiLine } from "../../components/multi-line-input/multi-line-convert";
|
||||||
convertToMultiline,
|
import type { KeyValueType } from "../../components/attribute-form/attribute-convert";
|
||||||
MultiLine,
|
import { convertFormValuesToObject, convertToFormValues } from "../../util";
|
||||||
MultiLineInput,
|
import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput";
|
||||||
toValue,
|
|
||||||
} from "../../components/multi-line-input/MultiLineInput";
|
|
||||||
import { toClient } from "../routes/Client";
|
import { toClient } from "../routes/Client";
|
||||||
import { ScopePicker } from "./ScopePicker";
|
import { ScopePicker } from "./ScopePicker";
|
||||||
import {
|
|
||||||
arrayToAttributes,
|
|
||||||
attributesToArray,
|
|
||||||
KeyValueType,
|
|
||||||
} from "../../components/attribute-form/attribute-convert";
|
|
||||||
import { AttributeInput } from "../../components/attribute-input/AttributeInput";
|
import { AttributeInput } from "../../components/attribute-input/AttributeInput";
|
||||||
|
|
||||||
import "./resource-details.css";
|
import "./resource-details.css";
|
||||||
|
@ -75,15 +68,7 @@ export default function ResourceDetails() {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
const setupForm = (resource: ResourceRepresentation = {}) => {
|
const setupForm = (resource: ResourceRepresentation = {}) => {
|
||||||
Object.entries(resource).forEach(([key, value]) => {
|
convertToFormValues(resource, setValue, ["uris"]);
|
||||||
if (key === "uris") {
|
|
||||||
setValue("uris", convertToMultiline(value));
|
|
||||||
} else if (key === "attributes") {
|
|
||||||
setValue("attributes", attributesToArray(value));
|
|
||||||
} else {
|
|
||||||
setValue(key, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useFetch(
|
useFetch(
|
||||||
|
@ -113,12 +98,7 @@ export default function ResourceDetails() {
|
||||||
);
|
);
|
||||||
|
|
||||||
const save = async (submitted: SubmittedResource) => {
|
const save = async (submitted: SubmittedResource) => {
|
||||||
const { attributes, uris, ...rest } = submitted;
|
const resource = convertFormValuesToObject(submitted, ["uris"]);
|
||||||
const resource = {
|
|
||||||
...rest,
|
|
||||||
attributes: arrayToAttributes(attributes),
|
|
||||||
uris: toValue(uris),
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (resourceId) {
|
if (resourceId) {
|
||||||
|
|
|
@ -33,7 +33,7 @@ export const SignedJWT = () => {
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.token-endpoint-auth-signing-alg"
|
name="attributes.token.endpoint.auth.signing.alg"
|
||||||
defaultValue=""
|
defaultValue=""
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
|
|
@ -20,7 +20,7 @@ export const X509 = () => {
|
||||||
}
|
}
|
||||||
helperTextInvalid={t("common:required")}
|
helperTextInvalid={t("common:required")}
|
||||||
validated={
|
validated={
|
||||||
errors.attributes?.["x509-subjectdn"]
|
errors.attributes?.["x509.subjectdn"]
|
||||||
? ValidatedOptions.error
|
? ValidatedOptions.error
|
||||||
: ValidatedOptions.default
|
: ValidatedOptions.default
|
||||||
}
|
}
|
||||||
|
@ -30,9 +30,9 @@ export const X509 = () => {
|
||||||
ref={register({ required: true })}
|
ref={register({ required: true })}
|
||||||
type="text"
|
type="text"
|
||||||
id="kc-subject"
|
id="kc-subject"
|
||||||
name="attributes.x509-subjectdn"
|
name="attributes.x509.subjectdn"
|
||||||
validated={
|
validated={
|
||||||
errors.attributes?.["x509-subjectdn"]
|
errors.attributes?.["x509.subjectdn"]
|
||||||
? ValidatedOptions.error
|
? ValidatedOptions.error
|
||||||
: ValidatedOptions.default
|
: ValidatedOptions.default
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ export default function ImportForm() {
|
||||||
|
|
||||||
const { addAlert, addError } = useAlerts();
|
const { addAlert, addError } = useAlerts();
|
||||||
|
|
||||||
const handleFileChange = (obj: object) => {
|
const handleFileChange = (obj?: object) => {
|
||||||
const defaultClient = {
|
const defaultClient = {
|
||||||
protocol: "",
|
protocol: "",
|
||||||
clientId: "",
|
clientId: "",
|
||||||
|
@ -42,13 +42,7 @@ export default function ImportForm() {
|
||||||
description: "",
|
description: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.entries(obj || defaultClient).forEach((entries) => {
|
convertToFormValues(obj || defaultClient, setValue);
|
||||||
if (entries[0] === "attributes") {
|
|
||||||
convertToFormValues(entries[1], "attributes", form.setValue);
|
|
||||||
} else {
|
|
||||||
setValue(entries[0], entries[1]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
setImported(obj || defaultClient);
|
setImported(obj || defaultClient);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -56,8 +50,7 @@ export default function ImportForm() {
|
||||||
try {
|
try {
|
||||||
const newClient = await adminClient.clients.create({
|
const newClient = await adminClient.clients.create({
|
||||||
...imported,
|
...imported,
|
||||||
...client,
|
...convertFormValuesToObject(client),
|
||||||
attributes: convertFormValuesToObject(client.attributes || {}),
|
|
||||||
});
|
});
|
||||||
addAlert(t("clientImportSuccess"), AlertVariant.success);
|
addAlert(t("clientImportSuccess"), AlertVariant.success);
|
||||||
history.push(
|
history.push(
|
||||||
|
|
|
@ -54,7 +54,7 @@ export const Keys = ({ clientId, save }: KeysProps) => {
|
||||||
|
|
||||||
const useJwksUrl = useWatch({
|
const useJwksUrl = useWatch({
|
||||||
control,
|
control,
|
||||||
name: "attributes.use-jwks-url",
|
name: "attributes.use.jwks.url",
|
||||||
defaultValue: "false",
|
defaultValue: "false",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ export const Keys = ({ clientId, save }: KeysProps) => {
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.use-jwks-url"
|
name="attributes.use.jwks.url"
|
||||||
defaultValue="false"
|
defaultValue="false"
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -173,7 +173,7 @@ export const Keys = ({ clientId, save }: KeysProps) => {
|
||||||
<TextInput
|
<TextInput
|
||||||
type="text"
|
type="text"
|
||||||
id="jwksUrl"
|
id="jwksUrl"
|
||||||
name="attributes.jwks-url"
|
name="attributes.jwks.url"
|
||||||
ref={register}
|
ref={register}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
|
@ -38,12 +38,12 @@ export type KeyTypes = typeof KEYS[number];
|
||||||
|
|
||||||
const KEYS_MAPPING: { [key in KeyTypes]: { [index: string]: string } } = {
|
const KEYS_MAPPING: { [key in KeyTypes]: { [index: string]: string } } = {
|
||||||
"saml.signing": {
|
"saml.signing": {
|
||||||
name: "attributes.saml-client-signature",
|
name: "attributes.saml.client.signature",
|
||||||
title: "signingKeysConfig",
|
title: "signingKeysConfig",
|
||||||
key: "clientSignature",
|
key: "clientSignature",
|
||||||
},
|
},
|
||||||
"saml.encryption": {
|
"saml.encryption": {
|
||||||
name: "attributes.saml-encrypt",
|
name: "attributes.saml.encrypt",
|
||||||
title: "encryptionKeysConfig",
|
title: "encryptionKeysConfig",
|
||||||
key: "encryptAssertions",
|
key: "encryptAssertions",
|
||||||
},
|
},
|
||||||
|
|
|
@ -127,7 +127,7 @@ export default {
|
||||||
createError: "Could not create client: '{{error}}'",
|
createError: "Could not create client: '{{error}}'",
|
||||||
clientImportError: "Could not import client: {{error}}",
|
clientImportError: "Could not import client: {{error}}",
|
||||||
clientSaveSuccess: "Client successfully updated",
|
clientSaveSuccess: "Client successfully updated",
|
||||||
clientSaveError: "Client could not be updated:",
|
clientSaveError: "Client could not be updated: {{error}}",
|
||||||
clientImportSuccess: "Client imported successfully",
|
clientImportSuccess: "Client imported successfully",
|
||||||
clientDelete: "Delete {{clientId}} ?",
|
clientDelete: "Delete {{clientId}} ?",
|
||||||
clientDeletedSuccess: "The client has been deleted",
|
clientDeletedSuccess: "The client has been deleted",
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { FormGroup, Switch } from "@patternfly/react-core";
|
||||||
|
|
||||||
import type { ComponentProps } from "./components";
|
import type { ComponentProps } from "./components";
|
||||||
import { HelpItem } from "../help-enabler/HelpItem";
|
import { HelpItem } from "../help-enabler/HelpItem";
|
||||||
import { convertToHyphens } from "../../util";
|
|
||||||
|
|
||||||
export const BooleanComponent = ({
|
export const BooleanComponent = ({
|
||||||
name,
|
name,
|
||||||
|
@ -26,7 +25,7 @@ export const BooleanComponent = ({
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name={`config.${convertToHyphens(name!)}`}
|
name={`config.${name}`}
|
||||||
data-testid={name}
|
data-testid={name}
|
||||||
defaultValue={defaultValue}
|
defaultValue={defaultValue}
|
||||||
control={control}
|
control={control}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import type { ClientQuery } from "@keycloak/keycloak-admin-client/lib/resources/
|
||||||
import { useAdminClient, useFetch } from "../../context/auth/AdminClient";
|
import { useAdminClient, useFetch } from "../../context/auth/AdminClient";
|
||||||
import { HelpItem } from "../help-enabler/HelpItem";
|
import { HelpItem } from "../help-enabler/HelpItem";
|
||||||
import type { ComponentProps } from "./components";
|
import type { ComponentProps } from "./components";
|
||||||
import { convertToHyphens } from "../../util";
|
|
||||||
|
|
||||||
export const ClientSelectComponent = ({
|
export const ClientSelectComponent = ({
|
||||||
name,
|
name,
|
||||||
|
@ -58,7 +57,7 @@ export const ClientSelectComponent = ({
|
||||||
fieldId={name!}
|
fieldId={name!}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name={`config.${convertToHyphens(name!)}`}
|
name={`config.${name}`}
|
||||||
defaultValue={defaultValue || ""}
|
defaultValue={defaultValue || ""}
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
|
|
@ -10,7 +10,6 @@ import {
|
||||||
|
|
||||||
import type { ComponentProps } from "./components";
|
import type { ComponentProps } from "./components";
|
||||||
import { HelpItem } from "../help-enabler/HelpItem";
|
import { HelpItem } from "../help-enabler/HelpItem";
|
||||||
import { convertToHyphens } from "../../util";
|
|
||||||
|
|
||||||
export const ListComponent = ({
|
export const ListComponent = ({
|
||||||
name,
|
name,
|
||||||
|
@ -32,7 +31,7 @@ export const ListComponent = ({
|
||||||
fieldId={name!}
|
fieldId={name!}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name={`config.${convertToHyphens(name!)}`}
|
name={`config.${name}`}
|
||||||
data-testid={name}
|
data-testid={name}
|
||||||
defaultValue={defaultValue || ""}
|
defaultValue={defaultValue || ""}
|
||||||
control={control}
|
control={control}
|
||||||
|
|
|
@ -10,7 +10,6 @@ import {
|
||||||
|
|
||||||
import { HelpItem } from "../help-enabler/HelpItem";
|
import { HelpItem } from "../help-enabler/HelpItem";
|
||||||
import type { ComponentProps } from "./components";
|
import type { ComponentProps } from "./components";
|
||||||
import { convertToHyphens } from "../../util";
|
|
||||||
|
|
||||||
export const MultiValuedListComponent = ({
|
export const MultiValuedListComponent = ({
|
||||||
name,
|
name,
|
||||||
|
@ -32,7 +31,7 @@ export const MultiValuedListComponent = ({
|
||||||
fieldId={name!}
|
fieldId={name!}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name={`config.${convertToHyphens(name!)}`}
|
name={`config.${name}`}
|
||||||
control={control}
|
control={control}
|
||||||
defaultValue={defaultValue ? [defaultValue] : []}
|
defaultValue={defaultValue ? [defaultValue] : []}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
|
|
@ -11,10 +11,9 @@ import {
|
||||||
|
|
||||||
import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation";
|
import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation";
|
||||||
import type { ComponentProps } from "./components";
|
import type { ComponentProps } from "./components";
|
||||||
import type { MultiLine } from "../multi-line-input/MultiLineInput";
|
import type { MultiLine } from "../multi-line-input/multi-line-convert";
|
||||||
import { useAdminClient, useFetch } from "../../context/auth/AdminClient";
|
import { useAdminClient, useFetch } from "../../context/auth/AdminClient";
|
||||||
import { HelpItem } from "../help-enabler/HelpItem";
|
import { HelpItem } from "../help-enabler/HelpItem";
|
||||||
import { convertToHyphens } from "../../util";
|
|
||||||
import { useWhoAmI } from "../../context/whoami/WhoAmI";
|
import { useWhoAmI } from "../../context/whoami/WhoAmI";
|
||||||
|
|
||||||
export const MultivaluedRoleComponent = ({
|
export const MultivaluedRoleComponent = ({
|
||||||
|
@ -24,7 +23,7 @@ export const MultivaluedRoleComponent = ({
|
||||||
}: ComponentProps) => {
|
}: ComponentProps) => {
|
||||||
const { t } = useTranslation("dynamic");
|
const { t } = useTranslation("dynamic");
|
||||||
const { whoAmI } = useWhoAmI();
|
const { whoAmI } = useWhoAmI();
|
||||||
const fieldName = `config.${convertToHyphens(name!)}`;
|
const fieldName = `config.${name}`;
|
||||||
|
|
||||||
const adminClient = useAdminClient();
|
const adminClient = useAdminClient();
|
||||||
const { control } = useFormContext();
|
const { control } = useFormContext();
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { FormGroup } from "@patternfly/react-core";
|
||||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||||
import type { ComponentProps } from "./components";
|
import type { ComponentProps } from "./components";
|
||||||
import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput";
|
import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput";
|
||||||
import { convertToHyphens } from "../../util";
|
|
||||||
|
|
||||||
export const MultiValuedStringComponent = ({
|
export const MultiValuedStringComponent = ({
|
||||||
name,
|
name,
|
||||||
|
@ -23,7 +22,7 @@ export const MultiValuedStringComponent = ({
|
||||||
fieldId={name!}
|
fieldId={name!}
|
||||||
>
|
>
|
||||||
<MultiLineInput
|
<MultiLineInput
|
||||||
name={`config.${convertToHyphens(name!)}`}
|
name={`config.${name}`}
|
||||||
aria-label={name}
|
aria-label={name}
|
||||||
addButtonLabel={t("addMultivaluedLabel", {
|
addButtonLabel={t("addMultivaluedLabel", {
|
||||||
fieldLabel: t(label!).toLowerCase(),
|
fieldLabel: t(label!).toLowerCase(),
|
||||||
|
|
|
@ -18,7 +18,6 @@ import { useAdminClient, useFetch } from "../../context/auth/AdminClient";
|
||||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||||
import { HelpItem } from "../help-enabler/HelpItem";
|
import { HelpItem } from "../help-enabler/HelpItem";
|
||||||
import type { ComponentProps } from "./components";
|
import type { ComponentProps } from "./components";
|
||||||
import { convertToHyphens } from "../../util";
|
|
||||||
|
|
||||||
export const RoleComponent = ({ name, label, helpText }: ComponentProps) => {
|
export const RoleComponent = ({ name, label, helpText }: ComponentProps) => {
|
||||||
const { t } = useTranslation("dynamic");
|
const { t } = useTranslation("dynamic");
|
||||||
|
@ -34,7 +33,7 @@ export const RoleComponent = ({ name, label, helpText }: ComponentProps) => {
|
||||||
const [clientRoles, setClientRoles] = useState<RoleRepresentation[]>([]);
|
const [clientRoles, setClientRoles] = useState<RoleRepresentation[]>([]);
|
||||||
const [selectedRole, setSelectedRole] = useState<RoleRepresentation>();
|
const [selectedRole, setSelectedRole] = useState<RoleRepresentation>();
|
||||||
|
|
||||||
const fieldName = `config.${convertToHyphens(name!)}`;
|
const fieldName = `config.${name}`;
|
||||||
|
|
||||||
useFetch(
|
useFetch(
|
||||||
async () => {
|
async () => {
|
||||||
|
|
|
@ -6,7 +6,6 @@ import { CodeEditor, Language } from "@patternfly/react-code-editor";
|
||||||
|
|
||||||
import { HelpItem } from "../help-enabler/HelpItem";
|
import { HelpItem } from "../help-enabler/HelpItem";
|
||||||
import type { ComponentProps } from "./components";
|
import type { ComponentProps } from "./components";
|
||||||
import { convertToHyphens } from "../../util";
|
|
||||||
|
|
||||||
export const ScriptComponent = ({
|
export const ScriptComponent = ({
|
||||||
name,
|
name,
|
||||||
|
@ -30,7 +29,7 @@ export const ScriptComponent = ({
|
||||||
fieldId={name!}
|
fieldId={name!}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name={`config.${convertToHyphens(name!)}`}
|
name={`config.${name}`}
|
||||||
defaultValue={defaultValue}
|
defaultValue={defaultValue}
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { FormGroup, TextInput } from "@patternfly/react-core";
|
||||||
|
|
||||||
import { HelpItem } from "../help-enabler/HelpItem";
|
import { HelpItem } from "../help-enabler/HelpItem";
|
||||||
import type { ComponentProps } from "./components";
|
import type { ComponentProps } from "./components";
|
||||||
import { convertToHyphens } from "../../util";
|
|
||||||
|
|
||||||
export const StringComponent = ({
|
export const StringComponent = ({
|
||||||
name,
|
name,
|
||||||
|
@ -29,7 +28,7 @@ export const StringComponent = ({
|
||||||
data-testid={name}
|
data-testid={name}
|
||||||
ref={register()}
|
ref={register()}
|
||||||
type="text"
|
type="text"
|
||||||
name={`config.${convertToHyphens(name!)}`}
|
name={`config.${name}`}
|
||||||
defaultValue={defaultValue?.toString()}
|
defaultValue={defaultValue?.toString()}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
|
@ -10,20 +10,6 @@ import {
|
||||||
import { MinusCircleIcon, PlusCircleIcon } from "@patternfly/react-icons";
|
import { MinusCircleIcon, PlusCircleIcon } from "@patternfly/react-icons";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
export type MultiLine = {
|
|
||||||
value: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function convertToMultiline(fields: string[]): MultiLine[] {
|
|
||||||
return (fields.length > 0 ? fields : [""]).map((field) => {
|
|
||||||
return { value: field };
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toValue(formValue: MultiLine[]): string[] {
|
|
||||||
return formValue.map((field) => field.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
export type MultiLineInputProps = Omit<TextInputProps, "form"> & {
|
export type MultiLineInputProps = Omit<TextInputProps, "form"> & {
|
||||||
name: string;
|
name: string;
|
||||||
addButtonLabel?: string;
|
addButtonLabel?: string;
|
||||||
|
|
13
src/components/multi-line-input/multi-line-convert.ts
Normal file
13
src/components/multi-line-input/multi-line-convert.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
export type MultiLine = {
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function convertToMultiline(fields: string[]): MultiLine[] {
|
||||||
|
return (fields.length > 0 ? fields : [""]).map((field) => {
|
||||||
|
return { value: field };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toValue(formValue: MultiLine[]): string[] {
|
||||||
|
return formValue.map((field) => field.value);
|
||||||
|
}
|
|
@ -91,18 +91,17 @@ export default function AddMapper() {
|
||||||
|
|
||||||
const save = async (idpMapper: IdentityProviderMapperRepresentation) => {
|
const save = async (idpMapper: IdentityProviderMapperRepresentation) => {
|
||||||
const attributes = JSON.stringify(idpMapper.config?.attributes ?? []);
|
const attributes = JSON.stringify(idpMapper.config?.attributes ?? []);
|
||||||
const config = convertFormValuesToObject({
|
const mapper = convertFormValuesToObject(idpMapper);
|
||||||
...idpMapper.config,
|
|
||||||
attributes,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (id) {
|
if (id) {
|
||||||
const updatedMapper = {
|
const updatedMapper = {
|
||||||
...idpMapper,
|
...mapper,
|
||||||
|
config: {
|
||||||
|
attributes,
|
||||||
|
},
|
||||||
identityProviderAlias: alias!,
|
identityProviderAlias: alias!,
|
||||||
id: id,
|
id: id,
|
||||||
name: currentMapper?.name!,
|
name: currentMapper?.name!,
|
||||||
config,
|
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
await adminClient.identityProviders.updateMapper(
|
await adminClient.identityProviders.updateMapper(
|
||||||
|
@ -120,9 +119,11 @@ export default function AddMapper() {
|
||||||
try {
|
try {
|
||||||
const createdMapper = await adminClient.identityProviders.createMapper({
|
const createdMapper = await adminClient.identityProviders.createMapper({
|
||||||
identityProviderMapper: {
|
identityProviderMapper: {
|
||||||
...idpMapper,
|
...mapper,
|
||||||
identityProviderAlias: alias,
|
identityProviderAlias: alias,
|
||||||
config,
|
config: {
|
||||||
|
attributes,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
alias: alias!,
|
alias: alias!,
|
||||||
});
|
});
|
||||||
|
@ -161,28 +162,8 @@ export default function AddMapper() {
|
||||||
|
|
||||||
const setupForm = (mapper: IdentityProviderMapperRepresentation) => {
|
const setupForm = (mapper: IdentityProviderMapperRepresentation) => {
|
||||||
form.reset();
|
form.reset();
|
||||||
Object.entries(mapper).map(([key, value]) => {
|
convertToFormValues(mapper, form.setValue);
|
||||||
if (key === "config") {
|
form.setValue("config.attributes", JSON.parse(mapper.config.attributes));
|
||||||
if (mapper.config?.["are.attribute.values.regex"]) {
|
|
||||||
form.setValue(
|
|
||||||
"config.are-attribute-values-regex",
|
|
||||||
mapper.config["are.attribute.values.regex"]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mapper.config?.attributes) {
|
|
||||||
form.setValue("config.attributes", JSON.parse(value.attributes));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mapper.config?.role) {
|
|
||||||
form.setValue("config.role", value.role[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
convertToFormValues(value, "config", form.setValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
form.setValue(key, value);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const targetOptions = ["local", "brokerId", "brokerUsername"];
|
const targetOptions = ["local", "brokerId", "brokerUsername"];
|
||||||
|
@ -229,7 +210,6 @@ export default function AddMapper() {
|
||||||
() => formValues.identityProviderMapper?.includes("user-attribute-mapper"),
|
() => formValues.identityProviderMapper?.includes("user-attribute-mapper"),
|
||||||
[formValues.identityProviderMapper]
|
[formValues.identityProviderMapper]
|
||||||
);
|
);
|
||||||
|
|
||||||
const toggleModal = () => {
|
const toggleModal = () => {
|
||||||
setRolesModalOpen(!rolesModalOpen);
|
setRolesModalOpen(!rolesModalOpen);
|
||||||
};
|
};
|
||||||
|
@ -357,8 +337,8 @@ export default function AddMapper() {
|
||||||
<Controller
|
<Controller
|
||||||
name={
|
name={
|
||||||
isOIDCAdvancedClaimToRole
|
isOIDCAdvancedClaimToRole
|
||||||
? "config.are-claim-values-regex"
|
? "config.are.claim.values.regex"
|
||||||
: "config.are-attribute-values-regex"
|
: "config.are.attribute.values.regex"
|
||||||
}
|
}
|
||||||
control={control}
|
control={control}
|
||||||
defaultValue="false"
|
defaultValue="false"
|
||||||
|
@ -548,14 +528,14 @@ export default function AddMapper() {
|
||||||
<TextInput
|
<TextInput
|
||||||
ref={register()}
|
ref={register()}
|
||||||
type="text"
|
type="text"
|
||||||
defaultValue={currentMapper?.config["attribute-value"]}
|
defaultValue={currentMapper?.config["attribute.value"]}
|
||||||
data-testid={
|
data-testid={
|
||||||
isHardcodedUserSessionAttribute
|
isHardcodedUserSessionAttribute
|
||||||
? "user-session-attribute-value"
|
? "user-session-attribute-value"
|
||||||
: "user-attribute-value"
|
: "user-attribute-value"
|
||||||
}
|
}
|
||||||
id="kc-user-session-attribute-value"
|
id="kc-user-session-attribute-value"
|
||||||
name="config.attribute-value"
|
name="config.attribute.value"
|
||||||
validated={
|
validated={
|
||||||
errors.name
|
errors.name
|
||||||
? ValidatedOptions.error
|
? ValidatedOptions.error
|
||||||
|
@ -594,10 +574,10 @@ export default function AddMapper() {
|
||||||
<TextInput
|
<TextInput
|
||||||
ref={register()}
|
ref={register()}
|
||||||
type="text"
|
type="text"
|
||||||
defaultValue={currentMapper?.config["attribute-name"]}
|
defaultValue={currentMapper?.config["attribute.name"]}
|
||||||
id="kc-attribute-name"
|
id="kc-attribute-name"
|
||||||
data-testid="attribute-name"
|
data-testid="attribute-name"
|
||||||
name="config.attribute-name"
|
name="config.attribute.name"
|
||||||
validated={
|
validated={
|
||||||
errors.name
|
errors.name
|
||||||
? ValidatedOptions.error
|
? ValidatedOptions.error
|
||||||
|
@ -629,11 +609,11 @@ export default function AddMapper() {
|
||||||
ref={register()}
|
ref={register()}
|
||||||
type="text"
|
type="text"
|
||||||
defaultValue={
|
defaultValue={
|
||||||
currentMapper?.config["attribute-friendly-name"]
|
currentMapper?.config["attribute.friendly.name"]
|
||||||
}
|
}
|
||||||
data-testid="attribute-friendly-name"
|
data-testid="attribute-friendly-name"
|
||||||
id="kc-attribute-friendly-name"
|
id="kc-attribute-friendly-name"
|
||||||
name="config.attribute-friendly-name"
|
name="config.attribute.friendly.name"
|
||||||
validated={
|
validated={
|
||||||
errors.name
|
errors.name
|
||||||
? ValidatedOptions.error
|
? ValidatedOptions.error
|
||||||
|
@ -715,11 +695,11 @@ export default function AddMapper() {
|
||||||
type="text"
|
type="text"
|
||||||
defaultValue={
|
defaultValue={
|
||||||
isOIDCclaimToRole
|
isOIDCclaimToRole
|
||||||
? currentMapper?.config["claim-value"]
|
? currentMapper?.config["claim.value"]
|
||||||
: currentMapper?.config["attribute-value"]
|
: currentMapper?.config["attribute.value"]
|
||||||
}
|
}
|
||||||
data-testid={
|
data-testid={
|
||||||
isOIDCclaimToRole ? "claim-value" : "user-attribute-name"
|
isOIDCclaimToRole ? "claim.value" : "user-attribute-name"
|
||||||
}
|
}
|
||||||
id={
|
id={
|
||||||
isOIDCclaimToRole
|
isOIDCclaimToRole
|
||||||
|
@ -727,7 +707,7 @@ export default function AddMapper() {
|
||||||
: "kc-user-attribute-name"
|
: "kc-user-attribute-name"
|
||||||
}
|
}
|
||||||
name={
|
name={
|
||||||
isOIDCclaimToRole ? "config.claim" : "config.user-attribute"
|
isOIDCclaimToRole ? "config.claim" : "config.user.attribute"
|
||||||
}
|
}
|
||||||
validated={
|
validated={
|
||||||
errors.name
|
errors.name
|
||||||
|
|
|
@ -77,12 +77,7 @@ export default function ExecutorForm() {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (profileExecutor) {
|
if (profileExecutor) {
|
||||||
Object.entries(profileExecutor).map(([key, value]) => {
|
convertToFormValues(profileExecutor, setValue);
|
||||||
if (key === "configuration") {
|
|
||||||
convertToFormValues(value, "config", setValue);
|
|
||||||
}
|
|
||||||
setValue(key, value);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
|
|
|
@ -33,7 +33,7 @@ import type { EditClientPolicyConditionParams } from "./routes/EditCondition";
|
||||||
import {
|
import {
|
||||||
convertToMultiline,
|
convertToMultiline,
|
||||||
toValue,
|
toValue,
|
||||||
} from "../components/multi-line-input/MultiLineInput";
|
} from "../components/multi-line-input/multi-line-convert";
|
||||||
import {
|
import {
|
||||||
COMPONENTS,
|
COMPONENTS,
|
||||||
isValidComponentType,
|
isValidComponentType,
|
||||||
|
|
|
@ -49,7 +49,6 @@ import { toRealmSettings } from "./routes/RealmSettings";
|
||||||
import { LocalizationTab } from "./LocalizationTab";
|
import { LocalizationTab } from "./LocalizationTab";
|
||||||
import { HelpItem } from "../components/help-enabler/HelpItem";
|
import { HelpItem } from "../components/help-enabler/HelpItem";
|
||||||
import { UserRegistration } from "./UserRegistration";
|
import { UserRegistration } from "./UserRegistration";
|
||||||
import { DEFAULT_LOCALE } from "../i18n";
|
|
||||||
import { toDashboard } from "../dashboard/routes/Dashboard";
|
import { toDashboard } from "../dashboard/routes/Dashboard";
|
||||||
import environment from "../environment";
|
import environment from "../environment";
|
||||||
import { UserProfileTab } from "./UserProfileTab";
|
import { UserProfileTab } from "./UserProfileTab";
|
||||||
|
@ -188,15 +187,7 @@ export const RealmSettingsTabs = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const setupForm = (r: RealmRepresentation = realm) => {
|
const setupForm = (r: RealmRepresentation = realm) => {
|
||||||
Object.entries(r).map(([key, value]) => {
|
convertToFormValues(r, setValue);
|
||||||
if (key === "attributes") {
|
|
||||||
convertToFormValues(value, "attributes", setValue);
|
|
||||||
} else if (key === "supportedLocales" && value?.length === 0) {
|
|
||||||
setValue(key, [DEFAULT_LOCALE]);
|
|
||||||
} else {
|
|
||||||
setValue(key, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
resetForm(getValues());
|
resetForm(getValues());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -206,18 +197,13 @@ export const RealmSettingsTabs = ({
|
||||||
|
|
||||||
const save = async (realm: RealmRepresentation) => {
|
const save = async (realm: RealmRepresentation) => {
|
||||||
try {
|
try {
|
||||||
const attributes = Object.fromEntries(
|
realm = convertFormValuesToObject(realm);
|
||||||
Object.entries(
|
|
||||||
convertFormValuesToObject(realm.attributes, true)
|
|
||||||
).filter(([, v]) => v !== "")
|
|
||||||
);
|
|
||||||
|
|
||||||
await adminClient.realms.update(
|
await adminClient.realms.update(
|
||||||
{ realm: realmName },
|
{ realm: realmName },
|
||||||
{
|
{
|
||||||
...realm,
|
...realm,
|
||||||
id: realmName,
|
id: realmName,
|
||||||
attributes,
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
setupForm(realm);
|
setupForm(realm);
|
||||||
|
|
|
@ -88,20 +88,7 @@ export const AESGeneratedForm = ({
|
||||||
|
|
||||||
const setupForm = (component: ComponentRepresentation) => {
|
const setupForm = (component: ComponentRepresentation) => {
|
||||||
form.reset();
|
form.reset();
|
||||||
Object.entries(component).map(([key, value]) => {
|
convertToFormValues(component, form.setValue);
|
||||||
if (
|
|
||||||
key === "config" &&
|
|
||||||
component.config?.secretSize &&
|
|
||||||
component.config.active
|
|
||||||
) {
|
|
||||||
form.setValue("config.secretSize", value.secretSize[0]);
|
|
||||||
|
|
||||||
form.setValue("config.active", value.active[0]);
|
|
||||||
|
|
||||||
convertToFormValues(value, "config", form.setValue);
|
|
||||||
}
|
|
||||||
form.setValue(key, value);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useFetch(
|
useFetch(
|
||||||
|
|
|
@ -88,20 +88,7 @@ export const ECDSAGeneratedForm = ({
|
||||||
|
|
||||||
const setupForm = (component: ComponentRepresentation) => {
|
const setupForm = (component: ComponentRepresentation) => {
|
||||||
form.reset();
|
form.reset();
|
||||||
Object.entries(component).map(([key, value]) => {
|
convertToFormValues(component, form.setValue);
|
||||||
if (
|
|
||||||
key === "config" &&
|
|
||||||
component.config?.ecdsaEllipticCurveKey &&
|
|
||||||
component.config.active
|
|
||||||
) {
|
|
||||||
form.setValue("config.secretSize", value.ecdsaEllipticCurveKey[0]);
|
|
||||||
|
|
||||||
form.setValue("config.active", value.active[0]);
|
|
||||||
|
|
||||||
convertToFormValues(value, "config", form.setValue);
|
|
||||||
}
|
|
||||||
form.setValue(key, value);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useFetch(
|
useFetch(
|
||||||
|
|
|
@ -90,23 +90,7 @@ export const HMACGeneratedForm = ({
|
||||||
|
|
||||||
const setupForm = (component: ComponentRepresentation) => {
|
const setupForm = (component: ComponentRepresentation) => {
|
||||||
form.reset();
|
form.reset();
|
||||||
Object.entries(component).map(([key, value]) => {
|
convertToFormValues(component, form.setValue);
|
||||||
if (
|
|
||||||
key === "config" &&
|
|
||||||
component.config?.secretSize &&
|
|
||||||
component.config.active &&
|
|
||||||
component.config.algorithm
|
|
||||||
) {
|
|
||||||
form.setValue("config.secretSize", value.secretSize[0]);
|
|
||||||
|
|
||||||
form.setValue("config.active", value.active[0]);
|
|
||||||
|
|
||||||
form.setValue("config.algorithm", value.active[0]);
|
|
||||||
|
|
||||||
convertToFormValues(value, "config", form.setValue);
|
|
||||||
}
|
|
||||||
form.setValue(key, value);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useFetch(
|
useFetch(
|
||||||
|
|
|
@ -88,33 +88,7 @@ export const JavaKeystoreForm = ({
|
||||||
|
|
||||||
const setupForm = (component: ComponentRepresentation) => {
|
const setupForm = (component: ComponentRepresentation) => {
|
||||||
form.reset();
|
form.reset();
|
||||||
Object.entries(component).map(([key, value]) => {
|
convertToFormValues(component, form.setValue);
|
||||||
if (
|
|
||||||
key === "config" &&
|
|
||||||
component.config?.secretSize &&
|
|
||||||
component.config.active &&
|
|
||||||
component.config.algorithm &&
|
|
||||||
component.config.keystore &&
|
|
||||||
component.config.keystorePassword &&
|
|
||||||
component.config.keyAlias &&
|
|
||||||
component.config.keyPassword
|
|
||||||
) {
|
|
||||||
form.setValue("config.secretSize", value.secretSize[0]);
|
|
||||||
|
|
||||||
form.setValue("config.active", value.active[0]);
|
|
||||||
|
|
||||||
form.setValue("config.algorithm", value.algorithm[0]);
|
|
||||||
|
|
||||||
form.setValue("config.keystore", value.keystore[0]);
|
|
||||||
|
|
||||||
form.setValue("config.keyAlias", value.keyAlias[0]);
|
|
||||||
|
|
||||||
form.setValue("config.keyPassword", value.keyPassword[0]);
|
|
||||||
|
|
||||||
convertToFormValues(value, "config", form.setValue);
|
|
||||||
}
|
|
||||||
form.setValue(key, value);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useFetch(
|
useFetch(
|
||||||
|
|
|
@ -90,23 +90,7 @@ export const RSAGeneratedForm = ({
|
||||||
|
|
||||||
const setupForm = (component: ComponentRepresentation) => {
|
const setupForm = (component: ComponentRepresentation) => {
|
||||||
form.reset();
|
form.reset();
|
||||||
Object.entries(component).map(([key, value]) => {
|
convertToFormValues(component, form.setValue);
|
||||||
if (
|
|
||||||
key === "config" &&
|
|
||||||
component.config?.secretSize &&
|
|
||||||
component.config.active &&
|
|
||||||
component.config.algorithm
|
|
||||||
) {
|
|
||||||
form.setValue("config.secretSize", value.secretSize[0]);
|
|
||||||
|
|
||||||
form.setValue("config.active", value.active[0]);
|
|
||||||
|
|
||||||
form.setValue("config.algorithm", value.active[0]);
|
|
||||||
|
|
||||||
convertToFormValues(value, "config", form.setValue);
|
|
||||||
}
|
|
||||||
form.setValue(key, value);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useFetch(
|
useFetch(
|
||||||
|
|
|
@ -95,29 +95,7 @@ export const RSAForm = ({
|
||||||
|
|
||||||
const setupForm = (component: ComponentRepresentation) => {
|
const setupForm = (component: ComponentRepresentation) => {
|
||||||
form.reset();
|
form.reset();
|
||||||
Object.entries(component).map(([key, value]) => {
|
convertToFormValues(component, form.setValue);
|
||||||
if (
|
|
||||||
key === "config" &&
|
|
||||||
component.config?.secretSize &&
|
|
||||||
component.config.active &&
|
|
||||||
component.config.algorithm &&
|
|
||||||
component.config.privateKey &&
|
|
||||||
component.config.certificate
|
|
||||||
) {
|
|
||||||
form.setValue("config.secretSize", value.secretSize[0]);
|
|
||||||
|
|
||||||
form.setValue("config.active", value.active[0]);
|
|
||||||
|
|
||||||
form.setValue("config.algorithm", value.algorithm[0]);
|
|
||||||
|
|
||||||
form.setValue("config.privateKey", value.privateKey[0]);
|
|
||||||
|
|
||||||
form.setValue("config.certificate", value.certificate[0]);
|
|
||||||
|
|
||||||
convertToFormValues(value, "config", form.setValue);
|
|
||||||
}
|
|
||||||
form.setValue(key, value);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useFetch(
|
useFetch(
|
||||||
|
|
|
@ -12,7 +12,6 @@ import {
|
||||||
import { KerberosSettingsRequired } from "./kerberos/KerberosSettingsRequired";
|
import { KerberosSettingsRequired } from "./kerberos/KerberosSettingsRequired";
|
||||||
import { SettingsCache } from "./shared/SettingsCache";
|
import { SettingsCache } from "./shared/SettingsCache";
|
||||||
import { useRealm } from "../context/realm-context/RealmContext";
|
import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
import { convertToFormValues } from "../util";
|
|
||||||
import type ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation";
|
import type ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation";
|
||||||
|
|
||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
|
@ -107,16 +106,7 @@ export default function UserFederationKerberosSettings() {
|
||||||
);
|
);
|
||||||
|
|
||||||
const setupForm = (component: ComponentRepresentation) => {
|
const setupForm = (component: ComponentRepresentation) => {
|
||||||
Object.entries(component).map((entry) => {
|
form.reset({ ...component });
|
||||||
form.setValue(
|
|
||||||
"config.allowPasswordAuthentication",
|
|
||||||
component.config?.allowPasswordAuthentication
|
|
||||||
);
|
|
||||||
if (entry[0] === "config") {
|
|
||||||
convertToFormValues(entry[1], "config", form.setValue);
|
|
||||||
}
|
|
||||||
form.setValue(entry[0], entry[1]);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const save = async (component: ComponentRepresentation) => {
|
const save = async (component: ComponentRepresentation) => {
|
||||||
|
|
|
@ -21,7 +21,6 @@ import { LdapSettingsConnection } from "./ldap/LdapSettingsConnection";
|
||||||
import { LdapSettingsSearching } from "./ldap/LdapSettingsSearching";
|
import { LdapSettingsSearching } from "./ldap/LdapSettingsSearching";
|
||||||
|
|
||||||
import { useRealm } from "../context/realm-context/RealmContext";
|
import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
import { convertToFormValues } from "../util";
|
|
||||||
import type ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation";
|
import type ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation";
|
||||||
|
|
||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
|
@ -220,22 +219,16 @@ export default function UserFederationLdapSettings() {
|
||||||
);
|
);
|
||||||
|
|
||||||
const setupForm = (component: ComponentRepresentation) => {
|
const setupForm = (component: ComponentRepresentation) => {
|
||||||
Object.entries(component).map((entry) => {
|
form.reset({ ...component });
|
||||||
if (entry[0] === "config") {
|
form.setValue(
|
||||||
form.setValue(
|
"config.periodicChangedUsersSync",
|
||||||
"config.periodicChangedUsersSync",
|
component.config?.["changedSyncPeriod"][0] !== "-1"
|
||||||
entry[1].changedSyncPeriod[0] !== "-1"
|
);
|
||||||
);
|
|
||||||
|
|
||||||
form.setValue(
|
form.setValue(
|
||||||
"config.periodicFullSync",
|
"config.periodicFullSync",
|
||||||
entry[1].fullSyncPeriod[0] !== "-1"
|
component.config?.["fullSyncPeriod"][0] !== "-1"
|
||||||
);
|
);
|
||||||
|
|
||||||
convertToFormValues(entry[1], "config", form.setValue);
|
|
||||||
}
|
|
||||||
form.setValue(entry[0], entry[1]);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeImportedUsers = async () => {
|
const removeImportedUsers = async () => {
|
||||||
|
|
|
@ -71,21 +71,11 @@ export default function LdapMapperDetails() {
|
||||||
);
|
);
|
||||||
|
|
||||||
const setupForm = (mapper: ComponentRepresentation) => {
|
const setupForm = (mapper: ComponentRepresentation) => {
|
||||||
Object.entries(mapper).map((entry) => {
|
convertToFormValues(mapper, form.setValue);
|
||||||
if (entry[0] === "config") {
|
|
||||||
convertToFormValues(entry[1], "config", form.setValue);
|
|
||||||
} else {
|
|
||||||
form.setValue(entry[0], entry[1]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const save = async (mapper: ComponentRepresentation) => {
|
const save = async (mapper: ComponentRepresentation) => {
|
||||||
let config = {};
|
const map = convertFormValuesToObject(mapper);
|
||||||
if (mapper.config !== undefined) {
|
|
||||||
config = convertFormValuesToObject(mapper.config);
|
|
||||||
}
|
|
||||||
const map = { ...mapper, config };
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (mapperId) {
|
if (mapperId) {
|
||||||
|
|
|
@ -34,7 +34,7 @@ export const LdapMapperFullNameAttribute = ({
|
||||||
defaultValue="cn"
|
defaultValue="cn"
|
||||||
id="kc-full-name-attribute"
|
id="kc-full-name-attribute"
|
||||||
data-testid="mapper-fullNameAttribute-fld"
|
data-testid="mapper-fullNameAttribute-fld"
|
||||||
name="config.ldap-full-name-attribute[0]"
|
name="config.ldap.full.name.attribute[0]"
|
||||||
ref={form.register}
|
ref={form.register}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
@ -51,7 +51,7 @@ export const LdapMapperFullNameAttribute = ({
|
||||||
hasNoPaddingTop
|
hasNoPaddingTop
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="config.read-only"
|
name="config.read.only"
|
||||||
defaultValue={["true"]}
|
defaultValue={["true"]}
|
||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -79,7 +79,7 @@ export const LdapMapperFullNameAttribute = ({
|
||||||
hasNoPaddingTop
|
hasNoPaddingTop
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="config.write-only"
|
name="config.write.only"
|
||||||
defaultValue={["false"]}
|
defaultValue={["false"]}
|
||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
|
|
@ -33,7 +33,7 @@ export const LdapMapperHardcodedAttribute = ({
|
||||||
type="text"
|
type="text"
|
||||||
id="kc-user-model-attribute"
|
id="kc-user-model-attribute"
|
||||||
data-testid="mapper-userModelAttributeName-fld"
|
data-testid="mapper-userModelAttributeName-fld"
|
||||||
name="config.user-model-attribute[0]"
|
name="config.user.model.attribute[0]"
|
||||||
ref={form.register}
|
ref={form.register}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
@ -54,7 +54,7 @@ export const LdapMapperHardcodedAttribute = ({
|
||||||
type="text"
|
type="text"
|
||||||
id="kc-attribute-value"
|
id="kc-attribute-value"
|
||||||
data-testid="mapper-attributeValue-fld"
|
data-testid="mapper-attributeValue-fld"
|
||||||
name="config.attribute-value[0]"
|
name="config.attribute.value[0]"
|
||||||
ref={form.register}
|
ref={form.register}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
|
@ -33,7 +33,7 @@ export const LdapMapperHardcodedLdapAttribute = ({
|
||||||
type="text"
|
type="text"
|
||||||
id="kc-ldap-attribute-name"
|
id="kc-ldap-attribute-name"
|
||||||
data-testid="mapper-ldapAttributeName-fld"
|
data-testid="mapper-ldapAttributeName-fld"
|
||||||
name="config.ldap-attribute-name[0]"
|
name="config.ldap.attribute.name[0]"
|
||||||
ref={form.register}
|
ref={form.register}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
@ -54,7 +54,7 @@ export const LdapMapperHardcodedLdapAttribute = ({
|
||||||
type="text"
|
type="text"
|
||||||
id="kc-ldap-attribute-value"
|
id="kc-ldap-attribute-value"
|
||||||
data-testid="mapper-ldapAttributeValue-fld"
|
data-testid="mapper-ldapAttributeValue-fld"
|
||||||
name="config.ldap-attribute-value[0]"
|
name="config.ldap.attribute.value[0]"
|
||||||
ref={form.register}
|
ref={form.register}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
|
@ -12,7 +12,7 @@ export const LdapMapperMsadUserAccount = ({
|
||||||
form,
|
form,
|
||||||
}: LdapMapperMsadUserAccountProps) => {
|
}: LdapMapperMsadUserAccountProps) => {
|
||||||
const { t } = useTranslation("user-federation");
|
const { t } = useTranslation("user-federation");
|
||||||
const helpText = useTranslation("user-federation-help").t;
|
const { t: helpText } = useTranslation("user-federation-help");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormGroup
|
<FormGroup
|
||||||
|
@ -28,7 +28,7 @@ export const LdapMapperMsadUserAccount = ({
|
||||||
hasNoPaddingTop
|
hasNoPaddingTop
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="config.ldap-password-policy-hints-enabled"
|
name="config.ldap.password.policy.hints.enabled"
|
||||||
defaultValue={["false"]}
|
defaultValue={["false"]}
|
||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
|
|
@ -67,11 +67,11 @@ export const LdapMapperRoleGroup = ({
|
||||||
if (mapperId === "new" && vendor === "ad") {
|
if (mapperId === "new" && vendor === "ad") {
|
||||||
form.setValue(
|
form.setValue(
|
||||||
isRole
|
isRole
|
||||||
? "config.role-object-classes[0]"
|
? "config.role.object.classes[0]"
|
||||||
: "config.group-object-classes[0]",
|
: "config.group.object.classes[0]",
|
||||||
"group"
|
"group"
|
||||||
);
|
);
|
||||||
form.setValue("config.membership-user-ldap-attribute[0]", "cn");
|
form.setValue("config.membership.user.ldap.attribute[0]", "cn");
|
||||||
}
|
}
|
||||||
} else if (id) {
|
} else if (id) {
|
||||||
throw new Error(t("common:notFound"));
|
throw new Error(t("common:notFound"));
|
||||||
|
@ -103,7 +103,7 @@ export const LdapMapperRoleGroup = ({
|
||||||
type="text"
|
type="text"
|
||||||
id="kc-ldap-dn"
|
id="kc-ldap-dn"
|
||||||
data-testid="ldap-dn"
|
data-testid="ldap-dn"
|
||||||
name={isRole ? "config.roles-dn[0]" : "config.groups-dn[0]"}
|
name={isRole ? "config.roles.dn[0]" : "config.groups.dn[0]"}
|
||||||
ref={form.register({ required: true })}
|
ref={form.register({ required: true })}
|
||||||
validated={
|
validated={
|
||||||
isRole
|
isRole
|
||||||
|
@ -144,8 +144,8 @@ export const LdapMapperRoleGroup = ({
|
||||||
defaultValue="cn"
|
defaultValue="cn"
|
||||||
name={
|
name={
|
||||||
isRole
|
isRole
|
||||||
? "config.role-name-ldap-attribute[0]"
|
? "config.role.name.ldap.attribute[0]"
|
||||||
: "config.group-name-ldap-attribute[0]"
|
: "config.group.name.ldap.attribute[0]"
|
||||||
}
|
}
|
||||||
ref={form.register}
|
ref={form.register}
|
||||||
/>
|
/>
|
||||||
|
@ -174,8 +174,8 @@ export const LdapMapperRoleGroup = ({
|
||||||
defaultValue="groupOfNames"
|
defaultValue="groupOfNames"
|
||||||
name={
|
name={
|
||||||
isRole
|
isRole
|
||||||
? "config.role-object-classes[0]"
|
? "config.role.object.classes[0]"
|
||||||
: "config.group-object-classes[0]"
|
: "config.group.object.classes[0]"
|
||||||
}
|
}
|
||||||
ref={form.register}
|
ref={form.register}
|
||||||
/>
|
/>
|
||||||
|
@ -195,7 +195,7 @@ export const LdapMapperRoleGroup = ({
|
||||||
hasNoPaddingTop
|
hasNoPaddingTop
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="config.preserve-group-inheritance"
|
name="config.preserve.group.inheritance"
|
||||||
defaultValue={["true"]}
|
defaultValue={["true"]}
|
||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -223,7 +223,7 @@ export const LdapMapperRoleGroup = ({
|
||||||
hasNoPaddingTop
|
hasNoPaddingTop
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="config.ignore-missing-groups"
|
name="config.ignore.missing.groups"
|
||||||
defaultValue={["false"]}
|
defaultValue={["false"]}
|
||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -258,7 +258,7 @@ export const LdapMapperRoleGroup = ({
|
||||||
defaultValue="member"
|
defaultValue="member"
|
||||||
id="kc-membership-ldap-attribute"
|
id="kc-membership-ldap-attribute"
|
||||||
data-testid="membership-ldap-attribute"
|
data-testid="membership-ldap-attribute"
|
||||||
name="config.membership-ldap-attribute[0]"
|
name="config.membership.ldap.attribute[0]"
|
||||||
ref={form.register}
|
ref={form.register}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
@ -274,7 +274,7 @@ export const LdapMapperRoleGroup = ({
|
||||||
fieldId="kc-membership-attribute-type"
|
fieldId="kc-membership-attribute-type"
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="config.membership-attribute-type[0]"
|
name="config.membership.attribute.type[0]"
|
||||||
defaultValue="DN"
|
defaultValue="DN"
|
||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -319,7 +319,7 @@ export const LdapMapperRoleGroup = ({
|
||||||
id="kc-membership-user-ldap-attribute"
|
id="kc-membership-user-ldap-attribute"
|
||||||
data-testid="membership-user-ldap-attribute"
|
data-testid="membership-user-ldap-attribute"
|
||||||
defaultValue="uid"
|
defaultValue="uid"
|
||||||
name="config.membership-user-ldap-attribute[0]"
|
name="config.membership.user.ldap.attribute[0]"
|
||||||
ref={form.register}
|
ref={form.register}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
@ -340,8 +340,8 @@ export const LdapMapperRoleGroup = ({
|
||||||
data-testid="ldap-filter"
|
data-testid="ldap-filter"
|
||||||
name={
|
name={
|
||||||
isRole
|
isRole
|
||||||
? "config.roles-ldap-filter[0]"
|
? "config.roles.ldap.filter[0]"
|
||||||
: "config.groups-ldap-filter[0]"
|
: "config.groups.ldap.filter[0]"
|
||||||
}
|
}
|
||||||
ref={form.register}
|
ref={form.register}
|
||||||
/>
|
/>
|
||||||
|
@ -399,7 +399,7 @@ export const LdapMapperRoleGroup = ({
|
||||||
fieldId="kc-user-retrieve-strategy"
|
fieldId="kc-user-retrieve-strategy"
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="config.user-roles-retrieve-strategy[0]"
|
name="config.user.roles.retrieve.strategy[0]"
|
||||||
defaultValue="LOAD_ROLES_BY_MEMBER_ATTRIBUTE"
|
defaultValue="LOAD_ROLES_BY_MEMBER_ATTRIBUTE"
|
||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -449,7 +449,7 @@ export const LdapMapperRoleGroup = ({
|
||||||
fieldId="kc-user-retrieve-strategy"
|
fieldId="kc-user-retrieve-strategy"
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="config.user-roles-retrieve-strategy[0]"
|
name="config.user.roles.retrieve.strategy[0]"
|
||||||
defaultValue="LOAD_GROUPS_BY_MEMBER_ATTRIBUTE"
|
defaultValue="LOAD_GROUPS_BY_MEMBER_ATTRIBUTE"
|
||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -505,7 +505,7 @@ export const LdapMapperRoleGroup = ({
|
||||||
id="kc-member-of-attribute"
|
id="kc-member-of-attribute"
|
||||||
defaultValue="memberOf"
|
defaultValue="memberOf"
|
||||||
data-testid="member-of-attribute"
|
data-testid="member-of-attribute"
|
||||||
name="config.memberof-ldap-attribute[0]"
|
name="config.memberof.ldap.attribute[0]"
|
||||||
ref={form.register}
|
ref={form.register}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
@ -524,7 +524,7 @@ export const LdapMapperRoleGroup = ({
|
||||||
hasNoPaddingTop
|
hasNoPaddingTop
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="config.use-realm-roles-mapping"
|
name="config.use.realm.roles.mapping"
|
||||||
defaultValue={["true"]}
|
defaultValue={["true"]}
|
||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -551,7 +551,7 @@ export const LdapMapperRoleGroup = ({
|
||||||
fieldId="kc-client-id"
|
fieldId="kc-client-id"
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="config.client-id[0]"
|
name="config.client.id[0]"
|
||||||
defaultValue=""
|
defaultValue=""
|
||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -596,7 +596,7 @@ export const LdapMapperRoleGroup = ({
|
||||||
type="text"
|
type="text"
|
||||||
id="kc-mapped-attributes"
|
id="kc-mapped-attributes"
|
||||||
data-testid="mapped-attributes"
|
data-testid="mapped-attributes"
|
||||||
name="config.mapped-group-attributes[0]"
|
name="config.mapped.group.attributes[0]"
|
||||||
ref={form.register}
|
ref={form.register}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
@ -613,7 +613,7 @@ export const LdapMapperRoleGroup = ({
|
||||||
hasNoPaddingTop
|
hasNoPaddingTop
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="config.drop-non-existing-groups-during-sync"
|
name="config.drop.non.existing.groups.during.sync"
|
||||||
defaultValue={["false"]}
|
defaultValue={["false"]}
|
||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -646,7 +646,7 @@ export const LdapMapperRoleGroup = ({
|
||||||
id="kc-path"
|
id="kc-path"
|
||||||
data-testid="path"
|
data-testid="path"
|
||||||
defaultValue="/"
|
defaultValue="/"
|
||||||
name="config.groups-path[0]"
|
name="config.groups.path[0]"
|
||||||
ref={form.register({ required: true })}
|
ref={form.register({ required: true })}
|
||||||
validated={
|
validated={
|
||||||
form.errors.config?.["groups-path"]
|
form.errors.config?.["groups-path"]
|
||||||
|
|
|
@ -35,7 +35,7 @@ export const LdapMapperUserAttribute = ({
|
||||||
type="text"
|
type="text"
|
||||||
id="kc-user-model-attribute"
|
id="kc-user-model-attribute"
|
||||||
data-testid="mapper-userModelAttribute-fld"
|
data-testid="mapper-userModelAttribute-fld"
|
||||||
name="config.user-model-attribute[0]"
|
name="config.user.model.attribute[0]"
|
||||||
ref={form.register}
|
ref={form.register}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
@ -56,7 +56,7 @@ export const LdapMapperUserAttribute = ({
|
||||||
type="text"
|
type="text"
|
||||||
id="kc-ldap-attribute"
|
id="kc-ldap-attribute"
|
||||||
data-testid="mapper-ldapAttribute-fld"
|
data-testid="mapper-ldapAttribute-fld"
|
||||||
name="config.ldap-attribute[0]"
|
name="config.ldap.attribute[0]"
|
||||||
ref={form.register}
|
ref={form.register}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
@ -73,7 +73,7 @@ export const LdapMapperUserAttribute = ({
|
||||||
hasNoPaddingTop
|
hasNoPaddingTop
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="config.read-only"
|
name="config.read.only"
|
||||||
defaultValue={
|
defaultValue={
|
||||||
mapperType === "user-attribute-ldap-mapper" ? ["true"] : ["false"]
|
mapperType === "user-attribute-ldap-mapper" ? ["true"] : ["false"]
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ export const LdapMapperUserAttribute = ({
|
||||||
hasNoPaddingTop
|
hasNoPaddingTop
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="config.always-read-value-from-ldap"
|
name="config.always.read.value.from.ldap"
|
||||||
defaultValue={["false"]}
|
defaultValue={["false"]}
|
||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -131,7 +131,7 @@ export const LdapMapperUserAttribute = ({
|
||||||
hasNoPaddingTop
|
hasNoPaddingTop
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="config.is-mandatory-in-ldap"
|
name="config.is.mandatory.in.ldap"
|
||||||
defaultValue={["false"]}
|
defaultValue={["false"]}
|
||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -161,7 +161,7 @@ export const LdapMapperUserAttribute = ({
|
||||||
type="text"
|
type="text"
|
||||||
id="kc-attribute-default-value"
|
id="kc-attribute-default-value"
|
||||||
data-testid="mapper-attributeDefaultValue-fld"
|
data-testid="mapper-attributeDefaultValue-fld"
|
||||||
name="config.attribute-default-value[0]"
|
name="config.attribute.default.value[0]"
|
||||||
ref={form.register}
|
ref={form.register}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
@ -178,7 +178,7 @@ export const LdapMapperUserAttribute = ({
|
||||||
hasNoPaddingTop
|
hasNoPaddingTop
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="config.is-binary-attribute"
|
name="config.is.binary.attribute"
|
||||||
defaultValue={["false"]}
|
defaultValue={["false"]}
|
||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
|
@ -207,12 +207,12 @@ export const LdapMapperUserAttribute = ({
|
||||||
hasNoPaddingTop
|
hasNoPaddingTop
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="config.is-der-formatted"
|
name="config.is.der.formatted"
|
||||||
defaultValue={["false"]}
|
defaultValue={["false"]}
|
||||||
control={form.control}
|
control={form.control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<Switch
|
<Switch
|
||||||
id={"kc-der-formatted"}
|
id="kc-der-formatted"
|
||||||
isDisabled={false}
|
isDisabled={false}
|
||||||
onChange={(value) => onChange([`${value}`])}
|
onChange={(value) => onChange([`${value}`])}
|
||||||
isChecked={value[0] === "true"}
|
isChecked={value[0] === "true"}
|
||||||
|
|
140
src/util.test.ts
Normal file
140
src/util.test.ts
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
import { convertFormValuesToObject, convertToFormValues } from "./util";
|
||||||
|
|
||||||
|
jest.mock("react");
|
||||||
|
|
||||||
|
describe("Tests the form convert util functions", () => {
|
||||||
|
it("convert to form values", () => {
|
||||||
|
const given = {
|
||||||
|
name: "client",
|
||||||
|
other: { one: "1", two: "2" },
|
||||||
|
attributes: { one: ["1"] },
|
||||||
|
};
|
||||||
|
const values: { [index: string]: any } = {};
|
||||||
|
const spy = (name: string, value: any) => (values[name] = value);
|
||||||
|
|
||||||
|
//when
|
||||||
|
convertToFormValues(given, spy);
|
||||||
|
|
||||||
|
//then
|
||||||
|
expect(values).toEqual({
|
||||||
|
name: "client",
|
||||||
|
other: { one: "1", two: "2" },
|
||||||
|
attributes: [
|
||||||
|
{ key: "one", value: "1" },
|
||||||
|
{ key: "", value: "" },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("convert save values", () => {
|
||||||
|
const given = {
|
||||||
|
name: "client",
|
||||||
|
attributes: [{ key: "one", value: "1" }],
|
||||||
|
config: { one: { two: "3" } },
|
||||||
|
};
|
||||||
|
|
||||||
|
//when
|
||||||
|
const values = convertFormValuesToObject(given);
|
||||||
|
|
||||||
|
//then
|
||||||
|
expect(values).toEqual({
|
||||||
|
name: "client",
|
||||||
|
attributes: { one: ["1"] },
|
||||||
|
config: { "one.two": "3" },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("convert attributes flatten", () => {
|
||||||
|
const given = {
|
||||||
|
name: "test",
|
||||||
|
description: "",
|
||||||
|
type: "default",
|
||||||
|
attributes: {
|
||||||
|
display: { on: { consent: { screen: "true" } } },
|
||||||
|
include: { in: { token: { scope: "true" } } },
|
||||||
|
gui: { order: "1" },
|
||||||
|
consent: { screen: { text: "" } },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
//when
|
||||||
|
const values = convertFormValuesToObject(given);
|
||||||
|
|
||||||
|
//then
|
||||||
|
expect(values).toEqual({
|
||||||
|
name: "test",
|
||||||
|
description: "",
|
||||||
|
type: "default",
|
||||||
|
attributes: {
|
||||||
|
"display.on.consent.screen": "true",
|
||||||
|
"include.in.token.scope": "true",
|
||||||
|
"gui.order": "1",
|
||||||
|
"consent.screen.text": "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("convert flatten attributes to object", () => {
|
||||||
|
const given = {
|
||||||
|
attributes: {
|
||||||
|
"display.on.consent.screen": "true",
|
||||||
|
"include.in.token.scope": "true",
|
||||||
|
"gui.order": "1",
|
||||||
|
"consent.screen.text": "",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const values: { [index: string]: any } = {};
|
||||||
|
const spy = (name: string, value: any) => (values[name] = value);
|
||||||
|
|
||||||
|
//when
|
||||||
|
convertToFormValues(given, spy);
|
||||||
|
|
||||||
|
//then
|
||||||
|
expect(values).toEqual({
|
||||||
|
attributes: {
|
||||||
|
display: { on: { consent: { screen: "true" } } },
|
||||||
|
include: { in: { token: { scope: "true" } } },
|
||||||
|
gui: { order: "1" },
|
||||||
|
consent: { screen: { text: "" } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("convert arrays to form values", () => {
|
||||||
|
const given = {
|
||||||
|
name: "test",
|
||||||
|
description: "",
|
||||||
|
redirectUris: ["http://bla.nl", "http://test.nl/bla", "http://test.nl"],
|
||||||
|
};
|
||||||
|
const values: { [index: string]: any } = {};
|
||||||
|
const spy = (name: string, value: any) => (values[name] = value);
|
||||||
|
|
||||||
|
//when
|
||||||
|
convertToFormValues(given, spy, ["redirectUris"]);
|
||||||
|
|
||||||
|
//then
|
||||||
|
expect(values).toEqual({
|
||||||
|
name: "test",
|
||||||
|
description: "",
|
||||||
|
redirectUris: [
|
||||||
|
{ value: "http://bla.nl" },
|
||||||
|
{ value: "http://test.nl/bla" },
|
||||||
|
{ value: "http://test.nl" },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("convert form values to object", () => {
|
||||||
|
const given = {
|
||||||
|
redirectUris: [{ value: "http://bla.nl" }, { value: "http://test.nl" }],
|
||||||
|
};
|
||||||
|
|
||||||
|
//when
|
||||||
|
const values = convertFormValuesToObject(given, ["redirectUris"]);
|
||||||
|
|
||||||
|
//then
|
||||||
|
expect(values).toEqual({
|
||||||
|
redirectUris: ["http://bla.nl", "http://test.nl"],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
98
src/util.ts
98
src/util.ts
|
@ -1,10 +1,22 @@
|
||||||
import type { IFormatter, IFormatterValueType } from "@patternfly/react-table";
|
import { cloneDeep } from "lodash";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
import FileSaver from "file-saver";
|
import FileSaver from "file-saver";
|
||||||
import _ from "lodash";
|
import type { IFormatter, IFormatterValueType } from "@patternfly/react-table";
|
||||||
|
import { unflatten, flatten } from "flat";
|
||||||
|
|
||||||
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
|
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
|
||||||
import type { ProviderRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/serverInfoRepesentation";
|
import type { ProviderRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/serverInfoRepesentation";
|
||||||
import type KeycloakAdminClient from "@keycloak/keycloak-admin-client";
|
import type KeycloakAdminClient from "@keycloak/keycloak-admin-client";
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
import {
|
||||||
|
arrayToAttributes,
|
||||||
|
attributesToArray,
|
||||||
|
KeyValueType,
|
||||||
|
} from "./components/attribute-form/attribute-convert";
|
||||||
|
import {
|
||||||
|
convertToMultiline,
|
||||||
|
toValue,
|
||||||
|
} from "./components/multi-line-input/multi-line-convert";
|
||||||
|
|
||||||
export const sortProviders = (providers: {
|
export const sortProviders = (providers: {
|
||||||
[index: string]: ProviderRepresentation;
|
[index: string]: ProviderRepresentation;
|
||||||
|
@ -34,7 +46,7 @@ const sortProvider = (
|
||||||
};
|
};
|
||||||
|
|
||||||
export const exportClient = (client: ClientRepresentation): void => {
|
export const exportClient = (client: ClientRepresentation): void => {
|
||||||
const clientCopy = _.cloneDeep(client);
|
const clientCopy = cloneDeep(client);
|
||||||
delete clientCopy.id;
|
delete clientCopy.id;
|
||||||
|
|
||||||
if (clientCopy.protocolMappers) {
|
if (clientCopy.protocolMappers) {
|
||||||
|
@ -54,49 +66,59 @@ export const exportClient = (client: ClientRepresentation): void => {
|
||||||
export const toUpperCase = <T extends string>(name: T) =>
|
export const toUpperCase = <T extends string>(name: T) =>
|
||||||
(name.charAt(0).toUpperCase() + name.slice(1)) as Capitalize<T>;
|
(name.charAt(0).toUpperCase() + name.slice(1)) as Capitalize<T>;
|
||||||
|
|
||||||
export const convertToHyphens = (s: string) => {
|
const isAttributesObject = (value: any) => {
|
||||||
return s.replaceAll(".", "-");
|
return (
|
||||||
|
Object.values(value).filter(
|
||||||
|
(value) => Array.isArray(value) && value.length === 1
|
||||||
|
).length !== 0
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isAttributeArray = (value: any) => {
|
||||||
|
if (!Array.isArray(value)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return value.filter((e) => e.key && e.value).length !== 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
const isEmpty = (obj: any) => Object.keys(obj).length === 0;
|
||||||
|
|
||||||
export const convertToFormValues = (
|
export const convertToFormValues = (
|
||||||
obj: any,
|
obj: any,
|
||||||
prefix: string,
|
setValue: (name: string, value: any) => void,
|
||||||
setValue: (name: string, value: any) => void
|
multiline?: string[]
|
||||||
) => {
|
) => {
|
||||||
return Object.keys(obj).map((key) => {
|
Object.entries(obj).map(([key, value]) => {
|
||||||
const newKey = convertToHyphens(key);
|
if (key === "attributes" && isAttributesObject(value)) {
|
||||||
setValue(prefix + "." + newKey, obj[key]);
|
setValue(key, attributesToArray(value as Record<string, string[]>));
|
||||||
|
} else if (key === "config" || key === "attributes") {
|
||||||
|
setValue(key, !isEmpty(value) ? unflatten(value) : undefined);
|
||||||
|
} else if (multiline?.includes(key)) {
|
||||||
|
setValue(key, convertToMultiline(value as string[]));
|
||||||
|
} else {
|
||||||
|
setValue(key, value);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const flatten = (
|
export function convertFormValuesToObject<T>(
|
||||||
obj: Record<string, any> | undefined,
|
obj: T,
|
||||||
path = ""
|
multiline: string[] | undefined = []
|
||||||
): {} => {
|
): Omit<T, typeof multiline[number] | "attributes" | "config"> {
|
||||||
if (!(obj instanceof Object)) return { [path.replace(/\.$/g, "")]: obj };
|
const result: any = {};
|
||||||
|
Object.entries(obj).map(([key, value]) => {
|
||||||
return Object.keys(obj).reduce((output, key) => {
|
if (isAttributeArray(value)) {
|
||||||
return obj instanceof Array
|
result[key] = arrayToAttributes(value as KeyValueType[]);
|
||||||
? {
|
} else if (multiline.includes(key)) {
|
||||||
...output,
|
result[key] = toValue(value);
|
||||||
...flatten(obj[key as unknown as number], path + "[" + key + "]."),
|
} else if (key === "config" || key === "attributes") {
|
||||||
}
|
result[key] = flatten(value as Record<string, any>, { safe: true });
|
||||||
: { ...output, ...flatten(obj[key], path + key + ".") };
|
} else {
|
||||||
}, {});
|
result[key] = value;
|
||||||
};
|
}
|
||||||
|
|
||||||
export const convertFormValuesToObject = (
|
|
||||||
obj: any,
|
|
||||||
firstInstanceOnly?: boolean
|
|
||||||
) => {
|
|
||||||
const keyValues = Object.keys(obj).map((key) => {
|
|
||||||
const newKey = firstInstanceOnly
|
|
||||||
? key.replace(/-/, ".")
|
|
||||||
: key.replace(/-/g, ".");
|
|
||||||
return { [newKey]: obj[key] };
|
|
||||||
});
|
});
|
||||||
return Object.assign({}, ...keyValues);
|
return result;
|
||||||
};
|
}
|
||||||
|
|
||||||
export const emptyFormatter =
|
export const emptyFormatter =
|
||||||
(): IFormatter => (data?: IFormatterValueType) => {
|
(): IFormatter => (data?: IFormatterValueType) => {
|
||||||
|
|
Loading…
Reference in a new issue