diff --git a/common/src/main/java/org/keycloak/common/Profile.java b/common/src/main/java/org/keycloak/common/Profile.java
index 5b5a1ea9fd..57f41ca778 100755
--- a/common/src/main/java/org/keycloak/common/Profile.java
+++ b/common/src/main/java/org/keycloak/common/Profile.java
@@ -105,8 +105,11 @@ public class Profile {
MULTI_SITE("Multi-site support", Type.PREVIEW),
OFFLINE_SESSION_PRELOADING("Offline session preloading", Type.DEPRECATED),
+
HOSTNAME_V1("Hostname Options V1", Type.DEFAULT),
//HOSTNAME_V2("Hostname Options V2", Type.DEFAULT, 2),
+
+ DECLARATIVE_UI("declarative ui spi", Type.EXPERIMENTAL),
;
private final Type type;
diff --git a/common/src/test/java/org/keycloak/common/ProfileTest.java b/common/src/test/java/org/keycloak/common/ProfileTest.java
index d58c99e7fa..0e09657edf 100644
--- a/common/src/test/java/org/keycloak/common/ProfileTest.java
+++ b/common/src/test/java/org/keycloak/common/ProfileTest.java
@@ -78,6 +78,7 @@ public class ProfileTest {
Profile.Feature.DYNAMIC_SCOPES,
Profile.Feature.DOCKER,
Profile.Feature.MULTI_SITE,
+ Profile.Feature.DECLARATIVE_UI,
Profile.Feature.RECOVERY_CODES,
Profile.Feature.SCRIPTS,
Profile.Feature.TOKEN_EXCHANGE,
diff --git a/js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties b/js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties
index f9b3d23759..860ebf6c43 100644
--- a/js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties
+++ b/js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties
@@ -2986,4 +2986,16 @@ customValue=Custom value
termsAndConditionsUserAttribute=Terms and conditions accepted timestamp
realmOverridesDescription= Realm overrides allow you to specify translations that will take effect for the entire realm. These translations will override any translation specified by a theme.
addTranslation=Add translation
-effectiveMessageBundlesDescription=An effective message bundle is the set of translations for a given language, theme, and theme type. It also takes into account any realm overrides, which will take precedence.
\ No newline at end of file
+effectiveMessageBundlesDescription=An effective message bundle is the set of translations for a given language, theme, and theme type. It also takes into account any realm overrides, which will take precedence.
+clientsClientScopesHelp=The scopes associated with this resource.
+searchItem=Search item
+createItem=Create item
+itemDelete=Delete item
+itemDeleteConfirm=Are you sure you want to permanently delete the item
+itemDeleteConfirmTitle=Delete item?
+itemDeletedSuccess=The item has been deleted
+itemDeleteError=Could not delete item: {{error}}
+noItems=There are no items
+noItemsInstructions=You haven't created any items in this realm. Create a item to get started.
+itemSaveError=Error could not save item\! {{error}}
+itemSaveSuccessful=Sucessful saved
\ No newline at end of file
diff --git a/js/apps/admin-ui/src/App.tsx b/js/apps/admin-ui/src/App.tsx
index a17a9d25eb..af0202c3fa 100644
--- a/js/apps/admin-ui/src/App.tsx
+++ b/js/apps/admin-ui/src/App.tsx
@@ -24,21 +24,23 @@ import { AuthWall } from "./root/AuthWall";
const AppContexts = ({ children }: PropsWithChildren) => (
-
-
-
-
-
-
-
- {children}
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ {children}
+
+
+
+
+
+
+
+
);
@@ -53,13 +55,11 @@ export const App = () => {
mainContainerId={mainPageContentId}
>
-
- }>
-
-
-
-
-
+ }>
+
+
+
+
diff --git a/js/apps/admin-ui/src/PageNav.tsx b/js/apps/admin-ui/src/PageNav.tsx
index af28026954..eb169fd251 100644
--- a/js/apps/admin-ui/src/PageNav.tsx
+++ b/js/apps/admin-ui/src/PageNav.tsx
@@ -9,23 +9,25 @@ import {
import { FormEvent } from "react";
import { useTranslation } from "react-i18next";
import { NavLink, useMatch, useNavigate } from "react-router-dom";
-
import { RealmSelector } from "./components/realm-selector/RealmSelector";
import { useAccess } from "./context/access/Access";
import { useRealm } from "./context/realm-context/RealmContext";
+import { useServerInfo } from "./context/server-info/ServerInfoProvider";
+import { toPage } from "./page/routes";
import { AddRealmRoute } from "./realm/routes/AddRealm";
import { routes } from "./routes";
import "./page-nav.css";
-type LeftNavProps = { title: string; path: string };
+type LeftNavProps = { title: string; path: string; id?: string };
-const LeftNav = ({ title, path }: LeftNavProps) => {
+const LeftNav = ({ title, path, id }: LeftNavProps) => {
const { t } = useTranslation();
const { hasAccess } = useAccess();
const { realm } = useRealm();
const route = routes.find(
- (route) => route.path.replace(/\/:.+?(\?|(?:(?!\/).)*|$)/g, "") === path,
+ (route) =>
+ route.path.replace(/\/:.+?(\?|(?:(?!\/).)*|$)/g, "") === (id || path),
);
const accessAllowed =
@@ -56,6 +58,9 @@ const LeftNav = ({ title, path }: LeftNavProps) => {
export const PageNav = () => {
const { t } = useTranslation();
const { hasSomeAccess } = useAccess();
+ const { componentTypes } = useServerInfo();
+ const pages =
+ componentTypes?.["org.keycloak.services.ui.extend.UiPageProvider"];
const navigate = useNavigate();
@@ -116,6 +121,14 @@ export const PageNav = () => {
+ {pages?.map((p) => (
+
+ ))}
)}
diff --git a/js/apps/admin-ui/src/components/routable-tabs/RoutableTabs.tsx b/js/apps/admin-ui/src/components/routable-tabs/RoutableTabs.tsx
index e84dcd3712..57e4fc6b16 100644
--- a/js/apps/admin-ui/src/components/routable-tabs/RoutableTabs.tsx
+++ b/js/apps/admin-ui/src/components/routable-tabs/RoutableTabs.tsx
@@ -1,4 +1,5 @@
import {
+ Tab,
TabProps,
Tabs,
TabsComponent,
@@ -6,11 +7,22 @@ import {
} from "@patternfly/react-core";
import {
Children,
- isValidElement,
JSXElementConstructor,
+ PropsWithChildren,
ReactElement,
+ isValidElement,
} from "react";
-import { Path, useHref, useLocation } from "react-router-dom";
+import {
+ Path,
+ generatePath,
+ matchPath,
+ useHref,
+ useLocation,
+ useParams,
+} from "react-router-dom";
+import { useServerInfo } from "../../context/server-info/ServerInfoProvider";
+import { PageHandler } from "../../page/PageHandler";
+import { TAB_PROVIDER } from "../../page/PageList";
// TODO: Remove the custom 'children' props and type once the following issue has been resolved:
// https://github.com/patternfly/patternfly-react/issues/6766
@@ -32,14 +44,31 @@ export const RoutableTabs = ({
...otherProps
}: RoutableTabsProps) => {
const { pathname } = useLocation();
+ const params = useParams();
+ const { componentTypes } = useServerInfo();
+ const tabs = componentTypes?.[TAB_PROVIDER] || [];
- // Extract event keys from children.
+ const matchedTabs = tabs
+ .filter((tab) => matchPath({ path: tab.metadata.path }, pathname))
+ .map((t) => ({
+ ...t,
+ pathname: generatePath(t.metadata.path, {
+ ...params,
+ ...t.metadata.params,
+ }),
+ }));
+ // Extract all keys from matchedTabs
+ const matchedTabsKeys = matchedTabs.map((t) => t.pathname);
+
+ // Extract event keys from children
const eventKeys = Children.toArray(children)
.filter((child): child is ChildElement => isValidElement(child))
.map((child) => child.props.eventKey.toString());
+ const allKeys = [...eventKeys, ...matchedTabsKeys];
+
// Determine if there is an exact match.
- const exactMatch = eventKeys.find(
+ const exactMatch = allKeys.find(
(eventKey) => eventKey === decodeURI(pathname),
);
@@ -63,10 +92,33 @@ export const RoutableTabs = ({
{...otherProps}
>
{children}
+ {matchedTabs.map((t) => (
+
+
+
+ ))}
);
};
+type DynamicTabProps = {
+ title: string;
+ eventKey: string;
+};
+
+const DynamicTab = ({
+ children,
+ ...props
+}: PropsWithChildren) => {
+ const href = useHref(props.eventKey);
+
+ return (
+
+ {children}
+
+ );
+};
+
export const useRoutableTab = (to: Partial) => ({
eventKey: to.pathname ?? "",
href: useHref(to),
diff --git a/js/apps/admin-ui/src/page/Page.tsx b/js/apps/admin-ui/src/page/Page.tsx
new file mode 100644
index 0000000000..b58be17355
--- /dev/null
+++ b/js/apps/admin-ui/src/page/Page.tsx
@@ -0,0 +1,67 @@
+import { ButtonVariant, DropdownItem } from "@patternfly/react-core";
+import { useTranslation } from "react-i18next";
+import { useNavigate, useParams } from "react-router-dom";
+import { adminClient } from "../admin-client";
+import { useAlerts } from "../components/alert/Alerts";
+import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
+import { ViewHeader } from "../components/view-header/ViewHeader";
+import { useServerInfo } from "../context/server-info/ServerInfoProvider";
+import { PageHandler } from "./PageHandler";
+import { PAGE_PROVIDER } from "./PageList";
+import { PageParams, toPage } from "./routes";
+import { useRealm } from "../context/realm-context/RealmContext";
+
+export default function Page() {
+ const { t } = useTranslation();
+ const { componentTypes } = useServerInfo();
+ const { realm } = useRealm();
+ const pages = componentTypes?.[PAGE_PROVIDER];
+ const navigate = useNavigate();
+ const { id, providerId } = useParams();
+ const { addAlert, addError } = useAlerts();
+
+ const page = pages?.find((p) => p.id === providerId);
+ if (!page) {
+ throw new Error(t("notFound"));
+ }
+
+ const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({
+ titleKey: "itemDeleteConfirmTitle",
+ messageKey: "itemDeleteConfirm",
+ continueButtonLabel: "delete",
+ continueButtonVariant: ButtonVariant.danger,
+ onConfirm: async () => {
+ try {
+ await adminClient.components.del({
+ id: id!,
+ });
+ addAlert(t("itemDeletedSuccess"));
+ navigate(toPage({ realm, providerId: providerId! }));
+ } catch (error) {
+ addError("itemSaveError", error);
+ }
+ },
+ });
+ return (
+ <>
+
+ toggleDeleteDialog()}
+ >
+ {t("delete")}
+ ,
+ ]
+ : undefined
+ }
+ />
+
+ >
+ );
+}
diff --git a/js/apps/admin-ui/src/page/PageHandler.tsx b/js/apps/admin-ui/src/page/PageHandler.tsx
new file mode 100644
index 0000000000..1d4bfe8f7f
--- /dev/null
+++ b/js/apps/admin-ui/src/page/PageHandler.tsx
@@ -0,0 +1,107 @@
+import ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation";
+import ComponentTypeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentTypeRepresentation";
+import RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
+import { ActionGroup, Button, Form, PageSection } from "@patternfly/react-core";
+import { useState } from "react";
+import { FormProvider, useForm } from "react-hook-form";
+import { useTranslation } from "react-i18next";
+import { Link } from "react-router-dom";
+import { adminClient } from "../admin-client";
+import { useAlerts } from "../components/alert/Alerts";
+import { DynamicComponents } from "../components/dynamic/DynamicComponents";
+import { useRealm } from "../context/realm-context/RealmContext";
+import { useFetch } from "../utils/useFetch";
+import { PAGE_PROVIDER, TAB_PROVIDER } from "./PageList";
+import { toPage } from "./routes";
+
+type PageHandlerProps = {
+ id?: string;
+ providerType: typeof TAB_PROVIDER | typeof PAGE_PROVIDER;
+ page: ComponentTypeRepresentation;
+};
+
+export const PageHandler = ({
+ id: idAttribute,
+ providerType,
+ page: { id: providerId, ...page },
+}: PageHandlerProps) => {
+ const { t } = useTranslation();
+ const form = useForm();
+ const { realm: realmName } = useRealm();
+ const [realm, setRealm] = useState();
+ const { addAlert, addError } = useAlerts();
+ const [id, setId] = useState(idAttribute);
+
+ useFetch(
+ async () =>
+ await Promise.all([
+ adminClient.realms.findOne({ realm: realmName }),
+ id ? adminClient.components.findOne({ id }) : Promise.resolve(),
+ providerType === TAB_PROVIDER
+ ? adminClient.components.find({ type: TAB_PROVIDER })
+ : Promise.resolve(),
+ ]),
+ ([realm, data, tabs]) => {
+ setRealm(realm);
+ const tab = (tabs || []).find((t) => t.providerId === providerId);
+ form.reset(data || tab || {});
+ if (tab) setId(tab.id);
+ },
+ [],
+ );
+
+ const onSubmit = async (component: ComponentRepresentation) => {
+ if (component.config)
+ Object.entries(component.config).forEach(
+ ([key, value]) =>
+ (component.config![key] = Array.isArray(value) ? value : [value]),
+ );
+ try {
+ const updatedComponent = {
+ ...component,
+ providerId,
+ providerType,
+ parentId: realm?.id,
+ };
+ if (id) {
+ await adminClient.components.update({ id }, updatedComponent);
+ } else {
+ await adminClient.components.create(updatedComponent);
+ }
+ addAlert("itemSaveSuccessful");
+ } catch (error) {
+ addError("itemSaveError", error);
+ }
+ };
+
+ return (
+
+
+
+ );
+};
diff --git a/js/apps/admin-ui/src/page/PageList.tsx b/js/apps/admin-ui/src/page/PageList.tsx
new file mode 100644
index 0000000000..056a1deece
--- /dev/null
+++ b/js/apps/admin-ui/src/page/PageList.tsx
@@ -0,0 +1,140 @@
+import ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation";
+import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
+import type { ComponentQuery } from "@keycloak/keycloak-admin-client/lib/resources/components";
+import {
+ Button,
+ ButtonVariant,
+ PageSection,
+ ToolbarItem,
+} from "@patternfly/react-core";
+import { IRowData } from "@patternfly/react-table";
+import { useState } from "react";
+import { useTranslation } from "react-i18next";
+import { Link, useNavigate, useParams } from "react-router-dom";
+import { adminClient } from "../admin-client";
+import { useAlerts } from "../components/alert/Alerts";
+import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
+import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
+import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
+import { ViewHeader } from "../components/view-header/ViewHeader";
+import { useRealm } from "../context/realm-context/RealmContext";
+import { useServerInfo } from "../context/server-info/ServerInfoProvider";
+import { useFetch } from "../utils/useFetch";
+import { PageListParams, toDetailPage } from "./routes";
+
+export const PAGE_PROVIDER = "org.keycloak.services.ui.extend.UiPageProvider";
+export const TAB_PROVIDER = "org.keycloak.services.ui.extend.UiTabProvider";
+
+const DetailLink = (obj: ComponentRepresentation) => {
+ const { realm } = useRealm();
+ return (
+
+ {obj.id}
+
+ );
+};
+export default function PageList() {
+ const { t } = useTranslation();
+ const { addAlert, addError } = useAlerts();
+ const navigate = useNavigate();
+ const { providerId } = useParams();
+ const [key, setKey] = useState(0);
+ const refresh = () => setKey(key + 1);
+
+ const { realm: realmName } = useRealm();
+ const [realm, setRealm] = useState();
+ const [selectedItem, setSelectedItem] = useState();
+ const { componentTypes } = useServerInfo();
+ const pages = componentTypes?.[PAGE_PROVIDER];
+
+ const page = pages?.find((p) => p.id === providerId)!;
+
+ useFetch(
+ async () => adminClient.realms.findOne({ realm: realmName }),
+ setRealm,
+ [],
+ );
+
+ const loader = async () => {
+ const params: ComponentQuery = {
+ parent: realm?.id,
+ type: PAGE_PROVIDER,
+ };
+ return await adminClient.components.find({ ...params });
+ };
+
+ const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({
+ titleKey: "itemDeleteConfirmTitle",
+ messageKey: "itemDeleteConfirm",
+ continueButtonLabel: "delete",
+ continueButtonVariant: ButtonVariant.danger,
+ onConfirm: async () => {
+ try {
+ await adminClient.components.del({
+ id: selectedItem!.id!,
+ });
+ addAlert(t("itemDeletedSuccess"));
+ refresh();
+ } catch (error) {
+ addError("itemSaveError", error);
+ }
+ },
+ });
+
+ return (
+
+
+
+
+
+
+ }
+ actionResolver={(item: IRowData) => [
+ {
+ title: t("delete"),
+ onClick() {
+ setSelectedItem(item.data);
+ toggleDeleteDialog();
+ },
+ },
+ ]}
+ searchPlaceholderKey="searchItem"
+ loader={loader}
+ columns={[
+ { name: "id", cellRenderer: DetailLink },
+ ...page.properties.slice(0, 3).map((p) => ({
+ name: `config.${p.name}[0]`,
+ displayKey: p.label,
+ })),
+ ]}
+ ariaLabelKey="list"
+ emptyState={
+
+ navigate(toDetailPage({ realm: realmName, providerId: page.id }))
+ }
+ />
+ }
+ />
+
+ );
+}
diff --git a/js/apps/admin-ui/src/page/routes.tsx b/js/apps/admin-ui/src/page/routes.tsx
new file mode 100644
index 0000000000..0ffb86e383
--- /dev/null
+++ b/js/apps/admin-ui/src/page/routes.tsx
@@ -0,0 +1,39 @@
+import { Path, generatePath } from "react-router-dom";
+import type { AppRouteObject } from "../routes";
+import { lazy } from "react";
+
+export type PageListParams = { realm?: string; providerId: string };
+export type PageParams = { realm: string; providerId: string; id?: string };
+
+const PageList = lazy(() => import("./PageList"));
+const Page = lazy(() => import("./Page"));
+
+const PageListRoute: AppRouteObject = {
+ path: "/:realm?/page-section/:providerId",
+ element: ,
+ breadcrumb: (t) => t("page"),
+ handle: {
+ access: "view-realm",
+ },
+};
+
+const PageDetailRoute: AppRouteObject = {
+ path: "/:realm/page/:providerId/:id?",
+ element: ,
+ breadcrumb: (t) => t("page"),
+ handle: {
+ access: "view-realm",
+ },
+};
+
+const routes: AppRouteObject[] = [PageListRoute, PageDetailRoute];
+
+export const toPage = (params: PageListParams): Partial => ({
+ pathname: generatePath(PageListRoute.path, params),
+});
+
+export const toDetailPage = (params: PageParams): Partial => ({
+ pathname: generatePath(PageDetailRoute.path, params),
+});
+
+export default routes;
diff --git a/js/apps/admin-ui/src/routes.tsx b/js/apps/admin-ui/src/routes.tsx
index f71b74cae9..077d04842a 100644
--- a/js/apps/admin-ui/src/routes.tsx
+++ b/js/apps/admin-ui/src/routes.tsx
@@ -18,6 +18,7 @@ import realmRoutes from "./realm/routes";
import sessionRoutes from "./sessions/routes";
import userFederationRoutes from "./user-federation/routes";
import userRoutes from "./user/routes";
+import pageRoutes from "./page/routes";
export type AppRouteObjectHandle = {
access: AccessType | AccessType[];
@@ -51,6 +52,7 @@ export const routes: AppRouteObject[] = [
...userRoutes,
...groupsRoutes,
...dashboardRoutes,
+ ...pageRoutes,
NotFoundRoute,
];
diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testBuildHelp.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testBuildHelp.unix.approved.txt
index 8b90686ac8..c965b912fd 100644
--- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testBuildHelp.unix.approved.txt
+++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testBuildHelp.unix.approved.txt
@@ -64,20 +64,21 @@ Feature:
--features Enables a set of one or more features. Possible values are: account-api[:v1],
account2[:v1], account3[:v1], admin-api[:v1], admin-fine-grained-authz[:v1],
admin2[:v1], authorization[:v1], ciba[:v1], client-policies[:v1],
- client-secret-rotation[:v1], device-flow[:v1], docker[:v1], dpop[:v1],
- dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation[:v1], js-adapter
- [:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
+ client-secret-rotation[:v1], declarative-ui[:v1], device-flow[:v1], docker[:
+ v1], dpop[:v1], dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation
+ [:v1], js-adapter[:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
offline-session-preloading[:v1], par[:v1], preview, recovery-codes[:v1],
scripts[:v1], step-up-authentication[:v1], token-exchange[:v1],
transient-users[:v1], update-email[:v1], web-authn[:v1].
--features-disabled
Disables a set of one or more features. Possible values are: account-api,
account2, account3, admin-api, admin-fine-grained-authz, admin2,
- authorization, ciba, client-policies, client-secret-rotation, device-flow,
- docker, dpop, dynamic-scopes, fips, impersonation, js-adapter, kerberos,
- linkedin-oauth, multi-site, offline-session-preloading, par, preview,
- recovery-codes, scripts, step-up-authentication, token-exchange,
- transient-users, update-email, web-authn.
+ authorization, ciba, client-policies, client-secret-rotation,
+ declarative-ui, device-flow, docker, dpop, dynamic-scopes, fips,
+ impersonation, js-adapter, kerberos, linkedin-oauth, multi-site,
+ offline-session-preloading, par, preview, recovery-codes, scripts,
+ step-up-authentication, token-exchange, transient-users, update-email,
+ web-authn.
HTTP(S):
diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testBuildHelp.windows.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testBuildHelp.windows.approved.txt
index ebcf0dbd3a..c9cb3c5b9d 100644
--- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testBuildHelp.windows.approved.txt
+++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testBuildHelp.windows.approved.txt
@@ -64,20 +64,21 @@ Feature:
--features Enables a set of one or more features. Possible values are: account-api[:v1],
account2[:v1], account3[:v1], admin-api[:v1], admin-fine-grained-authz[:v1],
admin2[:v1], authorization[:v1], ciba[:v1], client-policies[:v1],
- client-secret-rotation[:v1], device-flow[:v1], docker[:v1], dpop[:v1],
- dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation[:v1], js-adapter
- [:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
+ client-secret-rotation[:v1], declarative-ui[:v1], device-flow[:v1], docker[:
+ v1], dpop[:v1], dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation
+ [:v1], js-adapter[:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
offline-session-preloading[:v1], par[:v1], preview, recovery-codes[:v1],
scripts[:v1], step-up-authentication[:v1], token-exchange[:v1],
transient-users[:v1], update-email[:v1], web-authn[:v1].
--features-disabled
Disables a set of one or more features. Possible values are: account-api,
account2, account3, admin-api, admin-fine-grained-authz, admin2,
- authorization, ciba, client-policies, client-secret-rotation, device-flow,
- docker, dpop, dynamic-scopes, fips, impersonation, js-adapter, kerberos,
- linkedin-oauth, multi-site, offline-session-preloading, par, preview,
- recovery-codes, scripts, step-up-authentication, token-exchange,
- transient-users, update-email, web-authn.
+ authorization, ciba, client-policies, client-secret-rotation,
+ declarative-ui, device-flow, docker, dpop, dynamic-scopes, fips,
+ impersonation, js-adapter, kerberos, linkedin-oauth, multi-site,
+ offline-session-preloading, par, preview, recovery-codes, scripts,
+ step-up-authentication, token-exchange, transient-users, update-email,
+ web-authn.
HTTP(S):
diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testExportHelp.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testExportHelp.unix.approved.txt
index 15146fadfa..af3b7659cb 100644
--- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testExportHelp.unix.approved.txt
+++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testExportHelp.unix.approved.txt
@@ -59,20 +59,21 @@ Feature:
--features Enables a set of one or more features. Possible values are: account-api[:v1],
account2[:v1], account3[:v1], admin-api[:v1], admin-fine-grained-authz[:v1],
admin2[:v1], authorization[:v1], ciba[:v1], client-policies[:v1],
- client-secret-rotation[:v1], device-flow[:v1], docker[:v1], dpop[:v1],
- dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation[:v1], js-adapter
- [:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
+ client-secret-rotation[:v1], declarative-ui[:v1], device-flow[:v1], docker[:
+ v1], dpop[:v1], dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation
+ [:v1], js-adapter[:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
offline-session-preloading[:v1], par[:v1], preview, recovery-codes[:v1],
scripts[:v1], step-up-authentication[:v1], token-exchange[:v1],
transient-users[:v1], update-email[:v1], web-authn[:v1].
--features-disabled
Disables a set of one or more features. Possible values are: account-api,
account2, account3, admin-api, admin-fine-grained-authz, admin2,
- authorization, ciba, client-policies, client-secret-rotation, device-flow,
- docker, dpop, dynamic-scopes, fips, impersonation, js-adapter, kerberos,
- linkedin-oauth, multi-site, offline-session-preloading, par, preview,
- recovery-codes, scripts, step-up-authentication, token-exchange,
- transient-users, update-email, web-authn.
+ authorization, ciba, client-policies, client-secret-rotation,
+ declarative-ui, device-flow, docker, dpop, dynamic-scopes, fips,
+ impersonation, js-adapter, kerberos, linkedin-oauth, multi-site,
+ offline-session-preloading, par, preview, recovery-codes, scripts,
+ step-up-authentication, token-exchange, transient-users, update-email,
+ web-authn.
Config:
diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testExportHelpAll.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testExportHelpAll.unix.approved.txt
index 15146fadfa..af3b7659cb 100644
--- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testExportHelpAll.unix.approved.txt
+++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testExportHelpAll.unix.approved.txt
@@ -59,20 +59,21 @@ Feature:
--features Enables a set of one or more features. Possible values are: account-api[:v1],
account2[:v1], account3[:v1], admin-api[:v1], admin-fine-grained-authz[:v1],
admin2[:v1], authorization[:v1], ciba[:v1], client-policies[:v1],
- client-secret-rotation[:v1], device-flow[:v1], docker[:v1], dpop[:v1],
- dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation[:v1], js-adapter
- [:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
+ client-secret-rotation[:v1], declarative-ui[:v1], device-flow[:v1], docker[:
+ v1], dpop[:v1], dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation
+ [:v1], js-adapter[:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
offline-session-preloading[:v1], par[:v1], preview, recovery-codes[:v1],
scripts[:v1], step-up-authentication[:v1], token-exchange[:v1],
transient-users[:v1], update-email[:v1], web-authn[:v1].
--features-disabled
Disables a set of one or more features. Possible values are: account-api,
account2, account3, admin-api, admin-fine-grained-authz, admin2,
- authorization, ciba, client-policies, client-secret-rotation, device-flow,
- docker, dpop, dynamic-scopes, fips, impersonation, js-adapter, kerberos,
- linkedin-oauth, multi-site, offline-session-preloading, par, preview,
- recovery-codes, scripts, step-up-authentication, token-exchange,
- transient-users, update-email, web-authn.
+ authorization, ciba, client-policies, client-secret-rotation,
+ declarative-ui, device-flow, docker, dpop, dynamic-scopes, fips,
+ impersonation, js-adapter, kerberos, linkedin-oauth, multi-site,
+ offline-session-preloading, par, preview, recovery-codes, scripts,
+ step-up-authentication, token-exchange, transient-users, update-email,
+ web-authn.
Config:
diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testImportHelp.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testImportHelp.unix.approved.txt
index 328527ca57..ae700b6695 100644
--- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testImportHelp.unix.approved.txt
+++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testImportHelp.unix.approved.txt
@@ -59,20 +59,21 @@ Feature:
--features Enables a set of one or more features. Possible values are: account-api[:v1],
account2[:v1], account3[:v1], admin-api[:v1], admin-fine-grained-authz[:v1],
admin2[:v1], authorization[:v1], ciba[:v1], client-policies[:v1],
- client-secret-rotation[:v1], device-flow[:v1], docker[:v1], dpop[:v1],
- dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation[:v1], js-adapter
- [:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
+ client-secret-rotation[:v1], declarative-ui[:v1], device-flow[:v1], docker[:
+ v1], dpop[:v1], dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation
+ [:v1], js-adapter[:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
offline-session-preloading[:v1], par[:v1], preview, recovery-codes[:v1],
scripts[:v1], step-up-authentication[:v1], token-exchange[:v1],
transient-users[:v1], update-email[:v1], web-authn[:v1].
--features-disabled
Disables a set of one or more features. Possible values are: account-api,
account2, account3, admin-api, admin-fine-grained-authz, admin2,
- authorization, ciba, client-policies, client-secret-rotation, device-flow,
- docker, dpop, dynamic-scopes, fips, impersonation, js-adapter, kerberos,
- linkedin-oauth, multi-site, offline-session-preloading, par, preview,
- recovery-codes, scripts, step-up-authentication, token-exchange,
- transient-users, update-email, web-authn.
+ authorization, ciba, client-policies, client-secret-rotation,
+ declarative-ui, device-flow, docker, dpop, dynamic-scopes, fips,
+ impersonation, js-adapter, kerberos, linkedin-oauth, multi-site,
+ offline-session-preloading, par, preview, recovery-codes, scripts,
+ step-up-authentication, token-exchange, transient-users, update-email,
+ web-authn.
Config:
diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testImportHelpAll.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testImportHelpAll.unix.approved.txt
index 328527ca57..ae700b6695 100644
--- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testImportHelpAll.unix.approved.txt
+++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testImportHelpAll.unix.approved.txt
@@ -59,20 +59,21 @@ Feature:
--features Enables a set of one or more features. Possible values are: account-api[:v1],
account2[:v1], account3[:v1], admin-api[:v1], admin-fine-grained-authz[:v1],
admin2[:v1], authorization[:v1], ciba[:v1], client-policies[:v1],
- client-secret-rotation[:v1], device-flow[:v1], docker[:v1], dpop[:v1],
- dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation[:v1], js-adapter
- [:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
+ client-secret-rotation[:v1], declarative-ui[:v1], device-flow[:v1], docker[:
+ v1], dpop[:v1], dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation
+ [:v1], js-adapter[:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
offline-session-preloading[:v1], par[:v1], preview, recovery-codes[:v1],
scripts[:v1], step-up-authentication[:v1], token-exchange[:v1],
transient-users[:v1], update-email[:v1], web-authn[:v1].
--features-disabled
Disables a set of one or more features. Possible values are: account-api,
account2, account3, admin-api, admin-fine-grained-authz, admin2,
- authorization, ciba, client-policies, client-secret-rotation, device-flow,
- docker, dpop, dynamic-scopes, fips, impersonation, js-adapter, kerberos,
- linkedin-oauth, multi-site, offline-session-preloading, par, preview,
- recovery-codes, scripts, step-up-authentication, token-exchange,
- transient-users, update-email, web-authn.
+ authorization, ciba, client-policies, client-secret-rotation,
+ declarative-ui, device-flow, docker, dpop, dynamic-scopes, fips,
+ impersonation, js-adapter, kerberos, linkedin-oauth, multi-site,
+ offline-session-preloading, par, preview, recovery-codes, scripts,
+ step-up-authentication, token-exchange, transient-users, update-email,
+ web-authn.
Config:
diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelp.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelp.unix.approved.txt
index 74ce2256c0..805a9729a7 100644
--- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelp.unix.approved.txt
+++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelp.unix.approved.txt
@@ -89,20 +89,21 @@ Feature:
--features Enables a set of one or more features. Possible values are: account-api[:v1],
account2[:v1], account3[:v1], admin-api[:v1], admin-fine-grained-authz[:v1],
admin2[:v1], authorization[:v1], ciba[:v1], client-policies[:v1],
- client-secret-rotation[:v1], device-flow[:v1], docker[:v1], dpop[:v1],
- dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation[:v1], js-adapter
- [:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
+ client-secret-rotation[:v1], declarative-ui[:v1], device-flow[:v1], docker[:
+ v1], dpop[:v1], dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation
+ [:v1], js-adapter[:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
offline-session-preloading[:v1], par[:v1], preview, recovery-codes[:v1],
scripts[:v1], step-up-authentication[:v1], token-exchange[:v1],
transient-users[:v1], update-email[:v1], web-authn[:v1].
--features-disabled
Disables a set of one or more features. Possible values are: account-api,
account2, account3, admin-api, admin-fine-grained-authz, admin2,
- authorization, ciba, client-policies, client-secret-rotation, device-flow,
- docker, dpop, dynamic-scopes, fips, impersonation, js-adapter, kerberos,
- linkedin-oauth, multi-site, offline-session-preloading, par, preview,
- recovery-codes, scripts, step-up-authentication, token-exchange,
- transient-users, update-email, web-authn.
+ authorization, ciba, client-policies, client-secret-rotation,
+ declarative-ui, device-flow, docker, dpop, dynamic-scopes, fips,
+ impersonation, js-adapter, kerberos, linkedin-oauth, multi-site,
+ offline-session-preloading, par, preview, recovery-codes, scripts,
+ step-up-authentication, token-exchange, transient-users, update-email,
+ web-authn.
Hostname:
diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelp.windows.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelp.windows.approved.txt
index 27044fc912..bd1a3f3795 100644
--- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelp.windows.approved.txt
+++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelp.windows.approved.txt
@@ -89,20 +89,21 @@ Feature:
--features Enables a set of one or more features. Possible values are: account-api[:v1],
account2[:v1], account3[:v1], admin-api[:v1], admin-fine-grained-authz[:v1],
admin2[:v1], authorization[:v1], ciba[:v1], client-policies[:v1],
- client-secret-rotation[:v1], device-flow[:v1], docker[:v1], dpop[:v1],
- dynamic-scopes[:v1], fips[:v1], hostname[:v1],impersonation[:v1], js-adapter[:v1], kerberos
- [:v1], linkedin-oauth[:v1], multi-site[:v1], offline-session-preloading[:
- v1], par[:v1], preview, recovery-codes[:v1], scripts[:v1],
- step-up-authentication[:v1], token-exchange[:v1], transient-users[:v1],
- update-email[:v1], web-authn[:v1].
+ client-secret-rotation[:v1], declarative-ui[:v1], device-flow[:v1], docker[:
+ v1], dpop[:v1], dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation
+ [:v1], js-adapter[:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
+ offline-session-preloading[:v1], par[:v1], preview, recovery-codes[:v1],
+ scripts[:v1], step-up-authentication[:v1], token-exchange[:v1],
+ transient-users[:v1], update-email[:v1], web-authn[:v1].
--features-disabled
Disables a set of one or more features. Possible values are: account-api,
account2, account3, admin-api, admin-fine-grained-authz, admin2,
- authorization, ciba, client-policies, client-secret-rotation, device-flow,
- docker, dpop, dynamic-scopes, fips, impersonation, js-adapter, kerberos,
- linkedin-oauth, multi-site, offline-session-preloading, par, preview,
- recovery-codes, scripts, step-up-authentication, token-exchange,
- transient-users, update-email, web-authn.
+ authorization, ciba, client-policies, client-secret-rotation,
+ declarative-ui, device-flow, docker, dpop, dynamic-scopes, fips,
+ impersonation, js-adapter, kerberos, linkedin-oauth, multi-site,
+ offline-session-preloading, par, preview, recovery-codes, scripts,
+ step-up-authentication, token-exchange, transient-users, update-email,
+ web-authn.
Hostname:
diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelpAll.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelpAll.unix.approved.txt
index 74ce2256c0..805a9729a7 100644
--- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelpAll.unix.approved.txt
+++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelpAll.unix.approved.txt
@@ -89,20 +89,21 @@ Feature:
--features Enables a set of one or more features. Possible values are: account-api[:v1],
account2[:v1], account3[:v1], admin-api[:v1], admin-fine-grained-authz[:v1],
admin2[:v1], authorization[:v1], ciba[:v1], client-policies[:v1],
- client-secret-rotation[:v1], device-flow[:v1], docker[:v1], dpop[:v1],
- dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation[:v1], js-adapter
- [:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
+ client-secret-rotation[:v1], declarative-ui[:v1], device-flow[:v1], docker[:
+ v1], dpop[:v1], dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation
+ [:v1], js-adapter[:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
offline-session-preloading[:v1], par[:v1], preview, recovery-codes[:v1],
scripts[:v1], step-up-authentication[:v1], token-exchange[:v1],
transient-users[:v1], update-email[:v1], web-authn[:v1].
--features-disabled
Disables a set of one or more features. Possible values are: account-api,
account2, account3, admin-api, admin-fine-grained-authz, admin2,
- authorization, ciba, client-policies, client-secret-rotation, device-flow,
- docker, dpop, dynamic-scopes, fips, impersonation, js-adapter, kerberos,
- linkedin-oauth, multi-site, offline-session-preloading, par, preview,
- recovery-codes, scripts, step-up-authentication, token-exchange,
- transient-users, update-email, web-authn.
+ authorization, ciba, client-policies, client-secret-rotation,
+ declarative-ui, device-flow, docker, dpop, dynamic-scopes, fips,
+ impersonation, js-adapter, kerberos, linkedin-oauth, multi-site,
+ offline-session-preloading, par, preview, recovery-codes, scripts,
+ step-up-authentication, token-exchange, transient-users, update-email,
+ web-authn.
Hostname:
diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelpAll.windows.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelpAll.windows.approved.txt
index 27044fc912..bd1a3f3795 100644
--- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelpAll.windows.approved.txt
+++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartDevHelpAll.windows.approved.txt
@@ -89,20 +89,21 @@ Feature:
--features Enables a set of one or more features. Possible values are: account-api[:v1],
account2[:v1], account3[:v1], admin-api[:v1], admin-fine-grained-authz[:v1],
admin2[:v1], authorization[:v1], ciba[:v1], client-policies[:v1],
- client-secret-rotation[:v1], device-flow[:v1], docker[:v1], dpop[:v1],
- dynamic-scopes[:v1], fips[:v1], hostname[:v1],impersonation[:v1], js-adapter[:v1], kerberos
- [:v1], linkedin-oauth[:v1], multi-site[:v1], offline-session-preloading[:
- v1], par[:v1], preview, recovery-codes[:v1], scripts[:v1],
- step-up-authentication[:v1], token-exchange[:v1], transient-users[:v1],
- update-email[:v1], web-authn[:v1].
+ client-secret-rotation[:v1], declarative-ui[:v1], device-flow[:v1], docker[:
+ v1], dpop[:v1], dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation
+ [:v1], js-adapter[:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
+ offline-session-preloading[:v1], par[:v1], preview, recovery-codes[:v1],
+ scripts[:v1], step-up-authentication[:v1], token-exchange[:v1],
+ transient-users[:v1], update-email[:v1], web-authn[:v1].
--features-disabled
Disables a set of one or more features. Possible values are: account-api,
account2, account3, admin-api, admin-fine-grained-authz, admin2,
- authorization, ciba, client-policies, client-secret-rotation, device-flow,
- docker, dpop, dynamic-scopes, fips, impersonation, js-adapter, kerberos,
- linkedin-oauth, multi-site, offline-session-preloading, par, preview,
- recovery-codes, scripts, step-up-authentication, token-exchange,
- transient-users, update-email, web-authn.
+ authorization, ciba, client-policies, client-secret-rotation,
+ declarative-ui, device-flow, docker, dpop, dynamic-scopes, fips,
+ impersonation, js-adapter, kerberos, linkedin-oauth, multi-site,
+ offline-session-preloading, par, preview, recovery-codes, scripts,
+ step-up-authentication, token-exchange, transient-users, update-email,
+ web-authn.
Hostname:
diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelp.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelp.unix.approved.txt
index 587c1701e9..31a64523ba 100644
--- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelp.unix.approved.txt
+++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelp.unix.approved.txt
@@ -90,20 +90,21 @@ Feature:
--features Enables a set of one or more features. Possible values are: account-api[:v1],
account2[:v1], account3[:v1], admin-api[:v1], admin-fine-grained-authz[:v1],
admin2[:v1], authorization[:v1], ciba[:v1], client-policies[:v1],
- client-secret-rotation[:v1], device-flow[:v1], docker[:v1], dpop[:v1],
- dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation[:v1], js-adapter
- [:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
+ client-secret-rotation[:v1], declarative-ui[:v1], device-flow[:v1], docker[:
+ v1], dpop[:v1], dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation
+ [:v1], js-adapter[:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
offline-session-preloading[:v1], par[:v1], preview, recovery-codes[:v1],
scripts[:v1], step-up-authentication[:v1], token-exchange[:v1],
transient-users[:v1], update-email[:v1], web-authn[:v1].
--features-disabled
Disables a set of one or more features. Possible values are: account-api,
account2, account3, admin-api, admin-fine-grained-authz, admin2,
- authorization, ciba, client-policies, client-secret-rotation, device-flow,
- docker, dpop, dynamic-scopes, fips, impersonation, js-adapter, kerberos,
- linkedin-oauth, multi-site, offline-session-preloading, par, preview,
- recovery-codes, scripts, step-up-authentication, token-exchange,
- transient-users, update-email, web-authn.
+ authorization, ciba, client-policies, client-secret-rotation,
+ declarative-ui, device-flow, docker, dpop, dynamic-scopes, fips,
+ impersonation, js-adapter, kerberos, linkedin-oauth, multi-site,
+ offline-session-preloading, par, preview, recovery-codes, scripts,
+ step-up-authentication, token-exchange, transient-users, update-email,
+ web-authn.
Hostname:
diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelp.windows.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelp.windows.approved.txt
index 9ece031fc1..9c14fd37df 100644
--- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelp.windows.approved.txt
+++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelp.windows.approved.txt
@@ -90,20 +90,21 @@ Feature:
--features Enables a set of one or more features. Possible values are: account-api[:v1],
account2[:v1], account3[:v1], admin-api[:v1], admin-fine-grained-authz[:v1],
admin2[:v1], authorization[:v1], ciba[:v1], client-policies[:v1],
- client-secret-rotation[:v1], device-flow[:v1], docker[:v1], dpop[:v1],
- dynamic-scopes[:v1], fips[:v1], hostname[:v1],impersonation[:v1], js-adapter[:v1], kerberos
- [:v1], linkedin-oauth[:v1], multi-site[:v1], offline-session-preloading[:
- v1], par[:v1], preview, recovery-codes[:v1], scripts[:v1],
- step-up-authentication[:v1], token-exchange[:v1], transient-users[:v1],
- update-email[:v1], web-authn[:v1].
+ client-secret-rotation[:v1], declarative-ui[:v1], device-flow[:v1], docker[:
+ v1], dpop[:v1], dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation
+ [:v1], js-adapter[:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
+ offline-session-preloading[:v1], par[:v1], preview, recovery-codes[:v1],
+ scripts[:v1], step-up-authentication[:v1], token-exchange[:v1],
+ transient-users[:v1], update-email[:v1], web-authn[:v1].
--features-disabled
Disables a set of one or more features. Possible values are: account-api,
account2, account3, admin-api, admin-fine-grained-authz, admin2,
- authorization, ciba, client-policies, client-secret-rotation, device-flow,
- docker, dpop, dynamic-scopes, fips, impersonation, js-adapter, kerberos,
- linkedin-oauth, multi-site, offline-session-preloading, par, preview,
- recovery-codes, scripts, step-up-authentication, token-exchange,
- transient-users, update-email, web-authn.
+ authorization, ciba, client-policies, client-secret-rotation,
+ declarative-ui, device-flow, docker, dpop, dynamic-scopes, fips,
+ impersonation, js-adapter, kerberos, linkedin-oauth, multi-site,
+ offline-session-preloading, par, preview, recovery-codes, scripts,
+ step-up-authentication, token-exchange, transient-users, update-email,
+ web-authn.
Hostname:
diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelpAll.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelpAll.unix.approved.txt
index 587c1701e9..31a64523ba 100644
--- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelpAll.unix.approved.txt
+++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelpAll.unix.approved.txt
@@ -90,20 +90,21 @@ Feature:
--features Enables a set of one or more features. Possible values are: account-api[:v1],
account2[:v1], account3[:v1], admin-api[:v1], admin-fine-grained-authz[:v1],
admin2[:v1], authorization[:v1], ciba[:v1], client-policies[:v1],
- client-secret-rotation[:v1], device-flow[:v1], docker[:v1], dpop[:v1],
- dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation[:v1], js-adapter
- [:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
+ client-secret-rotation[:v1], declarative-ui[:v1], device-flow[:v1], docker[:
+ v1], dpop[:v1], dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation
+ [:v1], js-adapter[:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
offline-session-preloading[:v1], par[:v1], preview, recovery-codes[:v1],
scripts[:v1], step-up-authentication[:v1], token-exchange[:v1],
transient-users[:v1], update-email[:v1], web-authn[:v1].
--features-disabled
Disables a set of one or more features. Possible values are: account-api,
account2, account3, admin-api, admin-fine-grained-authz, admin2,
- authorization, ciba, client-policies, client-secret-rotation, device-flow,
- docker, dpop, dynamic-scopes, fips, impersonation, js-adapter, kerberos,
- linkedin-oauth, multi-site, offline-session-preloading, par, preview,
- recovery-codes, scripts, step-up-authentication, token-exchange,
- transient-users, update-email, web-authn.
+ authorization, ciba, client-policies, client-secret-rotation,
+ declarative-ui, device-flow, docker, dpop, dynamic-scopes, fips,
+ impersonation, js-adapter, kerberos, linkedin-oauth, multi-site,
+ offline-session-preloading, par, preview, recovery-codes, scripts,
+ step-up-authentication, token-exchange, transient-users, update-email,
+ web-authn.
Hostname:
diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelpAll.windows.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelpAll.windows.approved.txt
index 9ece031fc1..9c14fd37df 100644
--- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelpAll.windows.approved.txt
+++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartHelpAll.windows.approved.txt
@@ -90,20 +90,21 @@ Feature:
--features Enables a set of one or more features. Possible values are: account-api[:v1],
account2[:v1], account3[:v1], admin-api[:v1], admin-fine-grained-authz[:v1],
admin2[:v1], authorization[:v1], ciba[:v1], client-policies[:v1],
- client-secret-rotation[:v1], device-flow[:v1], docker[:v1], dpop[:v1],
- dynamic-scopes[:v1], fips[:v1], hostname[:v1],impersonation[:v1], js-adapter[:v1], kerberos
- [:v1], linkedin-oauth[:v1], multi-site[:v1], offline-session-preloading[:
- v1], par[:v1], preview, recovery-codes[:v1], scripts[:v1],
- step-up-authentication[:v1], token-exchange[:v1], transient-users[:v1],
- update-email[:v1], web-authn[:v1].
+ client-secret-rotation[:v1], declarative-ui[:v1], device-flow[:v1], docker[:
+ v1], dpop[:v1], dynamic-scopes[:v1], fips[:v1], hostname[:v1], impersonation
+ [:v1], js-adapter[:v1], kerberos[:v1], linkedin-oauth[:v1], multi-site[:v1],
+ offline-session-preloading[:v1], par[:v1], preview, recovery-codes[:v1],
+ scripts[:v1], step-up-authentication[:v1], token-exchange[:v1],
+ transient-users[:v1], update-email[:v1], web-authn[:v1].
--features-disabled
Disables a set of one or more features. Possible values are: account-api,
account2, account3, admin-api, admin-fine-grained-authz, admin2,
- authorization, ciba, client-policies, client-secret-rotation, device-flow,
- docker, dpop, dynamic-scopes, fips, impersonation, js-adapter, kerberos,
- linkedin-oauth, multi-site, offline-session-preloading, par, preview,
- recovery-codes, scripts, step-up-authentication, token-exchange,
- transient-users, update-email, web-authn.
+ authorization, ciba, client-policies, client-secret-rotation,
+ declarative-ui, device-flow, docker, dpop, dynamic-scopes, fips,
+ impersonation, js-adapter, kerberos, linkedin-oauth, multi-site,
+ offline-session-preloading, par, preview, recovery-codes, scripts,
+ step-up-authentication, token-exchange, transient-users, update-email,
+ web-authn.
Hostname:
diff --git a/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiPageProvider.java b/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiPageProvider.java
new file mode 100644
index 0000000000..3b82522805
--- /dev/null
+++ b/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiPageProvider.java
@@ -0,0 +1,10 @@
+package org.keycloak.services.ui.extend;
+
+import org.keycloak.provider.ConfiguredProvider;
+import org.keycloak.provider.Provider;
+
+import java.util.List;
+
+public interface UiPageProvider extends Provider, ConfiguredProvider {
+
+}
diff --git a/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiPageProviderFactory.java b/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiPageProviderFactory.java
new file mode 100644
index 0000000000..cbd931642a
--- /dev/null
+++ b/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiPageProviderFactory.java
@@ -0,0 +1,12 @@
+package org.keycloak.services.ui.extend;
+
+import org.keycloak.component.ComponentFactory;
+import org.keycloak.component.ComponentModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.provider.ProviderFactory;
+
+public interface UiPageProviderFactory extends ComponentFactory {
+ default T create(KeycloakSession session, ComponentModel model) {
+ return null;
+ }
+}
diff --git a/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiPageSpi.java b/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiPageSpi.java
new file mode 100644
index 0000000000..c1249cee10
--- /dev/null
+++ b/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiPageSpi.java
@@ -0,0 +1,33 @@
+package org.keycloak.services.ui.extend;
+
+import org.keycloak.common.Profile;
+import org.keycloak.provider.Provider;
+import org.keycloak.provider.ProviderFactory;
+import org.keycloak.provider.Spi;
+
+public class UiPageSpi implements Spi {
+ @Override
+ public boolean isInternal() {
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return "ui-page";
+ }
+
+ @Override
+ public Class extends Provider> getProviderClass() {
+ return UiPageProvider.class;
+ }
+
+ @Override
+ public Class extends ProviderFactory> getProviderFactoryClass() {
+ return UiPageProviderFactory.class;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return Profile.isFeatureEnabled(Profile.Feature.DECLARATIVE_UI);
+ }
+}
diff --git a/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiTabProvider.java b/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiTabProvider.java
new file mode 100644
index 0000000000..480a8d0489
--- /dev/null
+++ b/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiTabProvider.java
@@ -0,0 +1,8 @@
+package org.keycloak.services.ui.extend;
+
+import org.keycloak.provider.ConfiguredProvider;
+import org.keycloak.provider.Provider;
+
+public interface UiTabProvider extends Provider, ConfiguredProvider {
+
+}
diff --git a/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiTabProviderFactory.java b/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiTabProviderFactory.java
new file mode 100644
index 0000000000..6587192081
--- /dev/null
+++ b/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiTabProviderFactory.java
@@ -0,0 +1,26 @@
+package org.keycloak.services.ui.extend;
+
+import org.keycloak.component.ComponentFactory;
+import org.keycloak.component.ComponentModel;
+import org.keycloak.models.KeycloakSession;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public interface UiTabProviderFactory extends ComponentFactory {
+ default T create(KeycloakSession session, ComponentModel model) {
+ return null;
+ }
+
+ @Override
+ default Map getTypeMetadata() {
+ Map metadata = new HashMap<>();
+ metadata.put("path", getPath());
+ metadata.put("params", getParams());
+ return metadata;
+ }
+
+ String getPath();
+
+ Map getParams();
+}
diff --git a/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiTabSpi.java b/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiTabSpi.java
new file mode 100644
index 0000000000..bc97ef080d
--- /dev/null
+++ b/server-spi-private/src/main/java/org/keycloak/services/ui/extend/UiTabSpi.java
@@ -0,0 +1,33 @@
+package org.keycloak.services.ui.extend;
+
+import org.keycloak.common.Profile;
+import org.keycloak.provider.Provider;
+import org.keycloak.provider.ProviderFactory;
+import org.keycloak.provider.Spi;
+
+public class UiTabSpi implements Spi {
+ @Override
+ public boolean isInternal() {
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return "ui-tab";
+ }
+
+ @Override
+ public Class extends Provider> getProviderClass() {
+ return UiTabProvider.class;
+ }
+
+ @Override
+ public Class extends ProviderFactory> getProviderFactoryClass() {
+ return UiTabProviderFactory.class;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return Profile.isFeatureEnabled(Profile.Feature.DECLARATIVE_UI);
+ }
+}
diff --git a/server-spi-private/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/server-spi-private/src/main/resources/META-INF/services/org.keycloak.provider.Spi
index 3a1a5cd941..5d26788ba9 100755
--- a/server-spi-private/src/main/resources/META-INF/services/org.keycloak.provider.Spi
+++ b/server-spi-private/src/main/resources/META-INF/services/org.keycloak.provider.Spi
@@ -38,6 +38,8 @@ org.keycloak.scripting.ScriptingSpi
org.keycloak.services.managers.BruteForceProtectorSpi
org.keycloak.services.resource.AccountResourceSpi
org.keycloak.services.resource.RealmResourceSPI
+org.keycloak.services.ui.extend.UiPageSpi
+org.keycloak.services.ui.extend.UiTabSpi
org.keycloak.sessions.AuthenticationSessionSpi
org.keycloak.sessions.StickySessionEncoderSpi
org.keycloak.protocol.ClientInstallationSpi