Added missing logic to realm form (#80)
* made alerts easier to use * better clear message * added missing logic to realm form * format * fixed types * fixed test * fix merge error
This commit is contained in:
parent
782a09e064
commit
3798c41db0
13 changed files with 584 additions and 56 deletions
|
@ -10,12 +10,14 @@ import {
|
||||||
import { RealmSelector } from "./components/realm-selector/RealmSelector";
|
import { RealmSelector } from "./components/realm-selector/RealmSelector";
|
||||||
import { DataLoader } from "./components/data-loader/DataLoader";
|
import { DataLoader } from "./components/data-loader/DataLoader";
|
||||||
import { HttpClientContext } from "./http-service/HttpClientContext";
|
import { HttpClientContext } from "./http-service/HttpClientContext";
|
||||||
import { Realm } from "./realm/models/Realm";
|
import { RealmRepresentation } from "./realm/models/Realm";
|
||||||
|
|
||||||
export const PageNav: React.FunctionComponent = () => {
|
export const PageNav: React.FunctionComponent = () => {
|
||||||
const httpClient = useContext(HttpClientContext)!;
|
const httpClient = useContext(HttpClientContext)!;
|
||||||
const realmLoader = async () => {
|
const realmLoader = async () => {
|
||||||
const response = await httpClient.doGet<Realm[]>("/admin/realms");
|
const response = await httpClient.doGet<RealmRepresentation[]>(
|
||||||
|
"/admin/realms"
|
||||||
|
);
|
||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ import FileSaver from "file-saver";
|
||||||
import { ExternalLink } from "../components/external-link/ExternalLink";
|
import { ExternalLink } from "../components/external-link/ExternalLink";
|
||||||
import { HttpClientContext } from "../http-service/HttpClientContext";
|
import { HttpClientContext } from "../http-service/HttpClientContext";
|
||||||
import { useAlerts } from "../components/alert/Alerts";
|
import { useAlerts } from "../components/alert/Alerts";
|
||||||
import { AlertPanel } from "../components/alert/AlertPanel";
|
|
||||||
import { ClientRepresentation } from "./models/client-model";
|
import { ClientRepresentation } from "./models/client-model";
|
||||||
|
|
||||||
type ClientListProps = {
|
type ClientListProps = {
|
||||||
|
@ -32,7 +31,7 @@ const columns: (keyof ClientRepresentation)[] = [
|
||||||
export const ClientList = ({ baseUrl, clients }: ClientListProps) => {
|
export const ClientList = ({ baseUrl, clients }: ClientListProps) => {
|
||||||
const { t } = useTranslation("clients");
|
const { t } = useTranslation("clients");
|
||||||
const httpClient = useContext(HttpClientContext)!;
|
const httpClient = useContext(HttpClientContext)!;
|
||||||
const [add, alerts, hide] = useAlerts();
|
const [add, Alerts] = useAlerts();
|
||||||
|
|
||||||
const convertClientId = (clientId: string) =>
|
const convertClientId = (clientId: string) =>
|
||||||
clientId.substring(0, clientId.indexOf("#"));
|
clientId.substring(0, clientId.indexOf("#"));
|
||||||
|
@ -77,7 +76,7 @@ export const ClientList = ({ baseUrl, clients }: ClientListProps) => {
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<AlertPanel alerts={alerts} onCloseAlert={hide} />
|
<Alerts />
|
||||||
<Table
|
<Table
|
||||||
variant={TableVariant.compact}
|
variant={TableVariant.compact}
|
||||||
cells={[
|
cells={[
|
||||||
|
|
|
@ -11,7 +11,6 @@ import { HttpClientContext } from "../../http-service/HttpClientContext";
|
||||||
import { Step1 } from "./Step1";
|
import { Step1 } from "./Step1";
|
||||||
import { Step2 } from "./Step2";
|
import { Step2 } from "./Step2";
|
||||||
import { ClientRepresentation } from "../models/client-model";
|
import { ClientRepresentation } from "../models/client-model";
|
||||||
import { AlertPanel } from "../../components/alert/AlertPanel";
|
|
||||||
import { useAlerts } from "../../components/alert/Alerts";
|
import { useAlerts } from "../../components/alert/Alerts";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
@ -26,7 +25,7 @@ export const NewClientForm = () => {
|
||||||
publicClient: false,
|
publicClient: false,
|
||||||
authorizationServicesEnabled: false,
|
authorizationServicesEnabled: false,
|
||||||
});
|
});
|
||||||
const [add, alerts, hide] = useAlerts();
|
const [add, Alerts] = useAlerts();
|
||||||
|
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
try {
|
try {
|
||||||
|
@ -53,7 +52,7 @@ export const NewClientForm = () => {
|
||||||
const title = t("Create client");
|
const title = t("Create client");
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<AlertPanel alerts={alerts} onCloseAlert={hide} />
|
<Alerts />
|
||||||
<PageSection variant="light">
|
<PageSection variant="light">
|
||||||
<TextContent>
|
<TextContent>
|
||||||
<Text component="h1">{title}</Text>
|
<Text component="h1">{title}</Text>
|
||||||
|
|
|
@ -18,13 +18,12 @@ import { ClientDescription } from "../ClientDescription";
|
||||||
import { HttpClientContext } from "../../http-service/HttpClientContext";
|
import { HttpClientContext } from "../../http-service/HttpClientContext";
|
||||||
import { JsonFileUpload } from "../../components/json-file-upload/JsonFileUpload";
|
import { JsonFileUpload } from "../../components/json-file-upload/JsonFileUpload";
|
||||||
import { useAlerts } from "../../components/alert/Alerts";
|
import { useAlerts } from "../../components/alert/Alerts";
|
||||||
import { AlertPanel } from "../../components/alert/AlertPanel";
|
|
||||||
|
|
||||||
export const ImportForm = () => {
|
export const ImportForm = () => {
|
||||||
const { t } = useTranslation("clients");
|
const { t } = useTranslation("clients");
|
||||||
const httpClient = useContext(HttpClientContext)!;
|
const httpClient = useContext(HttpClientContext)!;
|
||||||
|
|
||||||
const [add, alerts, hide] = useAlerts();
|
const [add, Alerts] = useAlerts();
|
||||||
const defaultClient = {
|
const defaultClient = {
|
||||||
protocol: "",
|
protocol: "",
|
||||||
clientId: "",
|
clientId: "",
|
||||||
|
@ -57,7 +56,7 @@ export const ImportForm = () => {
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<AlertPanel alerts={alerts} onCloseAlert={hide} />
|
<Alerts />
|
||||||
<PageSection variant="light">
|
<PageSection variant="light">
|
||||||
<TextContent>
|
<TextContent>
|
||||||
<Text component="h1">{t("Import client")}</Text>
|
<Text component="h1">{t("Import client")}</Text>
|
||||||
|
|
|
@ -30,7 +30,6 @@ export function AlertPanel({ alerts, onCloseAlert }: AlertPanelProps) {
|
||||||
actionClose={
|
actionClose={
|
||||||
<AlertActionCloseButton
|
<AlertActionCloseButton
|
||||||
title={message}
|
title={message}
|
||||||
variantLabel={`${variant} alert`}
|
|
||||||
onClose={() => onCloseAlert(key)}
|
onClose={() => onCloseAlert(key)}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import { useState } from "react";
|
import React, { useState, ReactElement } from "react";
|
||||||
import { AlertType } from "./AlertPanel";
|
import { AlertType, AlertPanel } from "./AlertPanel";
|
||||||
import { AlertVariant } from "@patternfly/react-core";
|
import { AlertVariant } from "@patternfly/react-core";
|
||||||
|
|
||||||
export function useAlerts(): [
|
export function useAlerts(): [
|
||||||
(message: string, type: AlertVariant) => void,
|
(message: string, type?: AlertVariant) => void,
|
||||||
AlertType[],
|
() => ReactElement,
|
||||||
(key: number) => void
|
(key: number) => void,
|
||||||
|
AlertType[]
|
||||||
] {
|
] {
|
||||||
const [alerts, setAlerts] = useState<AlertType[]>([]);
|
const [alerts, setAlerts] = useState<AlertType[]>([]);
|
||||||
const createId = () => new Date().getTime();
|
const createId = () => new Date().getTime();
|
||||||
|
@ -14,11 +15,16 @@ export function useAlerts(): [
|
||||||
setAlerts((alerts) => [...alerts.filter((el) => el.key !== key)]);
|
setAlerts((alerts) => [...alerts.filter((el) => el.key !== key)]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const add = (message: string, variant: AlertVariant) => {
|
const add = (
|
||||||
|
message: string,
|
||||||
|
variant: AlertVariant = AlertVariant.default
|
||||||
|
) => {
|
||||||
const key = createId();
|
const key = createId();
|
||||||
setAlerts([...alerts, { key, message, variant }]);
|
setAlerts([...alerts, { key, message, variant }]);
|
||||||
setTimeout(() => hideAlert(key), 8000);
|
setTimeout(() => hideAlert(key), 8000);
|
||||||
};
|
};
|
||||||
|
|
||||||
return [add, alerts, hideAlert];
|
const Panel = () => <AlertPanel alerts={alerts} onCloseAlert={hideAlert} />;
|
||||||
|
|
||||||
|
return [add, Panel, hideAlert, alerts];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Button, AlertVariant } from "@patternfly/react-core";
|
import { Button } from "@patternfly/react-core";
|
||||||
import { mount } from "enzyme";
|
import { mount } from "enzyme";
|
||||||
import { act } from "react-dom/test-utils";
|
import { act } from "react-dom/test-utils";
|
||||||
|
|
||||||
|
@ -9,11 +9,11 @@ import { useAlerts } from "../Alerts";
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
|
|
||||||
const WithButton = () => {
|
const WithButton = () => {
|
||||||
const [add, alerts, hide] = useAlerts();
|
const [add, _, hide, alerts] = useAlerts();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<AlertPanel alerts={alerts} onCloseAlert={hide} />
|
<AlertPanel alerts={alerts} onCloseAlert={hide} />
|
||||||
<Button onClick={() => add("Hello", AlertVariant.default)}>Add</Button>
|
<Button onClick={() => add("Hello")}>Add</Button>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -104,7 +104,7 @@ exports[`remove alert after timeout: with alert 1`] = `
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
aria-disabled="false"
|
aria-disabled="false"
|
||||||
aria-label="Close default alert alert: Hello"
|
aria-label="Close alert: Hello"
|
||||||
class="pf-c-button pf-m-plain"
|
class="pf-c-button pf-m-plain"
|
||||||
data-ouia-component-id="2"
|
data-ouia-component-id="2"
|
||||||
data-ouia-component-type="PF4/Button"
|
data-ouia-component-type="PF4/Button"
|
||||||
|
|
|
@ -85,7 +85,7 @@ export const JsonFileUpload = ({
|
||||||
</Button>,
|
</Button>,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{t("confirmImportClear")}
|
{t("Are you sure you want to clear this file?")}
|
||||||
</Modal>
|
</Modal>
|
||||||
)}
|
)}
|
||||||
<FormGroup
|
<FormGroup
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useState, useContext, useEffect } from "react";
|
import React, { useState } from "react";
|
||||||
import { useHistory } from "react-router-dom";
|
import { useHistory } from "react-router-dom";
|
||||||
import { Realm } from "../../realm/models/Realm";
|
import { RealmRepresentation } from "../../realm/models/Realm";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Dropdown,
|
Dropdown,
|
||||||
|
@ -14,7 +14,7 @@ import "./realm-selector.css";
|
||||||
|
|
||||||
type RealmSelectorProps = {
|
type RealmSelectorProps = {
|
||||||
realm: string;
|
realm: string;
|
||||||
realmList: Realm[];
|
realmList: RealmRepresentation[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RealmSelector = ({ realm, realmList }: RealmSelectorProps) => {
|
export const RealmSelector = ({ realm, realmList }: RealmSelectorProps) => {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import React from "react";
|
import React, { useState, FormEvent, useContext } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
import {
|
import {
|
||||||
Text,
|
Text,
|
||||||
PageSection,
|
PageSection,
|
||||||
|
@ -7,22 +8,51 @@ import {
|
||||||
Form,
|
Form,
|
||||||
TextInput,
|
TextInput,
|
||||||
Switch,
|
Switch,
|
||||||
FileUpload,
|
|
||||||
ActionGroup,
|
ActionGroup,
|
||||||
Button,
|
Button,
|
||||||
Divider,
|
Divider,
|
||||||
|
AlertVariant,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
//type NewRealmFormProps = {
|
import { JsonFileUpload } from "../../components/json-file-upload/JsonFileUpload";
|
||||||
// realm: string;
|
import { RealmRepresentation } from "../models/Realm";
|
||||||
//};
|
import { HttpClientContext } from "../../http-service/HttpClientContext";
|
||||||
|
import { useAlerts } from "../../components/alert/Alerts";
|
||||||
|
|
||||||
export const NewRealmForm = () => {
|
export const NewRealmForm = () => {
|
||||||
const { t } = useTranslation("realm");
|
const { t } = useTranslation("realm");
|
||||||
//({ realm }: NewRealmFormProps) => {
|
const httpClient = useContext(HttpClientContext)!;
|
||||||
|
const [add, Alerts] = useAlerts();
|
||||||
|
|
||||||
|
const defaultRealm = { id: "", realm: "", enabled: true };
|
||||||
|
const [realm, setRealm] = useState<RealmRepresentation>(defaultRealm);
|
||||||
|
|
||||||
|
const handleFileChange = (value: string | File) => {
|
||||||
|
setRealm({
|
||||||
|
...realm,
|
||||||
|
...(value ? JSON.parse(value as string) : defaultRealm),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const handleChange = (
|
||||||
|
value: string | boolean,
|
||||||
|
event: FormEvent<HTMLInputElement>
|
||||||
|
) => {
|
||||||
|
const name = (event.target as HTMLInputElement).name;
|
||||||
|
setRealm({ ...realm, [name]: value });
|
||||||
|
};
|
||||||
|
|
||||||
|
const save = async () => {
|
||||||
|
try {
|
||||||
|
await httpClient.doPost("/admin/realms", realm);
|
||||||
|
add(t("Realm created"), AlertVariant.success);
|
||||||
|
} catch (error) {
|
||||||
|
add(`${t("Could not create realm:")} '${error}'`, AlertVariant.danger);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<Alerts />
|
||||||
<PageSection variant="light">
|
<PageSection variant="light">
|
||||||
<TextContent>
|
<TextContent>
|
||||||
<Text component="h1">Create Realm</Text>
|
<Text component="h1">Create Realm</Text>
|
||||||
|
@ -31,40 +61,31 @@ export const NewRealmForm = () => {
|
||||||
<Divider />
|
<Divider />
|
||||||
<PageSection variant="light">
|
<PageSection variant="light">
|
||||||
<Form isHorizontal>
|
<Form isHorizontal>
|
||||||
<FormGroup label={t("Upload JSON file")} fieldId="kc-realm-filename">
|
<JsonFileUpload id="kc-realm-filename" onChange={handleFileChange} />
|
||||||
<FileUpload
|
|
||||||
id="simple-text-file"
|
|
||||||
type="text"
|
|
||||||
// value={value}
|
|
||||||
// filename={filename}
|
|
||||||
// onChange={this.handleFileChange}
|
|
||||||
// onReadStarted={this.handleFileReadStarted}
|
|
||||||
// onReadFinished={this.handleFileReadFinished}
|
|
||||||
// isLoading={isLoading}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
<FormGroup label={t("Realm name")} isRequired fieldId="kc-realm-name">
|
<FormGroup label={t("Realm name")} isRequired fieldId="kc-realm-name">
|
||||||
<TextInput
|
<TextInput
|
||||||
isRequired
|
isRequired
|
||||||
type="text"
|
type="text"
|
||||||
id="kc-realm-name"
|
id="kc-realm-name"
|
||||||
name="kc-realm-name"
|
name="realm"
|
||||||
// value={value2}
|
value={realm.realm}
|
||||||
// onChange={this.handleTextInputChange2}
|
onChange={handleChange}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup label={t("Enabled")} fieldId="kc-realm-enabled-switch">
|
<FormGroup label={t("Enabled")} fieldId="kc-realm-enabled-switch">
|
||||||
<Switch
|
<Switch
|
||||||
id="kc-realm-enabled-switch"
|
id="kc-realm-enabled-switch"
|
||||||
name="kc-realm-enabled-switch"
|
name="enabled"
|
||||||
label={t("On")}
|
label={t("On")}
|
||||||
labelOff={t("Off")}
|
labelOff={t("Off")}
|
||||||
// isChecked={isChecked}
|
isChecked={realm.enabled}
|
||||||
// onChange={this.handleChange}
|
onChange={handleChange}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<ActionGroup>
|
<ActionGroup>
|
||||||
<Button variant="primary">{t("Create")}</Button>
|
<Button variant="primary" onClick={() => save()}>
|
||||||
|
{t("Create")}
|
||||||
|
</Button>
|
||||||
<Button variant="link">{t("Cancel")}</Button>
|
<Button variant="link">{t("Cancel")}</Button>
|
||||||
</ActionGroup>
|
</ActionGroup>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
@ -1,4 +1,507 @@
|
||||||
export interface Realm {
|
export interface RealmRepresentation {
|
||||||
id: string;
|
id: string;
|
||||||
realm: string;
|
realm: string;
|
||||||
|
displayName?: string;
|
||||||
|
displayNameHtml?: string;
|
||||||
|
notBefore?: number;
|
||||||
|
defaultSignatureAlgorithm?: string;
|
||||||
|
revokeRefreshToken?: boolean;
|
||||||
|
refreshTokenMaxReuse?: number;
|
||||||
|
accessTokenLifespan?: number;
|
||||||
|
accessTokenLifespanForImplicitFlow?: number;
|
||||||
|
ssoSessionIdleTimeout?: number;
|
||||||
|
ssoSessionMaxLifespan?: number;
|
||||||
|
ssoSessionIdleTimeoutRememberMe?: number;
|
||||||
|
ssoSessionMaxLifespanRememberMe?: number;
|
||||||
|
offlineSessionIdleTimeout?: number;
|
||||||
|
offlineSessionMaxLifespanEnabled?: boolean;
|
||||||
|
offlineSessionMaxLifespan?: number;
|
||||||
|
clientSessionIdleTimeout?: number;
|
||||||
|
clientSessionMaxLifespan?: number;
|
||||||
|
clientOfflineSessionIdleTimeout?: number;
|
||||||
|
clientOfflineSessionMaxLifespan?: number;
|
||||||
|
accessCodeLifespan?: number;
|
||||||
|
accessCodeLifespanUserAction?: number;
|
||||||
|
accessCodeLifespanLogin?: number;
|
||||||
|
actionTokenGeneratedByAdminLifespan?: number;
|
||||||
|
actionTokenGeneratedByUserLifespan?: number;
|
||||||
|
enabled?: boolean;
|
||||||
|
sslRequired?: string;
|
||||||
|
passwordCredentialGrantAllowed?: boolean;
|
||||||
|
registrationAllowed?: boolean;
|
||||||
|
registrationEmailAsUsername?: boolean;
|
||||||
|
rememberMe?: boolean;
|
||||||
|
verifyEmail?: boolean;
|
||||||
|
loginWithEmailAllowed?: boolean;
|
||||||
|
duplicateEmailsAllowed?: boolean;
|
||||||
|
resetPasswordAllowed?: boolean;
|
||||||
|
editUsernameAllowed?: boolean;
|
||||||
|
bruteForceProtected?: boolean;
|
||||||
|
permanentLockout?: boolean;
|
||||||
|
maxFailureWaitSeconds?: number;
|
||||||
|
minimumQuickLoginWaitSeconds?: number;
|
||||||
|
waitIncrementSeconds?: number;
|
||||||
|
quickLoginCheckMilliSeconds?: number;
|
||||||
|
maxDeltaTimeSeconds?: number;
|
||||||
|
failureFactor?: number;
|
||||||
|
privateKey?: string;
|
||||||
|
publicKey?: string;
|
||||||
|
certificate?: string;
|
||||||
|
codeSecret?: string;
|
||||||
|
roles?: RolesRepresentation;
|
||||||
|
groups?: GroupRepresentation[];
|
||||||
|
defaultRoles?: string[];
|
||||||
|
defaultGroups?: string[];
|
||||||
|
requiredCredentials?: string[];
|
||||||
|
passwordPolicy?: string;
|
||||||
|
otpPolicyType?: string;
|
||||||
|
otpPolicyAlgorithm?: string;
|
||||||
|
otpPolicyInitialCounter?: number;
|
||||||
|
otpPolicyDigits?: number;
|
||||||
|
otpPolicyLookAheadWindow?: number;
|
||||||
|
otpPolicyPeriod?: number;
|
||||||
|
otpSupportedApplications?: string[];
|
||||||
|
webAuthnPolicyRpEntityName?: string;
|
||||||
|
webAuthnPolicySignatureAlgorithms?: string[];
|
||||||
|
webAuthnPolicyRpId?: string;
|
||||||
|
webAuthnPolicyAttestationConveyancePreference?: string;
|
||||||
|
webAuthnPolicyAuthenticatorAttachment?: string;
|
||||||
|
webAuthnPolicyRequireResidentKey?: string;
|
||||||
|
webAuthnPolicyUserVerificationRequirement?: string;
|
||||||
|
webAuthnPolicyCreateTimeout?: number;
|
||||||
|
webAuthnPolicyAvoidSameAuthenticatorRegister?: boolean;
|
||||||
|
webAuthnPolicyAcceptableAaguids?: string[];
|
||||||
|
webAuthnPolicyPasswordlessRpEntityName?: string;
|
||||||
|
webAuthnPolicyPasswordlessSignatureAlgorithms?: string[];
|
||||||
|
webAuthnPolicyPasswordlessRpId?: string;
|
||||||
|
webAuthnPolicyPasswordlessAttestationConveyancePreference?: string;
|
||||||
|
webAuthnPolicyPasswordlessAuthenticatorAttachment?: string;
|
||||||
|
webAuthnPolicyPasswordlessRequireResidentKey?: string;
|
||||||
|
webAuthnPolicyPasswordlessUserVerificationRequirement?: string;
|
||||||
|
webAuthnPolicyPasswordlessCreateTimeout?: number;
|
||||||
|
webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister?: boolean;
|
||||||
|
webAuthnPolicyPasswordlessAcceptableAaguids?: string[];
|
||||||
|
users?: UserRepresentation[];
|
||||||
|
federatedUsers?: UserRepresentation[];
|
||||||
|
scopeMappings?: ScopeMappingRepresentation[];
|
||||||
|
clientScopeMappings?: { [index: string]: ScopeMappingRepresentation[] };
|
||||||
|
clients?: ClientRepresentation[];
|
||||||
|
clientScopes?: ClientScopeRepresentation[];
|
||||||
|
defaultDefaultClientScopes?: string[];
|
||||||
|
defaultOptionalClientScopes?: string[];
|
||||||
|
browserSecurityHeaders?: { [index: string]: string };
|
||||||
|
smtpServe?: { [index: string]: string };
|
||||||
|
userFederationProviders?: UserFederationProviderRepresentation[];
|
||||||
|
userFederationMappers?: UserFederationMapperRepresentation[];
|
||||||
|
loginTheme?: string;
|
||||||
|
accountTheme?: string;
|
||||||
|
adminTheme?: string;
|
||||||
|
emailTheme?: string;
|
||||||
|
eventsEnabled?: boolean;
|
||||||
|
eventsExpiration?: number;
|
||||||
|
eventsListeners?: string[];
|
||||||
|
enabledEventTypes?: string[];
|
||||||
|
adminEventsEnabled?: boolean;
|
||||||
|
adminEventsDetailsEnabled?: boolean;
|
||||||
|
identityProviders?: IdentityProviderRepresentation[];
|
||||||
|
identityProviderMappers?: IdentityProviderMapperRepresentation[];
|
||||||
|
protocolMappers?: ProtocolMapperRepresentation[];
|
||||||
|
components?: { [index: string]: ComponentExportRepresentation };
|
||||||
|
internationalizationEnabled?: boolean;
|
||||||
|
supportedLocales?: string[];
|
||||||
|
defaultLocale?: string;
|
||||||
|
authenticationFlows?: AuthenticationFlowRepresentation[];
|
||||||
|
authenticatorConfig?: AuthenticatorConfigRepresentation[];
|
||||||
|
requiredActions?: RequiredActionProviderRepresentation[];
|
||||||
|
browserFlow?: string;
|
||||||
|
registrationFlow?: string;
|
||||||
|
directGrantFlow?: string;
|
||||||
|
resetCredentialsFlow?: string;
|
||||||
|
clientAuthenticationFlow?: string;
|
||||||
|
dockerAuthenticationFlow?: string;
|
||||||
|
attributes?: { [index: string]: string };
|
||||||
|
keycloakVersion?: string;
|
||||||
|
userManagedAccessAllowed?: boolean;
|
||||||
|
social?: boolean;
|
||||||
|
updateProfileOnInitialSocialLogin?: boolean;
|
||||||
|
socialProviders?: { [index: string]: string };
|
||||||
|
applicationScopeMappings?: { [index: string]: ScopeMappingRepresentation[] };
|
||||||
|
applications?: ApplicationRepresentation[];
|
||||||
|
oauthClients?: OAuthClientRepresentation[];
|
||||||
|
clientTemplates?: ClientTemplateRepresentation[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface RolesRepresentation {
|
||||||
|
realm: RoleRepresentation[];
|
||||||
|
client: { [index: string]: RoleRepresentation[] };
|
||||||
|
application: { [index: string]: RoleRepresentation[] };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GroupRepresentation {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
path: string;
|
||||||
|
attributes: { [index: string]: string[] };
|
||||||
|
realmRoles: string[];
|
||||||
|
clientRoles: { [index: string]: string[] };
|
||||||
|
subGroups: GroupRepresentation[];
|
||||||
|
access: { [index: string]: boolean };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserRepresentation {
|
||||||
|
self: string;
|
||||||
|
id: string;
|
||||||
|
origin: string;
|
||||||
|
createdTimestamp: number;
|
||||||
|
username: string;
|
||||||
|
enabled: boolean;
|
||||||
|
totp: boolean;
|
||||||
|
emailVerified: boolean;
|
||||||
|
firstName: string;
|
||||||
|
lastName: string;
|
||||||
|
email: string;
|
||||||
|
federationLink: string;
|
||||||
|
serviceAccountClientId: string;
|
||||||
|
attributes: { [index: string]: string[] };
|
||||||
|
credentials: CredentialRepresentation[];
|
||||||
|
disableableCredentialTypes: string[];
|
||||||
|
requiredActions: string[];
|
||||||
|
federatedIdentities: FederatedIdentityRepresentation[];
|
||||||
|
realmRoles: string[];
|
||||||
|
clientRoles: { [index: string]: string[] };
|
||||||
|
clientConsents: UserConsentRepresentation[];
|
||||||
|
notBefore: number;
|
||||||
|
applicationRoles: { [index: string]: string[] };
|
||||||
|
socialLinks: SocialLinkRepresentation[];
|
||||||
|
groups: string[];
|
||||||
|
access: { [index: string]: boolean };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ScopeMappingRepresentation {
|
||||||
|
self: string;
|
||||||
|
client: string;
|
||||||
|
clientTemplate: string;
|
||||||
|
clientScope: string;
|
||||||
|
roles: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ClientRepresentation {
|
||||||
|
id: string;
|
||||||
|
clientId: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
rootUrl: string;
|
||||||
|
adminUrl: string;
|
||||||
|
baseUrl: string;
|
||||||
|
surrogateAuthRequired: boolean;
|
||||||
|
enabled: boolean;
|
||||||
|
alwaysDisplayInConsole: boolean;
|
||||||
|
clientAuthenticatorType: string;
|
||||||
|
secret: string;
|
||||||
|
registrationAccessToken: string;
|
||||||
|
defaultRoles: string[];
|
||||||
|
redirectUris: string[];
|
||||||
|
webOrigins: string[];
|
||||||
|
notBefore: number;
|
||||||
|
bearerOnly: boolean;
|
||||||
|
consentRequired: boolean;
|
||||||
|
standardFlowEnabled: boolean;
|
||||||
|
implicitFlowEnabled: boolean;
|
||||||
|
directAccessGrantsEnabled: boolean;
|
||||||
|
serviceAccountsEnabled: boolean;
|
||||||
|
authorizationServicesEnabled: boolean;
|
||||||
|
directGrantsOnly: boolean;
|
||||||
|
publicClient: boolean;
|
||||||
|
frontchannelLogout: boolean;
|
||||||
|
protocol: string;
|
||||||
|
attributes: { [index: string]: string };
|
||||||
|
authenticationFlowBindingOverrides: { [index: string]: string };
|
||||||
|
fullScopeAllowed: boolean;
|
||||||
|
nodeReRegistrationTimeout: number;
|
||||||
|
registeredNodes: { [index: string]: number };
|
||||||
|
protocolMappers: ProtocolMapperRepresentation[];
|
||||||
|
clientTemplate: string;
|
||||||
|
useTemplateConfig: boolean;
|
||||||
|
useTemplateScope: boolean;
|
||||||
|
useTemplateMappers: boolean;
|
||||||
|
defaultClientScopes: string[];
|
||||||
|
optionalClientScopes: string[];
|
||||||
|
authorizationSettings: ResourceServerRepresentation;
|
||||||
|
access: { [index: string]: boolean };
|
||||||
|
origin: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ClientScopeRepresentation {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
protocol: string;
|
||||||
|
attributes: { [index: string]: string };
|
||||||
|
protocolMappers: ProtocolMapperRepresentation[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserFederationProviderRepresentation {
|
||||||
|
id: string;
|
||||||
|
displayName: string;
|
||||||
|
providerName: string;
|
||||||
|
config: { [index: string]: string };
|
||||||
|
priority: number;
|
||||||
|
fullSyncPeriod: number;
|
||||||
|
changedSyncPeriod: number;
|
||||||
|
lastSync: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserFederationMapperRepresentation {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
federationProviderDisplayName: string;
|
||||||
|
federationMapperType: string;
|
||||||
|
config: { [index: string]: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IdentityProviderRepresentation {
|
||||||
|
alias: string;
|
||||||
|
displayName: string;
|
||||||
|
internalId: string;
|
||||||
|
providerId: string;
|
||||||
|
enabled: boolean;
|
||||||
|
updateProfileFirstLoginMode: string;
|
||||||
|
trustEmail: boolean;
|
||||||
|
storeToken: boolean;
|
||||||
|
addReadTokenRoleOnCreate: boolean;
|
||||||
|
authenticateByDefault: boolean;
|
||||||
|
linkOnly: boolean;
|
||||||
|
firstBrokerLoginFlowAlias: string;
|
||||||
|
postBrokerLoginFlowAlias: string;
|
||||||
|
config: { [index: string]: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IdentityProviderMapperRepresentation {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
identityProviderAlias: string;
|
||||||
|
identityProviderMapper: string;
|
||||||
|
config: { [index: string]: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProtocolMapperRepresentation {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
protocol: string;
|
||||||
|
protocolMapper: string;
|
||||||
|
consentRequired: boolean;
|
||||||
|
consentText: string;
|
||||||
|
config: { [index: string]: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ComponentExportRepresentation {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
providerId: string;
|
||||||
|
subType: string;
|
||||||
|
subComponents: { [index: string]: ComponentExportRepresentation };
|
||||||
|
config: { [index: string]: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AuthenticationFlowRepresentation extends Serializable {
|
||||||
|
id: string;
|
||||||
|
alias: string;
|
||||||
|
description: string;
|
||||||
|
providerId: string;
|
||||||
|
topLevel: boolean;
|
||||||
|
builtIn: boolean;
|
||||||
|
authenticationExecutions: AuthenticationExecutionExportRepresentation[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AuthenticatorConfigRepresentation extends Serializable {
|
||||||
|
id: string;
|
||||||
|
alias: string;
|
||||||
|
config: { [index: string]: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RequiredActionProviderRepresentation {
|
||||||
|
alias: string;
|
||||||
|
name: string;
|
||||||
|
providerId: string;
|
||||||
|
enabled: boolean;
|
||||||
|
defaultAction: boolean;
|
||||||
|
priority: number;
|
||||||
|
config: { [index: string]: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApplicationRepresentation extends ClientRepresentation {
|
||||||
|
claims: ClaimRepresentation;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OAuthClientRepresentation extends ApplicationRepresentation {}
|
||||||
|
|
||||||
|
export interface ClientTemplateRepresentation {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
protocol: string;
|
||||||
|
fullScopeAllowed: boolean;
|
||||||
|
bearerOnly: boolean;
|
||||||
|
consentRequired: boolean;
|
||||||
|
standardFlowEnabled: boolean;
|
||||||
|
implicitFlowEnabled: boolean;
|
||||||
|
directAccessGrantsEnabled: boolean;
|
||||||
|
serviceAccountsEnabled: boolean;
|
||||||
|
publicClient: boolean;
|
||||||
|
frontchannelLogout: boolean;
|
||||||
|
attributes: { [index: string]: string };
|
||||||
|
protocolMappers: ProtocolMapperRepresentation[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RoleRepresentation {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
scopeParamRequired: boolean;
|
||||||
|
composite: boolean;
|
||||||
|
composites: Composites;
|
||||||
|
clientRole: boolean;
|
||||||
|
containerId: string;
|
||||||
|
attributes: { [index: string]: string[] };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CredentialRepresentation {
|
||||||
|
id: string;
|
||||||
|
type: string;
|
||||||
|
userLabel: string;
|
||||||
|
createdDate: number;
|
||||||
|
secretData: string;
|
||||||
|
credentialData: string;
|
||||||
|
priority: number;
|
||||||
|
value: string;
|
||||||
|
temporary: boolean;
|
||||||
|
device: string;
|
||||||
|
hashedSaltedValue: string;
|
||||||
|
salt: string;
|
||||||
|
hashIterations: number;
|
||||||
|
counter: number;
|
||||||
|
algorithm: string;
|
||||||
|
digits: number;
|
||||||
|
period: number;
|
||||||
|
config: { [index: string]: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FederatedIdentityRepresentation {
|
||||||
|
identityProvider: string;
|
||||||
|
userId: string;
|
||||||
|
userName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserConsentRepresentation {
|
||||||
|
clientId: string;
|
||||||
|
grantedClientScopes: string[];
|
||||||
|
createdDate: number;
|
||||||
|
lastUpdatedDate: number;
|
||||||
|
grantedRealmRoles: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SocialLinkRepresentation {
|
||||||
|
socialProvider: string;
|
||||||
|
socialUserId: string;
|
||||||
|
socialUsername: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResourceServerRepresentation {
|
||||||
|
id: string;
|
||||||
|
clientId: string;
|
||||||
|
name: string;
|
||||||
|
allowRemoteResourceManagement: boolean;
|
||||||
|
policyEnforcementMode: PolicyEnforcementMode;
|
||||||
|
resources: ResourceRepresentation[];
|
||||||
|
policies: PolicyRepresentation[];
|
||||||
|
scopes: ScopeRepresentation[];
|
||||||
|
decisionStrategy: DecisionStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AuthenticationExecutionExportRepresentation
|
||||||
|
extends AbstractAuthenticationExecutionRepresentation {
|
||||||
|
flowAlias: string;
|
||||||
|
userSetupAllowed: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Serializable {}
|
||||||
|
|
||||||
|
export interface ClaimRepresentation {
|
||||||
|
name: boolean;
|
||||||
|
username: boolean;
|
||||||
|
profile: boolean;
|
||||||
|
picture: boolean;
|
||||||
|
website: boolean;
|
||||||
|
email: boolean;
|
||||||
|
gender: boolean;
|
||||||
|
locale: boolean;
|
||||||
|
address: boolean;
|
||||||
|
phone: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Composites {
|
||||||
|
realm: string[];
|
||||||
|
client: { [index: string]: string[] };
|
||||||
|
application: { [index: string]: string[] };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResourceRepresentation {
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
owner: ResourceOwnerRepresentation;
|
||||||
|
ownerManagedAccess: boolean;
|
||||||
|
displayName: string;
|
||||||
|
attributes: { [index: string]: string[] };
|
||||||
|
_id: string;
|
||||||
|
uris: string[];
|
||||||
|
scopes: ScopeRepresentation[];
|
||||||
|
icon_uri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PolicyRepresentation extends AbstractPolicyRepresentation {
|
||||||
|
config: { [index: string]: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ScopeRepresentation {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
iconUri: string;
|
||||||
|
policies: PolicyRepresentation[];
|
||||||
|
resources: ResourceRepresentation[];
|
||||||
|
displayName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AbstractAuthenticationExecutionRepresentation
|
||||||
|
extends Serializable {
|
||||||
|
authenticatorConfig: string;
|
||||||
|
authenticator: string;
|
||||||
|
requirement: string;
|
||||||
|
priority: number;
|
||||||
|
autheticatorFlow: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResourceOwnerRepresentation {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AbstractPolicyRepresentation {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
type: string;
|
||||||
|
policies: string[];
|
||||||
|
resources: string[];
|
||||||
|
scopes: string[];
|
||||||
|
logic: Logic;
|
||||||
|
decisionStrategy: DecisionStrategy;
|
||||||
|
owner: string;
|
||||||
|
resourcesData: ResourceRepresentation[];
|
||||||
|
scopesData: ScopeRepresentation[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PolicyEnforcementMode = "ENFORCING" | "PERMISSIVE" | "DISABLED";
|
||||||
|
|
||||||
|
export type DecisionStrategy = "AFFIRMATIVE" | "UNANIMOUS" | "CONSENSUS";
|
||||||
|
|
||||||
|
export type Logic = "POSITIVE" | "NEGATIVE";
|
||||||
|
|
|
@ -17,10 +17,10 @@ export const Api = () => (
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
export const AddAlert = () => {
|
export const AddAlert = () => {
|
||||||
const [add, alerts, hide] = useAlerts();
|
const [add, Alerts] = useAlerts();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<AlertPanel alerts={alerts} onCloseAlert={hide} />
|
<Alerts />
|
||||||
<Button onClick={() => add("Hello", AlertVariant.default)}>Add</Button>
|
<Button onClick={() => add("Hello", AlertVariant.default)}>Add</Button>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue