diff --git a/src/client-scopes/add/NewClientScopeForm.tsx b/src/client-scopes/add/NewClientScopeForm.tsx deleted file mode 100644 index 0a362e7c6f..0000000000 --- a/src/client-scopes/add/NewClientScopeForm.tsx +++ /dev/null @@ -1,222 +0,0 @@ -import React, { useState } from "react"; -import { useHistory } from "react-router-dom"; -import { - ActionGroup, - AlertVariant, - Button, - Form, - FormGroup, - PageSection, - Select, - SelectOption, - SelectVariant, - Switch, - TextInput, -} from "@patternfly/react-core"; -import { useTranslation } from "react-i18next"; -import { Controller, useForm } from "react-hook-form"; - -import { ClientScopeRepresentation } from "../models/client-scope"; -import { HelpItem } from "../../components/help-enabler/HelpItem"; -import { useAlerts } from "../../components/alert/Alerts"; -import { useAdminClient } from "../../context/auth/AdminClient"; -import { ViewHeader } from "../../components/view-header/ViewHeader"; -import { useLoginProviders } from "../../context/server-info/ServerInfoProvider"; - -export const NewClientScopeForm = () => { - const { t } = useTranslation("client-scopes"); - const helpText = useTranslation("client-scopes-help").t; - const { register, control, handleSubmit, errors } = useForm< - ClientScopeRepresentation - >(); - const history = useHistory(); - - const adminClient = useAdminClient(); - const providers = useLoginProviders(); - - const [open, isOpen] = useState(false); - const { addAlert } = useAlerts(); - - const save = async (clientScopes: ClientScopeRepresentation) => { - try { - const keyValues = Object.keys(clientScopes.attributes!).map((key) => { - const newKey = key.replace(/_/g, "."); - return { [newKey]: clientScopes.attributes![key] }; - }); - clientScopes.attributes = Object.assign({}, ...keyValues); - - await adminClient.clientScopes.create({ ...clientScopes }); - addAlert(t("createClientScopeSuccess"), AlertVariant.success); - } catch (error) { - addAlert( - `${t("createClientScopeError")} '${error}'`, - AlertVariant.danger - ); - } - }; - - return ( - <> - - - -
- - } - fieldId="kc-name" - isRequired - validated={errors.name ? "error" : "default"} - helperTextInvalid={t("common:required")} - > - - - - } - fieldId="kc-description" - > - - - - } - fieldId="kc-protocol" - > - ( - - )} - /> - - - } - fieldId="kc-display.on.consent.screen" - > - ( - - )} - /> - - - } - fieldId="kc-consent-screen-text" - > - - - - } - fieldId="kc-gui-order" - > - - - - - - -
-
- - ); -}; diff --git a/src/client-scopes/add/RoleMappingForm.tsx b/src/client-scopes/add/RoleMappingForm.tsx index 540c4bbf5b..0b8cf12f5d 100644 --- a/src/client-scopes/add/RoleMappingForm.tsx +++ b/src/client-scopes/add/RoleMappingForm.tsx @@ -21,13 +21,13 @@ import { import RoleRepresentation from "keycloak-admin/lib/defs/roleRepresentation"; import ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation"; +import ProtocolMapperRepresentation from "keycloak-admin/lib/defs/protocolMapperRepresentation"; import { useAlerts } from "../../components/alert/Alerts"; import { RealmContext } from "../../context/realm-context/RealmContext"; import { useAdminClient } from "../../context/auth/AdminClient"; import { ViewHeader } from "../../components/view-header/ViewHeader"; import { HelpItem } from "../../components/help-enabler/HelpItem"; -import { ProtocolMapperRepresentation } from "../models/client-scope"; export const RoleMappingForm = () => { const { realm } = useContext(RealmContext); diff --git a/src/client-scopes/details/MappingDetails.tsx b/src/client-scopes/details/MappingDetails.tsx index 9c75b2e2ff..f84dbcba90 100644 --- a/src/client-scopes/details/MappingDetails.tsx +++ b/src/client-scopes/details/MappingDetails.tsx @@ -21,10 +21,10 @@ import { ValidatedOptions, } from "@patternfly/react-core"; import { ConfigPropertyRepresentation } from "keycloak-admin/lib/defs/configPropertyRepresentation"; +import ProtocolMapperRepresentation from "keycloak-admin/lib/defs/protocolMapperRepresentation"; import { ViewHeader } from "../../components/view-header/ViewHeader"; import { useAdminClient } from "../../context/auth/AdminClient"; -import { ProtocolMapperRepresentation } from "../models/client-scope"; import { Controller, useForm } from "react-hook-form"; import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog"; import { useAlerts } from "../../components/alert/Alerts"; diff --git a/src/client-scopes/form/ClientScopeForm.tsx b/src/client-scopes/form/ClientScopeForm.tsx index 630d730566..91ac1e5bb1 100644 --- a/src/client-scopes/form/ClientScopeForm.tsx +++ b/src/client-scopes/form/ClientScopeForm.tsx @@ -19,8 +19,8 @@ import { } from "@patternfly/react-core"; import { useTranslation } from "react-i18next"; import { Controller, useForm } from "react-hook-form"; +import ClientScopeRepresentation from "keycloak-admin/lib/defs/clientScopeRepresentation"; -import { ClientScopeRepresentation } from "../models/client-scope"; import { HelpItem } from "../../components/help-enabler/HelpItem"; import { useAdminClient } from "../../context/auth/AdminClient"; import { useAlerts } from "../../components/alert/Alerts"; diff --git a/src/client-scopes/models/client-scope.ts b/src/client-scopes/models/client-scope.ts deleted file mode 100644 index d44a532c3e..0000000000 --- a/src/client-scopes/models/client-scope.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * https://www.keycloak.org/docs-api/4.1/rest-api/#_protocolmapperrepresentation - */ - -export interface ProtocolMapperRepresentation { - config?: Record; - id?: string; - name?: string; - protocol?: string; - protocolMapper?: string; -} - -/** - * https://www.keycloak.org/docs-api/6.0/rest-api/index.html#_clientscoperepresentation - */ - -export interface ClientScopeRepresentation { - attributes?: Record; - description?: string; - id?: string; - name?: string; - protocol?: string; - protocolMappers?: ProtocolMapperRepresentation[]; -} diff --git a/src/clients/models/client-model.ts b/src/clients/models/client-model.ts deleted file mode 100644 index 7ae3ca5fd2..0000000000 --- a/src/clients/models/client-model.ts +++ /dev/null @@ -1,119 +0,0 @@ -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 ProtocolMapperRepresentation { - id: string; - name: string; - protocol: string; - protocolMapper: string; - consentRequired: boolean; - consentText: string; - config: { [index: string]: string }; -} - -export interface ResourceServerRepresentation { - id: string; - clientId: string; - name: string; - allowRemoteResourceManagement: boolean; - policyEnforcementMode: PolicyEnforcementMode; - resources: ResourceRepresentation[]; - policies: PolicyRepresentation[]; - scopes: ScopeRepresentation[]; - decisionStrategy: DecisionStrategy; -} - -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 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"; diff --git a/src/components/table-toolbar/KeycloakDataTable.tsx b/src/components/table-toolbar/KeycloakDataTable.tsx index 8d85eefb09..6f72e18d28 100644 --- a/src/components/table-toolbar/KeycloakDataTable.tsx +++ b/src/components/table-toolbar/KeycloakDataTable.tsx @@ -9,14 +9,16 @@ import { TableHeader, TableVariant, } from "@patternfly/react-table"; -import { PaginatingTableToolbar } from "./PaginatingTableToolbar"; import { Spinner } from "@patternfly/react-core"; -import { TableToolbar } from "./TableToolbar"; import _ from "lodash"; +import { PaginatingTableToolbar } from "./PaginatingTableToolbar"; +import { TableToolbar } from "./TableToolbar"; + type Row = { data: T; - cells: (keyof T)[]; + selected: boolean; + cells: (keyof T | JSX.Element)[]; }; type DataTableProps = { @@ -24,6 +26,8 @@ type DataTableProps = { columns: Field[]; rows: Row[]; actions?: IActions; + onSelect?: (isSelected: boolean, rowIndex: number) => void; + canSelectAll: boolean; }; function DataTable({ @@ -31,11 +35,19 @@ function DataTable({ rows, actions, ariaLabelKey, + onSelect, + canSelectAll, }: DataTableProps) { const { t } = useTranslation(); return ( onSelect(isSelected, rowIndex) + : undefined + } + canSelectAll={canSelectAll} cells={columns.map((column) => { return { ...column, title: t(column.displayKey || column.name) }; })} @@ -62,6 +74,8 @@ export type Action = IAction & { export type DataListProps = { loader: (first?: number, max?: number, search?: string) => Promise; + onSelect?: (value: T[]) => void; + canSelectAll?: boolean; isPaginated?: boolean; ariaLabelKey: string; searchPlaceholderKey: string; @@ -96,6 +110,8 @@ export function KeycloakDataTable({ ariaLabelKey, searchPlaceholderKey, isPaginated = false, + onSelect, + canSelectAll = false, loader, columns, actions, @@ -119,6 +135,7 @@ export function KeycloakDataTable({ data!.map((value) => { return { data: value, + selected: false, cells: columns.map((col) => { if (col.cellRenderer) { return col.cellRenderer(value); @@ -135,12 +152,26 @@ export function KeycloakDataTable({ load(); }, [first, max]); + const getNodeText = (node: keyof T | JSX.Element): string => { + if (["string", "number"].includes(typeof node)) { + return node!.toString(); + } + if (node instanceof Array) { + return node.map(getNodeText).join(""); + } + if (typeof node === "object" && node) { + return getNodeText(node.props.children); + } + return ""; + }; + const filter = (search: string) => { setFilteredData( rows!.filter((row) => row.cells.some( (cell) => - cell && cell.toString().toLowerCase().includes(search.toLowerCase()) + cell && + getNodeText(cell).toLowerCase().includes(search.toLowerCase()) ) ) ); @@ -173,6 +204,21 @@ export function KeycloakDataTable({ ); + const _onSelect = (isSelected: boolean, rowIndex: number) => { + if (rowIndex === -1) { + setRows( + rows!.map((row) => { + row.selected = isSelected; + return row; + }) + ); + } else { + rows![rowIndex].selected = isSelected; + setRows([...rows!]); + } + onSelect!(rows!.filter((row) => row.selected).map((row) => row.data)); + }; + return ( <> {!rows && } @@ -195,6 +241,8 @@ export function KeycloakDataTable({ > {!loading && (emptyState === undefined || rows.length !== 0) && ( ({ > {(emptyState === undefined || rows.length !== 0) && ( { some json from the changed values )} - { eventKey={0} title={{t("userEvents")}} > - void; - tableRowSelectedArray: number[]; - setTableRowSelectedArray: (tableRowSelectedArray: number[]) => void; -}; - -type FormattedData = { - cells: JSX.Element[]; - selected: boolean; -}; - -export const GroupsList = ({ - list, - refresh, - tableRowSelectedArray, - setTableRowSelectedArray, -}: GroupsListProps) => { - const { t } = useTranslation("groups"); - const adminClient = useAdminClient(); - const columnGroupName: keyof GroupRepresentation = "name"; - const columnGroupNumber: keyof GroupRepresentation = "membersLength"; - const { addAlert } = useAlerts(); - const [formattedData, setFormattedData] = useState([]); - - const formatData = (data: GroupRepresentation[]) => - data.map((group: { [key: string]: any }, index) => { - const groupName = group[columnGroupName]; - const groupNumber = group[columnGroupNumber]; - return { - cells: [ - , -
- - {groupNumber} -
, - ], - selected: false, - }; - }); - - useEffect(() => { - setFormattedData(formatData(list!)); - }, [list]); - - function onSelect(isSelected: boolean, rowId: number) { - const localRow = [...formattedData]; - const localTableRow = [...tableRowSelectedArray]; - if (localRow[rowId].selected !== isSelected) { - localRow[rowId].selected = isSelected; - } - - if (localTableRow.includes(rowId)) { - const index = localTableRow.indexOf(rowId); - if (index === 0) { - localTableRow.shift(); - } else { - localTableRow.splice(index, 1); - } - setTableRowSelectedArray(localTableRow); - } else { - setTableRowSelectedArray([rowId, ...tableRowSelectedArray]); - } - setFormattedData(localRow); - } - - const tableHeader = [{ title: t("groupName") }, { title: t("members") }]; - const actions = [ - { - title: t("moveTo"), - onClick: () => console.log("TO DO: Add move to functionality"), - }, - { - title: t("common:Delete"), - onClick: async ( - _: React.MouseEvent, - rowId: number - ) => { - try { - await adminClient.groups.del({ id: list![rowId].id! }); - refresh(); - setTableRowSelectedArray([]); - addAlert(t("Group deleted"), AlertVariant.success); - } catch (error) { - addAlert(`${t("clientDeleteError")} ${error}`, AlertVariant.danger); - } - }, - }, - ]; - - return ( - <> - {formattedData && ( -
onSelect(isSelected, rowId)} - canSelectAll={false} - aria-label={t("tableOfGroups")} - cells={tableHeader} - rows={formattedData} - > - - -
- )} - - ); -}; diff --git a/src/groups/GroupsSection.tsx b/src/groups/GroupsSection.tsx index d28673087c..5f5b715f8b 100644 --- a/src/groups/GroupsSection.tsx +++ b/src/groups/GroupsSection.tsx @@ -1,12 +1,5 @@ -import React, { useEffect, useState } from "react"; +import React, { useState } from "react"; import { useTranslation } from "react-i18next"; -import { GroupsList } from "./GroupsList"; -import { GroupsCreateModal } from "./GroupsCreateModal"; -import { TableToolbar } from "../components/table-toolbar/TableToolbar"; -import { ViewHeader } from "../components/view-header/ViewHeader"; -import { ListEmptyState } from "../components/list-empty-state/ListEmptyState"; -import { useAdminClient } from "../context/auth/AdminClient"; -import { useAlerts } from "../components/alert/Alerts"; import { Button, Dropdown, @@ -14,180 +7,180 @@ import { KebabToggle, PageSection, PageSectionVariants, - Spinner, ToolbarItem, AlertVariant, } from "@patternfly/react-core"; -import "./GroupsSection.css"; +import { UsersIcon } from "@patternfly/react-icons"; import GroupRepresentation from "keycloak-admin/lib/defs/groupRepresentation"; +import { GroupsCreateModal } from "./GroupsCreateModal"; +import { ViewHeader } from "../components/view-header/ViewHeader"; +import { ListEmptyState } from "../components/list-empty-state/ListEmptyState"; +import { useAdminClient } from "../context/auth/AdminClient"; +import { useAlerts } from "../components/alert/Alerts"; +import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable"; + +import "./GroupsSection.css"; +import { Link } from "react-router-dom"; + +type GroupTableData = GroupRepresentation & { + membersLength?: number; +}; + export const GroupsSection = () => { const { t } = useTranslation("groups"); const adminClient = useAdminClient(); - const [rawData, setRawData] = useState<{ [key: string]: any }[]>(); - const [filteredData, setFilteredData] = useState<{ [key: string]: any }[]>(); const [isKebabOpen, setIsKebabOpen] = useState(false); const [createGroupName, setCreateGroupName] = useState(""); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); - const [tableRowSelectedArray, setTableRowSelectedArray] = useState< - Array - >([]); - const columnID: keyof GroupRepresentation = "id"; - const columnGroupName: keyof GroupRepresentation = "name"; + const [selectedRows, setSelectedRows] = useState([]); const { addAlert } = useAlerts(); - const membersLength = "membersLength"; + const [key, setKey] = useState(""); + const refresh = () => setKey(`${new Date().getTime()}`); + + const getMembers = async (id: string) => { + const response = await adminClient.groups.listMembers({ id }); + return response ? response.length : 0; + }; const loader = async () => { const groupsData = await adminClient.groups.find(); - const getMembers = async (id: string) => { - const response = await adminClient.groups.listMembers({ id }); - return response.length; - }; - - const memberPromises = groupsData.map((group: { [key: string]: any }) => - getMembers(group[columnID]) - ); + const memberPromises = groupsData.map((group) => getMembers(group.id!)); const memberData = await Promise.all(memberPromises); - const updatedObject = groupsData.map( - (group: { [key: string]: any }, i: number) => { - const object = Object.assign({}, group); - object[membersLength] = memberData[i]; - return object; - } - ); - setFilteredData(updatedObject); - setRawData(updatedObject); - }; - - useEffect(() => { - loader(); - }, []); - - // Filter groups - const filterGroups = (newInput: string) => { - const localRowData = rawData!.filter((obj: { [key: string]: string }) => { - const groupName = obj[columnGroupName]; - return groupName.toLowerCase().includes(newInput.toLowerCase()); + const updatedObject = groupsData.map((group: GroupTableData, i) => { + group.membersLength = memberData[i]; + return group; }); - setFilteredData(localRowData); - }; - - // Kebab delete action - const onKebabToggle = (isOpen: boolean) => { - setIsKebabOpen(isOpen); - }; - - const onKebabSelect = () => { - setIsKebabOpen(!isKebabOpen); + return updatedObject; }; const handleModalToggle = () => { setIsCreateModalOpen(!isCreateModalOpen); }; - const multiDelete = async () => { - if (tableRowSelectedArray.length !== 0) { - const deleteGroup = async (rowId: number) => { - try { - await adminClient.groups.del({ - id: filteredData ? filteredData![rowId].id : rawData![rowId].id, - }); - loader(); - } catch (error) { - addAlert(`${t("groupDeleteError")} ${error}`, AlertVariant.danger); - } - }; - - const chainedPromises = tableRowSelectedArray.map((rowId: number) => { - deleteGroup(rowId); + const deleteGroup = (group: GroupRepresentation) => { + try { + return adminClient.groups.del({ + id: group.id!, }); - - await Promise.all(chainedPromises) - .then(() => addAlert(t("groupsDeleted"), AlertVariant.success)) - .then(() => setTableRowSelectedArray([])); + } catch (error) { + addAlert(t("groupDeleteError", { error }), AlertVariant.danger); } }; + const multiDelete = async () => { + if (selectedRows!.length !== 0) { + const chainedPromises = selectedRows!.map((group) => deleteGroup(group)); + + await Promise.all(chainedPromises); + addAlert(t("groupsDeleted"), AlertVariant.success); + setSelectedRows([]); + refresh(); + } + }; + + const GroupNameCell = (group: GroupTableData) => ( + <> + + {group.name} + + + ); + + const GroupMemberCell = (group: GroupTableData) => ( +
+ + {group.membersLength} +
+ ); + return ( <> - {!rawData && ( -
- -
- )} - {rawData && rawData.length > 0 ? ( - <> - - - - - - } - isOpen={isKebabOpen} - isPlain - dropdownItems={[ - multiDelete()} - > - {t("common:Delete")} - , - ]} + setSelectedRows([...rows])} + canSelectAll={false} + loader={loader} + ariaLabelKey="client-scopes:clientScopeList" + searchPlaceholderKey="client-scopes:searchFor" + toolbarItem={ + <> + + + + + setIsKebabOpen(!isKebabOpen)} /> - - - } - > - {rawData && ( - { + multiDelete(); + setIsKebabOpen(false); + }} + > + {t("common:delete")} + , + ]} /> - )} - {filteredData && filteredData.length === 0 && ( - - )} - - - ) : ( - handleModalToggle()} - /> - )} + + + } + actions={[ + { + title: t("moveTo"), + onRowClick: () => console.log("TO DO: Add move to functionality"), + }, + { + title: t("common:delete"), + onRowClick: async (group: GroupRepresentation) => { + await deleteGroup(group); + return true; + }, + }, + ]} + columns={[ + { + name: "name", + displayKey: "groups:groupName", + cellRenderer: GroupNameCell, + }, + { + name: "members", + displayKey: "groups:members", + cellRenderer: GroupMemberCell, + }, + ]} + emptyState={ + handleModalToggle()} + /> + } + /> +
diff --git a/src/groups/messages.json b/src/groups/messages.json index 5649f86524..4c314934c0 100644 --- a/src/groups/messages.json +++ b/src/groups/messages.json @@ -19,7 +19,8 @@ "noSearchResultsInstructions": "Click on the search bar above to search for groups", "noGroupsInThisRealm": "No groups in this realm", "noGroupsInThisRealmInstructions": "You haven't created any groups in this realm. Create a group to get started.", + "groupDelete": "Group deleted", "groupsDeleted": "Groups deleted", - "groupDeleteError": "Error deleting group" + "groupDeleteError": "Error deleting group {error}" } } diff --git a/src/groups/models/groups.ts b/src/groups/models/groups.ts deleted file mode 100644 index 3a49f075a1..0000000000 --- a/src/groups/models/groups.ts +++ /dev/null @@ -1,13 +0,0 @@ -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 }; - groupNumber?: number; - membersLength?: number; - list?: []; -} diff --git a/src/groups/models/server-info.ts b/src/groups/models/server-info.ts deleted file mode 100644 index ad5871db40..0000000000 --- a/src/groups/models/server-info.ts +++ /dev/null @@ -1,15 +0,0 @@ -export interface ServerGroupsRepresentation { - id?: number; - name?: string; - path?: string; - subGroups?: []; -} - -// TO DO: Update this to represent the data that is returned -export interface ServerGroupMembersRepresentation { - data?: []; -} - -export interface ServerGroupsArrayRepresentation { - groups: { [index: string]: ServerGroupsRepresentation[] }; -} diff --git a/src/realm/models/Realm.ts b/src/realm/models/Realm.ts deleted file mode 100644 index 7515973f01..0000000000 --- a/src/realm/models/Realm.ts +++ /dev/null @@ -1,500 +0,0 @@ -import { ClientScopeRepresentation } from "../../client-scopes/models/client-scope"; - -export interface RealmRepresentation { - id: 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 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";