Align environment variables between consoles (#30125)
* change to make authServerUrl the same as authUrl fixes: #29641 Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * Remove `authUrl` entirely Signed-off-by: Jon Koops <jonkoops@gmail.com> * Remove file that is unrelated Signed-off-by: Jon Koops <jonkoops@gmail.com> * Split out and align environment variables between consoles Signed-off-by: Jon Koops <jonkoops@gmail.com> * Restore removed variables to preserve backwards compatibility Signed-off-by: Jon Koops <jonkoops@gmail.com> * Also deprecate the `authUrl` for the Admin Console Signed-off-by: Jon Koops <jonkoops@gmail.com> --------- Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> Signed-off-by: Jon Koops <jonkoops@gmail.com> Co-authored-by: Jon Koops <jonkoops@gmail.com>
This commit is contained in:
parent
2576429def
commit
5897334ddb
27 changed files with 242 additions and 176 deletions
|
@ -438,3 +438,22 @@ An external {jdgserver_name} deployment is supported for multi-site setups as ou
|
||||||
|
|
||||||
The Oracle Database JDBC driver is no longer part of the Keycloak distribution.
|
The Oracle Database JDBC driver is no longer part of the Keycloak distribution.
|
||||||
If you wish to use Oracle DB, you must manually install a version of the Oracle Driver that is compatible with your specific environment. Instructions for this process can be found in the https://www.keycloak.org/server/db[Configuring the database] {section}.
|
If you wish to use Oracle DB, you must manually install a version of the Oracle Driver that is compatible with your specific environment. Instructions for this process can be found in the https://www.keycloak.org/server/db[Configuring the database] {section}.
|
||||||
|
|
||||||
|
= Deprecated theme variables
|
||||||
|
|
||||||
|
The following variables were deprecated in the Account theme:
|
||||||
|
|
||||||
|
* `authUrl`. Use `authServerUrl` instead.
|
||||||
|
|
||||||
|
The following variables from the environment script injected into the page of the Account theme are deprecated:
|
||||||
|
|
||||||
|
* `authUrl`. Use `authServerUrl` instead.
|
||||||
|
* `features.isInternationalizationEnabled`. Do not use this variable.
|
||||||
|
|
||||||
|
The following variables were deprecated in the Admin theme:
|
||||||
|
|
||||||
|
* `authUrl`. Do not use this variable.
|
||||||
|
|
||||||
|
The following variables from the environment script injected into the page of the Admin theme are deprecated:
|
||||||
|
|
||||||
|
* `authUrl`. Do not use this variable.
|
||||||
|
|
|
@ -22,7 +22,7 @@ import { KeycloakProvider } from "@keycloak/keycloak-account-ui";
|
||||||
//...
|
//...
|
||||||
|
|
||||||
<KeycloakProvider environment={{
|
<KeycloakProvider environment={{
|
||||||
authUrl: "http://localhost:8080",
|
authServerUrl: "http://localhost:8080",
|
||||||
realm: "master",
|
realm: "master",
|
||||||
clientId: "security-admin-console"
|
clientId: "security-admin-console"
|
||||||
}}>
|
}}>
|
||||||
|
|
|
@ -149,13 +149,16 @@
|
||||||
<script id="environment" type="application/json">
|
<script id="environment" type="application/json">
|
||||||
{
|
{
|
||||||
"authUrl": "${authUrl}",
|
"authUrl": "${authUrl}",
|
||||||
"baseUrl": "${baseUrl}",
|
"authServerUrl": "${authServerUrl}",
|
||||||
"realm": "${realm.name}",
|
"realm": "${realm.name}",
|
||||||
"clientId": "${clientId}",
|
"clientId": "${clientId}",
|
||||||
"resourceUrl": "${resourceUrl}",
|
"resourceUrl": "${resourceUrl}",
|
||||||
"logo": "${properties.logo!""}",
|
"logo": "${properties.logo!""}",
|
||||||
"logoUrl": "${properties.logoUrl!""}",
|
"logoUrl": "${properties.logoUrl!""}",
|
||||||
|
"baseUrl": "${baseUrl}",
|
||||||
"locale": "${locale}",
|
"locale": "${locale}",
|
||||||
|
"referrerName": "${referrerName!""}",
|
||||||
|
"referrerUrl": "${referrer_uri!""}",
|
||||||
"features": {
|
"features": {
|
||||||
"isRegistrationEmailAsUsername": ${realm.registrationEmailAsUsername?c},
|
"isRegistrationEmailAsUsername": ${realm.registrationEmailAsUsername?c},
|
||||||
"isEditUserNameAllowed": ${realm.editUsernameAllowed?c},
|
"isEditUserNameAllowed": ${realm.editUsernameAllowed?c},
|
||||||
|
@ -167,9 +170,7 @@
|
||||||
"updateEmailActionEnabled": ${updateEmailActionEnabled?c},
|
"updateEmailActionEnabled": ${updateEmailActionEnabled?c},
|
||||||
"isViewGroupsEnabled": ${isViewGroupsEnabled?c},
|
"isViewGroupsEnabled": ${isViewGroupsEnabled?c},
|
||||||
"isOid4VciEnabled": ${isOid4VciEnabled?c}
|
"isOid4VciEnabled": ${isOid4VciEnabled?c}
|
||||||
},
|
}
|
||||||
"referrerName": "${referrerName!""}",
|
|
||||||
"referrerUrl": "${referrer_uri!""}"
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
import { KeycloakContext } from "@keycloak/keycloak-ui-shared";
|
import {
|
||||||
import { BaseEnvironment } from "@keycloak/keycloak-ui-shared/dist/context/environment";
|
KeycloakContext,
|
||||||
|
type BaseEnvironment,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
|
|
||||||
import { CallOptions } from "./api/methods";
|
import { CallOptions } from "./api/methods";
|
||||||
import { Links, parseLinks } from "./api/parse-links";
|
import { Links, parseLinks } from "./api/parse-links";
|
||||||
import { parseResponse } from "./api/parse-response";
|
import { parseResponse } from "./api/parse-response";
|
||||||
import {
|
import {
|
||||||
|
CredentialsIssuer,
|
||||||
Permission,
|
Permission,
|
||||||
Resource,
|
Resource,
|
||||||
Scope,
|
Scope,
|
||||||
CredentialsIssuer,
|
|
||||||
SupportedCredentialConfiguration,
|
SupportedCredentialConfiguration,
|
||||||
} from "./api/representations";
|
} from "./api/representations";
|
||||||
import { request } from "./api/request";
|
import { request } from "./api/request";
|
||||||
|
@ -85,7 +88,7 @@ export async function getIssuer(context: KeycloakContext<BaseEnvironment>) {
|
||||||
{},
|
{},
|
||||||
new URL(
|
new URL(
|
||||||
joinPath(
|
joinPath(
|
||||||
context.environment.authUrl +
|
context.environment.authServerUrl +
|
||||||
"/realms/" +
|
"/realms/" +
|
||||||
context.environment.realm +
|
context.environment.realm +
|
||||||
"/.well-known/openid-credential-issuer",
|
"/.well-known/openid-credential-issuer",
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import {
|
import {
|
||||||
AccountEnvironment,
|
BaseEnvironment,
|
||||||
KeycloakContext,
|
type KeycloakContext,
|
||||||
} from "@keycloak/keycloak-ui-shared";
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import { BaseEnvironment } from "@keycloak/keycloak-ui-shared/dist/context/environment";
|
|
||||||
import { joinPath } from "../utils/joinPath";
|
import { joinPath } from "../utils/joinPath";
|
||||||
import { parseResponse } from "./parse-response";
|
import { parseResponse } from "./parse-response";
|
||||||
import {
|
import {
|
||||||
|
@ -45,7 +45,7 @@ export async function getSupportedLocales({
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function savePersonalInfo(
|
export async function savePersonalInfo(
|
||||||
context: KeycloakContext<AccountEnvironment>,
|
context: KeycloakContext<BaseEnvironment>,
|
||||||
info: UserRepresentation,
|
info: UserRepresentation,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const response = await request("/", context, { body: info, method: "POST" });
|
const response = await request("/", context, { body: info, method: "POST" });
|
||||||
|
@ -134,7 +134,7 @@ export async function linkAccount(
|
||||||
) {
|
) {
|
||||||
const redirectUri = encodeURIComponent(
|
const redirectUri = encodeURIComponent(
|
||||||
joinPath(
|
joinPath(
|
||||||
context.environment.authUrl,
|
context.environment.authServerUrl,
|
||||||
"realms",
|
"realms",
|
||||||
context.environment.realm,
|
context.environment.realm,
|
||||||
"account",
|
"account",
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import { KeycloakContext } from "@keycloak/keycloak-ui-shared";
|
import {
|
||||||
import { BaseEnvironment } from "@keycloak/keycloak-ui-shared/dist/context/environment";
|
KeycloakContext,
|
||||||
|
type BaseEnvironment,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import Keycloak from "keycloak-js";
|
import Keycloak from "keycloak-js";
|
||||||
|
|
||||||
import { joinPath } from "../utils/joinPath";
|
import { joinPath } from "../utils/joinPath";
|
||||||
import { CONTENT_TYPE_HEADER, CONTENT_TYPE_JSON } from "./constants";
|
import { CONTENT_TYPE_HEADER, CONTENT_TYPE_JSON } from "./constants";
|
||||||
|
|
||||||
|
@ -50,7 +53,13 @@ export async function request(
|
||||||
|
|
||||||
export const url = (environment: BaseEnvironment, path: string) =>
|
export const url = (environment: BaseEnvironment, path: string) =>
|
||||||
new URL(
|
new URL(
|
||||||
joinPath(environment.authUrl, "realms", environment.realm, "account", path),
|
joinPath(
|
||||||
|
environment.authServerUrl,
|
||||||
|
"realms",
|
||||||
|
environment.realm,
|
||||||
|
"account",
|
||||||
|
path,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const token = (keycloak: Keycloak) =>
|
export const token = (keycloak: Keycloak) =>
|
||||||
|
|
61
js/apps/account-ui/src/environment.ts
Normal file
61
js/apps/account-ui/src/environment.ts
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
import {
|
||||||
|
getInjectedEnvironment,
|
||||||
|
type BaseEnvironment,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
|
|
||||||
|
export type Environment = BaseEnvironment & {
|
||||||
|
/** The URL to the root of the account console. */
|
||||||
|
baseUrl: string;
|
||||||
|
/** The locale of the user */
|
||||||
|
locale: string;
|
||||||
|
/** Name of the referrer application in the back link */
|
||||||
|
referrerName?: string;
|
||||||
|
/** UR to the referrer application in the back link */
|
||||||
|
referrerUrl?: string;
|
||||||
|
/** Feature flags */
|
||||||
|
features: Feature;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Feature = {
|
||||||
|
isRegistrationEmailAsUsername: boolean;
|
||||||
|
isEditUserNameAllowed: boolean;
|
||||||
|
isLinkedAccountsEnabled: boolean;
|
||||||
|
isMyResourcesEnabled: boolean;
|
||||||
|
deleteAccountAllowed: boolean;
|
||||||
|
updateEmailFeatureEnabled: boolean;
|
||||||
|
updateEmailActionEnabled: boolean;
|
||||||
|
isViewGroupsEnabled: boolean;
|
||||||
|
isOid4VciEnabled: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
// During development the realm can be passed as a query parameter when redirecting back from Keycloak.
|
||||||
|
const realm =
|
||||||
|
new URLSearchParams(window.location.search).get("realm") ||
|
||||||
|
location.pathname.match("/realms/(.*?)/account")?.[1] ||
|
||||||
|
"master";
|
||||||
|
|
||||||
|
const defaultEnvironment: Environment = {
|
||||||
|
// Base environment variables
|
||||||
|
authServerUrl: "http://localhost:8180",
|
||||||
|
realm: realm,
|
||||||
|
clientId: "security-admin-console-v2",
|
||||||
|
resourceUrl: "http://localhost:8080",
|
||||||
|
logo: "/logo.svg",
|
||||||
|
logoUrl: "/",
|
||||||
|
// Account Console specific environment variables
|
||||||
|
baseUrl: `http://localhost:8180/realms/${realm}/account/`,
|
||||||
|
locale: "en",
|
||||||
|
features: {
|
||||||
|
isRegistrationEmailAsUsername: false,
|
||||||
|
isEditUserNameAllowed: true,
|
||||||
|
isLinkedAccountsEnabled: true,
|
||||||
|
isMyResourcesEnabled: true,
|
||||||
|
deleteAccountAllowed: true,
|
||||||
|
updateEmailFeatureEnabled: true,
|
||||||
|
updateEmailActionEnabled: true,
|
||||||
|
isViewGroupsEnabled: true,
|
||||||
|
isOid4VciEnabled: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const environment = getInjectedEnvironment(defaultEnvironment);
|
|
@ -1,7 +1,8 @@
|
||||||
import { LanguageDetectorModule, createInstance } from "i18next";
|
import { LanguageDetectorModule, createInstance } from "i18next";
|
||||||
import HttpBackend from "i18next-http-backend";
|
import HttpBackend from "i18next-http-backend";
|
||||||
import { initReactI18next } from "react-i18next";
|
import { initReactI18next } from "react-i18next";
|
||||||
import { environment } from "@keycloak/keycloak-ui-shared";
|
|
||||||
|
import { environment } from "./environment";
|
||||||
import { joinPath } from "./utils/joinPath";
|
import { joinPath } from "./utils/joinPath";
|
||||||
|
|
||||||
const DEFAULT_LOCALE = "en";
|
const DEFAULT_LOCALE = "en";
|
||||||
|
@ -28,7 +29,7 @@ export const i18n = createInstance({
|
||||||
},
|
},
|
||||||
backend: {
|
backend: {
|
||||||
loadPath: joinPath(
|
loadPath: joinPath(
|
||||||
environment.authUrl,
|
environment.authServerUrl,
|
||||||
`resources/${environment.realm}/account/{{lng}}`,
|
`resources/${environment.realm}/account/{{lng}}`,
|
||||||
),
|
),
|
||||||
parse: (data: string) => {
|
parse: (data: string) => {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import {
|
import {
|
||||||
AccountEnvironment,
|
|
||||||
UserProfileFields,
|
UserProfileFields,
|
||||||
beerify,
|
beerify,
|
||||||
debeerify,
|
debeerify,
|
||||||
|
@ -20,6 +19,7 @@ import { TFunction } from "i18next";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { ErrorOption, useForm } from "react-hook-form";
|
import { ErrorOption, useForm } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getPersonalInfo,
|
getPersonalInfo,
|
||||||
getSupportedLocales,
|
getSupportedLocales,
|
||||||
|
@ -30,12 +30,13 @@ import {
|
||||||
UserRepresentation,
|
UserRepresentation,
|
||||||
} from "../api/representations";
|
} from "../api/representations";
|
||||||
import { Page } from "../components/page/Page";
|
import { Page } from "../components/page/Page";
|
||||||
|
import type { Environment } from "../environment";
|
||||||
import { TFuncKey, i18n } from "../i18n";
|
import { TFuncKey, i18n } from "../i18n";
|
||||||
import { usePromise } from "../utils/usePromise";
|
import { usePromise } from "../utils/usePromise";
|
||||||
|
|
||||||
export const PersonalInfo = () => {
|
export const PersonalInfo = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const context = useEnvironment<AccountEnvironment>();
|
const context = useEnvironment<Environment>();
|
||||||
const [userProfileMetadata, setUserProfileMetadata] =
|
const [userProfileMetadata, setUserProfileMetadata] =
|
||||||
useState<UserProfileMetadata>();
|
useState<UserProfileMetadata>();
|
||||||
const [supportedLocales, setSupportedLocales] = useState<string[]>([]);
|
const [supportedLocales, setSupportedLocales] = useState<string[]>([]);
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
|
import {
|
||||||
|
KeycloakMasthead,
|
||||||
|
label,
|
||||||
|
useEnvironment,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import { Button } from "@patternfly/react-core";
|
import { Button } from "@patternfly/react-core";
|
||||||
import { ExternalLinkSquareAltIcon } from "@patternfly/react-icons";
|
import { ExternalLinkSquareAltIcon } from "@patternfly/react-icons";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useHref } from "react-router-dom";
|
import { useHref } from "react-router-dom";
|
||||||
import {
|
|
||||||
KeycloakMasthead,
|
import { environment } from "../environment";
|
||||||
environment,
|
|
||||||
label,
|
|
||||||
useEnvironment,
|
|
||||||
} from "@keycloak/keycloak-ui-shared";
|
|
||||||
import { joinPath } from "../utils/joinPath";
|
import { joinPath } from "../utils/joinPath";
|
||||||
|
|
||||||
import style from "./header.module.css";
|
import style from "./header.module.css";
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { useEnvironment } from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
Nav,
|
Nav,
|
||||||
NavExpandable,
|
NavExpandable,
|
||||||
|
@ -22,13 +23,9 @@ import {
|
||||||
useLinkClickHandler,
|
useLinkClickHandler,
|
||||||
useLocation,
|
useLocation,
|
||||||
} from "react-router-dom";
|
} from "react-router-dom";
|
||||||
import {
|
|
||||||
AccountEnvironment,
|
|
||||||
environment,
|
|
||||||
useEnvironment,
|
|
||||||
type Feature,
|
|
||||||
} from "@keycloak/keycloak-ui-shared";
|
|
||||||
import fetchContentJson from "../content/fetchContent";
|
import fetchContentJson from "../content/fetchContent";
|
||||||
|
import { environment, type Environment, type Feature } from "../environment";
|
||||||
import { TFuncKey } from "../i18n";
|
import { TFuncKey } from "../i18n";
|
||||||
import { usePromise } from "../utils/usePromise";
|
import { usePromise } from "../utils/usePromise";
|
||||||
|
|
||||||
|
@ -49,7 +46,7 @@ export type MenuItem = RootMenuItem | MenuItemWithChildren;
|
||||||
|
|
||||||
export const PageNav = () => {
|
export const PageNav = () => {
|
||||||
const [menuItems, setMenuItems] = useState<MenuItem[]>();
|
const [menuItems, setMenuItems] = useState<MenuItem[]>();
|
||||||
const context = useEnvironment<AccountEnvironment>();
|
const context = useEnvironment<Environment>();
|
||||||
|
|
||||||
usePromise((signal) => fetchContentJson({ signal, context }), setMenuItems);
|
usePromise((signal) => fetchContentJson({ signal, context }), setMenuItems);
|
||||||
return (
|
return (
|
||||||
|
@ -86,7 +83,7 @@ function NavMenuItem({ menuItem }: NavMenuItemProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const {
|
const {
|
||||||
environment: { features },
|
environment: { features },
|
||||||
} = useEnvironment<AccountEnvironment>();
|
} = useEnvironment<Environment>();
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
const isActive = useMemo(
|
const isActive = useMemo(
|
||||||
() => matchMenuItem(pathname, menuItem),
|
() => matchMenuItem(pathname, menuItem),
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import { KeycloakProvider, environment } from "@keycloak/keycloak-ui-shared";
|
import { KeycloakProvider } from "@keycloak/keycloak-ui-shared";
|
||||||
import { Page, Spinner } from "@patternfly/react-core";
|
import { Page, Spinner } from "@patternfly/react-core";
|
||||||
import { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
import { Outlet } from "react-router-dom";
|
import { Outlet } from "react-router-dom";
|
||||||
|
|
||||||
|
import { environment } from "../environment";
|
||||||
import { Header } from "./Header";
|
import { Header } from "./Header";
|
||||||
import { PageNav } from "./PageNav";
|
import { PageNav } from "./PageNav";
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { lazy } from "react";
|
import { lazy } from "react";
|
||||||
import type { IndexRouteObject, RouteObject } from "react-router-dom";
|
import type { IndexRouteObject, RouteObject } from "react-router-dom";
|
||||||
import { environment } from "@keycloak/keycloak-ui-shared";
|
|
||||||
|
import { environment } from "./environment";
|
||||||
import { ErrorPage } from "./root/ErrorPage";
|
import { ErrorPage } from "./root/ErrorPage";
|
||||||
import { Root } from "./root/Root";
|
import { Root } from "./root/Root";
|
||||||
|
|
||||||
|
|
|
@ -124,16 +124,16 @@
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
<script id="environment" type="application/json">
|
<script id="environment" type="application/json">
|
||||||
{
|
{
|
||||||
|
"authUrl": "${authUrl}",
|
||||||
|
"authServerUrl": "${authServerUrl}",
|
||||||
"realm": "${loginRealm!"master"}",
|
"realm": "${loginRealm!"master"}",
|
||||||
"clientId": "${clientId}",
|
"clientId": "${clientId}",
|
||||||
"authServerUrl": "${authServerUrl}",
|
|
||||||
"authUrl": "${authUrl}",
|
|
||||||
"consoleBaseUrl": "${consoleBaseUrl}",
|
|
||||||
"resourceUrl": "${resourceUrl}",
|
"resourceUrl": "${resourceUrl}",
|
||||||
"masterRealm": "${masterRealm}",
|
|
||||||
"resourceVersion": "${resourceVersion}",
|
|
||||||
"logo": "${properties.logo!""}",
|
"logo": "${properties.logo!""}",
|
||||||
"logoUrl": "${properties.logoUrl!""}"
|
"logoUrl": "${properties.logoUrl!""}",
|
||||||
|
"consoleBaseUrl": "${consoleBaseUrl}",
|
||||||
|
"masterRealm": "${masterRealm}",
|
||||||
|
"resourceVersion": "${resourceVersion}"
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import KeycloakAdminClient from "@keycloak/keycloak-admin-client";
|
import KeycloakAdminClient from "@keycloak/keycloak-admin-client";
|
||||||
import { Page } from "@patternfly/react-core";
|
|
||||||
import { PropsWithChildren, Suspense, useEffect, useState } from "react";
|
|
||||||
import { Outlet } from "react-router-dom";
|
|
||||||
import {
|
import {
|
||||||
mainPageContentId,
|
mainPageContentId,
|
||||||
useEnvironment,
|
useEnvironment,
|
||||||
} from "@keycloak/keycloak-ui-shared";
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
|
import { Page } from "@patternfly/react-core";
|
||||||
|
import { PropsWithChildren, Suspense, useEffect, useState } from "react";
|
||||||
|
import { Outlet } from "react-router-dom";
|
||||||
|
|
||||||
import { Header } from "./PageHeader";
|
import { Header } from "./PageHeader";
|
||||||
import { PageNav } from "./PageNav";
|
import { PageNav } from "./PageNav";
|
||||||
import { AdminClientContext, initAdminClient } from "./admin-client";
|
import { AdminClientContext, initAdminClient } from "./admin-client";
|
||||||
|
@ -23,6 +24,7 @@ import { AccessContextProvider } from "./context/access/Access";
|
||||||
import { RealmContextProvider } from "./context/realm-context/RealmContext";
|
import { RealmContextProvider } from "./context/realm-context/RealmContext";
|
||||||
import { ServerInfoProvider } from "./context/server-info/ServerInfoProvider";
|
import { ServerInfoProvider } from "./context/server-info/ServerInfoProvider";
|
||||||
import { WhoAmIContextProvider } from "./context/whoami/WhoAmI";
|
import { WhoAmIContextProvider } from "./context/whoami/WhoAmI";
|
||||||
|
import type { Environment } from "./environment";
|
||||||
import { SubGroups } from "./groups/SubGroupsContext";
|
import { SubGroups } from "./groups/SubGroupsContext";
|
||||||
import { AuthWall } from "./root/AuthWall";
|
import { AuthWall } from "./root/AuthWall";
|
||||||
|
|
||||||
|
@ -47,7 +49,7 @@ const AppContexts = ({ children }: PropsWithChildren) => (
|
||||||
);
|
);
|
||||||
|
|
||||||
export const App = () => {
|
export const App = () => {
|
||||||
const { keycloak, environment } = useEnvironment();
|
const { keycloak, environment } = useEnvironment<Environment>();
|
||||||
const [adminClient, setAdminClient] = useState<KeycloakAdminClient>();
|
const [adminClient, setAdminClient] = useState<KeycloakAdminClient>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { KeycloakProvider, environment } from "@keycloak/keycloak-ui-shared";
|
import { KeycloakProvider } from "@keycloak/keycloak-ui-shared";
|
||||||
|
|
||||||
import { App } from "./App";
|
import { App } from "./App";
|
||||||
|
import { environment } from "./environment";
|
||||||
|
|
||||||
export const Root = () => (
|
export const Root = () => (
|
||||||
<KeycloakProvider environment={environment}>
|
<KeycloakProvider environment={environment}>
|
||||||
|
|
|
@ -3,9 +3,10 @@ import {
|
||||||
createNamedContext,
|
createNamedContext,
|
||||||
useRequiredContext,
|
useRequiredContext,
|
||||||
} from "@keycloak/keycloak-ui-shared";
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
import { BaseEnvironment } from "@keycloak/keycloak-ui-shared/dist/context/environment";
|
|
||||||
import type Keycloak from "keycloak-js";
|
import type Keycloak from "keycloak-js";
|
||||||
|
|
||||||
|
import type { Environment } from "./environment";
|
||||||
|
|
||||||
export type AdminClientProps = {
|
export type AdminClientProps = {
|
||||||
keycloak: Keycloak;
|
keycloak: Keycloak;
|
||||||
adminClient: KeycloakAdminClient;
|
adminClient: KeycloakAdminClient;
|
||||||
|
@ -19,12 +20,12 @@ export const useAdminClient = () => useRequiredContext(AdminClientContext);
|
||||||
|
|
||||||
export async function initAdminClient(
|
export async function initAdminClient(
|
||||||
keycloak: Keycloak,
|
keycloak: Keycloak,
|
||||||
environment: BaseEnvironment,
|
environment: Environment,
|
||||||
) {
|
) {
|
||||||
const adminClient = new KeycloakAdminClient();
|
const adminClient = new KeycloakAdminClient();
|
||||||
|
|
||||||
adminClient.setConfig({ realmName: environment.realm });
|
adminClient.setConfig({ realmName: environment.realm });
|
||||||
adminClient.baseUrl = environment.authUrl;
|
adminClient.baseUrl = environment.authServerUrl;
|
||||||
adminClient.registerTokenProvider({
|
adminClient.registerTokenProvider({
|
||||||
async getAccessToken() {
|
async getAccessToken() {
|
||||||
try {
|
try {
|
||||||
|
|
33
js/apps/admin-ui/src/environment.ts
Normal file
33
js/apps/admin-ui/src/environment.ts
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import {
|
||||||
|
getInjectedEnvironment,
|
||||||
|
type BaseEnvironment,
|
||||||
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
|
|
||||||
|
export type Environment = BaseEnvironment & {
|
||||||
|
/** The URL to the base of the Admin Console. */
|
||||||
|
consoleBaseUrl: string;
|
||||||
|
/** The name of the master realm. */
|
||||||
|
masterRealm: string;
|
||||||
|
/** The version hash of the auth server. */
|
||||||
|
resourceVersion: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
// During development the realm can be passed as a query parameter when redirecting back from Keycloak.
|
||||||
|
const realm =
|
||||||
|
new URLSearchParams(window.location.search).get("realm") || "master";
|
||||||
|
|
||||||
|
const defaultEnvironment: Environment = {
|
||||||
|
// Base environment variables
|
||||||
|
authServerUrl: "http://localhost:8180",
|
||||||
|
realm: realm,
|
||||||
|
clientId: "security-admin-console-v2",
|
||||||
|
resourceUrl: "http://localhost:8080",
|
||||||
|
logo: "/logo.svg",
|
||||||
|
logoUrl: "",
|
||||||
|
// Admin Console specific environment variables
|
||||||
|
consoleBaseUrl: "/admin/master/console/",
|
||||||
|
masterRealm: "master",
|
||||||
|
resourceVersion: "unknown",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const environment = getInjectedEnvironment(defaultEnvironment);
|
|
@ -1,7 +1,8 @@
|
||||||
import { createInstance } from "i18next";
|
import { createInstance } from "i18next";
|
||||||
import HttpBackend from "i18next-http-backend";
|
import HttpBackend from "i18next-http-backend";
|
||||||
import { initReactI18next } from "react-i18next";
|
import { initReactI18next } from "react-i18next";
|
||||||
import { environment } from "@keycloak/keycloak-ui-shared";
|
|
||||||
|
import { environment } from "../environment";
|
||||||
import { joinPath } from "../utils/joinPath";
|
import { joinPath } from "../utils/joinPath";
|
||||||
|
|
||||||
type KeyValue = { key: string; value: string };
|
type KeyValue = { key: string; value: string };
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
import { fetchWithError } from "@keycloak/keycloak-admin-client";
|
import { fetchWithError } from "@keycloak/keycloak-admin-client";
|
||||||
import type IdentityProviderRepresentation from "@keycloak/keycloak-admin-client/lib/defs/identityProviderRepresentation";
|
import type IdentityProviderRepresentation from "@keycloak/keycloak-admin-client/lib/defs/identityProviderRepresentation";
|
||||||
import { FormGroup, Title } from "@patternfly/react-core";
|
|
||||||
import { useFormContext } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import {
|
import {
|
||||||
AdminEnvironment,
|
|
||||||
FormErrorText,
|
FormErrorText,
|
||||||
HelpItem,
|
HelpItem,
|
||||||
TextControl,
|
TextControl,
|
||||||
useEnvironment,
|
useEnvironment,
|
||||||
} from "@keycloak/keycloak-ui-shared";
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
|
import { FormGroup, Title } from "@patternfly/react-core";
|
||||||
|
import { useFormContext } from "react-hook-form";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import { useAdminClient } from "../../admin-client";
|
import { useAdminClient } from "../../admin-client";
|
||||||
import { FileUploadForm } from "../../components/json-file-upload/FileUploadForm";
|
import { FileUploadForm } from "../../components/json-file-upload/FileUploadForm";
|
||||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||||
|
import type { Environment } from "../../environment";
|
||||||
import { addTrailingSlash } from "../../util";
|
import { addTrailingSlash } from "../../util";
|
||||||
import { getAuthorizationHeaders } from "../../utils/getAuthorizationHeaders";
|
import { getAuthorizationHeaders } from "../../utils/getAuthorizationHeaders";
|
||||||
import { DiscoveryEndpointField } from "../component/DiscoveryEndpointField";
|
import { DiscoveryEndpointField } from "../component/DiscoveryEndpointField";
|
||||||
|
@ -24,7 +25,7 @@ type FormFields = IdentityProviderRepresentation & {
|
||||||
|
|
||||||
export const SamlConnectSettings = () => {
|
export const SamlConnectSettings = () => {
|
||||||
const { adminClient } = useAdminClient();
|
const { adminClient } = useAdminClient();
|
||||||
const { environment } = useEnvironment<AdminEnvironment>();
|
const { environment } = useEnvironment<Environment>();
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const id = "saml";
|
const id = "saml";
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
import { FormGroup } from "@patternfly/react-core";
|
|
||||||
import { useFormContext, useWatch } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import {
|
import {
|
||||||
HelpItem,
|
HelpItem,
|
||||||
TextControl,
|
TextControl,
|
||||||
useEnvironment,
|
useEnvironment,
|
||||||
} from "@keycloak/keycloak-ui-shared";
|
} from "@keycloak/keycloak-ui-shared";
|
||||||
|
import { FormGroup } from "@patternfly/react-core";
|
||||||
|
import { useFormContext, useWatch } from "react-hook-form";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import { FormattedLink } from "../../components/external-link/FormattedLink";
|
import { FormattedLink } from "../../components/external-link/FormattedLink";
|
||||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||||
|
import type { Environment } from "../../environment";
|
||||||
import { DisplayOrder } from "../component/DisplayOrder";
|
import { DisplayOrder } from "../component/DisplayOrder";
|
||||||
import { RedirectUrl } from "../component/RedirectUrl";
|
import { RedirectUrl } from "../component/RedirectUrl";
|
||||||
|
|
||||||
|
@ -22,7 +24,7 @@ export const SamlGeneralSettings = ({
|
||||||
}: SamlGeneralSettingsProps) => {
|
}: SamlGeneralSettingsProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { realm } = useRealm();
|
const { realm } = useRealm();
|
||||||
const { environment } = useEnvironment();
|
const { environment } = useEnvironment<Environment>();
|
||||||
|
|
||||||
const { control } = useFormContext();
|
const { control } = useFormContext();
|
||||||
const alias = useWatch({ control, name: "alias" });
|
const alias = useWatch({ control, name: "alias" });
|
||||||
|
@ -54,7 +56,7 @@ export const SamlGeneralSettings = ({
|
||||||
>
|
>
|
||||||
<FormattedLink
|
<FormattedLink
|
||||||
title={t("samlEndpointsLabel")}
|
title={t("samlEndpointsLabel")}
|
||||||
href={`${environment.authUrl}/realms/${realm}/broker/${alias}/endpoint/descriptor`}
|
href={`${environment.authServerUrl}/realms/${realm}/broker/${alias}/endpoint/descriptor`}
|
||||||
isInline
|
isInline
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { fetchWithError } from "@keycloak/keycloak-admin-client";
|
import { fetchWithError } from "@keycloak/keycloak-admin-client";
|
||||||
import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
|
import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
|
||||||
import { UserProfileConfig } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
import { UserProfileConfig } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
||||||
import { AdminEnvironment, useEnvironment } from "@keycloak/keycloak-ui-shared";
|
import { useEnvironment } from "@keycloak/keycloak-ui-shared";
|
||||||
import {
|
import {
|
||||||
AlertVariant,
|
AlertVariant,
|
||||||
ButtonVariant,
|
ButtonVariant,
|
||||||
|
@ -16,6 +16,7 @@ import { useEffect, useState } from "react";
|
||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import { useAdminClient } from "../admin-client";
|
import { useAdminClient } from "../admin-client";
|
||||||
import { useAlerts } from "../components/alert/Alerts";
|
import { useAlerts } from "../components/alert/Alerts";
|
||||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||||
|
@ -29,6 +30,7 @@ import { useRealms } from "../context/RealmsContext";
|
||||||
import { useAccess } from "../context/access/Access";
|
import { useAccess } from "../context/access/Access";
|
||||||
import { useRealm } from "../context/realm-context/RealmContext";
|
import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
import { toDashboard } from "../dashboard/routes/Dashboard";
|
import { toDashboard } from "../dashboard/routes/Dashboard";
|
||||||
|
import type { Environment } from "../environment";
|
||||||
import helpUrls from "../help-urls";
|
import helpUrls from "../help-urls";
|
||||||
import { convertFormValuesToObject, convertToFormValues } from "../util";
|
import { convertFormValuesToObject, convertToFormValues } from "../util";
|
||||||
import { getAuthorizationHeaders } from "../utils/getAuthorizationHeaders";
|
import { getAuthorizationHeaders } from "../utils/getAuthorizationHeaders";
|
||||||
|
@ -74,7 +76,7 @@ const RealmSettingsHeader = ({
|
||||||
refresh,
|
refresh,
|
||||||
}: RealmSettingsHeaderProps) => {
|
}: RealmSettingsHeaderProps) => {
|
||||||
const { adminClient } = useAdminClient();
|
const { adminClient } = useAdminClient();
|
||||||
const { environment } = useEnvironment<AdminEnvironment>();
|
const { environment } = useEnvironment<Environment>();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { refresh: refreshRealms } = useRealms();
|
const { refresh: refreshRealms } = useRealms();
|
||||||
const { addAlert, addError } = useAlerts();
|
const { addAlert, addError } = useAlerts();
|
||||||
|
|
|
@ -49,7 +49,7 @@ export const KeycloakProvider = <T extends BaseEnvironment>({
|
||||||
const [error, setError] = useState<unknown>();
|
const [error, setError] = useState<unknown>();
|
||||||
const keycloak = useMemo(() => {
|
const keycloak = useMemo(() => {
|
||||||
const keycloak = new Keycloak({
|
const keycloak = new Keycloak({
|
||||||
url: environment.authUrl,
|
url: environment.authServerUrl,
|
||||||
realm: environment.realm,
|
realm: environment.realm,
|
||||||
clientId: environment.clientId,
|
clientId: environment.clientId,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,109 +1,33 @@
|
||||||
export const DEFAULT_REALM = "master";
|
/** The base environment variables that are shared between the Admin and Account Consoles. */
|
||||||
|
|
||||||
export type Feature = {
|
|
||||||
isRegistrationEmailAsUsername: boolean;
|
|
||||||
isEditUserNameAllowed: boolean;
|
|
||||||
isInternationalizationEnabled: boolean;
|
|
||||||
isLinkedAccountsEnabled: boolean;
|
|
||||||
isEventsEnabled: boolean;
|
|
||||||
isMyResourcesEnabled: boolean;
|
|
||||||
isTotpConfigured: boolean;
|
|
||||||
deleteAccountAllowed: boolean;
|
|
||||||
updateEmailFeatureEnabled: boolean;
|
|
||||||
updateEmailActionEnabled: boolean;
|
|
||||||
isViewGroupsEnabled: boolean;
|
|
||||||
isOid4VciEnabled: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type BaseEnvironment = {
|
export type BaseEnvironment = {
|
||||||
/** The URL to the root of the auth server. */
|
/**
|
||||||
authUrl: string;
|
* The URL to the root of the Keycloak server, this is **NOT** always equivalent to the URL of the Admin Console.
|
||||||
/** The URL to the root of the account console. */
|
* For example, the Keycloak server could be hosted on `auth.example.com` and Admin Console may be hosted on `admin.example.com`.
|
||||||
baseUrl: string;
|
*
|
||||||
/** The realm used to authenticate the user to the Account Console. */
|
* @see {@link https://www.keycloak.org/server/hostname#_administration_console}
|
||||||
|
*/
|
||||||
|
authServerUrl: string;
|
||||||
|
/** The identifier of the realm used to authenticate the user. */
|
||||||
realm: string;
|
realm: string;
|
||||||
/** The identifier of the client used to authenticate the user to the Account Console. */
|
/** The identifier of the client used to authenticate the user. */
|
||||||
clientId: string;
|
clientId: string;
|
||||||
/** The URL to resources such as the files in the `public` directory. */
|
/** The base URL of the resources. */
|
||||||
resourceUrl: string;
|
resourceUrl: string;
|
||||||
/** Indicates the src for the Brand image */
|
/** The source URL for the the logo image. */
|
||||||
logo: string;
|
logo: string;
|
||||||
/** Indicates the url to be followed when Brand image is clicked */
|
/** The URL to be followed when the logo is clicked. */
|
||||||
logoUrl: string;
|
logoUrl: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AdminEnvironment = BaseEnvironment & {
|
|
||||||
/** The URL to the root of the auth server. */
|
|
||||||
authServerUrl: string;
|
|
||||||
/** The name of the master realm. */
|
|
||||||
masterRealm: string;
|
|
||||||
/** The URL to the base of the Admin UI. */
|
|
||||||
consoleBaseUrl: string;
|
|
||||||
/** The version hash of the auth server. */
|
|
||||||
resourceVersion: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type AccountEnvironment = BaseEnvironment & {
|
|
||||||
/** The locale of the user */
|
|
||||||
locale: string;
|
|
||||||
/** Feature flags */
|
|
||||||
features: Feature;
|
|
||||||
/** Name of the referrer application in the back link */
|
|
||||||
referrerName?: string;
|
|
||||||
/** UR to the referrer application in the back link */
|
|
||||||
referrerUrl?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
// During development the realm can be passed as a query parameter when redirecting back from Keycloak.
|
|
||||||
const realm =
|
|
||||||
new URLSearchParams(window.location.search).get("realm") ||
|
|
||||||
location.pathname.match("/realms/(.*?)/account")?.[1];
|
|
||||||
|
|
||||||
const defaultEnvironment: AdminEnvironment & AccountEnvironment = {
|
|
||||||
authUrl: "http://localhost:8180",
|
|
||||||
authServerUrl: "http://localhost:8180",
|
|
||||||
baseUrl: `http://localhost:8180/realms/${realm ?? DEFAULT_REALM}/account/`,
|
|
||||||
realm: realm ?? DEFAULT_REALM,
|
|
||||||
clientId: "security-admin-console-v2",
|
|
||||||
resourceUrl: "http://localhost:8080",
|
|
||||||
logo: "/logo.svg",
|
|
||||||
logoUrl: "/",
|
|
||||||
locale: "en",
|
|
||||||
consoleBaseUrl: "/admin/master/console/",
|
|
||||||
masterRealm: "master",
|
|
||||||
resourceVersion: "unknown",
|
|
||||||
features: {
|
|
||||||
isRegistrationEmailAsUsername: false,
|
|
||||||
isEditUserNameAllowed: true,
|
|
||||||
isInternationalizationEnabled: true,
|
|
||||||
isLinkedAccountsEnabled: true,
|
|
||||||
isEventsEnabled: true,
|
|
||||||
isMyResourcesEnabled: true,
|
|
||||||
isTotpConfigured: true,
|
|
||||||
deleteAccountAllowed: true,
|
|
||||||
updateEmailFeatureEnabled: true,
|
|
||||||
updateEmailActionEnabled: true,
|
|
||||||
isViewGroupsEnabled: true,
|
|
||||||
isOid4VciEnabled: false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Merge the default and injected environment variables together.
|
|
||||||
const environment = {
|
|
||||||
...defaultEnvironment,
|
|
||||||
...getInjectedEnvironment(),
|
|
||||||
};
|
|
||||||
|
|
||||||
export { environment };
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts the environment variables that are passed if the application is running as a Keycloak theme.
|
* Extracts the environment variables that are passed if the application is running as a Keycloak theme and combines them with the provided defaults.
|
||||||
* These variables are injected by Keycloak into the `index.ftl` as a script tag, the contents of which can be parsed as JSON.
|
* These variables are injected by Keycloak into the `index.ftl` as a script tag, the contents of which can be parsed as JSON.
|
||||||
|
*
|
||||||
|
* @argument defaults - The default values to fall to if a value is not present in the environment.
|
||||||
*/
|
*/
|
||||||
function getInjectedEnvironment(): Record<string, string | number | boolean> {
|
export function getInjectedEnvironment<T>(defaults: T): T {
|
||||||
const element = document.getElementById("environment");
|
const element = document.getElementById("environment");
|
||||||
|
let env = {} as T;
|
||||||
let env = {} as Record<string, string | number | boolean>;
|
|
||||||
|
|
||||||
// Attempt to parse the contents as JSON and return its value.
|
// Attempt to parse the contents as JSON and return its value.
|
||||||
try {
|
try {
|
||||||
|
@ -115,6 +39,6 @@ function getInjectedEnvironment(): Record<string, string | number | boolean> {
|
||||||
console.error("Unable to parse environment variables.");
|
console.error("Unable to parse environment variables.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, return an empty record.
|
// Return the merged environment variables with the defaults.
|
||||||
return env;
|
return { ...defaults, ...env };
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,8 @@ export {
|
||||||
type KeycloakContext,
|
type KeycloakContext,
|
||||||
} from "./context/KeycloakContext";
|
} from "./context/KeycloakContext";
|
||||||
export {
|
export {
|
||||||
environment,
|
getInjectedEnvironment,
|
||||||
type AccountEnvironment,
|
type BaseEnvironment,
|
||||||
type AdminEnvironment,
|
|
||||||
type Feature,
|
|
||||||
} from "./context/environment";
|
} from "./context/environment";
|
||||||
export { ContinueCancelModal } from "./continue-cancel/ContinueCancelModal";
|
export { ContinueCancelModal } from "./continue-cancel/ContinueCancelModal";
|
||||||
export {
|
export {
|
||||||
|
|
|
@ -105,7 +105,10 @@ public class AccountConsole implements AccountResourceProvider {
|
||||||
|
|
||||||
URI adminBaseUri = session.getContext().getUri(UrlType.ADMIN).getBaseUri();
|
URI adminBaseUri = session.getContext().getUri(UrlType.ADMIN).getBaseUri();
|
||||||
URI authUrl = uriInfo.getBaseUri();
|
URI authUrl = uriInfo.getBaseUri();
|
||||||
map.put("authUrl", authUrl.getPath().endsWith("/") ? authUrl : authUrl + "/");
|
var authServerUrl = authUrl.getPath().endsWith("/") ? authUrl : authUrl + "/";
|
||||||
|
// TODO: The 'authUrl' variable is deprecated and only exists to provide backwards compatibility for older themes, it should be removed in a future version.
|
||||||
|
map.put("authUrl", authServerUrl);
|
||||||
|
map.put("authServerUrl", authServerUrl);
|
||||||
map.put("baseUrl", accountBaseUrl.getPath().endsWith("/") ? accountBaseUrl : accountBaseUrl + "/");
|
map.put("baseUrl", accountBaseUrl.getPath().endsWith("/") ? accountBaseUrl : accountBaseUrl + "/");
|
||||||
map.put("realm", realm);
|
map.put("realm", realm);
|
||||||
map.put("clientId", Constants.ACCOUNT_CONSOLE_CLIENT_ID);
|
map.put("clientId", Constants.ACCOUNT_CONSOLE_CLIENT_ID);
|
||||||
|
|
|
@ -346,6 +346,7 @@ public class AdminConsole {
|
||||||
}
|
}
|
||||||
|
|
||||||
map.put("authServerUrl", authServerBaseUrl);
|
map.put("authServerUrl", authServerBaseUrl);
|
||||||
|
// TODO: The 'authUrl' variable is deprecated and only exists to provide backwards compatibility for older themes, it should be removed in a future version.
|
||||||
map.put("authUrl", adminBaseUrl);
|
map.put("authUrl", adminBaseUrl);
|
||||||
map.put("consoleBaseUrl", Urls.adminConsoleRoot(adminBaseUri, realm.getName()).getPath());
|
map.put("consoleBaseUrl", Urls.adminConsoleRoot(adminBaseUri, realm.getName()).getPath());
|
||||||
map.put("resourceUrl", Urls.themeRoot(adminBaseUri).getPath() + "/admin/" + theme.getName());
|
map.put("resourceUrl", Urls.themeRoot(adminBaseUri).getPath() + "/admin/" + theme.getName());
|
||||||
|
|
Loading…
Reference in a new issue