fixes issue (#663)
* fixes issue fixes: #636 * fixed display order * more fixes * fix reseet and sync default value * fixed types * fixed? * fixed titles * fixed default id * fixed redirect url for oidc * fixed more issues * revert "none" option on sync mode * updated text to use "None" * fixed tests
This commit is contained in:
parent
1f1fa7681e
commit
1a9618edff
21 changed files with 195 additions and 83 deletions
|
@ -45,7 +45,7 @@ export default class CreateProviderPage {
|
|||
}
|
||||
|
||||
clickCreateDropdown() {
|
||||
cy.contains('Add provider').click();
|
||||
cy.contains("Add provider").click();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,8 @@ export default class CreateProviderPage {
|
|||
}
|
||||
|
||||
fillDiscoveryUrl(value: string) {
|
||||
cy.getId(this.discoveryEndpoint).type(value).blur();
|
||||
cy.getId(this.discoveryEndpoint).type("x");
|
||||
cy.getId(this.discoveryEndpoint).clear().type(value).blur();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ export const AdvancedTab = ({
|
|||
if (date > 0) {
|
||||
return moment(date * 1000).format("LLL");
|
||||
} else {
|
||||
return t("none");
|
||||
return t("common:none");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -83,10 +83,10 @@ export const FineGrainOpenIdConnect = ({
|
|||
|
||||
const requestObjectOptions = [
|
||||
<SelectOption key="any" value="any">
|
||||
{t("any")}
|
||||
{t("common:any")}
|
||||
</SelectOption>,
|
||||
<SelectOption key="none" value="none">
|
||||
{t("none")}
|
||||
{t("common:none")}
|
||||
</SelectOption>,
|
||||
...sortProviders(clientSignatureProviders!).map((p) => (
|
||||
<SelectOption key={p} value={p} />
|
||||
|
|
|
@ -164,8 +164,6 @@
|
|||
"addNode": "Add node",
|
||||
"push": "Push",
|
||||
"clear": "Clear",
|
||||
"none": "None",
|
||||
"any": "Any",
|
||||
"nodeReRegistrationTimeout": "Node Re-registration timeout",
|
||||
"registeredClusterNodes": "Registered cluster nodes",
|
||||
"nodeHost": "Node host",
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
"disable": "Disable",
|
||||
"selectOne": "Select an option",
|
||||
"choose": "Choose...",
|
||||
"any": "Any",
|
||||
"none": "None",
|
||||
"signOut": "Sign out",
|
||||
"manageAccount": "Manage account",
|
||||
"serverInfo": "Server info",
|
||||
|
|
|
@ -136,7 +136,7 @@ export const IdentityProvidersSection = () => {
|
|||
{manageDisplayDialog && (
|
||||
<ManageOderDialog
|
||||
onClose={() => setManageDisplayDialog(false)}
|
||||
providers={providers!}
|
||||
providers={providers?.filter((p) => p.enabled)}
|
||||
/>
|
||||
)}
|
||||
<ViewHeader
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
PageSection,
|
||||
} from "@patternfly/react-core";
|
||||
|
||||
import type { BreadcrumbData } from "use-react-router-breadcrumbs";
|
||||
import type IdentityProviderRepresentation from "keycloak-admin/lib/defs/identityProviderRepresentation";
|
||||
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
||||
import { toUpperCase } from "../../util";
|
||||
|
@ -18,6 +19,29 @@ import { useRealm } from "../../context/realm-context/RealmContext";
|
|||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
import { GeneralSettings } from "./GeneralSettings";
|
||||
|
||||
export const IdentityProviderCrumb = ({ match, location }: BreadcrumbData) => {
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
params: { id },
|
||||
} = (match as unknown) as {
|
||||
params: { [id: string]: string };
|
||||
};
|
||||
return (
|
||||
<>
|
||||
{t(
|
||||
`identity-providers:${
|
||||
location.pathname.endsWith("settings")
|
||||
? "provider"
|
||||
: "addIdentityProvider"
|
||||
}`,
|
||||
{
|
||||
provider: toUpperCase(id),
|
||||
}
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const AddIdentityProvider = () => {
|
||||
const { t } = useTranslation("identity-providers");
|
||||
const { id } = useParams<{ id: string }>();
|
||||
|
@ -42,7 +66,12 @@ export const AddIdentityProvider = () => {
|
|||
addAlert(t("createSuccess"), AlertVariant.success);
|
||||
history.push(`/${realm}/identity-providers/${id}/settings`);
|
||||
} catch (error) {
|
||||
addAlert(t("createError", { error }), AlertVariant.danger);
|
||||
addAlert(
|
||||
t("createError", {
|
||||
error: error.response?.data?.errorMessage || error,
|
||||
}),
|
||||
AlertVariant.danger
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -58,7 +87,7 @@ export const AddIdentityProvider = () => {
|
|||
onSubmit={handleSubmit(save)}
|
||||
>
|
||||
<FormProvider {...form}>
|
||||
<GeneralSettings />
|
||||
<GeneralSettings id={id} />
|
||||
</FormProvider>
|
||||
<ActionGroup>
|
||||
<Button
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { useHistory, useRouteMatch } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FormProvider, useForm } from "react-hook-form";
|
||||
import {
|
||||
|
@ -19,10 +19,16 @@ import { useRealm } from "../../context/realm-context/RealmContext";
|
|||
import { OIDCAuthentication } from "./OIDCAuthentication";
|
||||
import { useAlerts } from "../../components/alert/Alerts";
|
||||
|
||||
type DiscoveryIdentity = IdentityProviderRepresentation & {
|
||||
discoveryEndpoint?: string;
|
||||
};
|
||||
|
||||
export const AddOpenIdConnect = () => {
|
||||
const { t } = useTranslation("identity-providers");
|
||||
const history = useHistory();
|
||||
const id = "oidc";
|
||||
const { url } = useRouteMatch();
|
||||
const isKeycloak = url.endsWith("keycloak-oidc");
|
||||
const id = `${isKeycloak ? "keycloak-" : ""}oidc`;
|
||||
|
||||
const form = useForm<IdentityProviderRepresentation>({
|
||||
defaultValues: { alias: id },
|
||||
|
@ -36,7 +42,8 @@ export const AddOpenIdConnect = () => {
|
|||
const { addAlert } = useAlerts();
|
||||
const { realm } = useRealm();
|
||||
|
||||
const save = async (provider: IdentityProviderRepresentation) => {
|
||||
const save = async (provider: DiscoveryIdentity) => {
|
||||
delete provider.discoveryEndpoint;
|
||||
try {
|
||||
await adminClient.identityProviders.create({
|
||||
...provider,
|
||||
|
@ -45,13 +52,22 @@ export const AddOpenIdConnect = () => {
|
|||
addAlert(t("createSuccess"), AlertVariant.success);
|
||||
history.push(`/${realm}/identity-providers/${id}/settings`);
|
||||
} catch (error) {
|
||||
addAlert(t("createError", { error }), AlertVariant.danger);
|
||||
addAlert(
|
||||
t("createError", {
|
||||
error: error.response?.data?.errorMessage || error,
|
||||
}),
|
||||
AlertVariant.danger
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewHeader titleKey={t("addOpenIdProvider")} />
|
||||
<ViewHeader
|
||||
titleKey={t(
|
||||
isKeycloak ? "addKeycloakOpenIdProvider" : "addOpenIdProvider"
|
||||
)}
|
||||
/>
|
||||
<PageSection variant="light">
|
||||
<FormProvider {...form}>
|
||||
<FormAccess
|
||||
|
@ -59,7 +75,7 @@ export const AddOpenIdConnect = () => {
|
|||
isHorizontal
|
||||
onSubmit={handleSubmit(save)}
|
||||
>
|
||||
<OIDCGeneralSettings />
|
||||
<OIDCGeneralSettings id={id} />
|
||||
<OpenIdConnectSettings />
|
||||
<OIDCAuthentication />
|
||||
<ActionGroup>
|
||||
|
|
|
@ -2,8 +2,6 @@ import React, { useState } from "react";
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import {
|
||||
ActionGroup,
|
||||
Button,
|
||||
FormGroup,
|
||||
Select,
|
||||
SelectOption,
|
||||
|
@ -29,7 +27,12 @@ const LoginFlow = ({
|
|||
const [flows, setFlows] = useState<AuthenticationFlowRepresentation[]>();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
useFetch(() => adminClient.authenticationManagement.getFlows(), setFlows, []);
|
||||
useFetch(
|
||||
() => adminClient.authenticationManagement.getFlows(),
|
||||
(flows) =>
|
||||
setFlows(flows?.filter((flow) => flow.providerId === "basic-flow")),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<FormGroup
|
||||
|
@ -56,21 +59,30 @@ const LoginFlow = ({
|
|||
onChange(value as string);
|
||||
setOpen(false);
|
||||
}}
|
||||
selections={value}
|
||||
selections={value || t("common:none")}
|
||||
variant={SelectVariant.single}
|
||||
aria-label={t(label)}
|
||||
isOpen={open}
|
||||
>
|
||||
{flows &&
|
||||
flows.map((option) => (
|
||||
<SelectOption
|
||||
selected={option.alias === value}
|
||||
key={option.id}
|
||||
value={option.alias}
|
||||
>
|
||||
{option.alias}
|
||||
<>
|
||||
{defaultValue === "" && (
|
||||
<SelectOption key="empty" value={defaultValue}>
|
||||
{t("common:none")}
|
||||
</SelectOption>
|
||||
))}
|
||||
)}
|
||||
</>
|
||||
<>
|
||||
{flows &&
|
||||
flows.map((option) => (
|
||||
<SelectOption
|
||||
selected={option.alias === value}
|
||||
key={option.id}
|
||||
value={option.alias}
|
||||
>
|
||||
{option.alias}
|
||||
</SelectOption>
|
||||
))}
|
||||
</>
|
||||
</Select>
|
||||
)}
|
||||
/>
|
||||
|
@ -159,15 +171,6 @@ export const AdvancedSettings = ({ isOIDC }: { isOIDC: boolean }) => {
|
|||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<ActionGroup className="keycloak__form_actions">
|
||||
<Button data-testid={"save"} variant="tertiary" type="submit">
|
||||
{t("common:save")}
|
||||
</Button>
|
||||
<Button data-testid={"revert"} variant="link" onClick={() => {}}>
|
||||
{t("common:revert")}
|
||||
</Button>
|
||||
</ActionGroup>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import { useHistory, useParams } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, FormProvider, useForm } from "react-hook-form";
|
||||
import {
|
||||
ActionGroup,
|
||||
AlertVariant,
|
||||
Button,
|
||||
ButtonVariant,
|
||||
Divider,
|
||||
DropdownItem,
|
||||
|
@ -55,7 +57,7 @@ const Header = ({ onChange, value, save, toggleDeleteDialog }: HeaderProps) => {
|
|||
<>
|
||||
<DisableConfirm />
|
||||
<ViewHeader
|
||||
titleKey={t("addIdentityProvider", { provider: toUpperCase(id) })}
|
||||
titleKey={toUpperCase(id)}
|
||||
divider={false}
|
||||
dropdownItems={[
|
||||
<DropdownItem key="delete" onClick={() => toggleDeleteDialog()}>
|
||||
|
@ -80,8 +82,9 @@ export const DetailSettings = () => {
|
|||
const { t } = useTranslation("identity-providers");
|
||||
const { id } = useParams<{ id: string }>();
|
||||
|
||||
const [provider, setProvider] = useState<IdentityProviderRepresentation>();
|
||||
const form = useForm<IdentityProviderRepresentation>();
|
||||
const { handleSubmit, setValue, getValues } = form;
|
||||
const { handleSubmit, setValue, getValues, reset } = form;
|
||||
|
||||
const adminClient = useAdminClient();
|
||||
const { addAlert } = useAlerts();
|
||||
|
@ -91,7 +94,10 @@ export const DetailSettings = () => {
|
|||
useFetch(
|
||||
() => adminClient.identityProviders.findOne({ alias: id }),
|
||||
(provider) => {
|
||||
Object.entries(provider).map((entry) => setValue(entry[0], entry[1]));
|
||||
if (provider) {
|
||||
setProvider(provider);
|
||||
Object.entries(provider).map((entry) => setValue(entry[0], entry[1]));
|
||||
}
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
@ -103,6 +109,7 @@ export const DetailSettings = () => {
|
|||
{ alias: id },
|
||||
{ ...p, alias: id, providerId: id }
|
||||
);
|
||||
setProvider(p);
|
||||
addAlert(t("updateSuccess"), AlertVariant.success);
|
||||
} catch (error) {
|
||||
addAlert(
|
||||
|
@ -131,7 +138,7 @@ export const DetailSettings = () => {
|
|||
});
|
||||
|
||||
const sections = [t("generalSettings"), t("advancedSettings")];
|
||||
const isOIDC = id === "oidc";
|
||||
const isOIDC = id.indexOf("oidc") !== -1;
|
||||
|
||||
if (isOIDC) {
|
||||
sections.splice(1, 0, t("oidcSettings"));
|
||||
|
@ -168,15 +175,15 @@ export const DetailSettings = () => {
|
|||
isHorizontal
|
||||
onSubmit={handleSubmit(save)}
|
||||
>
|
||||
{!isOIDC && <GeneralSettings />}
|
||||
{isOIDC && <OIDCGeneralSettings />}
|
||||
{!isOIDC && <GeneralSettings create={false} id={id} />}
|
||||
{isOIDC && <OIDCGeneralSettings id={id} />}
|
||||
</FormAccess>
|
||||
{isOIDC && (
|
||||
<>
|
||||
<DiscoverySettings readOnly={false} />
|
||||
<Form isHorizontal className="pf-u-py-lg">
|
||||
<Divider />
|
||||
<OIDCAuthentication />
|
||||
<OIDCAuthentication create={false} />
|
||||
</Form>
|
||||
<ExtendedNonDiscoverySettings />
|
||||
</>
|
||||
|
@ -187,6 +194,20 @@ export const DetailSettings = () => {
|
|||
onSubmit={handleSubmit(save)}
|
||||
>
|
||||
<AdvancedSettings isOIDC={isOIDC} />
|
||||
<ActionGroup className="keycloak__form_actions">
|
||||
<Button data-testid={"save"} type="submit">
|
||||
{t("common:save")}
|
||||
</Button>
|
||||
<Button
|
||||
data-testid={"revert"}
|
||||
variant="link"
|
||||
onClick={() => {
|
||||
reset(provider);
|
||||
}}
|
||||
>
|
||||
{t("common:revert")}
|
||||
</Button>
|
||||
</ActionGroup>
|
||||
</FormAccess>
|
||||
</ScrollForm>
|
||||
</Tab>
|
||||
|
|
|
@ -136,7 +136,6 @@ export const DiscoverySettings = ({ readOnly }: DiscoverySettingsProps) => {
|
|||
</ExpandableSection>
|
||||
)}
|
||||
{!readOnly && <Fields readOnly={readOnly} />}
|
||||
<Divider />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -4,10 +4,18 @@ import { RedirectUrl } from "../component/RedirectUrl";
|
|||
import { ClientIdSecret } from "../component/ClientIdSecret";
|
||||
import { DisplayOrder } from "../component/DisplayOrder";
|
||||
|
||||
export const GeneralSettings = () => (
|
||||
type GeneralSettingsProps = {
|
||||
id: string;
|
||||
create?: boolean;
|
||||
};
|
||||
|
||||
export const GeneralSettings = ({
|
||||
create = true,
|
||||
id,
|
||||
}: GeneralSettingsProps) => (
|
||||
<>
|
||||
<RedirectUrl />
|
||||
<ClientIdSecret />
|
||||
<RedirectUrl id={id} />
|
||||
<ClientIdSecret create={create} />
|
||||
<DisplayOrder />
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -18,7 +18,7 @@ const clientAuthenticationTypes = [
|
|||
"clientAuth_privatekey_jwt",
|
||||
];
|
||||
|
||||
export const OIDCAuthentication = () => {
|
||||
export const OIDCAuthentication = ({ create = true }: { create?: boolean }) => {
|
||||
const { t } = useTranslation("identity-providers");
|
||||
const { t: th } = useTranslation("identity-providers-help");
|
||||
|
||||
|
@ -76,6 +76,7 @@ export const OIDCAuthentication = () => {
|
|||
</FormGroup>
|
||||
<ClientIdSecret
|
||||
secretRequired={clientAuthMethod !== "clientAuth_privatekey_jwt"}
|
||||
create={create}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -8,7 +8,7 @@ import { RedirectUrl } from "../component/RedirectUrl";
|
|||
import { TextField } from "../component/TextField";
|
||||
import { DisplayOrder } from "../component/DisplayOrder";
|
||||
|
||||
export const OIDCGeneralSettings = () => {
|
||||
export const OIDCGeneralSettings = ({ id }: { id: string }) => {
|
||||
const { t } = useTranslation("identity-providers");
|
||||
const { t: th } = useTranslation("identity-providers-help");
|
||||
|
||||
|
@ -16,7 +16,7 @@ export const OIDCGeneralSettings = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<RedirectUrl />
|
||||
<RedirectUrl id={id} />
|
||||
|
||||
<FormGroup
|
||||
label={t("alias")}
|
||||
|
@ -30,7 +30,7 @@ export const OIDCGeneralSettings = () => {
|
|||
fieldId="alias"
|
||||
isRequired
|
||||
validated={
|
||||
errors.errors ? ValidatedOptions.error : ValidatedOptions.default
|
||||
errors.alias ? ValidatedOptions.error : ValidatedOptions.default
|
||||
}
|
||||
helperTextInvalid={t("common:required")}
|
||||
>
|
||||
|
@ -40,6 +40,9 @@ export const OIDCGeneralSettings = () => {
|
|||
id="alias"
|
||||
data-testid="alias"
|
||||
name="alias"
|
||||
validated={
|
||||
errors.alias ? ValidatedOptions.error : ValidatedOptions.default
|
||||
}
|
||||
ref={register({ required: true })}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
|
|
@ -21,7 +21,7 @@ export const OpenIdConnectSettings = () => {
|
|||
|
||||
const adminClient = useAdminClient();
|
||||
const { realm } = useRealm();
|
||||
const { setValue } = useFormContext();
|
||||
const { setValue, register, errors } = useFormContext();
|
||||
|
||||
const [discovery, setDiscovery] = useState(true);
|
||||
const [discoveryUrl, setDiscoveryUrl] = useState("");
|
||||
|
@ -117,17 +117,23 @@ export const OpenIdConnectSettings = () => {
|
|||
/>
|
||||
}
|
||||
validated={
|
||||
discoveryResult && discoveryResult.error
|
||||
(discoveryResult && discoveryResult.error) ||
|
||||
errors.discoveryEndpoint
|
||||
? "error"
|
||||
: !discoveryResult
|
||||
? "default"
|
||||
: "success"
|
||||
}
|
||||
helperTextInvalid={t("noValidMetaDataFound")}
|
||||
helperTextInvalid={
|
||||
errors.discoveryEndpoint
|
||||
? t("common:required")
|
||||
: t("noValidMetaDataFound")
|
||||
}
|
||||
isRequired
|
||||
>
|
||||
<TextInput
|
||||
type="text"
|
||||
name="discoveryEndpoint"
|
||||
data-testid="discoveryEndpoint"
|
||||
id="kc-discovery-endpoint"
|
||||
placeholder="https://hostname/.well-known/openid-configuration"
|
||||
|
@ -135,7 +141,8 @@ export const OpenIdConnectSettings = () => {
|
|||
onChange={setDiscoveryUrl}
|
||||
onBlur={() => setDiscovering(!discovering)}
|
||||
validated={
|
||||
discoveryResult && discoveryResult.error
|
||||
(discoveryResult && discoveryResult.error) ||
|
||||
errors.discoveryEndpoint
|
||||
? "error"
|
||||
: !discoveryResult
|
||||
? "default"
|
||||
|
@ -146,6 +153,7 @@ export const OpenIdConnectSettings = () => {
|
|||
? 'data:image/svg+xml;charset=utf8,%3Csvg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"%3E%3Ccircle cx="50" cy="50" fill="none" stroke="%230066cc" stroke-width="10" r="35" stroke-dasharray="164.93361431346415 56.97787143782138"%3E%3CanimateTransform attributeName="transform" type="rotate" repeatCount="indefinite" dur="1s" values="0 50 50;360 50 50" keyTimes="0;1"%3E%3C/animateTransform%3E%3C/circle%3E%3C/svg%3E'
|
||||
: ""
|
||||
}
|
||||
ref={register({ required: true })}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
|
|
|
@ -4,11 +4,14 @@ import { useFormContext } from "react-hook-form";
|
|||
import { FormGroup, TextInput, ValidatedOptions } from "@patternfly/react-core";
|
||||
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
import { PasswordInput } from "../../components/password-input/PasswordInput";
|
||||
|
||||
export const ClientIdSecret = ({
|
||||
secretRequired = true,
|
||||
create = true,
|
||||
}: {
|
||||
secretRequired?: boolean;
|
||||
create?: boolean;
|
||||
}) => {
|
||||
const { t } = useTranslation("identity-providers");
|
||||
const { t: th } = useTranslation("identity-providers-help");
|
||||
|
@ -62,14 +65,25 @@ export const ClientIdSecret = ({
|
|||
}
|
||||
helperTextInvalid={t("common:required")}
|
||||
>
|
||||
<TextInput
|
||||
isRequired={secretRequired}
|
||||
type="password"
|
||||
id="kc-client-secret"
|
||||
data-testid="clientSecret"
|
||||
name="config.clientSecret"
|
||||
ref={register({ required: secretRequired })}
|
||||
/>
|
||||
{create && (
|
||||
<PasswordInput
|
||||
isRequired={secretRequired}
|
||||
id="kc-client-secret"
|
||||
data-testid="clientSecret"
|
||||
name="config.clientSecret"
|
||||
ref={register({ required: secretRequired })}
|
||||
/>
|
||||
)}
|
||||
{!create && (
|
||||
<TextInput
|
||||
isRequired={secretRequired}
|
||||
type="password"
|
||||
id="kc-client-secret"
|
||||
data-testid="clientSecret"
|
||||
name="config.clientSecret"
|
||||
ref={register({ required: secretRequired })}
|
||||
/>
|
||||
)}
|
||||
</FormGroup>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -31,9 +31,10 @@ export const DisplayOrder = () => {
|
|||
<NumberInput
|
||||
value={value}
|
||||
data-testid="displayOrder"
|
||||
onMinus={() => onChange(value - 1)}
|
||||
min={0}
|
||||
onMinus={() => onChange(Number.parseInt(value) - 1)}
|
||||
onChange={onChange}
|
||||
onPlus={() => onChange(value + 1)}
|
||||
onPlus={() => onChange(Number.parseInt(value) + 1)}
|
||||
inputName="input"
|
||||
inputAriaLabel={t("displayOrder")}
|
||||
minusBtnAriaLabel={t("common:minus")}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import React from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ClipboardCopy, FormGroup } from "@patternfly/react-core";
|
||||
|
||||
|
@ -8,14 +7,13 @@ import { HelpItem } from "../../components/help-enabler/HelpItem";
|
|||
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||
import { useAdminClient } from "../../context/auth/AdminClient";
|
||||
|
||||
export const RedirectUrl = () => {
|
||||
export const RedirectUrl = ({ id }: { id: string }) => {
|
||||
const { t } = useTranslation("identity-providers");
|
||||
const { t: th } = useTranslation("identity-providers-help");
|
||||
const { id } = useParams<{ id: string }>();
|
||||
|
||||
const adminClient = useAdminClient();
|
||||
const { realm } = useRealm();
|
||||
const callbackUrl = `${getBaseUrl(adminClient)}/realms/${realm}/broker`;
|
||||
const callbackUrl = `${getBaseUrl(adminClient)}realms/${realm}/broker`;
|
||||
|
||||
return (
|
||||
<FormGroup
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"displayName": "Friendly name for Identity Providers.",
|
||||
"clientId": "The client identifier registered with the identity provider.",
|
||||
"clientSecret": "The client secret registered with the identity provider. This field is able to obtain its value from vault, use ${vault.ID} format.",
|
||||
"displayOrder": "Number defining order of the provider in GUI (for example, on Login page).",
|
||||
"displayOrder": "Number defining the order of the providers in GUI (for example, on the Login page). The lowest number will be applied first.",
|
||||
"useDiscoveryEndpoint": "If this setting is enabled, the discovery endpoint will be used to fetch the provider config. Keycloak can load the config from the endpoint and automatically update the config if the source has any updates",
|
||||
"discoveryEndpoint": "Import metadata from a remote IDP discovery descriptor.",
|
||||
"importConfig": "Import metadata from a downloaded IDP discovery descriptor.",
|
||||
|
@ -30,7 +30,7 @@
|
|||
"accountLinkingOnly": "If true, users cannot log in through this provider. They can only link to this provider. This is useful if you don't want to allow login from the provider, but want to integrate with a provider",
|
||||
"hideOnLoginPage": "If hidden, login with this provider is possible only if requested explicitly, for example using the 'kc_idp_hint' parameter.",
|
||||
"firstBrokerLoginFlowAlias": "Alias of authentication flow, which is triggered after first login with this identity provider. Term 'First Login' means that no Keycloak account is currently linked to the authenticated identity provider account.",
|
||||
"postBrokerLoginFlowAlias": "Alias of authentication flow, which is triggered after each login with this identity provider. Useful if you want additional verification of each user authenticated with this identity provider (for example OTP). Leave this empty if you need no any additional authenticators to be triggered after login with this identity provider. Also note that authenticator implementations must assume that user is already set in ClientSession as identity provider already set it.",
|
||||
"postBrokerLoginFlowAlias": "Alias of authentication flow, which is triggered after each login with this identity provider. Useful if you want additional verification of each user authenticated with this identity provider (for example OTP). Leave this to \"None\" if you need no any additional authenticators to be triggered after login with this identity provider. Also note that authenticator implementations must assume that user is already set in ClientSession as identity provider already set it.",
|
||||
"syncMode": "Default sync mode for all mappers. The sync mode determines when user data will be synced using the mappers. Possible values are: 'legacy' to keep the behaviour before this option was introduced, 'import' to only import the user once during first login of the user with this identity provider, 'force' to always update the user during every login with this identity provider."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
"identity-providers": {
|
||||
"listExplain": "Through Identity Brokering it's easy to allow users to authenticate to Keycloak using external Identity Provider or Social Networks.",
|
||||
"searchForProvider": "Search for provider",
|
||||
"provider": "Provider",
|
||||
"provider": "Provider details",
|
||||
"addProvider": "Add provider",
|
||||
"addOpenIdProvider": "Add OpenId Connect provider",
|
||||
"addKeycloakOpenIdProvider": "Add Keycloak OpenID Connect provider",
|
||||
"addOpenIdProvider": "Add OpenID Connect provider",
|
||||
"manageDisplayOrder": "Manage display order",
|
||||
"deleteProvider": "Delete provider?",
|
||||
"deleteConfirm": "Are you sure you want to permanently delete the provider '{{provider}}'",
|
||||
|
@ -23,7 +24,7 @@
|
|||
"clientSecret": "Client Secret",
|
||||
"displayOrder": "Display order",
|
||||
"createSuccess": "Identity provider successfully created",
|
||||
"createError": "Could not create the identity provider provider {{error}}",
|
||||
"createError": "Could not create the identity provider: {{error}}",
|
||||
"oderDialogIntro": "The order that the providers are listed in the login page or the account console. You can drag the row handles to change the order.",
|
||||
"manageOrderTableAria": "List of identity providers in the order listed on the login page",
|
||||
"manageOrderItemAria": "Press space or enter to begin dragging, and use the arrow keys to navigate up or down. Press enter to confirm the drag, or any other key to cancel the drag operation.",
|
||||
|
@ -52,7 +53,7 @@
|
|||
"disableUserInfo": "Disable user info",
|
||||
"userInfoUrl": "User Info URL",
|
||||
"issuer": "Issuer",
|
||||
"scopes": "Default scopes",
|
||||
"scopes": "Scopes",
|
||||
"prompt": "Prompt",
|
||||
"prompts": {
|
||||
"unspecified": "Unspecified",
|
||||
|
|
|
@ -30,7 +30,10 @@ import { RealmRoleTabs } from "./realm-roles/RealmRoleTabs";
|
|||
import { SearchGroups } from "./groups/SearchGroups";
|
||||
import { CreateInitialAccessToken } from "./clients/initial-access/CreateInitialAccessToken";
|
||||
import { LdapMapperDetails } from "./user-federation/ldap/mappers/LdapMapperDetails";
|
||||
import { AddIdentityProvider } from "./identity-providers/add/AddIdentityProvider";
|
||||
import {
|
||||
AddIdentityProvider,
|
||||
IdentityProviderCrumb,
|
||||
} from "./identity-providers/add/AddIdentityProvider";
|
||||
import { AddOpenIdConnect } from "./identity-providers/add/AddOpenIdConnect";
|
||||
import { DetailSettings } from "./identity-providers/add/DetailSettings";
|
||||
|
||||
|
@ -199,13 +202,19 @@ export const routes: RoutesFn = (t: TFunction) => [
|
|||
access: "manage-identity-providers",
|
||||
},
|
||||
{
|
||||
path: "/:realm/identity-providers/:id",
|
||||
component: AddIdentityProvider,
|
||||
breadcrumb: t("identity-providers:provider"),
|
||||
path: "/:realm/identity-providers/keycloak-oidc",
|
||||
component: AddOpenIdConnect,
|
||||
breadcrumb: t("identity-providers:addKeycloakOpenIdProvider"),
|
||||
access: "manage-identity-providers",
|
||||
},
|
||||
{
|
||||
path: "/:realm/identity-providers/:id/settings",
|
||||
path: "/:realm/identity-providers/:id",
|
||||
component: AddIdentityProvider,
|
||||
breadcrumb: IdentityProviderCrumb,
|
||||
access: "manage-identity-providers",
|
||||
},
|
||||
{
|
||||
path: "/:realm/identity-providers/:id/:tab?",
|
||||
component: DetailSettings,
|
||||
breadcrumb: null,
|
||||
access: "manage-identity-providers",
|
||||
|
|
Loading…
Reference in a new issue