Use browser router for Account Console (#22192)
Closes #27442 Signed-off-by: Jon Koops <jonkoops@gmail.com>
This commit is contained in:
parent
be3e2fabc4
commit
7afd75ba08
14 changed files with 152 additions and 115 deletions
|
@ -1,4 +1,5 @@
|
||||||
import { defineConfig, devices } from "@playwright/test";
|
import { defineConfig, devices } from "@playwright/test";
|
||||||
|
import { getRootPath } from "./src/utils/getRootPath";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See https://playwright.dev/docs/test-configuration.
|
* See https://playwright.dev/docs/test-configuration.
|
||||||
|
@ -11,9 +12,7 @@ export default defineConfig({
|
||||||
workers: 1,
|
workers: 1,
|
||||||
reporter: process.env.CI ? [["github"], ["html"]] : "list",
|
reporter: process.env.CI ? [["github"], ["html"]] : "list",
|
||||||
use: {
|
use: {
|
||||||
baseURL: process.env.CI
|
baseURL: `http://localhost:8080${getRootPath()}`,
|
||||||
? "http://localhost:8080/realms/master/account/"
|
|
||||||
: "http://localhost:8080/",
|
|
||||||
trace: "on-first-retry",
|
trace: "on-first-retry",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
2
js/apps/account-ui/src/constants.ts
Normal file
2
js/apps/account-ui/src/constants.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export const DEFAULT_REALM = "master";
|
||||||
|
export const ROOT_PATH = "/realms/:realm/account";
|
|
@ -1,3 +1,6 @@
|
||||||
|
import { matchPath } from "react-router-dom";
|
||||||
|
import { DEFAULT_REALM, ROOT_PATH } from "./constants";
|
||||||
|
|
||||||
export type Feature = {
|
export type Feature = {
|
||||||
isRegistrationEmailAsUsername: boolean;
|
isRegistrationEmailAsUsername: boolean;
|
||||||
isEditUserNameAllowed: boolean;
|
isEditUserNameAllowed: boolean;
|
||||||
|
@ -31,11 +34,12 @@ export type Environment = {
|
||||||
features: Feature;
|
features: Feature;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The default environment, used during development.
|
// Detect the current realm from the URL.
|
||||||
const realm = new URLSearchParams(window.location.search).get("realm");
|
const match = matchPath(ROOT_PATH, location.pathname);
|
||||||
|
|
||||||
const defaultEnvironment: Environment = {
|
const defaultEnvironment: Environment = {
|
||||||
authUrl: "http://localhost:8180",
|
authUrl: "http://localhost:8180",
|
||||||
realm: realm || "master",
|
realm: match?.params.realm ?? DEFAULT_REALM,
|
||||||
clientId: "security-admin-console-v2",
|
clientId: "security-admin-console-v2",
|
||||||
resourceUrl: "http://localhost:8080",
|
resourceUrl: "http://localhost:8080",
|
||||||
logo: "/logo.svg",
|
logo: "/logo.svg",
|
||||||
|
|
|
@ -3,18 +3,22 @@ import "@patternfly/patternfly/patternfly-addons.css";
|
||||||
|
|
||||||
import { StrictMode } from "react";
|
import { StrictMode } from "react";
|
||||||
import { createRoot } from "react-dom/client";
|
import { createRoot } from "react-dom/client";
|
||||||
import { createHashRouter, RouterProvider } from "react-router-dom";
|
import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
||||||
|
|
||||||
|
import { environment } from "./environment";
|
||||||
import { i18n } from "./i18n";
|
import { i18n } from "./i18n";
|
||||||
import { routes } from "./routes";
|
import { routes } from "./routes";
|
||||||
|
import { getRootPath } from "./utils/getRootPath";
|
||||||
|
|
||||||
// Initialize required components before rendering app.
|
// Initialize required components before rendering app.
|
||||||
await i18n.init();
|
await i18n.init();
|
||||||
|
|
||||||
const router = createHashRouter(routes);
|
|
||||||
const container = document.getElementById("app");
|
const container = document.getElementById("app");
|
||||||
const root = createRoot(container!);
|
const root = createRoot(container!);
|
||||||
|
|
||||||
|
const basename = getRootPath(environment.realm);
|
||||||
|
const router = createBrowserRouter(routes, { basename });
|
||||||
|
|
||||||
root.render(
|
root.render(
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<RouterProvider router={router} />
|
<RouterProvider router={router} />
|
||||||
|
|
5
js/apps/account-ui/src/utils/getRootPath.ts
Normal file
5
js/apps/account-ui/src/utils/getRootPath.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import { generatePath } from "react-router-dom";
|
||||||
|
import { DEFAULT_REALM, ROOT_PATH } from "../constants";
|
||||||
|
|
||||||
|
export const getRootPath = (realm = DEFAULT_REALM) =>
|
||||||
|
generatePath(ROOT_PATH, { realm });
|
|
@ -1,18 +1,20 @@
|
||||||
import { expect, test } from "@playwright/test";
|
|
||||||
import {
|
|
||||||
createIdentityProvider,
|
|
||||||
deleteIdentityProvider,
|
|
||||||
createClient,
|
|
||||||
deleteClient,
|
|
||||||
inRealm,
|
|
||||||
findClientByClientId,
|
|
||||||
createRandomUserWithPassword,
|
|
||||||
deleteUser,
|
|
||||||
} from "../admin-client";
|
|
||||||
import groupsIdPClient from "../realms/groups-idp.json" assert { type: "json" };
|
|
||||||
import ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
|
import ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
|
||||||
import IdentityProviderRepresentation from "@keycloak/keycloak-admin-client/lib/defs/identityProviderRepresentation";
|
import IdentityProviderRepresentation from "@keycloak/keycloak-admin-client/lib/defs/identityProviderRepresentation";
|
||||||
import { randomUUID } from "crypto";
|
import { expect, test } from "@playwright/test";
|
||||||
|
import { randomUUID } from "node:crypto";
|
||||||
|
|
||||||
|
import {
|
||||||
|
createClient,
|
||||||
|
createIdentityProvider,
|
||||||
|
createRandomUserWithPassword,
|
||||||
|
deleteClient,
|
||||||
|
deleteIdentityProvider,
|
||||||
|
deleteUser,
|
||||||
|
findClientByClientId,
|
||||||
|
inRealm,
|
||||||
|
} from "../admin-client";
|
||||||
|
import groupsIdPClient from "../realms/groups-idp.json" assert { type: "json" };
|
||||||
|
import { getBaseUrl } from "../utils";
|
||||||
|
|
||||||
const realm = "groups";
|
const realm = "groups";
|
||||||
|
|
||||||
|
@ -30,7 +32,7 @@ test.describe("Account linking", () => {
|
||||||
groupIdPClientId = await createClient(
|
groupIdPClientId = await createClient(
|
||||||
groupsIdPClient as ClientRepresentation,
|
groupsIdPClient as ClientRepresentation,
|
||||||
);
|
);
|
||||||
const kc = process.env.KEYCLOAK_SERVER || "http://localhost:8080";
|
const baseUrl = getBaseUrl();
|
||||||
const idp: IdentityProviderRepresentation = {
|
const idp: IdentityProviderRepresentation = {
|
||||||
alias: "master-idp",
|
alias: "master-idp",
|
||||||
providerId: "oidc",
|
providerId: "oidc",
|
||||||
|
@ -39,12 +41,12 @@ test.describe("Account linking", () => {
|
||||||
clientId: "groups-idp",
|
clientId: "groups-idp",
|
||||||
clientSecret: "H0JaTc7VBu3HJR26vrzMxgidfJmgI5Dw",
|
clientSecret: "H0JaTc7VBu3HJR26vrzMxgidfJmgI5Dw",
|
||||||
validateSignature: "false",
|
validateSignature: "false",
|
||||||
tokenUrl: `${kc}/realms/master/protocol/openid-connect/token`,
|
tokenUrl: `${baseUrl}/realms/master/protocol/openid-connect/token`,
|
||||||
jwksUrl: `${kc}/realms/master/protocol/openid-connect/certs`,
|
jwksUrl: `${baseUrl}/realms/master/protocol/openid-connect/certs`,
|
||||||
issuer: `${kc}/realms/master`,
|
issuer: `${baseUrl}/realms/master`,
|
||||||
authorizationUrl: `${kc}/realms/master/protocol/openid-connect/auth`,
|
authorizationUrl: `${baseUrl}/realms/master/protocol/openid-connect/auth`,
|
||||||
logoutUrl: `${kc}/realms/master/protocol/openid-connect/logout`,
|
logoutUrl: `${baseUrl}/realms/master/protocol/openid-connect/logout`,
|
||||||
userInfoUrl: `${kc}/realms/master/protocol/openid-connect/userinfo`,
|
userInfoUrl: `${baseUrl}/realms/master/protocol/openid-connect/userinfo`,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,12 @@ import RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmR
|
||||||
import type { UserProfileConfig } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
import type { UserProfileConfig } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
|
||||||
import UserRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userRepresentation";
|
import UserRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userRepresentation";
|
||||||
|
|
||||||
|
import { DEFAULT_REALM } from "../src/constants";
|
||||||
|
import { getBaseUrl } from "./utils";
|
||||||
|
|
||||||
const adminClient = new KeycloakAdminClient({
|
const adminClient = new KeycloakAdminClient({
|
||||||
baseUrl: process.env.KEYCLOAK_SERVER || "http://127.0.0.1:8080",
|
baseUrl: getBaseUrl(),
|
||||||
realmName: "master",
|
realmName: DEFAULT_REALM,
|
||||||
});
|
});
|
||||||
|
|
||||||
await adminClient.auth({
|
await adminClient.auth({
|
||||||
|
@ -18,9 +21,12 @@ await adminClient.auth({
|
||||||
});
|
});
|
||||||
|
|
||||||
export async function useTheme() {
|
export async function useTheme() {
|
||||||
const masterRealm = await adminClient.realms.findOne({ realm: "master" });
|
const masterRealm = await adminClient.realms.findOne({
|
||||||
|
realm: DEFAULT_REALM,
|
||||||
|
});
|
||||||
|
|
||||||
await adminClient.realms.update(
|
await adminClient.realms.update(
|
||||||
{ realm: "master" },
|
{ realm: DEFAULT_REALM },
|
||||||
{ ...masterRealm, accountTheme: "keycloak.v3" },
|
{ ...masterRealm, accountTheme: "keycloak.v3" },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -76,7 +82,7 @@ export async function importUserProfile(
|
||||||
await adminClient.users.updateProfile({ ...userProfile, realm });
|
await adminClient.users.updateProfile({ ...userProfile, realm });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function enableLocalization(realm: string) {
|
export async function enableLocalization(realm = DEFAULT_REALM) {
|
||||||
const realmRepresentation = await adminClient.realms.findOne({ realm });
|
const realmRepresentation = await adminClient.realms.findOne({ realm });
|
||||||
await adminClient.realms.update(
|
await adminClient.realms.update(
|
||||||
{ realm },
|
{ realm },
|
||||||
|
@ -121,9 +127,9 @@ export async function getUserByUsername(username: string, realm: string) {
|
||||||
|
|
||||||
export async function deleteUser(username: string) {
|
export async function deleteUser(username: string) {
|
||||||
try {
|
try {
|
||||||
const users = await adminClient.users.find({ username, realm });
|
const users = await adminClient.users.find({ username });
|
||||||
const { id } = users[0];
|
const { id } = users[0];
|
||||||
await adminClient.users.del({ id: id!, realm });
|
await adminClient.users.del({ id: id! });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "@playwright/test";
|
||||||
|
import { getRootPath } from "../src/utils/getRootPath";
|
||||||
import { login } from "./login";
|
import { login } from "./login";
|
||||||
|
import { getAccountUrl, getAdminUrl } from "./utils";
|
||||||
|
|
||||||
test.describe("Applications test", () => {
|
test.describe("Applications test", () => {
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
// Sign out all devices before each test
|
// Sign out all devices before each test
|
||||||
await login(page, "admin", "admin", "master");
|
await login(page, "admin", "admin");
|
||||||
await page.getByTestId("accountSecurity").click();
|
await page.getByTestId("accountSecurity").click();
|
||||||
await page.getByTestId("account-security/device-activity").click();
|
await page.getByTestId("account-security/device-activity").click();
|
||||||
|
|
||||||
|
@ -19,7 +21,7 @@ test.describe("Applications test", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Single application", async ({ page }) => {
|
test("Single application", async ({ page }) => {
|
||||||
await login(page, "admin", "admin", "master");
|
await login(page, "admin", "admin");
|
||||||
|
|
||||||
await page.getByTestId("applications").click();
|
await page.getByTestId("applications").click();
|
||||||
|
|
||||||
|
@ -39,8 +41,8 @@ test.describe("Applications test", () => {
|
||||||
const page1 = await context1.newPage();
|
const page1 = await context1.newPage();
|
||||||
const page2 = await context2.newPage();
|
const page2 = await context2.newPage();
|
||||||
|
|
||||||
await login(page1, "admin", "admin", "master");
|
await login(page1, "admin", "admin");
|
||||||
await login(page2, "admin", "admin", "master");
|
await login(page2, "admin", "admin");
|
||||||
|
|
||||||
await page1.getByTestId("applications").click();
|
await page1.getByTestId("applications").click();
|
||||||
|
|
||||||
|
@ -62,15 +64,15 @@ test.describe("Applications test", () => {
|
||||||
"Skip this test if not running with regular Keycloak",
|
"Skip this test if not running with regular Keycloak",
|
||||||
);
|
);
|
||||||
|
|
||||||
await login(page, "admin", "admin", "master");
|
await login(page, "admin", "admin");
|
||||||
|
|
||||||
// go to admin console
|
// go to admin console
|
||||||
await page.goto("/");
|
await page.goto("/");
|
||||||
await expect(page).toHaveURL("http://localhost:8080/admin/master/console/");
|
await expect(page).toHaveURL(getAdminUrl());
|
||||||
await page.waitForURL("http://localhost:8080/admin/master/console/");
|
await page.waitForURL(getAdminUrl());
|
||||||
|
|
||||||
await page.goto("/realms/master/account");
|
await page.goto(getRootPath());
|
||||||
await page.waitForURL("http://localhost:8080/realms/master/account/");
|
await page.waitForURL(getAccountUrl());
|
||||||
|
|
||||||
await page.getByTestId("applications").click();
|
await page.getByTestId("applications").click();
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
import { Page } from "@playwright/test";
|
import { Page } from "@playwright/test";
|
||||||
|
import { DEFAULT_REALM } from "../src/constants";
|
||||||
|
import { getRootPath } from "../src/utils/getRootPath";
|
||||||
|
|
||||||
export const login = async (
|
export const login = async (
|
||||||
page: Page,
|
page: Page,
|
||||||
username: string,
|
username: string,
|
||||||
password: string,
|
password: string,
|
||||||
realm?: string,
|
realm = DEFAULT_REALM,
|
||||||
) => {
|
) => {
|
||||||
if (realm)
|
const rootPath = getRootPath(realm);
|
||||||
await page.goto(
|
|
||||||
process.env.CI ? `/realms/${realm}/account` : `/?realm=${realm}`,
|
await page.goto(rootPath);
|
||||||
);
|
|
||||||
await page.getByLabel("Username").fill(username);
|
await page.getByLabel("Username").fill(username);
|
||||||
await page.getByLabel("Password", { exact: true }).fill(password);
|
await page.getByLabel("Password", { exact: true }).fill(password);
|
||||||
await page.getByRole("button", { name: "Sign In" }).click();
|
await page.getByRole("button", { name: "Sign In" }).click();
|
||||||
|
|
|
@ -18,7 +18,7 @@ test.describe("Personal info page", () => {
|
||||||
test("sets basic information", async ({ page }) => {
|
test("sets basic information", async ({ page }) => {
|
||||||
user = await createRandomUserWithPassword("user-" + randomUUID(), "pwd");
|
user = await createRandomUserWithPassword("user-" + randomUUID(), "pwd");
|
||||||
|
|
||||||
await login(page, user, "pwd", "master");
|
await login(page, user, "pwd");
|
||||||
|
|
||||||
await page.getByTestId("email").fill(`${user}@somewhere.com`);
|
await page.getByTestId("email").fill(`${user}@somewhere.com`);
|
||||||
await page.getByTestId("firstName").fill("Erik");
|
await page.getByTestId("firstName").fill("Erik");
|
||||||
|
@ -84,7 +84,7 @@ test.describe("Personal info with userprofile enabled", async () => {
|
||||||
|
|
||||||
// skip currently the locale is not part of the response
|
// skip currently the locale is not part of the response
|
||||||
test.describe.skip("Realm localization", async () => {
|
test.describe.skip("Realm localization", async () => {
|
||||||
test.beforeAll(() => enableLocalization("master"));
|
test.beforeAll(() => enableLocalization());
|
||||||
|
|
||||||
test("change locale", async ({ page }) => {
|
test("change locale", async ({ page }) => {
|
||||||
const user = await createRandomUserWithPassword(
|
const user = await createRandomUserWithPassword(
|
||||||
|
@ -92,7 +92,7 @@ test.describe.skip("Realm localization", async () => {
|
||||||
"pwd",
|
"pwd",
|
||||||
);
|
);
|
||||||
|
|
||||||
await login(page, user, "pwd", "master");
|
await login(page, user, "pwd");
|
||||||
await page
|
await page
|
||||||
.locator("div")
|
.locator("div")
|
||||||
.filter({ hasText: /^Deutsch$/ })
|
.filter({ hasText: /^Deutsch$/ })
|
||||||
|
|
13
js/apps/account-ui/test/utils.ts
Normal file
13
js/apps/account-ui/test/utils.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { getRootPath } from "../src/utils/getRootPath";
|
||||||
|
|
||||||
|
export function getBaseUrl(): string {
|
||||||
|
return process.env.KEYCLOAK_SERVER ?? "http://localhost:8080";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAccountUrl() {
|
||||||
|
return getBaseUrl() + getRootPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAdminUrl() {
|
||||||
|
return getBaseUrl() + "/admin/master/console/";
|
||||||
|
}
|
|
@ -4,6 +4,8 @@ import { defineConfig, loadEnv } from "vite";
|
||||||
import { checker } from "vite-plugin-checker";
|
import { checker } from "vite-plugin-checker";
|
||||||
import dts from "vite-plugin-dts";
|
import dts from "vite-plugin-dts";
|
||||||
|
|
||||||
|
import { getRootPath } from "./src/utils/getRootPath";
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig(({ mode }) => {
|
export default defineConfig(({ mode }) => {
|
||||||
const env = loadEnv(mode, process.cwd(), "");
|
const env = loadEnv(mode, process.cwd(), "");
|
||||||
|
@ -26,6 +28,7 @@ export default defineConfig(({ mode }) => {
|
||||||
base: "",
|
base: "",
|
||||||
server: {
|
server: {
|
||||||
port: 8080,
|
port: 8080,
|
||||||
|
open: getRootPath(),
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
...lib,
|
...lib,
|
||||||
|
|
|
@ -18,7 +18,7 @@ describe("Masthead tests", () => {
|
||||||
it("Go to account console and back to admin console", () => {
|
it("Go to account console and back to admin console", () => {
|
||||||
sidebarPage.waitForPageLoad();
|
sidebarPage.waitForPageLoad();
|
||||||
masthead.accountManagement();
|
masthead.accountManagement();
|
||||||
cy.url().should("contain", "/realms/master/account/");
|
cy.url().should("contain", "/realms/master/account");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign out reachs to log in screen", () => {
|
it("Sign out reachs to log in screen", () => {
|
||||||
|
|
|
@ -92,76 +92,72 @@ public class AccountConsole implements AccountResourceProvider {
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@NoCache
|
@NoCache
|
||||||
|
@Path("{any:.*}")
|
||||||
public Response getMainPage() throws IOException, FreeMarkerException {
|
public Response getMainPage() throws IOException, FreeMarkerException {
|
||||||
UriInfo uriInfo = session.getContext().getUri(UrlType.FRONTEND);
|
UriInfo uriInfo = session.getContext().getUri(UrlType.FRONTEND);
|
||||||
URI accountBaseUrl = uriInfo.getBaseUriBuilder().path(RealmsResource.class).path(realm.getName())
|
URI accountBaseUrl = uriInfo.getBaseUriBuilder().path(RealmsResource.class).path(realm.getName())
|
||||||
.path(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).path("/").build(realm);
|
.path(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).path("/").build(realm);
|
||||||
|
|
||||||
if (!session.getContext().getUri().getRequestUri().getPath().endsWith("/")) {
|
Map<String, Object> map = new HashMap<>();
|
||||||
UriBuilder redirectUri = session.getContext().getUri().getRequestUriBuilder().uri(accountBaseUrl);
|
|
||||||
return Response.status(302).location(redirectUri.build()).build();
|
|
||||||
} else {
|
|
||||||
Map<String, Object> map = new HashMap<>();
|
|
||||||
|
|
||||||
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 + "/");
|
map.put("authUrl", authUrl.getPath().endsWith("/") ? authUrl : authUrl + "/");
|
||||||
map.put("baseUrl", accountBaseUrl);
|
map.put("baseUrl", 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);
|
||||||
map.put("resourceUrl", Urls.themeRoot(authUrl).getPath() + "/" + Constants.ACCOUNT_MANAGEMENT_CLIENT_ID + "/" + theme.getName());
|
map.put("resourceUrl", Urls.themeRoot(authUrl).getPath() + "/" + Constants.ACCOUNT_MANAGEMENT_CLIENT_ID + "/" + theme.getName());
|
||||||
map.put("resourceCommonUrl", Urls.themeRoot(adminBaseUri).getPath() + "/common/keycloak");
|
map.put("resourceCommonUrl", Urls.themeRoot(adminBaseUri).getPath() + "/common/keycloak");
|
||||||
map.put("resourceVersion", Version.RESOURCES_VERSION);
|
map.put("resourceVersion", Version.RESOURCES_VERSION);
|
||||||
|
|
||||||
String[] referrer = getReferrer();
|
|
||||||
if (referrer != null) {
|
|
||||||
map.put("referrer", referrer[0]);
|
|
||||||
map.put("referrerName", referrer[1]);
|
|
||||||
map.put("referrer_uri", referrer[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
UserModel user = null;
|
|
||||||
if (auth != null) user = auth.getUser();
|
|
||||||
Locale locale = session.getContext().resolveLocale(user);
|
|
||||||
map.put("locale", locale.toLanguageTag());
|
|
||||||
Properties messages = theme.getEnhancedMessages(realm, locale);
|
|
||||||
map.put("msg", new MessageFormatterMethod(locale, messages));
|
|
||||||
map.put("msgJSON", messagesToJsonString(messages));
|
|
||||||
map.put("supportedLocales", supportedLocales(messages));
|
|
||||||
map.put("properties", theme.getProperties());
|
|
||||||
map.put("theme", (Function<String, String>) file -> {
|
|
||||||
try {
|
|
||||||
final InputStream resource = theme.getResourceAsStream(file);
|
|
||||||
return new Scanner(resource, "UTF-8").useDelimiter("\\A").next();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("could not load file", e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
map.put("isAuthorizationEnabled", Profile.isFeatureEnabled(Profile.Feature.AUTHORIZATION));
|
String[] referrer = getReferrer();
|
||||||
|
if (referrer != null) {
|
||||||
boolean deleteAccountAllowed = false;
|
map.put("referrer", referrer[0]);
|
||||||
boolean isViewGroupsEnabled= false;
|
map.put("referrerName", referrer[1]);
|
||||||
if (user != null) {
|
map.put("referrer_uri", referrer[2]);
|
||||||
RoleModel deleteAccountRole = realm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).getRole(AccountRoles.DELETE_ACCOUNT);
|
|
||||||
deleteAccountAllowed = deleteAccountRole != null && user.hasRole(deleteAccountRole) && realm.getRequiredActionProviderByAlias(DeleteAccount.PROVIDER_ID).isEnabled();
|
|
||||||
RoleModel viewGrouRole = realm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).getRole(AccountRoles.VIEW_GROUPS);
|
|
||||||
isViewGroupsEnabled = viewGrouRole != null && user.hasRole(viewGrouRole);
|
|
||||||
}
|
|
||||||
|
|
||||||
map.put("deleteAccountAllowed", deleteAccountAllowed);
|
|
||||||
|
|
||||||
map.put("isViewGroupsEnabled", isViewGroupsEnabled);
|
|
||||||
|
|
||||||
map.put("updateEmailFeatureEnabled", Profile.isFeatureEnabled(Profile.Feature.UPDATE_EMAIL));
|
|
||||||
RequiredActionProviderModel updateEmailActionProvider = realm.getRequiredActionProviderByAlias(UserModel.RequiredAction.UPDATE_EMAIL.name());
|
|
||||||
map.put("updateEmailActionEnabled", updateEmailActionProvider != null && updateEmailActionProvider.isEnabled());
|
|
||||||
|
|
||||||
FreeMarkerProvider freeMarkerUtil = session.getProvider(FreeMarkerProvider.class);
|
|
||||||
String result = freeMarkerUtil.processTemplate(map, "index.ftl", theme);
|
|
||||||
Response.ResponseBuilder builder = Response.status(Response.Status.OK).type(MediaType.TEXT_HTML_UTF_8).language(Locale.ENGLISH).entity(result);
|
|
||||||
return builder.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UserModel user = null;
|
||||||
|
if (auth != null) user = auth.getUser();
|
||||||
|
Locale locale = session.getContext().resolveLocale(user);
|
||||||
|
map.put("locale", locale.toLanguageTag());
|
||||||
|
Properties messages = theme.getEnhancedMessages(realm, locale);
|
||||||
|
map.put("msg", new MessageFormatterMethod(locale, messages));
|
||||||
|
map.put("msgJSON", messagesToJsonString(messages));
|
||||||
|
map.put("supportedLocales", supportedLocales(messages));
|
||||||
|
map.put("properties", theme.getProperties());
|
||||||
|
map.put("theme", (Function<String, String>) file -> {
|
||||||
|
try {
|
||||||
|
final InputStream resource = theme.getResourceAsStream(file);
|
||||||
|
return new Scanner(resource, "UTF-8").useDelimiter("\\A").next();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("could not load file", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
map.put("isAuthorizationEnabled", Profile.isFeatureEnabled(Profile.Feature.AUTHORIZATION));
|
||||||
|
|
||||||
|
boolean deleteAccountAllowed = false;
|
||||||
|
boolean isViewGroupsEnabled= false;
|
||||||
|
if (user != null) {
|
||||||
|
RoleModel deleteAccountRole = realm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).getRole(AccountRoles.DELETE_ACCOUNT);
|
||||||
|
deleteAccountAllowed = deleteAccountRole != null && user.hasRole(deleteAccountRole) && realm.getRequiredActionProviderByAlias(DeleteAccount.PROVIDER_ID).isEnabled();
|
||||||
|
RoleModel viewGrouRole = realm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).getRole(AccountRoles.VIEW_GROUPS);
|
||||||
|
isViewGroupsEnabled = viewGrouRole != null && user.hasRole(viewGrouRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
map.put("deleteAccountAllowed", deleteAccountAllowed);
|
||||||
|
|
||||||
|
map.put("isViewGroupsEnabled", isViewGroupsEnabled);
|
||||||
|
|
||||||
|
map.put("updateEmailFeatureEnabled", Profile.isFeatureEnabled(Profile.Feature.UPDATE_EMAIL));
|
||||||
|
RequiredActionProviderModel updateEmailActionProvider = realm.getRequiredActionProviderByAlias(UserModel.RequiredAction.UPDATE_EMAIL.name());
|
||||||
|
map.put("updateEmailActionEnabled", updateEmailActionProvider != null && updateEmailActionProvider.isEnabled());
|
||||||
|
|
||||||
|
FreeMarkerProvider freeMarkerUtil = session.getProvider(FreeMarkerProvider.class);
|
||||||
|
String result = freeMarkerUtil.processTemplate(map, "index.ftl", theme);
|
||||||
|
Response.ResponseBuilder builder = Response.status(Response.Status.OK).type(MediaType.TEXT_HTML_UTF_8).language(Locale.ENGLISH).entity(result);
|
||||||
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, String> supportedLocales(Properties messages) {
|
private Map<String, String> supportedLocales(Properties messages) {
|
||||||
|
|
Loading…
Reference in a new issue