migrated to use ui-shared (#27849)
* migrated to use ui-shared Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * fixed tests Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * fixed tests Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> --------- Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
parent
c3a98ae387
commit
4fb2f73b2c
7 changed files with 77 additions and 168 deletions
|
@ -237,8 +237,8 @@ describe("Realm settings events tab tests", () => {
|
|||
it("Realm header settings", () => {
|
||||
sidebarPage.goToRealmSettings();
|
||||
cy.findByTestId("rs-security-defenses-tab").click();
|
||||
cy.findByTestId("headers-form-tab-save").should("be.disabled");
|
||||
cy.get("#xFrameOptions").clear().type("DENY");
|
||||
cy.findByTestId("browserSecurityHeaders.xFrameOptions").clear();
|
||||
cy.findByTestId("browserSecurityHeaders.xFrameOptions").type("DENY");
|
||||
cy.findByTestId("headers-form-tab-save").should("be.enabled").click();
|
||||
|
||||
masthead.checkNotificationMessage("Realm successfully updated");
|
||||
|
@ -249,8 +249,6 @@ describe("Realm settings events tab tests", () => {
|
|||
cy.findAllByTestId("rs-security-defenses-tab").click();
|
||||
cy.get("#pf-tab-20-bruteForce").click();
|
||||
|
||||
cy.findByTestId("brute-force-tab-save").should("be.disabled");
|
||||
|
||||
cy.get("#kc-brute-force-mode").click();
|
||||
cy.findByTestId("select-brute-force-mode")
|
||||
.contains("Lockout temporarily")
|
||||
|
|
|
@ -136,7 +136,8 @@ describe("Realm settings tabs tests", () => {
|
|||
it("Realm header settings- update single input", () => {
|
||||
sidebarPage.goToRealmSettings();
|
||||
realmSettingsPage.goToSecurityDefensesTab();
|
||||
cy.get("#xFrameOptions").clear().type("DENY");
|
||||
cy.findByTestId("browserSecurityHeaders.xFrameOptions").clear();
|
||||
cy.findByTestId("browserSecurityHeaders.xFrameOptions").type("DENY");
|
||||
realmSettingsPage.saveSecurityDefensesHeaders();
|
||||
masthead.checkNotificationMessage("Realm successfully updated");
|
||||
});
|
||||
|
@ -144,14 +145,34 @@ describe("Realm settings tabs tests", () => {
|
|||
it("Realm header settings- update all inputs", () => {
|
||||
sidebarPage.goToRealmSettings();
|
||||
realmSettingsPage.goToSecurityDefensesTab();
|
||||
cy.get("#xFrameOptions").clear().type("SAMEORIGIN");
|
||||
cy.get("#contentSecurityPolicy").clear().type("default-src 'self'");
|
||||
cy.get("#strictTransportSecurity").clear().type("max-age=31536000");
|
||||
cy.get("#xContentTypeOptions").clear().type("nosniff");
|
||||
cy.get("#xRobotsTag").clear().type("none");
|
||||
cy.get("#xXSSProtection").clear().type("1; mode=block");
|
||||
cy.get("#strictTransportSecurity").clear().type("max-age=31537000");
|
||||
cy.get("#referrerPolicy").clear().type("referrer");
|
||||
cy.findByTestId("browserSecurityHeaders.xFrameOptions").clear();
|
||||
cy.findByTestId("browserSecurityHeaders.xFrameOptions").type(
|
||||
"SAMEORIGIN",
|
||||
);
|
||||
cy.findByTestId("browserSecurityHeaders.contentSecurityPolicy").clear();
|
||||
cy.findByTestId("browserSecurityHeaders.contentSecurityPolicy").type(
|
||||
"default-src 'self'",
|
||||
);
|
||||
cy.findByTestId("browserSecurityHeaders.strictTransportSecurity").clear();
|
||||
cy.findByTestId("browserSecurityHeaders.strictTransportSecurity").type(
|
||||
"max-age=31536000",
|
||||
);
|
||||
cy.findByTestId("browserSecurityHeaders.xContentTypeOptions").clear();
|
||||
cy.findByTestId("browserSecurityHeaders.xContentTypeOptions").type(
|
||||
"nosniff",
|
||||
);
|
||||
cy.findByTestId("browserSecurityHeaders.xRobotsTag").clear();
|
||||
cy.findByTestId("browserSecurityHeaders.xRobotsTag").type("none");
|
||||
cy.findByTestId("browserSecurityHeaders.xXSSProtection").clear();
|
||||
cy.findByTestId("browserSecurityHeaders.xXSSProtection").type(
|
||||
"1; mode=block",
|
||||
);
|
||||
cy.findByTestId("browserSecurityHeaders.strictTransportSecurity").clear();
|
||||
cy.findByTestId("browserSecurityHeaders.strictTransportSecurity").type(
|
||||
"max-age=31537000",
|
||||
);
|
||||
cy.findByTestId("browserSecurityHeaders.referrerPolicy").clear();
|
||||
cy.findByTestId("browserSecurityHeaders.referrerPolicy").type("referrer");
|
||||
realmSettingsPage.saveSecurityDefensesHeaders();
|
||||
masthead.checkNotificationMessage("Realm successfully updated");
|
||||
});
|
||||
|
|
|
@ -3,17 +3,15 @@ import {
|
|||
ActionGroup,
|
||||
Button,
|
||||
FormGroup,
|
||||
NumberInput,
|
||||
Select,
|
||||
SelectOption,
|
||||
SelectVariant,
|
||||
} from "@patternfly/react-core";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Controller, FormProvider, useForm } from "react-hook-form";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem, NumberControl } from "ui-shared";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import { HelpItem } from "ui-shared";
|
||||
import { convertToFormValues } from "../../util";
|
||||
import { Time } from "./Time";
|
||||
|
||||
|
@ -31,7 +29,6 @@ export const BruteForceDetection = ({
|
|||
const {
|
||||
setValue,
|
||||
handleSubmit,
|
||||
control,
|
||||
formState: { isDirty },
|
||||
} = form;
|
||||
|
||||
|
@ -131,74 +128,26 @@ export const BruteForceDetection = ({
|
|||
</FormGroup>
|
||||
{bruteForceMode !== BruteForceMode.Disabled && (
|
||||
<>
|
||||
<FormGroup
|
||||
label={t("failureFactor")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("failureFactorHelp")}
|
||||
fieldLabelId="failureFactor"
|
||||
/>
|
||||
}
|
||||
fieldId="failureFactor"
|
||||
>
|
||||
<Controller
|
||||
<NumberControl
|
||||
name="failureFactor"
|
||||
defaultValue={0}
|
||||
control={control}
|
||||
rules={{ required: true }}
|
||||
render={({ field }) => (
|
||||
<NumberInput
|
||||
type="text"
|
||||
id="failureFactor"
|
||||
value={field.value}
|
||||
onPlus={() => field.onChange(field.value + 1)}
|
||||
onMinus={() => field.onChange(field.value - 1)}
|
||||
onChange={(event) =>
|
||||
field.onChange(
|
||||
Number((event.target as HTMLInputElement).value),
|
||||
)
|
||||
}
|
||||
label={t("failureFactor")}
|
||||
labelIcon={t("failureFactorHelp")}
|
||||
controller={{
|
||||
defaultValue: 0,
|
||||
rules: { required: t("required") },
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{bruteForceMode ===
|
||||
BruteForceMode.PermanentAfterTemporaryLockout && (
|
||||
<FormGroup
|
||||
label={t("maxTemporaryLockouts")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("maxTemporaryLockoutsHelp")}
|
||||
fieldLabelId="maxTemporaryLockouts"
|
||||
/>
|
||||
}
|
||||
fieldId="maxTemporaryLockouts"
|
||||
hasNoPaddingTop
|
||||
>
|
||||
<Controller
|
||||
<NumberControl
|
||||
name="maxTemporaryLockouts"
|
||||
defaultValue={0}
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<NumberInput
|
||||
type="text"
|
||||
id="maxTemporaryLockouts"
|
||||
value={field.value}
|
||||
onPlus={() => field.onChange(field.value + 1)}
|
||||
onMinus={() => field.onChange(field.value - 1)}
|
||||
onChange={(event) =>
|
||||
field.onChange(
|
||||
Number((event.target as HTMLInputElement).value),
|
||||
)
|
||||
}
|
||||
aria-label={t("maxTemporaryLockouts")}
|
||||
label={t("maxTemporaryLockouts")}
|
||||
labelIcon={t("maxTemporaryLockoutsHelp")}
|
||||
controller={{
|
||||
defaultValue: 0,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
|
||||
{(bruteForceMode === BruteForceMode.TemporaryLockout ||
|
||||
bruteForceMode ===
|
||||
BruteForceMode.PermanentAfterTemporaryLockout) && (
|
||||
|
@ -208,38 +157,14 @@ export const BruteForceDetection = ({
|
|||
<Time name="maxDeltaTimeSeconds" />
|
||||
</>
|
||||
)}
|
||||
|
||||
<FormGroup
|
||||
label={t("quickLoginCheckMilliSeconds")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("quickLoginCheckMilliSecondsHelp")}
|
||||
fieldLabelId="quickLoginCheckMilliSeconds"
|
||||
/>
|
||||
}
|
||||
fieldId="quickLoginCheckMilliSeconds"
|
||||
>
|
||||
<Controller
|
||||
<NumberControl
|
||||
name="quickLoginCheckMilliSeconds"
|
||||
defaultValue={0}
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<NumberInput
|
||||
type="text"
|
||||
id="quickLoginCheckMilliSeconds"
|
||||
value={field.value}
|
||||
onPlus={() => field.onChange(field.value + 1)}
|
||||
onMinus={() => field.onChange(field.value - 1)}
|
||||
onChange={(event) =>
|
||||
field.onChange(
|
||||
Number((event.target as HTMLInputElement).value),
|
||||
)
|
||||
}
|
||||
label={t("quickLoginCheckMilliSeconds")}
|
||||
labelIcon={t("quickLoginCheckMilliSecondsHelp")}
|
||||
controller={{
|
||||
defaultValue: 0,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<Time name="minimumQuickLoginWaitSeconds" />
|
||||
</>
|
||||
)}
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
import { FormGroup } from "@patternfly/react-core";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
|
||||
import { TextControl } from "ui-shared";
|
||||
import { FormattedLink } from "../../components/external-link/FormattedLink";
|
||||
import { HelpItem } from "ui-shared";
|
||||
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
|
||||
|
||||
type HelpLinkTextInputProps = {
|
||||
fieldName: string;
|
||||
|
@ -16,25 +12,17 @@ export const HelpLinkTextInput = ({
|
|||
url,
|
||||
}: HelpLinkTextInputProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { register } = useFormContext();
|
||||
const name = fieldName.substr(fieldName.indexOf(".") + 1);
|
||||
return (
|
||||
<FormGroup
|
||||
<TextControl
|
||||
name={fieldName}
|
||||
label={t(name)}
|
||||
fieldId={name}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={
|
||||
<Trans i18nKey={`${name}Help`}>
|
||||
Default value prevents pages from being included
|
||||
<FormattedLink href={url} title={t("learnMore")} />
|
||||
</Trans>
|
||||
}
|
||||
fieldLabelId={name}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<KeycloakTextInput id={name} {...register(fieldName)} />
|
||||
</FormGroup>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import { FormGroup, ValidatedOptions } from "@patternfly/react-core";
|
||||
import { CSSProperties } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "ui-shared";
|
||||
import { TimeSelector } from "../../components/time-selector/TimeSelector";
|
||||
import { TimeSelectorControl } from "../../components/time-selector/TimeSelectorControl";
|
||||
|
||||
export const Time = ({
|
||||
name,
|
||||
|
@ -14,37 +11,16 @@ export const Time = ({
|
|||
style?: CSSProperties;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
control,
|
||||
formState: { errors },
|
||||
} = useFormContext();
|
||||
return (
|
||||
<FormGroup
|
||||
<TimeSelectorControl
|
||||
name={name}
|
||||
style={style}
|
||||
label={t(name)}
|
||||
fieldId={name}
|
||||
labelIcon={<HelpItem helpText={t(`${name}Help`)} fieldLabelId={name} />}
|
||||
validated={
|
||||
errors[name] ? ValidatedOptions.error : ValidatedOptions.default
|
||||
}
|
||||
helperTextInvalid={t("required")}
|
||||
>
|
||||
<Controller
|
||||
name={name}
|
||||
defaultValue=""
|
||||
control={control}
|
||||
rules={{ required: true }}
|
||||
render={({ field }) => (
|
||||
<TimeSelector
|
||||
data-testid={name}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
validated={
|
||||
errors[name] ? ValidatedOptions.error : ValidatedOptions.default
|
||||
}
|
||||
labelIcon={t(`${name}Help`)}
|
||||
controller={{
|
||||
defaultValue: "",
|
||||
rules: { required: t("required") },
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -3,14 +3,14 @@ import {
|
|||
FormGroupProps,
|
||||
ValidatedOptions,
|
||||
} from "@patternfly/react-core";
|
||||
import { PropsWithChildren } from "react";
|
||||
import { PropsWithChildren, ReactNode } from "react";
|
||||
import { FieldError, FieldValues, Merge } from "react-hook-form";
|
||||
import { HelpItem } from "./HelpItem";
|
||||
|
||||
export type FieldProps<T extends FieldValues = FieldValues> = {
|
||||
label?: string;
|
||||
name: string;
|
||||
labelIcon?: string;
|
||||
labelIcon?: string | ReactNode;
|
||||
error?: FieldError | Merge<FieldError, T>;
|
||||
isRequired: boolean;
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
|
||||
import { KeycloakTextInput } from "../keycloak-text-input/KeycloakTextInput";
|
||||
import { FormLabel } from "./FormLabel";
|
||||
import { ReactNode } from "react";
|
||||
|
||||
export type TextControlProps<
|
||||
T extends FieldValues,
|
||||
|
@ -16,7 +17,7 @@ export type TextControlProps<
|
|||
> = UseControllerProps<T, P> &
|
||||
Omit<TextInputProps, "name" | "isRequired" | "required"> & {
|
||||
label: string;
|
||||
labelIcon?: string;
|
||||
labelIcon?: string | ReactNode;
|
||||
isDisabled?: boolean;
|
||||
helperText?: string;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue