mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-10 15:32:05 -03:30
Moved PKCE Code Challenge Method to more prominent section (#39631)
fixes: #30227 Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
parent
4c1507f4ff
commit
59e99ed5d5
@ -1,16 +1,16 @@
|
||||
import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
|
||||
import { HelpItem, SelectControl } from "@keycloak/keycloak-ui-shared";
|
||||
import {
|
||||
Checkbox,
|
||||
FormGroup,
|
||||
Grid,
|
||||
GridItem,
|
||||
InputGroup,
|
||||
Switch,
|
||||
InputGroupItem,
|
||||
Switch,
|
||||
} from "@patternfly/react-core";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
||||
import { DefaultSwitchControl } from "../../components/SwitchControl";
|
||||
import { FormAccess } from "../../components/form/FormAccess";
|
||||
import { convertAttributeNameToForm } from "../../util";
|
||||
@ -338,6 +338,20 @@ export const CapabilityConfig = ({
|
||||
</GridItem>
|
||||
</Grid>
|
||||
</FormGroup>
|
||||
<SelectControl
|
||||
id="keyForCodeExchange"
|
||||
label={t("keyForCodeExchange")}
|
||||
labelIcon={t("keyForCodeExchangeHelp")}
|
||||
controller={{ defaultValue: "" }}
|
||||
name={convertAttributeNameToForm<FormFields>(
|
||||
"attributes.pkce.code.challenge.method",
|
||||
)}
|
||||
options={[
|
||||
{ key: "", value: t("choose") },
|
||||
{ key: "S256", value: "S256" },
|
||||
{ key: "plain", value: "plain" },
|
||||
]}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{protocol === "saml" && (
|
||||
|
||||
@ -1,14 +1,5 @@
|
||||
import { HelpItem, TextControl } from "@keycloak/keycloak-ui-shared";
|
||||
import {
|
||||
ActionGroup,
|
||||
Button,
|
||||
FormGroup,
|
||||
MenuToggle,
|
||||
Select,
|
||||
SelectList,
|
||||
SelectOption,
|
||||
} from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { ActionGroup, Button, FormGroup } from "@patternfly/react-core";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { DefaultSwitchControl } from "../../components/SwitchControl";
|
||||
@ -36,7 +27,6 @@ export const AdvancedSettings = ({
|
||||
hasConfigureAccess,
|
||||
}: AdvancedSettingsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const { realmRepresentation: realm } = useRealm();
|
||||
|
||||
@ -144,54 +134,6 @@ export const AdvancedSettings = ({
|
||||
stringify
|
||||
/>
|
||||
)}
|
||||
<FormGroup
|
||||
label={t("keyForCodeExchange")}
|
||||
fieldId="keyForCodeExchange"
|
||||
hasNoPaddingTop
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={t("keyForCodeExchangeHelp")}
|
||||
fieldLabelId="keyForCodeExchange"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Controller
|
||||
name={convertAttributeNameToForm<FormFields>(
|
||||
"attributes.pkce.code.challenge.method",
|
||||
)}
|
||||
defaultValue=""
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Select
|
||||
toggle={(ref) => (
|
||||
<MenuToggle
|
||||
id="keyForCodeExchange"
|
||||
ref={ref}
|
||||
onClick={() => setOpen(!open)}
|
||||
isExpanded={open}
|
||||
>
|
||||
{[field.value || t("choose")]}
|
||||
</MenuToggle>
|
||||
)}
|
||||
isOpen={open}
|
||||
onOpenChange={(isOpen) => setOpen(isOpen)}
|
||||
onSelect={(_, value) => {
|
||||
field.onChange(value);
|
||||
setOpen(false);
|
||||
}}
|
||||
selected={field.value}
|
||||
>
|
||||
<SelectList>
|
||||
{["", "S256", "plain"].map((v) => (
|
||||
<SelectOption key={v} value={v}>
|
||||
{v || t("choose")}
|
||||
</SelectOption>
|
||||
))}
|
||||
</SelectList>
|
||||
</Select>
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
<DefaultSwitchControl
|
||||
name={convertAttributeNameToForm<FormFields>(
|
||||
"attributes.require.pushed.authorization.requests",
|
||||
|
||||
@ -8,7 +8,6 @@ import {
|
||||
assertAccessTokenSignatureAlgorithm,
|
||||
assertAdvancedSwitchesOn,
|
||||
assertBrowserFlowInput,
|
||||
assertKeyForCodeExchangeInput,
|
||||
assertOnExcludeSessionStateSwitch,
|
||||
assertTestClusterAvailability,
|
||||
assertTokenLifespanClientOfflineSessionMaxVisible,
|
||||
@ -28,7 +27,6 @@ import {
|
||||
selectAccessTokenSignatureAlgorithm,
|
||||
selectBrowserFlowInput,
|
||||
selectDirectGrantInput,
|
||||
selectKeyForCodeExchangeInput,
|
||||
switchOffExcludeSessionStateSwitch,
|
||||
saveAuthFlowOverride,
|
||||
revertAuthFlowOverride,
|
||||
@ -83,15 +81,10 @@ test.describe("Advanced tab test", () => {
|
||||
|
||||
test("Advanced settings", async ({ page }) => {
|
||||
await clickAdvancedSwitches(page);
|
||||
await selectKeyForCodeExchangeInput(page, "S256");
|
||||
await saveAdvanced(page);
|
||||
await assertAdvancedSwitchesOn(page);
|
||||
await assertKeyForCodeExchangeInput(page, "S256");
|
||||
await selectKeyForCodeExchangeInput(page, "plain");
|
||||
await assertKeyForCodeExchangeInput(page, "plain");
|
||||
await clickAdvancedSwitches(page, false);
|
||||
await revertAdvanced(page);
|
||||
await assertKeyForCodeExchangeInput(page, "S256");
|
||||
await assertAdvancedSwitchesOn(page);
|
||||
});
|
||||
|
||||
|
||||
@ -125,18 +125,6 @@ export async function assertAdvancedSwitchesOn(page: Page) {
|
||||
).toBeChecked();
|
||||
}
|
||||
|
||||
function getKeyForCodeExchangeInput(page: Page) {
|
||||
return page.locator("#keyForCodeExchange");
|
||||
}
|
||||
|
||||
export async function selectKeyForCodeExchangeInput(page: Page, value: string) {
|
||||
await selectItem(page, getKeyForCodeExchangeInput(page), value);
|
||||
}
|
||||
|
||||
export async function assertKeyForCodeExchangeInput(page: Page, value: string) {
|
||||
await assertSelectValue(getKeyForCodeExchangeInput(page), value);
|
||||
}
|
||||
|
||||
export async function saveAdvanced(page: Page) {
|
||||
await page.getByTestId("OIDCAdvancedSave").click();
|
||||
}
|
||||
|
||||
@ -5,8 +5,12 @@ import { assertRequiredFieldError } from "../utils/form";
|
||||
import { login } from "../utils/login";
|
||||
import { assertNotificationMessage } from "../utils/masthead";
|
||||
import { goToClients, goToRealm } from "../utils/sidebar";
|
||||
import { searchItem } from "../utils/table";
|
||||
import { clickTableRowItem, searchItem } from "../utils/table";
|
||||
import { continueNext, createClient, save } from "./utils";
|
||||
import {
|
||||
assertKeyForCodeExchangeInput,
|
||||
selectKeyForCodeExchangeInput,
|
||||
} from "./details";
|
||||
|
||||
test.describe("Clients details test", () => {
|
||||
const realmName = `clients-details-realm-${uuid()}`;
|
||||
@ -61,4 +65,12 @@ test.describe("Clients details test", () => {
|
||||
|
||||
await assertNotificationMessage(page, "Client created successfully");
|
||||
});
|
||||
|
||||
test("Should be able to update a client", async ({ page }) => {
|
||||
await clickTableRowItem(page, clientId);
|
||||
await selectKeyForCodeExchangeInput(page, "S256");
|
||||
await save(page);
|
||||
await assertNotificationMessage(page, "Client successfully updated");
|
||||
await assertKeyForCodeExchangeInput(page, "S256");
|
||||
});
|
||||
});
|
||||
|
||||
14
js/apps/admin-ui/test/clients/details.ts
Normal file
14
js/apps/admin-ui/test/clients/details.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Page } from "@playwright/test";
|
||||
import { selectItem, assertSelectValue } from "../utils/form";
|
||||
|
||||
function getKeyForCodeExchangeInput(page: Page) {
|
||||
return page.locator("#keyForCodeExchange");
|
||||
}
|
||||
|
||||
export async function selectKeyForCodeExchangeInput(page: Page, value: string) {
|
||||
await selectItem(page, getKeyForCodeExchangeInput(page), value);
|
||||
}
|
||||
|
||||
export async function assertKeyForCodeExchangeInput(page: Page, value: string) {
|
||||
await assertSelectValue(getKeyForCodeExchangeInput(page), value);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user